Snowflake Cortex Agents Deep Search
Give a Snowflake Cortex Agent Deep Search as three custom tools. The user describes the rows they need, the agent shows how the request was read and the most it can cost, and after a yes SpecStream returns every match on the live web as a table. Source URL and read time on every value.
SpecStream for Snowflake Cortex Agents Deep SearchAgent frameworks & buildersWhat you need
- A Snowflake account where you can use the
ACCOUNTADMINrole. Creating an External Access Integration needs theCREATE INTEGRATIONprivilege on the account. - A SpecStream API key with a total spending limit. New accounts start with $10 of credit, no card. Create an account.
- 1
1. Create a SpecStream API key
In the SpecStream workspace, open API keys and click New key. Name it for Snowflake and check Authorize paid work under Permissions: starting a search needs it.
Enter a Total spending limit, the most the agent may spend across all its calls, then click Create key. Copy the key from Copy your key now, because it is shown once.
- 2
2. Create the role, the External Access and the quote table
In a Snowsight worksheet, run this as
ACCOUNTADMIN. Put your key in place ofYOUR_SPECSTREAM_KEY. Snowflake stores it encrypted, and no query prints it. Each statement isIF NOT EXISTS, so if you already followed the Cortex Agents web search guide, it keeps your role, secret and integration.The
deep_search_quotestable keeps each price the agent gets. The start procedure reads the amount to approve from this table, never from the model.Snowflake worksheet - 3
3. Create the price procedure
price_deep_searchsends the request toPOST /v1/parse, which returnsread_back, the request in plain words, andast_hash. It then asksPOST /v1/capacity/quotesfor the price of that many rows and keeps the quote in the table. The quote'smaximum_centsis the most the search can cost. Pricing spends nothing, and the quote stays open for 30 minutes.It is a procedure, not a function, because it writes to the table.
EXECUTE AS OWNERlets it write there while the agent's role has no access to the table.Snowflake worksheet - 4
4. Create the start procedure
start_deep_searchtakes only thequote_id. It reads the quote's hash and maximum from the table, deletes the row so the quote is used once, and approves it withPOST /v1/capacity/executions. The quote's own ID is the request key, so a repeated call cannot start a second search.Snowflake worksheet - 5
5. Create the read function
read_deep_searchreads the find's status fromGET /v1/finds/{id}and the first 10 rows fromGET /v1/finds/{id}/rowswithformat=markdown: one table with a column for each fact the user asked for and a Source column. It only reads, so it is a function.Snowflake worksheet - 6
6. Try the three tools from SQL
The first call spends nothing. The second starts a search and spends up to the maximum the first one returned, so run it only for a request you want.
Snowflake worksheet - 7
7. Create the agent
Register the three tools as custom tools. Each
tool_specof typegenericgives the agent the tool's inputs, andtool_resourcesmaps it to its procedure or function and the warehouse that runs it. The instructions make the agent show the price and wait for a yes before it starts anything. The specification is YAML; this one is written as JSON, which YAML reads as it is.Snowflake worksheet - 8
8. Ask the agent
In Snowsight, open AI & ML, then Agents, and select DEEP_SEARCH_AGENT. Ask for rows in the agent playground and say how many. The agent shows how it read the request and the maximum price. Approve it, and the agent starts the search. A search runs for minutes; ask for the rows later, in the same conversation.
Agent playground
What the agent gets back
Deep Search turns one request in plain words into rows from the live web: companies, local businesses, people, grants, tenders, papers and other records, each with the facts the user asked for. Every row meets the conditions in the request.
read_deep_search hands the model a Markdown table. Its Source column holds the page most of the row's values were read on, and a value read on another page carries its own link.
For the full rows in your own code, call GET /v1/finds/{id}/rows without format: each row's cells hold the column's label, the value as display, and a provenance with source_url and observed_at. format=csv returns the same page as one CSV text. Follow next_cursor for the rows past the first page.
How spending stays under control
- Pricing spends nothing.
price_deep_searchonly reads the request and returns a quote. - The user approves the price. The agent's instructions make it show the maximum and wait for a yes before
start_deep_search. - The model cannot change the amount.
confirm_max_centscomes from the quote table, and a search never costs more than it. - The row limit holds in code.
price_deep_searchcaps the rows at 100 whatever number the model sends. - The key has a ceiling. Its total spending limit caps what the agent can spend across all calls, and a call over it is refused with
403. - The role gets
USAGEon the two procedures and the function, not on the integration, the secret or the table, so its users cannot read the key or reach another host.
If something doesn't work
| What you see | What to do |
|---|---|
price_deep_search returns a status other than runnable | The request needs more detail, such as the place or the facts to bring back. The agent asks the user and prices it again. |
Unknown, used or expired quote | The quote was used, or it is more than 30 minutes old. Price the request again. |
status 402 | The balance is too low for the approved maximum. Add balance in your SpecStream workspace. |
status 403 | The key has no Authorize paid work, or the search would go over its total spending limit. Make a key with it, then run ALTER SECRET specstream.tools.specstream_api_key SET SECRET_STRING = 'NEW_KEY';. |
status 401 | The key in the secret is unknown, expired or revoked. Create a new key and run ALTER SECRET. |
A Python error that names api.specstream.ai | The network rule does not allow the host. Check it with SHOW NETWORK RULES and DESCRIBE EXTERNAL ACCESS INTEGRATION specstream_api_access. |
Cost
Pricing a request, reading rows and checking a search's status cost nothing. A search is charged per delivered row: 5¢, 15¢ or $1 a row depending on how much each row needs, plus 5¢ for a person's email and 15¢ for a phone when the request asks for them. Duplicates and rows a page contradicts are not charged, a search that finds nothing costs nothing, and no search costs more than the maximum the user approved. Snowflake bills the warehouse that runs the tools, as it bills any warehouse. The rates are on pricing, and balance and billing covers quotes.
Web search and page reading too
For one fact or the text of a page, the Cortex Agents web search guide adds web_search and read_pages tools on the same integration. The Search API is $5 per 1,000 searches of up to 10 results and the Extract API $0.80 per 1,000 pages, with no quote and no approval. The REST API reference lists every call on this page.
Remove
Run DROP AGENT specstream.tools.deep_search_agent;, then DROP PROCEDURE for specstream.tools.price_deep_search(STRING, INTEGER) and specstream.tools.start_deep_search(STRING), DROP FUNCTION specstream.tools.read_deep_search(STRING); and DROP TABLE specstream.tools.deep_search_quotes;. Then open API keys in your SpecStream workspace and revoke the key. Rows already delivered stay in your account. Questions: [email protected].
More
SpecStream for Snowflake Cortex Agents Deep Search covers what it does in Snowflake Cortex Agents Deep Search on one page. Every other tool has its guide in Connect your tools. You see the most a request can cost before it starts, and the matches are paid from your balance. Billing has the details. For help, email [email protected].