|
| 1 | +--- |
| 2 | +name: cortex-agents |
| 3 | +description: "Create Cortex Agents that orchestrate across structured and unstructured data using Cortex Analyst, Cortex Search, and custom tools. Use for: building AI agents, CREATE AGENT, agent orchestration, multi-tool agents, natural language Q&A over data, combining structured and unstructured search. Triggers: cortex agent, create agent, ai agent, agent orchestration, analyst and search, multi-tool agent, data agent, agent specification, agent tools." |
| 4 | +--- |
| 5 | + |
| 6 | +# Cortex Agents |
| 7 | + |
| 8 | +Create a Cortex Agent that orchestrates across your data — routing questions to Cortex Analyst (structured/SQL), Cortex Search (unstructured/semantic), and custom tools (UDFs/stored procedures) automatically. |
| 9 | + |
| 10 | +## When to Use |
| 11 | + |
| 12 | +- User wants to build an AI agent that answers questions across multiple data sources |
| 13 | +- User mentions `CREATE AGENT`, Cortex Agents, or agent orchestration |
| 14 | +- User wants a natural language interface over both structured and unstructured data |
| 15 | +- User needs to combine Cortex Analyst (text-to-SQL) with Cortex Search (RAG) |
| 16 | +- User wants to add custom tools (UDFs/stored procedures) to an agent |
| 17 | + |
| 18 | +## Tools Used |
| 19 | + |
| 20 | +- `snowflake_sql_execute` — Create semantic views, search services, agents, test queries |
| 21 | +- `ask_user_question` — Confirm architecture, tool selection, instructions |
| 22 | +- `read` / `write` / `edit` — Configure SQL templates with user-specific values |
| 23 | + |
| 24 | +## Bundled Files |
| 25 | + |
| 26 | +``` |
| 27 | +cortex-agents/ |
| 28 | +├── SKILL.md # This file (agent instructions) |
| 29 | +├── README.md # Human-facing docs |
| 30 | +└── templates/ |
| 31 | + ├── setup.sql # Create DB, schema, sample data, semantic view, search service |
| 32 | + ├── create-agent.sql # CREATE AGENT with Analyst + Search + custom tools |
| 33 | + └── invoke-agent.sql # Call agent via REST API and SNOWFLAKE.CORTEX.AGENT() |
| 34 | +``` |
| 35 | + |
| 36 | +## Stopping Points |
| 37 | + |
| 38 | +- Phase 0: User approves the workflow before any action |
| 39 | +- Step 1: User confirms target objects and data sources |
| 40 | +- Step 3: User reviews agent specification before creation |
| 41 | +- Step 5: User tests agent and reviews answers |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +## Phase 0: Briefing and Consent |
| 46 | + |
| 47 | +Present the following briefing to the user: |
| 48 | + |
| 49 | +> ### Cortex Agents — What This Skill Does |
| 50 | +> |
| 51 | +> I'll build a Cortex Agent — an AI orchestrator that automatically routes questions |
| 52 | +> to the right tool and synthesizes answers from your data. |
| 53 | +> |
| 54 | +> **How agents work:** |
| 55 | +> ``` |
| 56 | +> User Question → Agent (LLM plans & routes) |
| 57 | +> → Cortex Analyst (structured data → SQL → results) |
| 58 | +> → Cortex Search (unstructured data → semantic search → context) |
| 59 | +> → Custom Tools (UDFs/stored procedures) |
| 60 | +> → Agent synthesizes final answer |
| 61 | +> ``` |
| 62 | +> |
| 63 | +> **What gets created:** |
| 64 | +> 1. A semantic view (for structured data via Cortex Analyst) |
| 65 | +> 2. A Cortex Search Service (for unstructured data) |
| 66 | +> 3. A Cortex Agent object with tools and instructions |
| 67 | +> |
| 68 | +> **Key features:** |
| 69 | +> - Automatic tool routing — agent decides which tool to call |
| 70 | +> - Multi-step reasoning — splits complex questions into subtasks |
| 71 | +> - Custom tools — add UDFs/stored procedures as tools |
| 72 | +> - Budget controls — limit execution time and tokens |
| 73 | +> |
| 74 | +> **Models available:** claude-4-sonnet, claude-3-7-sonnet, openai-gpt-5, openai-gpt-4-1, llama3.1-70b |
| 75 | +> |
| 76 | +> Ready to proceed? |
| 77 | +
|
| 78 | +**STOP** — Wait for user approval before continuing. |
| 79 | +
|
| 80 | +--- |
| 81 | +
|
| 82 | +## Step 1: Gather Targets |
| 83 | +
|
| 84 | +Ask the user: |
| 85 | +
|
| 86 | +``` |
| 87 | +Where should I create the agent? |
| 88 | + |
| 89 | +- Database: (e.g., AGENTS_DB) |
| 90 | +- Schema: (e.g., AGENTS) |
| 91 | +- Agent name: (e.g., MY_BUSINESS_AGENT) |
| 92 | +- Warehouse: (e.g., COMPUTE_WH) |
| 93 | +- Role: (must have CREATE AGENT privilege) |
| 94 | +- Data sources: Demo data or your own? |
| 95 | + |
| 96 | +If your own data: |
| 97 | +- Structured data: Which tables/views contain queryable metrics? |
| 98 | +- Unstructured data: Which tables contain searchable text? |
| 99 | +``` |
| 100 | +
|
| 101 | +**STOP** — Wait for response. |
| 102 | +
|
| 103 | +--- |
| 104 | +
|
| 105 | +## Step 2: Create Prerequisites |
| 106 | +
|
| 107 | +An agent needs tools. The two core tools are: |
| 108 | +
|
| 109 | +### Cortex Analyst (Structured Data) |
| 110 | +
|
| 111 | +Requires a **semantic view** that defines business meanings for your tables: |
| 112 | +
|
| 113 | +```sql |
| 114 | +CREATE OR REPLACE SEMANTIC VIEW {{DATABASE}}.{{SCHEMA}}.SALES_SEMANTIC_VIEW |
| 115 | + AS ( |
| 116 | + -- Define tables, dimensions, measures, metrics |
| 117 | + -- See the cortex-search-rag skill or Snowflake docs for semantic view syntax |
| 118 | + ); |
| 119 | +``` |
| 120 | + |
| 121 | +If the user doesn't have a semantic view, use demo data from `templates/setup.sql` which creates one. |
| 122 | + |
| 123 | +### Cortex Search (Unstructured Data) |
| 124 | + |
| 125 | +Requires a **Cortex Search Service** on a text column: |
| 126 | + |
| 127 | +```sql |
| 128 | +CREATE OR REPLACE CORTEX SEARCH SERVICE {{DATABASE}}.{{SCHEMA}}.DOC_SEARCH_SERVICE |
| 129 | + ON body |
| 130 | + ATTRIBUTES title, category |
| 131 | + WAREHOUSE = {{WAREHOUSE}} |
| 132 | + TARGET_LAG = '1 hour' |
| 133 | + EMBEDDING_MODEL = 'snowflake-arctic-embed-l-v2.0' |
| 134 | + AS (SELECT id, title, category, body FROM DOCUMENTS); |
| 135 | +``` |
| 136 | + |
| 137 | +Read `templates/setup.sql` and substitute placeholders. Execute to create the demo data, semantic view, and search service. |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## Step 3: Create the Agent |
| 142 | + |
| 143 | +Read `templates/create-agent.sql` and substitute placeholders. |
| 144 | + |
| 145 | +The core command: |
| 146 | + |
| 147 | +```sql |
| 148 | +CREATE OR REPLACE AGENT {{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}} |
| 149 | + COMMENT = '{{AGENT_DESCRIPTION}}' |
| 150 | + PROFILE = '{"display_name": "{{DISPLAY_NAME}}"}' |
| 151 | + FROM SPECIFICATION |
| 152 | + $$ |
| 153 | + models: |
| 154 | + orchestration: claude-4-sonnet |
| 155 | + |
| 156 | + orchestration: |
| 157 | + budget: |
| 158 | + seconds: 30 |
| 159 | + tokens: 16000 |
| 160 | + |
| 161 | + instructions: |
| 162 | + system: "You are a helpful business assistant." |
| 163 | + orchestration: "Use Analyst for metrics and numbers. Use Search for policies and documentation." |
| 164 | + response: "Be concise and cite your sources." |
| 165 | + sample_questions: |
| 166 | + - question: "What was total revenue last quarter?" |
| 167 | + - question: "What is our return policy for electronics?" |
| 168 | + |
| 169 | + tools: |
| 170 | + - tool_spec: |
| 171 | + type: "cortex_analyst_text_to_sql" |
| 172 | + name: "Analyst" |
| 173 | + description: "Queries structured business data by converting questions to SQL" |
| 174 | + - tool_spec: |
| 175 | + type: "cortex_search" |
| 176 | + name: "Search" |
| 177 | + description: "Searches company documentation and policies" |
| 178 | + |
| 179 | + tool_resources: |
| 180 | + Analyst: |
| 181 | + semantic_view: "{{DATABASE}}.{{SCHEMA}}.SALES_SEMANTIC_VIEW" |
| 182 | + execution_environment: |
| 183 | + type: "warehouse" |
| 184 | + warehouse: "{{WAREHOUSE}}" |
| 185 | + Search: |
| 186 | + name: "{{DATABASE}}.{{SCHEMA}}.DOC_SEARCH_SERVICE" |
| 187 | + max_results: "5" |
| 188 | + $$; |
| 189 | +``` |
| 190 | + |
| 191 | +**STOP** — Show the spec to the user. Ask: "Agent spec looks good? Ready to create?" |
| 192 | + |
| 193 | +--- |
| 194 | + |
| 195 | +## Step 4: Verify Agent |
| 196 | + |
| 197 | +```sql |
| 198 | +-- List agents |
| 199 | +SHOW AGENTS IN SCHEMA {{DATABASE}}.{{SCHEMA}}; |
| 200 | + |
| 201 | +-- Describe the agent |
| 202 | +DESCRIBE AGENT {{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}}; |
| 203 | +``` |
| 204 | + |
| 205 | +--- |
| 206 | + |
| 207 | +## Step 5: Invoke the Agent |
| 208 | + |
| 209 | +Read `templates/invoke-agent.sql` for examples. |
| 210 | + |
| 211 | +### Via REST API (recommended for apps) |
| 212 | + |
| 213 | +```bash |
| 214 | +curl -X POST "https://{{ACCOUNT_URL}}/api/v2/cortex/agent:run" \ |
| 215 | + --header "Authorization: Bearer $PAT" \ |
| 216 | + --header "Content-Type: application/json" \ |
| 217 | + --data '{ |
| 218 | + "agent_name": "{{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}}", |
| 219 | + "messages": [ |
| 220 | + { |
| 221 | + "role": "user", |
| 222 | + "content": [{"type": "text", "text": "What was total revenue last quarter?"}] |
| 223 | + } |
| 224 | + ], |
| 225 | + "stream": false |
| 226 | + }' |
| 227 | +``` |
| 228 | + |
| 229 | +### Via SQL |
| 230 | + |
| 231 | +```sql |
| 232 | +SELECT SNOWFLAKE.CORTEX.AGENT( |
| 233 | + '{{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}}', |
| 234 | + OBJECT_CONSTRUCT( |
| 235 | + 'messages', ARRAY_CONSTRUCT( |
| 236 | + OBJECT_CONSTRUCT( |
| 237 | + 'role', 'user', |
| 238 | + 'content', ARRAY_CONSTRUCT( |
| 239 | + OBJECT_CONSTRUCT('type', 'text', 'text', 'What was total revenue last quarter?') |
| 240 | + ) |
| 241 | + ) |
| 242 | + ) |
| 243 | + ) |
| 244 | +) AS response; |
| 245 | +``` |
| 246 | + |
| 247 | +**STOP** — Show results. Ask the user to try different questions to test routing. |
| 248 | + |
| 249 | +--- |
| 250 | + |
| 251 | +## Step 6: Add Custom Tools (Optional) |
| 252 | + |
| 253 | +Add UDFs or stored procedures as agent tools: |
| 254 | + |
| 255 | +```sql |
| 256 | +-- Create a UDF |
| 257 | +CREATE OR REPLACE FUNCTION {{DATABASE}}.{{SCHEMA}}.GET_WEATHER(city VARCHAR) |
| 258 | + RETURNS VARCHAR |
| 259 | + LANGUAGE PYTHON |
| 260 | + RUNTIME_VERSION = '3.8' |
| 261 | + HANDLER = 'get_weather' |
| 262 | + AS $$ |
| 263 | +def get_weather(city): |
| 264 | + return f"Weather for {city}: 72°F, sunny" |
| 265 | +$$; |
| 266 | + |
| 267 | +-- Add to agent via ALTER |
| 268 | +ALTER AGENT {{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}} |
| 269 | + MODIFY LIVE VERSION SET SPECIFICATION = |
| 270 | + $$ |
| 271 | + -- ... (existing spec plus new tool) |
| 272 | + tools: |
| 273 | + - tool_spec: |
| 274 | + type: "cortex_analyst_text_to_sql" |
| 275 | + name: "Analyst" |
| 276 | + description: "Queries structured business data" |
| 277 | + - tool_spec: |
| 278 | + type: "cortex_search" |
| 279 | + name: "Search" |
| 280 | + description: "Searches documentation" |
| 281 | + - tool_spec: |
| 282 | + type: "generic" |
| 283 | + name: "get_weather" |
| 284 | + description: "Gets current weather for a city" |
| 285 | + input_schema: |
| 286 | + type: "object" |
| 287 | + properties: |
| 288 | + city: |
| 289 | + type: "string" |
| 290 | + description: "City name" |
| 291 | + required: ["city"] |
| 292 | + tool_resources: |
| 293 | + Analyst: |
| 294 | + semantic_view: "{{DATABASE}}.{{SCHEMA}}.SALES_SEMANTIC_VIEW" |
| 295 | + execution_environment: |
| 296 | + type: "warehouse" |
| 297 | + warehouse: "{{WAREHOUSE}}" |
| 298 | + Search: |
| 299 | + name: "{{DATABASE}}.{{SCHEMA}}.DOC_SEARCH_SERVICE" |
| 300 | + max_results: "5" |
| 301 | + get_weather: |
| 302 | + type: "function" |
| 303 | + execution_environment: |
| 304 | + type: "warehouse" |
| 305 | + warehouse: "{{WAREHOUSE}}" |
| 306 | + identifier: "{{DATABASE}}.{{SCHEMA}}.GET_WEATHER" |
| 307 | + $$; |
| 308 | +``` |
| 309 | + |
| 310 | +--- |
| 311 | + |
| 312 | +## Tool Types Reference |
| 313 | + |
| 314 | +| Type | Purpose | Resource Config | |
| 315 | +|------|---------|----------------| |
| 316 | +| `cortex_analyst_text_to_sql` | Text-to-SQL over semantic views | `semantic_view`, `execution_environment` | |
| 317 | +| `cortex_search` | Semantic search over text | `name` (search service), `max_results`, `filter` | |
| 318 | +| `data_to_chart` | Generate visualizations from data | (no resource config needed) | |
| 319 | +| `web_search` | Search the web | `Function` (UDF identifier) | |
| 320 | +| `generic` | Custom UDF or stored procedure | `type` (function/procedure), `identifier`, `execution_environment` | |
| 321 | + |
| 322 | +## Model Choices |
| 323 | + |
| 324 | +| Model | Best For | |
| 325 | +|-------|----------| |
| 326 | +| `auto` | Let Snowflake pick the best available (recommended) | |
| 327 | +| `claude-4-sonnet` | Strong reasoning, good tool routing | |
| 328 | +| `claude-3-7-sonnet` | Balanced performance | |
| 329 | +| `openai-gpt-5` | Alternative strong reasoning | |
| 330 | +| `openai-gpt-4-1` | Cost-effective | |
| 331 | + |
| 332 | +## Access Control |
| 333 | + |
| 334 | +```sql |
| 335 | +-- Grant agent creation |
| 336 | +GRANT CREATE AGENT ON SCHEMA {{DATABASE}}.{{SCHEMA}} TO ROLE {{ROLE}}; |
| 337 | + |
| 338 | +-- Grant agent usage (for other users) |
| 339 | +GRANT USAGE ON DATABASE {{DATABASE}} TO ROLE {{CONSUMER_ROLE}}; |
| 340 | +GRANT USAGE ON SCHEMA {{DATABASE}}.{{SCHEMA}} TO ROLE {{CONSUMER_ROLE}}; |
| 341 | +GRANT USAGE ON AGENT {{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}} TO ROLE {{CONSUMER_ROLE}}; |
| 342 | + |
| 343 | +-- Required database role |
| 344 | +GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE {{ROLE}}; |
| 345 | +``` |
| 346 | + |
| 347 | +## Agent Lifecycle |
| 348 | + |
| 349 | +```sql |
| 350 | +-- Update agent spec |
| 351 | +ALTER AGENT {{AGENT_NAME}} MODIFY LIVE VERSION SET SPECIFICATION = $$ ... $$; |
| 352 | + |
| 353 | +-- Drop agent |
| 354 | +DROP AGENT IF EXISTS {{DATABASE}}.{{SCHEMA}}.{{AGENT_NAME}}; |
| 355 | + |
| 356 | +-- Monitor agent |
| 357 | +-- Use Snowsight > AI & ML > Agents for traces and logs |
| 358 | +``` |
0 commit comments