About snowflake-cortex-ai
A skill for using Snowflake Cortex AI functions and Cortex Search from SQL and application APIs. It helps data teams build AI features and hybrid search workflows while keeping data inside Snowflake.
Key features
- 01SQL-callable AI functions
- 02Text, image, and document processing
- 03Managed hybrid vector and keyword search
- 04Search filtering and relevance tuning
- 05RAG workflow guidance
Use cases
- 01Classifying and extracting fields from table data
- 02Searching enterprise content for chatbot context
- 03Transcribing media and redacting personal data
- 04Estimating token use for batch AI jobs
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ mindrally/ skills --skill snowflake-cortex-aiAfter installing, type/snowflake-cortex-aiin Claude Code to confirm it loaded.
Details
From the project READMESnowflake Cortex AI
This skill covers Snowflake Cortex — the SQL-callable AI layer of Snowflake, including Cortex AI Functions for LLM/ML tasks and Cortex Search for managed hybrid (vector + keyword) search — all running inside Snowflake with no data leaving the platform.
Workflow for Building a Cortex-Powered Feature
- Pick the narrowest function for the task — Use
AI_CLASSIFYfor categorization,AI_FILTERfor natural-language row filtering,AI_EXTRACTfor structured field pulls, and reserveAI_COMPLETEfor open-ended generation — narrower functions are cheaper and more reliable than routing everything throughAI_COMPLETE. - Check token cost before batch jobs — Run
AI_COUNT_TOKENS(model, text)on a sample before running a function over a large table. - Prototype in SQL — Call the function on a small
LIMIT-ed sample and inspect results before running it over a full table. - Structure prompts explicitly — Use
PROMPT('template {0}', arg)for parameterized prompts and cast JSON output toVARIANTwhen you need structured fields back. - For RAG, stand up Cortex Search — Create a
CORTEX SEARCH SERVICEover the source table, query it via the Python or REST API to retrieve context, then pass that context intoAI_COMPLETE. - Use dedicated compute — Size Cortex Search's backing warehouse no larger than MEDIUM, and separate it from other pipeline warehouses.
- Guard against failures — Use
TRY_COMPLETEin place ofAI_COMPLETEfor batch jobs where a single failure shouldn't fail the whole run; it returnsNULLinstead of raising an error.
Cortex AI Functions
Available functions (use these current names — do not use deprecated names like COMPLETE or CLASSIFY_TEXT):
| Function | Purpose |
|---|---|
AI_COMPLETE | General-purpose LLM completion over text, images, or documents |
AI_CLASSIFY | Classify text/images into user-defined categories (multi-label supported) |
AI_FILTER | Returns TRUE/FALSE for text/image input — usable directly in WHERE |
AI_AGG | Aggregate insights across many rows of text, no context-window limit |
AI_EMBED | Generate embedding vectors for similarity search or clustering |
AI_EXTRACT | Extract structured fields from text, images, or documents |
AI_SENTIMENT | Sentiment score from text, ranging -1 to 1 |
AI_SUMMARIZE_AGG | Summarize across many rows, no context-window limit |
AI_SIMILARITY | Embedding similarity between two inputs |
AI_TRANSCRIBE | Transcribe audio/video files from a stage |
AI_PARSE_DOCUMENT | OCR or text+layout extraction from documents in a stage |
AI_REDACT | Redact PII from text |
AI_TRANSLATE | Translate text between supported languages |
Helper functions:
TO_FILE('@stage', 'filename')— build a file reference for document/image processing.AI_COUNT_TOKENS(model, text)— check token count before calling a model, especially before large batch jobs.PROMPT('template {0}', arg)— build parameterized prompt objects forAI_COMPLETE.TRY_COMPLETE— likeAI_COMPLETEbut returnsNULLon failure instead of raising an error.
AI_COMPLETE — the primary function
Supported models include claude-4-opus, claude-4-sonnet, claude-sonnet-4-5, claude-opus-4-5, claude-haiku-4-5, gemini-3-pro, llama3.1-70b, llama3.1-8b, llama3.3-70b, mistral-large2, mistral-small2, and deepseek-r1. Model availability varies by region — do not hardcode a model name without checking regional availability.
-- Text completion
SELECT AI_COMPLETE(MODEL => 'claude-4-sonnet', PROMPT => 'Summarize: ' || review_text) FROM reviews;
-- Document processing
SELECT AI_COMPLETE(
MODEL => 'claude-4-sonnet',
PROMPT => PROMPT('Extract the invoice total from {0}', TO_FILE('@docs', 'invoice.pdf'))
);
-- Structured JSON output
SELECT AI_COMPLETE(MODEL => 'claude-4-sonnet',
PROMPT => 'Extract name, email, company as JSON: ' || raw_text)::VARIANT AS extracted
FROM contacts;
Classification, filtering, and aggregation
-- AI_CLASSIFY: cheaper than AI_COMPLETE for categorization tasks
SELECT AI_CLASSIFY(ticket_text, ['billing', 'technical', 'account', 'other']) AS category FROM tickets;
-- Multi-label: AI_CLASSIFY(input, categories, {'output_mode': 'multi'})
-- AI_FILTER: natural-language predicate directly in WHERE
SELECT * FROM reviews WHERE AI_FILTER(review_text, 'mentions product quality issues');
-- AI_AGG: cross-row aggregation with no context-window limit
SELECT AI_AGG(feedback_text, 'What are the top 3 themes?') FROM customer_feedback;
-- AI_EXTRACT: pull named fields out of free text
SELECT AI_EXTRACT(email_body, 'meeting date', 'attendees', 'action items') FROM emails;
Other functions
SELECT review_text, AI_SENTIMENT(review_text) AS sentiment FROM product_reviews;
SELECT AI_EMBED(description) AS embedding FROM products;
SELECT AI_PARSE_DOCUMENT(TO_FILE('@docs', 'contract.pdf'), MODE => 'LAYOUT');
SELECT AI_TRANSCRIBE(TO_FILE('@media', 'recording.mp3')) AS transcript;
SELECT AI_REDACT(customer_notes) AS redacted FROM support_cases;
Privileges
Cortex AI functions require the USE AI FUNCTIONS account privilege plus the SNOWFLAKE.CORTEX_USER database role — both are granted to PUBLIC by default, so most workloads work without extra grants.
Cortex Search — Hybrid Vector + Keyword Search
Cortex Search is fully managed search combining vector (semantic) and keyword (lexical) retrieval. Typical use cases are RAG for LLM chatbots, enterprise search, and AI-powered Q&A.
Single-index service
CREATE OR REPLACE CORTEX SEARCH SERVICE my_search
ON transcript_text
ATTRIBUTES region, agent_id
WAREHOUSE = my_wh
TARGET_LAG = '1 day'
EMBEDDING_MODEL = 'snowflake-arctic-embed-l-v2.0'
AS (SELECT transcript_text, region, agent_id FROM support_transcripts);
Multi-index service (text + vector across columns)
CREATE OR REPLACE CORTEX SEARCH SERVICE my_multi_search
TEXT INDEXES transcript_text, summary
VECTOR INDEXES transcript_text (model='snowflake-arctic-embed-l-v2.0')
ATTRIBUTES region
WAREHOUSE = my_wh
TARGET_LAG = '1 hour'
AS (SELECT transcript_text, summary, region FROM support_transcripts);
Key parameters: ON (single-index column), TEXT INDEXES, VECTOR INDEXES, ATTRIBUTES (filterable columns), TARGET_LAG (freshness), EMBEDDING_MODEL, and PRIMARY KEY (enables optimized incremental refresh — set it whenever the source table has a stable key).
Querying — Python API (recommended for applications)
from snowflake.core import Root
root = Root(session)
service = root.databases["db"].schemas["schema"].cortex_search_services["my_search"]
resp = service.search(
query="internet connection issues",
columns=["transcript_text", "region"],
filter={"@eq": {"region": "North America"}},
limit=5,
)
Querying — REST API
POST /api/v2/databases/<db>/schemas/<schema>/cortex-search-services/<service>:query
Body: {"query": "...", "columns": [...], "filter": {...}, "limit": N}
Filter syntax
{"@eq": {"region": "NA"}}
{"@contains": {"tags": "urgent"}}
{"@gte": {"score": 0.8}}
{"@and": [f1, f2]}
{"@or": [f1, f2]}
{"@not": f}
Tuning relevance
Adjust the weighting between text match, vector similarity, and reranker score:
resp = service.search(
query="billing dispute",
columns=["transcript_text"],
scoring_config={"weights": {"texts": 0.3, "vectors": 0.5, "reranker": 0.2}},
limit=10,
)
RAG pattern
- Retrieve context:
results = service.search(query=question, columns=["content"], limit=5) - Pass the retrieved context into
AI_COMPLETE:
SELECT AI_COMPLETE(
MODEL => 'claude-4-sonnet',
PROMPT => 'Answer using only this context: ' || context || ' Question: ' || question
);
Best Practices
- Use
AI_CLASSIFYinstead ofAI_COMPLETEfor categorization — it is purpose-built and cheaper. - Run
AI_COUNT_TOKENSbefore large batch jobs to estimate cost and avoid truncation surprises. - Set
PRIMARY KEYon a Cortex Search service so refreshes are incremental rather than full rebuilds. - Use
ATTRIBUTESfor any column you need to filter on at query time. - Use
SEARCH_PREVIEWfor interactive testing during development; use the Python or REST API for production integrations. - Size the warehouse backing a search service no larger than MEDIUM, and dedicate it to that service.
Anti-Patterns
- Do not use deprecated function names (
COMPLETE,CLASSIFY_TEXT, etc.) — use the currentAI_*versions. - Do not pass an entire table through
AI_COMPLETErow-by-row without first estimating cost withAI_COUNT_TOKENS. - Do not hardcode model names without checking regional availability.
- Do not use
AI_COMPLETEfor tasks a narrower function (AI_CLASSIFY,AI_FILTER,AI_EXTRACT) already covers.