CertSafari
    Snowflake SnowPro Specialty: Gen AI (GES-C02)· Lessons

    Domain 2 · Lesson 3/15

    Cortex Embeddings, Vector Functions and Helper Functions

    Apply AI functions in Snowflake.

    14 min read
    7.6% of exam
    9 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    What you will be able to do

    • Generate embeddings with AI_EMBED and store them in a VECTOR column
    • Choose among similarity, manipulation and aggregate vector functions
    • Assemble a semantic-search and RAG query from AI_EMBED, VECTOR_COSINE_SIMILARITY and AI_COMPLETE
    • Estimate input tokens with AI_COUNT_TOKENS and explain what its result does and doesn't include
    • Use TRY_COMPLETE, SPLIT_TEXT_RECURSIVE_CHARACTER and SPLIT_TEXT_MARKDOWN_HEADER appropriately

    1.AI_EMBED: turning text into vectors

    An embedding converts unstructured data such as text into a numeric vector, so that semantic similarity becomes geometric closeness. A help desk, for example, can find already-resolved cases that resemble a new one even when they share no keywords, because the search goes beyond keyword matching to semantic similarity.

    AI_EMBED generates an embedding vector for text or image input. The vector can be used for similarity search, clustering and classification. AI_EMBED is a Cortex AI Function, so the same access controls apply as for the others. Older material uses EMBED_TEXT_768 and EMBED_TEXT_1024, where the number is the output dimension. The model you choose determines the dimension, so it has to match the VECTOR column you store into.

    Text embedding models offered by Snowflake
    ModelOutput dimensionsContext windowLanguage support
    snowflake-arctic-embed-m-v1.5768512English-only
    snowflake-arctic-embed-m768512English-only
    e5-base-v2768512English-only
    snowflake-arctic-embed-l-v2.01024512Multilingual
    voyage-multilingual-2102432000Multilingual
    nv-embed-qa-41024512English-only
    Add a 768-dimension VECTOR column and fill it with AI_EMBEDsql
    ALTER TABLE issues ADD COLUMN issue_vec VECTOR(FLOAT, 768);
    
    UPDATE issues
      SET issue_vec = AI_EMBED('snowflake-arctic-embed-m', issue_text);

    If you only need a similarity score between two inputs and don't want to store vectors, AI_SIMILARITY calculates the embedding similarity between two inputs in a single call.

    Checkpoint 1 of 7· Check yourself

    You embed multilingual product reviews with snowflake-arctic-embed-l-v2.0. What must the target column be?

    Sources12

    2.Vector functions: similarity, manipulation and aggregation

    Once you have vectors, SQL vector functions work with them. They fall into three families:

    - Similarity: VECTOR_INNER_PRODUCT, VECTOR_L1_DISTANCE, VECTOR_L2_DISTANCE and VECTOR_COSINE_SIMILARITY. Each takes two VECTOR arguments of equal element type and dimension and returns a metric. - Manipulation: VECTOR_TRUNCATE and VECTOR_NORMALIZE. Each takes one vector and returns a new vector, for example a truncated or normalized one. - Aggregation: VECTOR_SUM, VECTOR_MIN, VECTOR_MAX and VECTOR_AVG. These work element-wise down a column of vectors within a group.

    Two details are worth remembering. The functions are optimized in a way that can reduce floating-point precision, with a margin of error up to 1e-4. And VECTOR_COSINE_SIMILARITY isn't supported in the Snowpark API, so Snowpark Python examples use functions such as vector_l2_distance instead.

    A little more detail on each family. VECTOR_INNER_PRODUCT, VECTOR_L1_DISTANCE and VECTOR_L2_DISTANCE compute the inner product, the L1 distance and the L2 distance of two vectors. VECTOR_COSINE_SIMILARITY computes their cosine similarity, which is why the search examples rank it with ORDER BY ... DESC. The Snowpark example that uses vector_l2_distance sorts by the distance to put the nearest vector first.

    On the manipulation side, VECTOR_TRUNCATE truncates a VECTOR to a smaller dimension. VECTOR_NORMALIZE normalizes a VECTOR in the L2 vector space so that it has a magnitude of 1. On the aggregation side, VECTOR_SUM, VECTOR_MIN, VECTOR_MAX and VECTOR_AVG compute the element-wise sum, minimum, maximum and average of the vectors in an aggregate, for example VECTOR_AVG over a group of embeddings.

    Checkpoint 2 of 7· Fill the gap

    Which function completes this query that finds the vector closest to [1,2,3]? (Higher values mean more similar.)

    SELECT a,  ? (a, [1,2,3]::VECTOR(FLOAT, 3)) AS similarity
        FROM vectors
    ORDER BY similarity DESC
    LIMIT 1;

    Checkpoint 3 of 7· Exam question

    A data engineer needs every completion returned by an LLM call to conform to a fixed JSON schema so downstream ETL code can parse fields without try/catch logic. Which capability should they configure?

    Sources34

    3.From vectors to answers: semantic search and RAG

    Semantic search combines the pieces. First store embeddings for the documents and keep them up to date as documents change. Then embed the search term, compare it with the stored vectors using a similarity function, and use ORDER BY and LIMIT to keep the top k matches.

    One performance rule: put the similarity call in the SELECT clause, not the WHERE clause. That way it runs only on rows that survive other filters, such as a date range. To filter on similarity, give the call a column alias in SELECT and test the alias in WHERE.

    Retrieval-augmented generation (RAG) adds one more step. The best-matching document goes to an LLM together with the user's question, which gives the model context for its answer.

    RAG: retrieve the closest wiki article, then pass it to AI_COMPLETE as contextsql
    WITH result AS (
        SELECT
            w.content,
            $query AS query_text,
            VECTOR_COSINE_SIMILARITY(w.vec, q.query_vec) AS similarity
        FROM wiki w, query_table q
        ORDER BY similarity DESC
        LIMIT 1
    )
    
    -- Pass to large language model as context
    SELECT AI_COMPLETE('mistral-7b',
        CONCAT('Answer this question: ', query_text, ' using this text: ', content)) FROM result;

    Checkpoint 4 of 7· Put it in order

    Put the RAG steps in order

    1. 1.Pass the query and the retrieved text to AI_COMPLETE
    2. 2.Rank documents by VECTOR_COSINE_SIMILARITY and keep the top match
    3. 3.Embed the incoming query with the same embedding model
    4. 4.Store AI_EMBED vectors for the documents in a VECTOR column

    Sources2

    4.AI_COUNT_TOKENS: estimating input before you spend

    AI_COUNT_TOKENS takes a function name and, where relevant, a model name, the input text, and options that affect the count, such as AI_CLASSIFY categories. It returns an INTEGER estimate of the *input* tokens. Rules to know:

    - Write function and model names in lowercase. The function name must start with ai_. It doesn't work with functions in the SNOWFLAKE.CORTEX namespace or with fine-tuned models. - It accepts text only, not images, audio or video. - It incurs compute cost only and isn't billed per token. It is available in all regions, even for models that aren't available there. - For actual billed input and output tokens, use the CORTEX_FUNCTIONS_QUERY_USAGE_HISTORY view. - With AI_COMPLETE structured output on Anthropic Claude models, billed input tokens can be materially higher than the estimate.

    Counting input tokens for an AI_SENTIMENT call (response: 139)sql
    SELECT AI_COUNT_TOKENS('ai_sentiment',
      'This place makes the best truffle pizza in the world! Too bad I cannot afford it');
    How accurate AI_COUNT_TOKENS is, by model family
    ModelToken count accuracy
    Anthropic ClaudeEstimate; relative error under 3%
    Google GeminiEstimate; relative error under 3%
    OpenAINear-exact
    All other modelsExact

    Checkpoint 5 of 7· Check yourself

    Which AI_COUNT_TOKENS call is valid?

    Checkpoint 6 of 7· Exam question

    A product feedback table has millions of rows and support tickets can belong to more than one issue type at once (e.g. both 'Shipping Delay' and 'Damaged Item'). Which AI_CLASSIFY configuration is required to return more than one label per row?

    Sources5

    5.TRY_COMPLETE and the text-splitting helpers

    TRY_COMPLETE (SNOWFLAKE.CORTEX) does the same thing as COMPLETE, but returns NULL instead of raising an error when the operation can't be performed. That made it the safe choice for long batch jobs that use the legacy function. It is now a legacy function that will be deprecated by the end of 2026. Snowflake directs new work to AI_COMPLETE, which already returns NULL for failed rows by default.

    One syntax difference matters when you migrate. In the legacy TRY_COMPLETE and COMPLETE, response_format (structured output) is a key inside the options object. In AI_COMPLETE it moves out into its own named argument, response_format, and the hyperparameters go in model_parameters. If you leave response_format inside model_parameters, it isn't recognized and the response comes back as an unstructured string.

    For RAG, long documents must be split into chunks before embedding. Two helpers do this.

    SPLIT_TEXT_RECURSIVE_CHARACTER splits text recursively and returns an array of chunks. It tries its separators in order: the defaults for the chosen format, or those you pass in separators. Any chunk still longer than chunk_size is split again with the next separator. overlap is optional.

    SPLIT_TEXT_MARKDOWN_HEADER first splits a Markdown document on the header levels you list in headers_to_split_on, such as # and ##, then splits each section to chunk_size characters. Each chunk it returns is an object with the chunk text and the headers it falls under, so chunk boundaries follow the document's sections.

    SPLIT_TEXT_RECURSIVE_CHARACTER syntaxsql
    SNOWFLAKE.CORTEX.SPLIT_TEXT_RECURSIVE_CHARACTER (
      '<text_to_split>',
      '<format>',
      <chunk_size>,
      [ <overlap> ],
      [ <separators> ]
    )

    Checkpoint 7 of 7· Check yourself

    A knowledge base of Markdown articles uses #, ## and ### headers. Each embedded chunk should stay within one section and carry its section titles. Which helper fits?

    Sources6789

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.AI_COUNT_TOKENS predicts the full token bill for a batch.Why is that wrong?

      It estimates input tokens only. Output tokens are billed on top, and the CORTEX_FUNCTIONS_QUERY_USAGE_HISTORY view shows the actual billed counts.

      Covered in AI_COUNT_TOKENS: estimating input before you spend

    2. 2.Every SQL vector function, including VECTOR_COSINE_SIMILARITY, is also available in the Snowpark Python API.Why is that wrong?

      VECTOR_COSINE_SIMILARITY isn't supported in Snowpark. Use SQL, or another metric such as vector_l2_distance, in Snowpark code.

      Covered in Vector functions: similarity, manipulation and aggregation

    3. 3.TRY_COMPLETE is the recommended long-term way to make completions error-tolerant.Why is that wrong?

      TRY_COMPLETE is a legacy function that will be deprecated by the end of 2026. New work should use AI_COMPLETE.

      Covered in TRY_COMPLETE and the text-splitting helpers

    Practise it for real

    Build a small semantic search and RAG flow over a support-issues table using AI_EMBED, VECTOR_COSINE_SIMILARITY and AI_COMPLETE

    1. 1.Run ALTER TABLE issues ADD COLUMN issue_vec VECTOR(FLOAT, 768); then UPDATE issues SET issue_vec = AI_EMBED('snowflake-arctic-embed-m', issue_text);

      Why: Stored document embeddings are the index that semantic search compares against.

      You should see: Every row has a 768-element vector in issue_vec.

    2. 2.Run AI_COUNT_TOKENS('ai_embed', 'snowflake-arctic-embed-m', <a sample issue_text>) on a few representative rows.

      Why: This checks input size against the model's 512-token context window before you embed at scale.

      You should see: An INTEGER per row. It is an input-only estimate.

    3. 3.SELECT issue_text and VECTOR_COSINE_SIMILARITY(issue_vec, AI_EMBED('snowflake-arctic-embed-m', 'User could not install Facebook app on his phone')) AS similarity, ORDER BY similarity DESC, LIMIT 5.

      Why: Embed the query with the same model, then rank by cosine similarity to get the top k matches.

      You should see: Five issues, most similar first, with similarity values between -1 and 1.

    4. 4.Wrap the LIMIT 1 version in a CTE and call AI_COMPLETE('mistral-7b', CONCAT('Answer this question: ', <question>, ' using this text: ', issue_text)).

      Why: Passing the retrieved text to the LLM as context is the generation step of RAG.

      You should see: One generated answer based on the closest matching issue. It is NULL only if the completion fails for that row.

    Stuck? Get a nudge

    If the similarity call is slow, keep it in SELECT and filter on its alias, so it runs only on rows that pass your other WHERE conditions.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “AI_EMBED: Generates an embedding vector for a text or image input, which can be used for similarity search, clustering, and classification tasks.”
      ↩︎ AI_EMBED: turning text into vectors
      “AI_SIMILARITY: Calculates the embedding similarity between two inputs.”
      ↩︎ AI_EMBED: turning text into vectors
    2. 2.
      “it goes beyond keyword matching to semantic similarity”
      ↩︎ AI_EMBED: turning text into vectors
      “Generally, the call to the vector similarity function should appear in the SELECT clause, not in the WHERE clause.”
      ↩︎ From vectors to answers: semantic search and RAG
      “providing context for the generative response (completion)”
      ↩︎ From vectors to answers: semantic search and RAG
      “The Snowpark Python library does not support the VECTOR_COSINE_SIMILARITY function.”
      ↩︎ Exam trap 2
      “Snowflake Cortex offers the EMBED_TEXT_768 and EMBED_TEXT_1024 functions and several Vector functions to compare them for various applications.”
      ↩︎ Checkpoint
      “create an embedding of the search term or target document, and then use a vector similarity function to locate documents with similar embeddings”
      ↩︎ Checkpoint
    3. 3.
      “Similarity functions operate on two VECTOR arguments of equal element type and dimension, computing the specified metric.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
      “Vector manipulation functions take an existing vector and return a new vector with different properties, such as truncation or normalization.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
      “perform element-wise mathematical operations such as sum, average, minimum, and maximum across all vectors in a group”
      ↩︎ Vector functions: similarity, manipulation and aggregation
      “These functions have a margin of error up to 1e-4.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
    4. 4.
      “Normalizes a VECTOR in the L2 vector space, giving its elements values in the range of [0,1] and giving it a magnitude of 1.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
      “Truncates a VECTOR to a smaller dimension.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
      “Computes the element-wise sum of vectors in an aggregate.”
      ↩︎ Vector functions: similarity, manipulation and aggregation
    5. 5.
      “Returns an estimate of the number of input tokens in a prompt for the specified large language model or task-specific function.”
      ↩︎ AI_COUNT_TOKENS: estimating input before you spend
      “AI_COUNT_TOKENS only incurs compute costs and does not bill based on token count.”
      ↩︎ AI_COUNT_TOKENS: estimating input before you spend
      “AI_COUNT_TOKENS accepts only text, not image, audio, or video inputs.”
      ↩︎ AI_COUNT_TOKENS: estimating input before you spend
      “AI_COUNT_TOKENS estimates input tokens only. It does not estimate output (generated) tokens, which also contribute to billing.”
      ↩︎ Exam trap 1
      “This value does not include output (generated) tokens.”
      ↩︎ Prediction
      “AI_COUNT_TOKENS does not work with LLM functions in the SNOWFLAKE.CORTEX namespace or with fine-tuned models.”
      ↩︎ Checkpoint
    6. 6.
      “Performs the same operation as the COMPLETE function but returns NULL instead of raising an error when the operation cannot be performed.”
      ↩︎ TRY_COMPLETE and the text-splitting helpers
      “For new use cases, start with AI_COMPLETE, which is the canonical surface going forward.”
      ↩︎ TRY_COMPLETE and the text-splitting helpers
      “This legacy function will be deprecated by the end of 2026.”
      ↩︎ Exam trap 3
    7. 8.
      “for preprocessing text to be used with text embedding or search indexing functions”
      ↩︎ TRY_COMPLETE and the text-splitting helpers
      “Splitting is then applied to each chunk that is longer than the specified chunk_size, recursively”
      ↩︎ TRY_COMPLETE and the text-splitting helpers
    8. 9.
      “splits a Markdown-formatted document into structured text chunks based on header levels”
      ↩︎ TRY_COMPLETE and the text-splitting helpers
      “The function returns an array of objects, where each object contains the text chunk and the associated headers under which that chunk falls.”
      ↩︎ Checkpoint

    Ready to test yourself?

    Practise the 27 questions on this subdomain.

    Spotted a mistake, or was something unclear? Tell us.