cortex
RelationalAI-Cortex Integration
Deploy Snowflake Cortex AI agents powered by RelationalAI semantic models for Snowflake Intelligence.
Quickstart
Section titled “Quickstart”from snowflake import snowpark
from relationalai.config import create_config, SnowflakeConnectionfrom relationalai.agent.cortex import CortexAgentManager, DeploymentConfig, discover_imports, ToolRegistry
# Create session using role for deploymentsession: snowpark.Session = create_config().get_session(SnowflakeConnection)
# Configure managermanager = CortexAgentManager( session=session, config=DeploymentConfig( agent_name="MY_ASSISTANT", # Unique name for the agent database="MY_DB", # Snowflake database for deployment (sprocs & agent) schema="MY_SCHEMA", # Snowflake schema for deployment (sprocs & agent) warehouse="COMPUTE_WH")) # Warehouse for RAI tool execution (SI users need USAGE)
# Initialize RAI Tools# - This function is executed during each sproc invocation.# It must be self-contained — don't close over local# runtime state (sessions, connections, dataframes, etc.).def init_tools(): # IMPORTANT: import your RelationalAI Model and dependent code # inside init_tools so it runs within the sproc session. from my_project.model import core return ToolRegistry().add( model=core.model, # Expose model through tools description="...")
# Deploymanager.deploy( init_tools=init_tools, # Initialize RAI Tools imports=discover_imports()) # Specify local python modules to package into sproc
print(manager.status())After deployment, you can find the Cortex Agent in the Snowflake UI under AI & ML > Agents. The UI allows you to chat with the agent, preview or add it to Snowflake Intelligence, and view traces of conversations the agent participates in.
For programmatic access (testing, automation):
chat = manager.chat()response = chat.send("What can I ask about?")print(response.full_text())Conversations through the programmatic interface are persisted and available through the Monitoring tab for the agent in the Snowflake UI.
How It Works
Section titled “How It Works”The RelationalAI-Cortex integration
- operationalizes your RAI Model into Snowflake stored procedures
- configures a Cortex Agent with these tools, and instructions on how to explore your semantic models and answer questions about your data.
| Tool | Purpose |
|---|---|
RAI_DISCOVER_MODELS | Discover available models and their key concepts |
RAI_VERBALIZE_MODEL | Get detailed model structure and relationships |
RAI_EXPLAIN_CONCEPT | Understand business rules for specific concepts |
RAI_QUERY_MODEL | Execute pre-defined queries (PREVIEW — requires allow_preview=True) |
RBAC: Caller’s Rights
Section titled “RBAC: Caller’s Rights”All stored procedures are created with CALLER’S RIGHTS — they execute under the SI user’s Snowflake role, not the deployer’s role. This means:
- Data access is governed by the caller’s role. Users only see data their role can
SELECT. - No privilege escalation. The agent never operates with more permissions than the person using it.
This makes Snowflake’s existing RBAC the single source of truth for data governance across all agent interactions.
Snowflake Privileges
Section titled “Snowflake Privileges”The following permissions are required for two roles:
- deployer/admin who creates the Cortex Agent
- SI users who interact with it through the Snowflake Intelligence UI (or, programmatic users of the Cortex Agent)
> Some installations grant these via a convenience role like rai_developer that bundles the Native App application role and external-access integration USAGE. The tables below list the underlying privileges directly so they apply regardless of whether the convenience role exists.
Deployer / Admin
Section titled “Deployer / Admin”| Privilege | Purpose |
|---|---|
CREATE STAGE on target schema | Store sproc dependencies (if manage_stage=True) |
CREATE PROCEDURE on target schema | Register RAI tool sprocs |
CREATE AGENT on target schema | Register the Cortex agent |
USE AI FUNCTIONS on account | Access Cortex AI functions (granted to PUBLIC by default) |
database role snowflake.cortex_user | Access Cortex services (granted to PUBLIC by default) |
database role snowflake.pypi_repository_user | Install Python packages in the sproc environment |
application role snowflake.ai_observability_events_lookup | Monitor AI observability events |
application role relationalai.rai_user | Access the RAI Native App (created during install) |
USAGE on S3_RAI_INTERNAL_BUCKET_EGRESS_INTEGRATION | Network egress to RAI services from inside the sproc |
USAGE on database, schema, and warehouse | Access the deployment target |
SI Users
Section titled “SI Users”Because sprocs use CALLER’S RIGHTS, SI users need privileges on the resources the agent accesses at runtime:
| Privilege | Purpose |
|---|---|
USAGE on warehouse | Execute sprocs (warehouse from DeploymentConfig, or session default) |
USE AI FUNCTIONS on account | Access Cortex AI functions (granted to PUBLIC by default) |
database role snowflake.cortex_user | Access Cortex services (granted to PUBLIC by default) |
database role snowflake.pypi_repository_user | Install Python packages in the sproc environment |
application role relationalai.rai_user | Access the RAI Native App at sproc runtime |
USAGE on S3_RAI_INTERNAL_BUCKET_EGRESS_INTEGRATION | Network egress to RAI services from inside the sproc |
USAGE on database and schema | Access the data |
SELECT on tables | Read data accessed by the model |
EXECUTE on stored procedures | Invoke RAI tools |
Example Role Definitions
Section titled “Example Role Definitions”-- Deployer rolecreate role my_deployer_role;grant create stage on schema my_db.my_schema to role my_deployer_role;grant create procedure on schema my_db.my_schema to role my_deployer_role;grant create agent on schema my_db.my_schema to role my_deployer_role;grant use ai functions on account to role my_deployer_role;grant database role snowflake.cortex_user to role my_deployer_role;grant database role snowflake.pypi_repository_user to role my_deployer_role;grant application role snowflake.ai_observability_events_lookup to role my_deployer_role;grant application role relationalai.rai_user to role my_deployer_role;grant usage on integration s3_rai_internal_bucket_egress_integration to role my_deployer_role;grant usage on database my_db to role my_deployer_role;grant usage on schema my_db.my_schema to role my_deployer_role;grant usage on warehouse compute_wh to role my_deployer_role;
-- SI user rolecreate role my_si_user_role;grant usage on warehouse compute_wh to role my_si_user_role;grant use ai functions on account to role my_si_user_role;grant database role snowflake.cortex_user to role my_si_user_role;grant database role snowflake.pypi_repository_user to role my_si_user_role;grant application role relationalai.rai_user to role my_si_user_role;grant usage on integration s3_rai_internal_bucket_egress_integration to role my_si_user_role;grant usage on database my_db to role my_si_user_role;grant usage on schema my_db.my_schema to role my_si_user_role;grant select on all tables in schema my_db.my_schema to role my_si_user_role;grant execute on all procedures in schema my_db.my_schema to role my_si_user_role;S3_RAI_INTERNAL_BUCKET_EGRESS_INTEGRATION is created by Step 4 of the RAI Native App install notebook (Warehouse Notebooks subsection). If your admin says the integration does not exist, that step has not been run.
Diagnostics
Section titled “Diagnostics”Cortex deployments depend on a stack of grants and integrations that are easy to misconfigure. The diagnostics module turns cryptic Snowflake errors (“Object X does not exist or not authorized”) into one upfront list of named GRANTs, with a paste-ready SQL block.
Preflight
Section titled “Preflight”manager.deploy() runs manager.preflight() automatically. To inspect findings without raising:
report = manager.preflight()print(report.format(config=manager.config, role=report.role))
if report.has_errors: print(manager.print_setup_sql(deployer_role="MY_ROLE"))Preflight probes are read-only (SHOW/DESCRIBE/SELECT):
| Check | Severity |
|---|---|
| Database, schema, warehouse exist + USAGE | error |
| External access integration visible | error |
snowflake.pypi_repository_user granted (primary or secondary role) | error |
snowflake.cortex_user granted | error |
CREATE STAGE/PROCEDURE/AGENT on schema (direct grants) | warning |
Agent schema (if agent_schema set) | error/warning |
The database-role check uses IS_DATABASE_ROLE_IN_SESSION plus a fallback that walks CURRENT_AVAILABLE_ROLES() × SHOW GRANTS OF DATABASE ROLE, so secondary-role grants are recognized.
Setup SQL
Section titled “Setup SQL”Generate a GRANT block parameterized with this manager’s config:
print(manager.print_setup_sql( deployer_role="MY_DEPLOYER", si_role="MY_SI", # optional — also emit SI-user block create_role=False, # prepend CREATE ROLE IF NOT EXISTS))The block is the deployer-friendly version of the privilege table above — hand it to a Snowflake admin verbatim instead of writing it by hand.
Skip preflight
Section titled “Skip preflight”For fast iteration once you know the environment is correctly granted:
manager.deploy(init_tools=init_tools, imports=imports, skip_preflight=True)If deploy still fails, the underlying Snowflake error is post-processed: the diagnostic message includes the named GRANT that fixes the most common cases (missing pypi_repository_user, missing EAI, etc.).
Command-line diagnostics
Section titled “Command-line diagnostics”For ad-hoc probing without writing Python:
python -m relationalai.agent.cortex.diagnostics \ --account MY_ACCT --user me@example.com \ --role MY_ROLE --warehouse MY_WH \ --database MY_DB --schema MY_SCHEMA \ --agent-name MY_AGENT \ [--preflight-only] # skip the deeper SQL/REST sweep [--no-rest] # skip Cortex REST API probes [--json-out FILE] # write the full report as JSONRead-only — never creates or drops resources.
Configuration
Section titled “Configuration”DeploymentConfig
Section titled “DeploymentConfig”| Parameter | Required | Default | Description |
|---|---|---|---|
database | Yes | - | Snowflake database where agent will be deployed |
schema | Yes | - | Snowflake schema where sprocs and stage will be created |
agent_name | Yes | - | Unique name for the Cortex agent within the schema |
model_name | No | Same as agent_name | Name for the Model instance created inside each stored procedure |
warehouse | No | None | Snowflake warehouse the Cortex agent will use when executing RAI tools. SI users need USAGE on this warehouse. If omitted, tools use the caller’s session warehouse. Stored procedures are created with CALLER’S RIGHTS |
stage_name | No | "rai_sprocs" | Name of the Snowflake stage for storing sproc dependencies |
manage_stage | No | True | If True, automatically create/drop the stage during deploy/cleanup. Set to False if using a pre-existing stage |
llm | No | "claude-sonnet-4-5" | Language model for agent orchestration. Must be available in Snowflake Cortex |
query_timeout_s | No | 300 | Timeout in seconds for stored procedure execution |
budget_seconds | No | None | Time budget in seconds for agent execution. Can be used with budget_tokens |
budget_tokens | No | None | Token budget for model consumption. Can be used with budget_seconds |
external_access_integration | No | "S3_RAI_INTERNAL_BUCKET_EGRESS_INTEGRATION" | External access integration for sprocs. Both deployer and SI roles need USAGE on it. Created by Step 4 of the RAI Native App install notebook |
artifact_repository | No | "snowflake.snowpark.pypi_shared_repository" | Artifact repository for Python packages |
allow_preview | No | False | Allow Preview capabilities (e.g., queries) |
agent_schema | No | None | Fully-qualified DATABASE.SCHEMA where the agent is created. Sprocs and stage remain in database/schema. Use SNOWFLAKE_INTELLIGENCE.AGENTS to expose the agent in SI. If not set, agent is created alongside sprocs |
Verbalizers
Section titled “Verbalizers”Verbalizers control how model structure is presented to the agent.
ModelVerbalizer (Default)
Section titled “ModelVerbalizer (Default)”Returns relationship readings extracted from the RAI model:
Customer has many OrdersOrder has one CustomerOrder contains many OrderItems...This is the default — no configuration needed.
SourceCodeVerbalizer
Section titled “SourceCodeVerbalizer”Extends ModelVerbalizer: explain_model returns the standard relationship
readings, while explain_concept returns the Python source code from the
modules you provide, filtered to those that reference the requested concept.
Pass the model as the first argument, followed by your model definition modules:
from relationalai.agent.cortex import SourceCodeVerbalizer, ToolRegistry
def init_tools(): from my_project.model import core, computed return ToolRegistry().add( model=core.model, description="Customers and orders", verbalizer=SourceCodeVerbalizer(core.model, core, computed) )The agent sees actual Python code for specific concepts, including business logic and computed properties.
Comments are included, so clarifications and justifications of your code will benefit the agent as well.
Queries (PREVIEW)
Section titled “Queries (PREVIEW)”> Note: The queries capability is in PREVIEW. Deployment requires allow_preview=True. Please contact us first!
Pre-defined queries let domain experts create common analytical queries that agents can discover and execute.
Defining Queries
Section titled “Defining Queries”Define queries as module-level functions that return a rai.Fragment:
import relationalai.semantics as raifrom my_project.model.core import model, Customer, Order
def segment_summary() -> rai.Fragment: # Topline metrics per customer value segment customer = Customer.ref() segment = Customer.ValueSegment.ref() order = Order.ref() g = rai.per(segment) return model.select( segment.name.alias("segment"), g.sum(customer.ltv).alias("revenue"), g.sum(order.profit) .where(customer.order(order)) .alias("profit") ).where( customer.value_segment(segment) )Registering Queries
Section titled “Registering Queries”from relationalai.agent.cortex import ( CortexAgentManager, DeploymentConfig, discover_imports, ToolRegistry, SourceCodeVerbalizer, QueryCatalog,)
def init_tools(): from my_project.model import core, computed, queries return ToolRegistry().add( model=core.model, description="Customers and orders", verbalizer=SourceCodeVerbalizer(core.model, core, computed), queries=QueryCatalog(queries.segment_summary) )
# Deploy with preview enabled — set allow_preview on DeploymentConfigmanager = CortexAgentManager( session=session, config=DeploymentConfig( agent_name="MY_ASSISTANT", database="EXAMPLE", schema="CORTEX", warehouse="COMPUTE_WH", allow_preview=True, ))
manager.deploy( init_tools=init_tools, imports=discover_imports(),)The agent can discover these queries and execute them with appropriate parameters based on user requests.
Packaging Code for Deployment
Section titled “Packaging Code for Deployment”When deploying, you need to provide code that runs inside Snowflake stored procedures. There are two parameters for this:
imports - Your Project Code
Section titled “imports - Your Project Code”The imports parameter packages your local Python files (model definitions, queries, etc.) and uploads them to Snowflake. Use discover_imports() to automatically find all modules imported by your init_tools function:
manager.deploy( init_tools=init_tools, imports=discover_imports() # Packages your project code)discover_imports() recursively discovers all local imports starting from the calling file. It excludes standard library and installed packages.
extra_packages - PyPI Dependencies
Section titled “extra_packages - PyPI Dependencies”The extra_packages parameter specifies PyPI packages that Snowflake will install in the stored procedure environment. Use this for third-party libraries your code depends on:
manager.deploy( init_tools=init_tools, imports=discover_imports(), extra_packages=["pandas==2.0.0", "numpy"] # Installed by Snowflake)Note: relationalai is included automatically.
Updating Agents
Section titled “Updating Agents”Update tool definitions without recreating the agent:
def init_tools_v2(): # Updated tool definitions ...
manager.update(init_tools=init_tools_v2, imports=discover_imports())Lifecycle
Section titled “Lifecycle”Check deployment status or tear down all resources:
print(manager.status()) # Reports what exists (agent, stage, sprocs)manager.cleanup() # Drops agent, sprocs, and stage — permanently loses SI conversation historyFunctions
Section titled “Functions”Functions exposed by this module.
relationalai.agent.cortex.api.client. Classes
Section titled “Classes”Classes exposed by this module.
relationalai.agent.cortex.cortex_agent_manager. relationalai.agent.cortex.deployment_config. relationalai.agent.cortex.deployment_config. relationalai.agent.cortex.tool. relationalai.agent.cortex.api.agent. relationalai.agent.cortex.api.agent. relationalai.agent.cortex.api.thread. relationalai.agent.cortex.chat. relationalai.agent.cortex.chat. relationalai.agent.cortex.tool. relationalai.agent.cortex.tool. relationalai.agent.cortex.tool. relationalai.agent.cortex.verbalize. relationalai.agent.cortex.verbalize. relationalai.agent.cortex.verbalize. relationalai.agent.cortex.queries. relationalai.agent.cortex.queries. Modules and Subpackages
Section titled “Modules and Subpackages”Submodules and subpackages available under this namespace.
discover_imports module provides utilities for discovering project imports for Snowflake stored procedure deployment. verbalize module provides verbalizers for presenting RAI model structure and semantics to Cortex agents. deployment_config module provides configuration and status types for Cortex agent deployments. queries module provides abstractions for managing pre-defined RAI queries that Cortex agents can discover and execute. tool module provides the tool abstraction and registry for RAI-powered Cortex agent tools. chat module provides a programmatic chat interface for interacting with deployed Cortex agents. cortex_agent_manager module provides a unified interface for managing Cortex agents with RAI-powered tools.