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

    Domain 2 · Lesson 5/15

    Cortex chat apps: privileges and multi-turn COMPLETE calls

    Build or interact with interfaces to chat with data in Snowflake.

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

    What you will be able to do

    • Grant the account privilege and database role a role needs before application code can call Cortex AI functions
    • Explain why a chat built on COMPLETE has to resend the whole conversation on every turn
    • Build a messages array with system, user and assistant roles in the correct order
    • Choose an entry point for application code that supports the multi-message form of COMPLETE

    Key concept

    Stateless completion — Each call to COMPLETE or AI_COMPLETE is independent: the model keeps no memory between calls. A chat interface feels conversational only because the application stores the conversation and sends all of it with every new request.

    1.Setting up access: one privilege plus one database role

    Before you write any chat code, the role your application runs as must be allowed to call Cortex. Access depends on two separate things, and you need both. The first is the account-level privilege USE AI FUNCTIONS, or a per-function privilege such as USE AI FUNCTION AI_COMPLETE. The second is one of the database roles in the SNOWFLAKE database, either CORTEX_USER or AI_FUNCTIONS_USER. Having only one of the two is a common reason a new chat app fails on its first call.

    The defaults are permissive. USE AI FUNCTIONS is granted to PUBLIC by default, and so is CORTEX_USER. Because every user and role gets PUBLIC, a new account can usually call Cortex functions straight away. To lock this down, an administrator revokes the grants from PUBLIC and gives them to chosen roles. Only ACCOUNTADMIN can manage the USE AI FUNCTIONS privilege. Neither database role can be granted directly to a user. You grant it to an account role, and then grant that account role to users.

    Remove blanket access from PUBLIC, then build a role that can call only AI_COMPLETEsql
    USE ROLE ACCOUNTADMIN;
    
    -- Remove blanket access from PUBLIC
    REVOKE USE AI FUNCTIONS ON ACCOUNT FROM ROLE PUBLIC;
    
    -- Create a role with access to only AI_COMPLETE
    CREATE ROLE ai_complete_user_role;
    GRANT USE AI FUNCTION AI_COMPLETE ON ACCOUNT TO ROLE ai_complete_user_role;
    GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE ai_complete_user_role;
    
    GRANT ROLE ai_complete_user_role TO USER example_user;

    The two database roles differ in scope, and the difference matters for chat. AI_FUNCTIONS_USER covers the scalar AI functions only. It does not include the aggregate functions AI_AGG and AI_SUMMARIZE_AGG, and it gives no access to Cortex services such as Cortex Agent, Cortex Analyst or Cortex Search. It is also not granted to PUBLIC by default. A chat app that only calls AI_COMPLETE can run under AI_FUNCTIONS_USER. An app that calls an agent cannot, because agents need a different role (see the Cortex Agents lesson). Per-function grants and the blanket privilege work as an OR: a role with USE AI FUNCTIONS can call everything, whatever per-function grants it has or has lost.

    Database roles that pair with the USE AI FUNCTIONS privilege
    Database roleGranted to PUBLIC by default?What it covers
    SNOWFLAKE.CORTEX_USERYesCortex AI functions, including the aggregate functions
    SNOWFLAKE.AI_FUNCTIONS_USERNoScalar AI functions only; no Cortex Agent, Cortex Analyst, Cortex Fine-tuning or Cortex Search
    CORTEX_EMBED_USERNot statedAI_EMBED, EMBED_TEXT_768, EMBED_TEXT_1024 and Cortex Search Services with managed embeddings

    Checkpoint 1 of 7· Check yourself

    An administrator revoked USE AI FUNCTIONS from PUBLIC and then granted it to the role CHAT_APP_ROLE. The app's first AI_COMPLETE call still fails. What is the most likely missing grant?

    Checkpoint 2 of 7· Exam question

    Which database role provides the minimum privileges required for a user to invoke Cortex Analyst, following the principle of least privilege?

    Sources1

    2.Multi-turn architecture: the messages array

    The second argument of COMPLETE is called prompt_or_history, and the name explains what it does. Without the options argument, it must be a single prompt string. With options, even an empty object {}, it must be an array of message objects listed in the order they happened. Each object has a role key and a content key. This array is the parameter you update on every turn: add the user's new message, call the function, then add the model's reply as an assistant message so it is there for the next call.

    Roles allowed in the prompt_or_history array
    rolecontentPlacement rule
    systemBackground information and instructions for response style; the model does not reply to itAt most one, and it must be first
    userA prompt from the userFollows the system prompt (if any) or an assistant response
    assistantA response the model gave earlierMust follow a user prompt

    Checkpoint 3 of 7· Put it in order

    Put the entries of a second-turn messages array in the order COMPLETE requires

    1. 1.system: instructions on tone and background
    2. 2.user: the follow-up question
    3. 3.user: the first question
    4. 4.assistant: the model's earlier answer

    This design has a cost. The history grows every turn, so the number of tokens processed also grows each round, and cost rises with it. Passing options also changes what comes back. Without options you get a plain string. With options but no response_format, you get a JSON string with choices (the reply), created, model and usage (completion_tokens, prompt_tokens, total_tokens). You can use the usage field to watch a conversation grow. The options object also sets the generation parameters listed below. AI_COMPLETE is the updated version of COMPLETE and the one to use for new code. The legacy COMPLETE page says that function will be deprecated by the end of 2026.

    COMPLETE options that shape each chat turn
    OptionEffectDefault
    temperatureRandomness of output, 0 to 10
    top_pRestricts the set of possible tokens; alternative to temperature0
    max_tokensMaximum output tokens (maximum allowed 8192)4096
    guardrailsFilters unsafe responses using Cortex GuardFALSE
    response_formatJSON schema the response must followNot set

    Checkpoint 4 of 7· Check yourself

    A developer adds options => {} to an existing COMPLETE call that passed a single prompt string, and the call stops working. Why?

    Checkpoint 5 of 7· Exam question

    A team builds a Streamlit in Snowflake app that calls Cortex Analyst using a semantic model YAML file stored in an internal stage. Business users already hold the CORTEX_ANALYST_USER role but still get "insufficient privileges" errors when submitting questions. What is the most likely missing grant?

    Sources23

    3.Calling Cortex from application code

    A Streamlit app or a Python script can call Cortex functions without writing SQL. The Snowpark Python API includes snake_case versions of the newer functions, such as ai_complete, ai_classify and ai_filter. Snowflake ML (snowflake.cortex) includes the older ones, such as complete, summarize and translate. If a script runs outside Snowflake, it must first create a Snowpark session. With Snowflake ML, you pass hyperparameters through a CompleteOptions object.

    Checkpoint 6 of 7· Fill the gap

    Which option name limits how many output tokens this Snowflake ML call can generate?

    from snowflake.cortex import complete, CompleteOptions
    
    model_options1 = CompleteOptions(
        {' ? ':30}
    )
    
    print(complete("llama3.1-8b", "how do snowflakes get their unique patterns?", options=model_options1))

    For a chat app, one limitation matters more than any other. The multi-message, chat-style form of COMPLETE is not supported in Snowflake ML Python or in the Snowflake CLI. Those surfaces take a single prompt only. To send a messages array, call the function through SQL, for example from a Streamlit app that runs a query. On the app side, the conversation lives in client state. Snowflake's Streamlit agent guide keeps chat history in Streamlit session state to support multi-turn conversations. That client-held history is what you turn into prompt_or_history on each call.

    Checkpoint 7 of 7· Check yourself

    A team wants its Python chatbot to pass a system/user/assistant history to COMPLETE. Which approach does the documentation support?

    Sources45

    Exam traps

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

    1. 1.Granting USE AI FUNCTIONS to a role is enough to let it call AI_COMPLETE.Why is that wrong?

      The account privilege must be paired with the CORTEX_USER or AI_FUNCTIONS_USER database role. Either one alone is not enough.

      Covered in Setting up access: one privilege plus one database role

    2. 2.Snowflake remembers earlier turns of a COMPLETE conversation, so the app only needs to send the newest question.Why is that wrong?

      COMPLETE is stateless. The app must resend all earlier prompts and responses, and the token cost grows each round.

      Covered in Multi-turn architecture: the messages array

    3. 3.The Snowflake CLI command snow cortex complete can run a multi-turn conversation.Why is that wrong?

      The chat-style multi-message form of COMPLETE is not supported in the Snowflake CLI.

      Covered in Calling Cortex from application code

    Sources

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

    1. 1.
      “By default, the USE AI FUNCTIONS privilege is granted to the PUBLIC role.”
      ↩︎ Setting up access: one privilege plus one database role
      “You must use the ACCOUNTADMIN role to manage the USE AI FUNCTIONS account-level privilege.”
      ↩︎ Setting up access: one privilege plus one database role
      “The SNOWFLAKE.CORTEX_USER database role cannot be granted directly to a user.”
      ↩︎ Setting up access: one privilege plus one database role
      “without granting access to Cortex services such as Cortex Agent, Cortex Analyst, Cortex Fine-tuning, or Cortex Search.”
      ↩︎ Setting up access: one privilege plus one database role
      “AI_FUNCTIONS_USER role is not granted to the PUBLIC role by default.”
      ↩︎ Setting up access: one privilege plus one database role
      “If a role has USE AI FUNCTIONS, it can call all Cortex AI functions, regardless of any per-function grants or revocations.”
      ↩︎ Setting up access: one privilege plus one database role
      “and one of the CORTEX_USER or AI_FUNCTIONS_USER database roles to use Snowflake Cortex AI Functions.”
      ↩︎ Exam trap 1
      “and one of the CORTEX_USER or AI_FUNCTIONS_USER database roles to use Snowflake Cortex AI Functions.”
      ↩︎ Checkpoint
    2. 2.
      “Each object must contain a role key and a content key.”
      ↩︎ Multi-turn architecture: the messages array
      “The model does not generate a response to a system prompt.”
      ↩︎ Multi-turn architecture: the messages array
      “the number of tokens processed increases for each”
      ↩︎ Multi-turn architecture: the messages array
      “affects how the prompt argument is interpreted and how the response is formatted”
      ↩︎ Multi-turn architecture: the messages array
      “An object recording the number of tokens consumed and generated by this completion.”
      ↩︎ Multi-turn architecture: the messages array
      “This legacy function will be deprecated by the end of 2026.”
      ↩︎ Multi-turn architecture: the messages array
      “COMPLETE does not retain any state from one call to the next.”
      ↩︎ Key concept
      “COMPLETE does not retain any state from one call to the next.”
      ↩︎ Exam trap 2
      “pass all previous user prompts and model responses in the conversation as part of the prompt_or_history array”
      ↩︎ Prediction
      “Only one system prompt may be provided, and if it is present, it must be the first in the array.”
      ↩︎ Checkpoint
      “If options is present, the argument must be an array of objects representing a conversation in chronological order.”
      ↩︎ Checkpoint
    3. 3.
      “AI_COMPLETE is the updated version of COMPLETE. For the latest functionality, use AI_COMPLETE.”
      ↩︎ Multi-turn architecture: the messages array
    4. 4.
      “integrate AI Functions into application code or scripts rather than running them as SQL statements”
      ↩︎ Calling Cortex from application code
      “If you run your Python script outside of Snowflake, you must create a Snowpark session to use these functions.”
      ↩︎ Calling Cortex from application code
      “The advanced chat-style (multi-message) form of COMPLETE is not currently supported in Snowflake CLI.”
      ↩︎ Calling Cortex from application code
      “The advanced chat-style (multi-message) form of COMPLETE is not currently supported in Snowflake CLI.”
      ↩︎ Exam trap 3
      “The advanced chat-style (multi-message) form of COMPLETE is not currently supported in Snowflake ML Python.”
      ↩︎ Checkpoint

    Continue to page 2 of 2

    Snowflake Intelligence and Cortex Agents for chat with data

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