---
title: "How to Prepare Snowflake Data for AI: A 2026 Step-by-Step Guide"
url: "https://atlan.com/know/snowflake/prepare-snowflake-data-for-ai/"
description: "How to prepare Snowflake data for AI: a seven-step run order with SQL for tags, masking, DMFs, semantic views and Cortex Search, plus fixes for wrong answers."
author: "Emily Winks"
author_role: "Data Governance Expert"
published: "2026-11-02"
updated: "2026-11-02"
---

## How do you prepare Snowflake data for AI?

You prepare Snowflake data for AI by encoding meaning, permissions and quality as Snowflake objects before an agent reads them. Classify and mask sensitive columns by tag, describe tables and name owners, attach data metric functions, build a semantic view, redact and index documents, then give the agent's users a least-privilege access role and trace what the agent reads in access history.

What an agent-ready table carries:

- **Sensitivity tags**: your own tag, applied by classification through a tag map, with a masking policy attached to it
- **Meaning and ownership**: reviewed COMMENT descriptions and a named contact
- **A quality floor**: data metric functions with expectations
- **A semantic view**: relationships, metrics, sample values and verified queries

## Key takeaways

- Run the prep in dependency order: masking needs tags, semantic views draw on descriptions, agent access needs both.
- Tag-based masking, classification, DMFs, access history and lineage require Snowflake Enterprise Edition or higher.
- SAMPLE_VALUES with IS_ENUM on a dimension makes Cortex Analyst filter only on declared values, so keep the list current.
- Snowflake recommended moving from Cortex Analyst to Cortex Agents on 2026-08-28; semantic views carry over unchanged.

---

To prepare Snowflake data for AI, work through seven steps in dependency order: scope one domain with about 10 test questions, classify and mask sensitive columns by tag, describe tables and name owners, set data metric functions, build a semantic view, redact and index documents for Cortex Search, then give the agent's users a least-privilege access role and trace what the agent reads.

### Audit Your Data for AI Readiness

Runs a twelve-check audit of whether your Snowflake data is ready for AI agents, across meaning, trust, boundaries, and reproducibility, and returns a fetch list for every unknown. [Read the skill](/skills/ai-ready-data-audit.md).

*Paste into a new chat*

```
Use the skill at https://atlan.com/skills/ai-ready-data-audit.md to run a twelve-check AI-readiness audit on our Snowflake data. Ask me for whatever it needs.
```

*Run once in a terminal*

```
curl -fsSL --create-dirs \
  -o ~/.agents/skills/ai-ready-data-audit/SKILL.md \
  https://atlan.com/skills/ai-ready-data-audit.md
```

*For an agent*

```
curl -fsSL https://atlan.com/skills/ai-ready-data-audit.md
```


    Human
    Agent


  ClaudeChatGPTGeminiCursorOther
  Copy

---

Call the result an agent-ready table: a Snowflake table with classification tags, masking by tag, reviewed descriptions, a named owner, quality expectations and a place in a semantic view. Each step below ends with a check you can run before moving on.

- Cortex Agents is the consumer, [generally available since 2025-11-04 (Snowflake release notes)](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents).
- On 2026-08-28 Snowflake [recommended moving from Cortex Analyst to Cortex Agents](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-28-cortex-analyst-transition-cortex-agents), adding: "Your semantic views carry over unchanged."
- Tag-based masking, [classification](https://docs.snowflake.com/en/user-guide/classify-intro), [data metric functions](https://docs.snowflake.com/en/user-guide/data-quality-intro), [access history](https://docs.snowflake.com/en/user-guide/access-history) and [lineage](https://docs.snowflake.com/en/user-guide/ui-snowsight-lineage) require Enterprise Edition or higher.

| Item | Detail |
|---|---|
| Scope | One business domain, 5 to 10 tables, per [Snowflake's semantic views best-practices guide](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) |
| Difficulty | Intermediate: SQL plus role administration |
| Prerequisites | Enterprise Edition for Steps 2, 4 and 7; a role with the create privileges in the checklist below; about 10 test questions |
| Tools | Snowsight or SQL, Cortex Agents, optionally the Snowflake-managed MCP server |

---

## Why does Snowflake data need preparation before an AI agent can use it?

An agent in Snowflake [generates SQL](https://atlan.com/know/ai-agent/data-for-ai/text-to-sql-for-enterprise/) from the semantic view and the metadata behind it. Preparing data for AI means encoding meaning, permissions and quality as Snowflake objects before the agent reads them.

Snowflake's [Horizon Catalog documentation](https://docs.snowflake.com/en/user-guide/snowflake-horizon) puts the problem plainly: "Without business context, AI agents cannot distinguish authoritative assets from noise." A column called `amt` in three schemas looks identical to a model until a description and an owner tell them apart.

Permissions follow the person asking. The [Cortex Agents documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents) says the service "determines permissions from the Snowflake context of the request," so loose grants on your users' roles become loose answers.

Snowflake also publishes a scoring model. Its [AI-Ready Data Framework guide](https://www.snowflake.com/en/developers/guides/ai-ready-data-framework-guide/) (as of its Apr 7, 2026 update) "provides six factors, 62 measurable requirements, and five workload profiles," and the agents profile carries 37 of those requirements. The framework "ships as an installable agent skill" that "scores every requirement 0-1, and guides you through remediation." Snowflake marks the guide as not maintained on an ongoing basis. Use the framework to score a domain; the run order below sequences the Snowflake objects for one domain.

For the platform-neutral view, start with [what makes data AI-ready](https://atlan.com/know/ai-agent/data-for-ai/what-makes-data-ai-ready/) or a broader [AI readiness assessment](https://atlan.com/know/ai-readiness/ai-ready-data/). The map of [where Snowflake's native context ends](https://atlan.com/know/context-layer-for-snowflake/) covers the boundary question.





---

## What order should you prepare Snowflake data for AI in?

Prepare Snowflake data for AI in dependency order, because each object builds on the one before it: masking needs tags, semantic views draw on described columns, and agent access needs both.

Classification applies your own tag through a tag map, and the masking policy attaches to that tag. Descriptions feed the semantic view. Lineage comes last because it can only trace objects you have already built, and an agent appears in lineage only if it was created, or had a new version committed, after [the 2026-09-02 change](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage). The shape matches a [platform-neutral prep guide](https://atlan.com/know/ai-agent/data-for-ai/how-to-prepare-enterprise-data-for-ai-agents/) and [preparing data for natural language analytics](https://atlan.com/know/ai-readiness/how-to-prepare-data-for-natural-language-analytics/); the table maps it to Snowflake objects, numbered by step.

| Step | What you are doing | Snowflake object or command | Status (as of 2026-11-02) | Source |
|---|---|---|---|---|
| 1 | Pick one domain and 10 test questions before touching a table | Evaluation set; start with 5 to 10 tables | Guidance | [Best-practices guide (Feb 3, 2026)](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) |
| 2a | Find sensitive columns automatically | `SNOWFLAKE.DATA_PRIVACY.CLASSIFICATION_PROFILE` with `'auto_tag': true` and a `tag_map`, then `ALTER DATABASE ... SET CLASSIFICATION_PROFILE` | AI mode: Public Preview (2026-08-17) | [Use SQL to set up sensitive data classification](https://docs.snowflake.com/en/user-guide/classify-auto); [2026-08-17 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-17-sensitive-data-classification-ai-mode-preview) |
| 2b | Protect them once, by tag | `CREATE TAG`, `CREATE MASKING POLICY`, `ALTER TAG ... SET MASKING POLICY` | Tag-based masking documented; tag-based row access, aggregation, projection and join policies: Public Preview (2026-07-21) | [Tag-based masking](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies); [Object tagging](https://docs.snowflake.com/en/user-guide/object-tagging/introduction); [2026-07-21 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-07-21-tag-based-policies-preview) |
| 3a | Say what each table and column means | `COMMENT ON ... IS`, or `CALL AI_GENERATE_TABLE_DESC(...)` then review | SQL descriptions GA (2025-09-29) | [COMMENT](https://docs.snowflake.com/en/sql-reference/sql/comment); [SQL descriptions](https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions); [2025-09-29 note](https://docs.snowflake.com/en/release-notes/2025/other/2025-09-29-sql-object-descriptions) |
| 3b | Name an owner the agent's answers trace back to | `CREATE CONTACT`, `ALTER TABLE ... SET CONTACT STEWARD = ...` | GA (2025-08-08) | [Using Contacts](https://docs.snowflake.com/en/user-guide/contacts-using); [2025-08-08 note](https://docs.snowflake.com/en/release-notes/2025/other/2025-08-08-contacts) |
| 4 | Put a measurable quality floor under the table | `ALTER TABLE ... ADD DATA METRIC FUNCTION ... EXPECTATION`, `DATA_METRIC_SCHEDULE` | Cortex Data Quality suggestions and Snowsight UI: Preview (2026-02-23); dashboard: Public Preview (2026-07-29) | [Use SQL to set up DMFs](https://docs.snowflake.com/en/user-guide/data-quality-working); [Expectations](https://docs.snowflake.com/en/user-guide/data-quality-expectations); [2026-02-23 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-02-23-data-quality-monitoring-setup); [2026-07-29 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-07-29-data-quality-monitoring-dashboard-pupr) |
| 5 | Encode business meaning the agent generates SQL from | `CREATE SEMANTIC VIEW` with relationships, facts, metrics, `SAMPLE_VALUES`/`IS_ENUM`, `AI_SQL_GENERATION`, `AI_VERIFIED_QUERIES`, `TAG` | Querying GA (release 9.25, Aug 2025); verified queries in DDL 2026-04-05; sample values in DDL 2026-06-25; range joins and `USING` relationship option: Preview | [CREATE SEMANTIC VIEW](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view); [SQL guide](https://docs.snowflake.com/en/user-guide/views-semantic/sql); [Release 9.25](https://docs.snowflake.com/en/release-notes/2025/9_25) |
| 6 | Make documents and free text retrievable | `AI_PARSE_DOCUMENT`, `AI_REDACT`, `CREATE CORTEX SEARCH SERVICE`; `WITH CORTEX SEARCH SERVICE` on fuzzy-matched dimensions | AI_REDACT GA (2025-12-08); multi-index search GA (2026-03-12) | [CREATE CORTEX SEARCH SERVICE](https://docs.snowflake.com/en/sql-reference/sql/create-cortex-search); [AI_REDACT](https://docs.snowflake.com/en/sql-reference/functions/ai_redact); [2025-12-08 note](https://docs.snowflake.com/en/release-notes/2025/other/2025-12-08-ai-redact-ga); [2026-03-12 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-03-12-recent-cortex-search) |
| 7a | Expose it to the agent with least privilege | `CREATE AGENT` with Cortex Analyst and Cortex Search tools; optionally `CREATE MCP SERVER`; grants to an access role | Cortex Agents GA (2025-11-04); managed MCP server GA (2025-11-04) | [2025-11-04 Cortex Agents note](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents); [2025-11-04 MCP note](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents-mcp); [MCP server docs](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) |
| 7b | Make every answer traceable | `SNOWFLAKE.CORE.GET_LINEAGE`; external lineage through OpenLineage events | Agent lineage (2026-09-02); external lineage GA (2026-09-03); semantic views: object-level lineage, for views created from early Feb 2026 | [Data lineage](https://docs.snowflake.com/en/user-guide/ui-snowsight-lineage); [GET_LINEAGE](https://docs.snowflake.com/en/sql-reference/functions/get_lineage-snowflake-core); [2026-09-02 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage); [2026-09-03 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-03-external-lineage-ga) |
| 7c | Watch what the agent actually reads | `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY`, including the `agents_info` column | Documented; Enterprise Edition; `agents_info` added 2026-08-03 | [Access History](https://docs.snowflake.com/en/user-guide/access-history); [2026-08-03 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-03-access-history-agents-info-column) |

---

## What do you need before you start preparing Snowflake data for AI?

Before you start, confirm your Snowflake edition, your role's privileges and your test questions, because three of the seven steps rely on Enterprise Edition features.

### Edition check

| Prep capability | Edition requirement (Snowflake docs, verbatim) | Source |
|---|---|---|
| Create and set tags | "Creating and setting tags is available to all accounts." | [Introduction to object tagging](https://docs.snowflake.com/en/user-guide/object-tagging/introduction) |
| Tag propagation, tag-based masking | "Your account must be Enterprise Edition or higher to use the following capabilities:" followed by "Tag propagation" and "Tag-based masking policies" | [Introduction to object tagging](https://docs.snowflake.com/en/user-guide/object-tagging/introduction) |
| Sensitive data classification | "Sensitive data classification requires Enterprise Edition or higher." | [Sensitive data classification](https://docs.snowflake.com/en/user-guide/classify-intro) |
| DMFs and data quality monitoring | "Data Quality Monitoring requires Enterprise Edition." | [Introduction to data quality checks](https://docs.snowflake.com/en/user-guide/data-quality-intro) |
| Access history | "Access History requires Enterprise Edition (or higher)." | [Access History](https://docs.snowflake.com/en/user-guide/access-history) |
| Data lineage | "This feature requires Enterprise Edition (or higher)." | [Data Lineage](https://docs.snowflake.com/en/user-guide/ui-snowsight-lineage) |

The [data quality introduction](https://docs.snowflake.com/en/user-guide/data-quality-intro) calls out trial accounts as unsupported for DMFs, so plan Step 4 on a paid Enterprise account.

### Access and people checklist

- [ ] A role that can create tags and masking policies ([tag-based masking](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies)), semantic views ([CREATE SEMANTIC VIEW](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view)), Cortex Search services ([CREATE CORTEX SEARCH SERVICE](https://docs.snowflake.com/en/sql-reference/sql/create-cortex-search)) and agents ([CREATE AGENT](https://docs.snowflake.com/en/sql-reference/sql/create-agent))
- [ ] A named steward or distribution list for the Step 3 contact
- [ ] One business domain and 5 to 10 tables
- [ ] About 10 representative questions with known-good answers, the evaluation set you reuse in Step 7

Scope and ownership are [context engineering](https://atlan.com/know/what-is-context-engineering/) decisions you make before any SQL runs. They are part of a [context layer](https://atlan.com/know/ai-readiness/context-layer-101/), too.

The SQL on this page follows the syntax in Snowflake's documentation code blocks; it was not run against a live account, so test each block in a dev account first.

---

## Step 1: Pick one domain and write ten test questions

Start by choosing one business domain and writing about ten questions the agent must answer correctly, so every later step has a test.

Scope keeps the semantic view small. [Snowflake's best-practices guide for semantic views](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) recommends starting with 5 to 10 tables and building an evaluation set of representative questions.

Pick a domain that already has an owner. Then write questions that probe the failure points in the symptom table further down:

- one filter on a category value, such as revenue for one region
- one loosely typed customer or product name
- one fiscal-period question

Check it: every question has an expected answer written down, and the table list sits inside the 5 to 10 range. Don't model the whole warehouse at once. When the steps are done, [test the result with the AI-ready data checklist](https://atlan.com/know/ai-agent/data-for-ai/ai-ready-data-checklist/).

---

## Step 2: Classify sensitive columns and mask them by tag

Classify sensitive columns automatically, map them to your own tag, then attach one masking policy to that tag so every column carrying it is masked.

Cortex Agents take permissions from the request, so masking applies to the role of the user asking ([how agent identity maps to a role](https://atlan.com/know/ai-agent/ai-agent-identity/)). Masking by tag protects every column that carries the tag. Add a tag map to the classification profile and the classifier applies that tag to new sensitive columns too, including columns added next quarter.

A [classification profile with `'auto_tag': true`](https://docs.snowflake.com/en/user-guide/classify-auto), set on the database, applies Snowflake's system classification tags as it classifies. A masking policy can't be assigned to a system tag, so add a `tag_map` that maps categories such as `EMAIL` to your own tag. Then create the tag and the policy, and attach the policy with `ALTER TAG ... SET MASKING POLICY`, per the [tag-based masking docs](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies). To scope rows by user as well, add a [row access policy](https://docs.snowflake.com/en/user-guide/security-row-intro).

Two limits matter. On wide tables, "the maximum number of unique tag-entity associations is 100" per CREATE or ALTER TABLE statement ([object tagging introduction](https://docs.snowflake.com/en/user-guide/object-tagging/introduction)). And once the policy sits on the tag, neither can be dropped. To swap the policy, use `ALTER TAG ... SET MASKING POLICY ... FORCE`; an unset followed by a set leaves the column unprotected in between, which the docs warn could lead to a data leak.

### SQL for this step

```sql
-- Step 2, tag and masking policy (Enterprise). Shape from tag-based-masking-policies (Example 1 and the column SET TAG example).
CREATE TAG IF NOT EXISTS governance.tags.pii;
CREATE MASKING POLICY IF NOT EXISTS governance.policies.email_mask
AS (val string) RETURNS string ->
  CASE
    WHEN CURRENT_ROLE() IN ('SALES_ADMIN') THEN val
    ELSE '***MASKED***'
  END;
ALTER TAG governance.tags.pii SET MASKING POLICY governance.policies.email_mask;
ALTER TABLE analytics.sales.orders MODIFY COLUMN
  customer_email SET TAG governance.tags.pii = 'email';
```

Sources: [Tag-based masking policies](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies); `IF NOT EXISTS` from [CREATE TAG](https://docs.snowflake.com/en/sql-reference/sql/create-tag) and [CREATE MASKING POLICY](https://docs.snowflake.com/en/sql-reference/sql/create-masking-policy). For role hierarchy, the CREATE MASKING POLICY page points to `IS_ROLE_IN_SESSION` over `CURRENT_ROLE`.

To classify at scale and map the classifier's `EMAIL` category to the masked tag:

```sql
-- Step 2, classification profile with a tag map. From classify-auto and CREATE CLASSIFICATION_PROFILE.
-- Run it in schema analytics.sch, the schema the ALTER DATABASE line names.
CREATE OR REPLACE SNOWFLAKE.DATA_PRIVACY.CLASSIFICATION_PROFILE
  my_classification_profile(
    {
      'minimum_object_age_for_classification_days': 0,
      'maximum_classification_validity_days': 30,
      'auto_tag': true,
      'tag_map': {
        'column_tag_map': [
          {
            'tag_name': 'governance.tags.pii',
            'tag_value': 'email',
            'semantic_categories': ['EMAIL']
          }
        ]
      },
      'classify_views': false
    });
ALTER DATABASE analytics
 SET CLASSIFICATION_PROFILE = 'analytics.sch.my_classification_profile';
```

Sources: [Use SQL to set up sensitive data classification](https://docs.snowflake.com/en/user-guide/classify-auto); [CREATE CLASSIFICATION_PROFILE](https://docs.snowflake.com/en/sql-reference/classes/classification_profile/commands/create-classification-profile).

Check it: a query run under a role other than `SALES_ADMIN` returns `***MASKED***` for `customer_email`, and after the next classification run a newly added email column carries `governance.tags.pii` and returns `***MASKED***` too. Masking column by column instead of by tag is how new PII columns slip through. For the wider pattern, see how teams [handle PII in AI pipelines](https://atlan.com/know/ai-agent/data-for-ai/how-to-handle-pii-in-ai-pipelines/).

---

## Step 3: Describe every table and column, and name an owner

Write a description for each table and column the agent will use and attach a named owner, because Semantic View Autopilot extracts those descriptions when it drafts a semantic view, and the owner is who checks a wrong answer.

Draft first, then review. [`AI_GENERATE_TABLE_DESC`](https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions) generates table and column descriptions in SQL. It returns a draft: to save one, "you must manually execute a SQL statement that includes the SET COMMENT parameter." Set `'use_table_data'` to `true` to sample table data, which the docs present as a way to improve accuracy. In Snowsight, bulk generation works "with a limit of 50 columns at a time," and a saved description "is preserved in the COMMENT property of the column, table, or view" ([Generate descriptions with Snowflake Cortex](https://docs.snowflake.com/en/user-guide/ui-snowsight-cortex-descriptions)).

The docs' own sample output reads: "A column holding data of type DecimalType representing age values." It describes the column's type, so review drafts before saving them.

Save the reviewed text with [`COMMENT ON TABLE` and `COMMENT ON COLUMN`](https://docs.snowflake.com/en/sql-reference/sql/comment). Since the [2026-10-12 Horizon Context preview](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-12-horizon-context-preview), "The APPLY COMMENT privilege lets data stewards curate descriptions without MODIFY or OWNERSHIP." Then make ownership an object: [Snowflake Contacts](https://docs.snowflake.com/en/user-guide/contacts-using) let you `CREATE CONTACT` and attach it with `SET CONTACT STEWARD`, and `SNOWFLAKE.CORE.GET_CONTACTS` shows who is attached.

An owner plus an expectation is the start of a [data contract for AI](https://atlan.com/know/ai-agent/data-for-ai/data-contracts-for-ai/).

### SQL for this step

```sql
-- 3a. Describe it. AI draft from sql-cortex-descriptions; COMMENT syntax from sql-reference/sql/comment.
-- The CALL returns a draft and does not save it.
CALL AI_GENERATE_TABLE_DESC(
  'analytics.sales.orders',
  {
    'describe_columns': true,
    'use_table_data': false
  });
COMMENT ON TABLE analytics.sales.orders IS 'One row per confirmed customer order, net of cancellations.';
COMMENT ON COLUMN analytics.sales.orders.amount IS 'Order value in USD after discounts, before tax.';

-- 3b. Owner. From contacts-using.
CREATE CONTACT sales_data_stewards EMAIL_DISTRIBUTION_LIST = 'sales-data@example.com';
ALTER TABLE analytics.sales.orders SET CONTACT STEWARD = sales_data_stewards;
```

Sources: [Using SQL to generate object descriptions](https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions); [COMMENT](https://docs.snowflake.com/en/sql-reference/sql/comment); [Using Contacts](https://docs.snowflake.com/en/user-guide/contacts-using).

Check it: every in-scope column has a non-empty COMMENT a business user would recognize, and `GET_CONTACTS` returns the steward.

---

## Step 4: Set a data quality floor with data metric functions

Attach data metric functions with expectations to each table, so stale, duplicated or null-heavy data shows up as a failed expectation you can alert on.

"A DMF measures an attribute of your data such as how many NULL values exist in a column," and "By default, the DMF schedule runs a DMF once every hour" ([data quality introduction](https://docs.snowflake.com/en/user-guide/data-quality-intro)). For a table loaded every few minutes, set a short interval such as `DATA_METRIC_SCHEDULE = '5 MINUTE'` or a CRON schedule, per [Use SQL to set up data metric functions](https://docs.snowflake.com/en/user-guide/data-quality-working). `TRIGGER_ON_CHANGES` runs only when DML modifies the table, so a FRESHNESS check on it never fires once loads stop. "All data metric functions on a table or view follow the same schedule," so the interval you pick covers every check below.

The [system DMFs](https://docs.snowflake.com/en/user-guide/data-quality-system-dmfs) include the three checks used below: `NULL_COUNT`, `DUPLICATE_COUNT` and `FRESHNESS`. Add an `EXPECTATION` to each and test with `SYSTEM$EVALUATE_DATA_QUALITY_EXPECTATIONS`, as the [expectations page](https://docs.snowflake.com/en/user-guide/data-quality-expectations) shows. DMFs "use serverless compute resources that incur costs," listed under Data Quality Monitoring on the monthly bill, so weigh that when you pick the interval.

### SQL for this step

```sql
-- 4. Quality floor (Enterprise). From data-quality-working and data-quality-expectations.
ALTER TABLE analytics.sales.orders SET
  DATA_METRIC_SCHEDULE = '5 MINUTE';
ALTER TABLE analytics.sales.orders
  ADD DATA METRIC FUNCTION SNOWFLAKE.CORE.NULL_COUNT ON (customer_id)
  EXPECTATION no_null_customers (VALUE = 0);
ALTER TABLE analytics.sales.orders
  ADD DATA METRIC FUNCTION SNOWFLAKE.CORE.DUPLICATE_COUNT ON (order_id)
  EXPECTATION no_duplicate_orders (VALUE = 0);
ALTER TABLE analytics.sales.orders
  ADD DATA METRIC FUNCTION SNOWFLAKE.CORE.FRESHNESS ON (loaded_at)
  EXPECTATION lessThan30Mins (VALUE < 1800);
SELECT *
  FROM TABLE(SYSTEM$EVALUATE_DATA_QUALITY_EXPECTATIONS(
      REF_ENTITY_NAME => 'analytics.sales.orders'));
```

Sources: [Use SQL to set up data metric functions](https://docs.snowflake.com/en/user-guide/data-quality-working); [Use SQL to work with expectations](https://docs.snowflake.com/en/user-guide/data-quality-expectations).

Check it: the evaluate call returns all three expectations passing. DMFs test the data; [context evals test the answer](https://atlan.com/know/ai-agent/ai-agent-evals/context-evals-vs-data-quality-testing/), and you want both. More on thresholds in [data quality for AI agents](https://atlan.com/know/data-for-ai/data-quality-for-ai-agent/).

---

## Step 5: Build a semantic view the agent generates SQL from

Define a [semantic view](https://atlan.com/know/semantic-views-human-meaning-to-materialized-context/) over your described tables, because Cortex Agents generate SQL from it.

"Semantic views improve accuracy by combining LLM reasoning with rule-based definitions," says the [semantic views overview](https://docs.snowflake.com/en/user-guide/views-semantic/overview). The view carries its own COMMENT clauses, so you copy the Step 3 text into it. Have one owner keep both current. Build it in this order, using [CREATE SEMANTIC VIEW](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view) and the [SQL guide for semantic views](https://docs.snowflake.com/en/user-guide/views-semantic/sql):

1. TABLES, each with a primary key.
2. RELATIONSHIPS. The [best-practices guide](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) says joins happen only when relationships are defined explicitly.
3. FACTS, the row-level values metrics are built from.
4. DIMENSIONS, with `WITH SYNONYMS` for the words people use and `SAMPLE_VALUES (...) IS_ENUM` on category columns. The [2026-06-25 release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-06-25-semantic-views-sample-values) states: "When IS_ENUM is set, Cortex Analyst only chooses from those values when filtering on the column." A value missing from the list can't be used as a filter, so update the list when a new region appears.
5. METRICS.
6. `AI_SQL_GENERATION` custom instructions, [in the DDL since 2026-01-12](https://docs.snowflake.com/en/release-notes/2026/other/2026-01-12-semantic-views-custom-instructions), for conventions such as the guide's example: "Our fiscal year starts on February 1st, not January 1st".
7. `AI_QUESTION_CATEGORIZATION` for questions the agent should decline (example in the symptom table below).
8. `AI_VERIFIED_QUERIES` with `VERIFIED_BY`, [in the DDL since 2026-04-05](https://docs.snowflake.com/en/release-notes/2026/other/2026-04-05-semantic-views-verified-queries). The best-practices guide suggests starting with 10 to 20.
9. `COPY GRANTS`, so a `CREATE OR REPLACE` keeps the Step 7 grants on the view.

For loosely typed product, customer or company names, add `WITH CORTEX SEARCH SERVICE` to the dimension; the best-practices guide reserves it for name columns over numeric or date columns. To skip the hand-written DDL, [Semantic View Autopilot](https://docs.snowflake.com/en/user-guide/views-semantic/autopilot) drafts a view in Snowsight, and [Semantic Studio](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-30-semantic-studio-ga) adds Git-backed versioning.

### SQL for this step

```sql
-- 5. Semantic view. Clause order from CREATE SEMANTIC VIEW; SAMPLE_VALUES, IS_ENUM, WITH SYNONYMS and VERIFIED_BY forms from the SQL guide.
CREATE OR REPLACE SEMANTIC VIEW analytics.sales.orders_sv
  TABLES (
    orders AS analytics.sales.orders
      PRIMARY KEY (order_id)
      COMMENT = 'Confirmed customer orders',
    customers AS analytics.sales.customers
      PRIMARY KEY (customer_id)
      COMMENT = 'One row per customer'
  )
  RELATIONSHIPS (
    orders_to_customers AS
      orders (customer_id) REFERENCES customers (customer_id)
  )
  FACTS (
    orders.amount AS amount
      COMMENT = 'Order value in USD after discounts, before tax'
  )
  DIMENSIONS (
    orders.region AS region
      WITH SYNONYMS = ('territory', 'sales region')
      COMMENT = 'Sales region'
      SAMPLE_VALUES ('AMER', 'EMEA', 'APAC')
      IS_ENUM,
    orders.order_date AS order_date
      COMMENT = 'Date the order was placed'
  )
  METRICS (
    orders.total_revenue AS SUM(orders.amount)
      WITH SYNONYMS = ('revenue', 'sales')
      COMMENT = 'Total order value in USD after discounts, before tax'
  )
  COMMENT = 'Revenue analysis for confirmed orders'
  AI_SQL_GENERATION 'Our fiscal year starts on February 1st. Round currency to 2 decimal places.'
  AI_VERIFIED_QUERIES (
    revenue_by_region_fy2025 AS (
      QUESTION 'What was total revenue by region in fiscal year 2025 (Feb 2025 to Jan 2026)?'
      VERIFIED_BY '(STEWARD = sales_data_stewards)'
      SQL 'SELECT region, SUM(amount) AS total_revenue FROM orders WHERE order_date >= ''2025-02-01'' AND order_date < ''2026-02-01'' GROUP BY region'
    )
  )
  COPY GRANTS;
```

Sources: [CREATE SEMANTIC VIEW](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view); [Using SQL commands to create and manage semantic views](https://docs.snowflake.com/en/user-guide/views-semantic/sql); [SAMPLE_VALUES and IS_ENUM release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-06-25-semantic-views-sample-values). The fiscal-year date range in the verified query is our example; it filters on the `order_date` column the view declares.

Check it: each Step 1 question returns its expected answer, and a filter on "EMEA" returns rows. Don't skip RELATIONSHIPS: Cortex Analyst will not join tables unless relationships are explicitly defined. For a deeper walk through the DDL, read [Snowflake semantic views in depth](https://atlan.com/know/snowflake/snowflake-semantic-views/).

---

## Step 6: Redact and index documents with Cortex Search

Parse documents and transcripts, redact personal data with AI_REDACT, then index only the clean text in a Cortex Search service.

Start with `AI_PARSE_DOCUMENT` for files or `AI_TRANSCRIBE` for audio, as the [AI_REDACT docs](https://docs.snowflake.com/en/sql-reference/functions/ai_redact) suggest. Then redact. Snowflake states that AI_REDACT "performs detection and redaction in a best-effort manner using AI models," so review a sample of the output before you index it. `CREATE TABLE ... AS SELECT` redacts the rows that exist today; new transcripts need the same AI_REDACT step on arrival before the service refreshes.

Index the redacted table with [CREATE CORTEX SEARCH SERVICE](https://docs.snowflake.com/en/sql-reference/sql/create-cortex-search), using `ATTRIBUTES` for filter columns and `TARGET_LAG` for refresh. "Cortex Search Services perform searches with owner's rights," and a querying role needs USAGE on the service, its database and its schema ([Cortex Search overview](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)). Create the service under a role that can read only the redacted table, and keep the raw transcripts table out of your users' access role.

Lineage has a gap on this path. Since [2026-10-06](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-06-lineage-integrations-monitors-search), lineage links a stage to a Cortex Search service created from that stage in Snowsight, a creation path that is still in preview. A service created with CREATE CORTEX SEARCH SERVICE, as below, doesn't record those stage relationships.

### SQL for this step

```sql
-- 6. Unstructured text: redact, then index. From ai_redact and create-cortex-search.
CREATE OR REPLACE TABLE support_db.public.transcripts_clean AS
  SELECT ticket_id, region, AI_REDACT(transcript_text) AS transcript_text
  FROM support_db.public.transcripts_raw;
CREATE OR REPLACE CORTEX SEARCH SERVICE support_db.public.transcripts_svc
  ON transcript_text
  ATTRIBUTES region
  WAREHOUSE = mywh
  TARGET_LAG = '1 hour'
AS (
  SELECT transcript_text, region, ticket_id
  FROM support_db.public.transcripts_clean
);
```

Sources: [AI_REDACT](https://docs.snowflake.com/en/sql-reference/functions/ai_redact); [CREATE CORTEX SEARCH SERVICE](https://docs.snowflake.com/en/sql-reference/sql/create-cortex-search).

Check it: a search for a known customer email returns the redacted token. Indexing raw transcripts and redacting later is the order to avoid. The same discipline applies to all [unstructured data for AI](https://atlan.com/know/data-for-ai/unstructured-data-for-ai/).

---

## Step 7: Expose it to the agent with least privilege, then trace what it reads

Create the agent, grant its users an access role that reaches only the semantic view, the tables under it and the search service, then use lineage and access history to confirm what it reads.

### Wire the agent

Create a Cortex Agent with a Cortex Analyst tool over the semantic view and a Cortex Search tool over the search service. The agent "determines permissions from the Snowflake context of the request," and "If the caller's role can't use every configured tool, the run can still continue with the tools it can access" ([Cortex Agents](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents)). Least privilege therefore lives on the users' role.

Agents outside Snowflake reach it through the [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp), [GA since 2025-11-04](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents-mcp), one of several [MCP server options for Snowflake](https://atlan.com/know/mcp/mcp-server-for-snowflake/). The MCP docs say "By default, MCP OAuth sessions use the connecting user's `DEFAULT_ROLE` as the primary role," so set each user's `DEFAULT_ROLE` to the access role. "OAuth scopes control only the primary role for the MCP session. Secondary roles are separate and are controlled by the OAuth security integration." Grants are per tool, too: "Access to the MCP Server does not give access to the tools."

Keep raw SQL apart. The MCP docs warn: "Exposing SYSTEM_EXECUTE_SQL on the same server allows the MCP client to bypass the agent's semantic views, verified queries, and orchestration." Put that tool on a separate server with a least-privileged role. For the pattern beyond Snowflake, see [serving semantic definitions over MCP](https://atlan.com/know/ai-agent/semantic-layer/mcp-semantic-layer-for-ai-agents/).

At run time, [Cortex AI Guardrails for CoWork and Cortex Agents became GA on 2026-05-14](https://docs.snowflake.com/en/release-notes/2026/other/2026-05-14-cortex-ai-guardrails-si-cortex-agents) for prompt-injection protection, which matters once [Snowflake CoWork](https://atlan.com/know/snowflake/snowflake-cowork/) users start asking questions.

```sql
-- 7a. Agent, MCP server and access role. Forms from create-agent and cortex-agents-mcp; replace .
-- The agent spec keeps only the models, tools and tool_resources keys from the docs' first example.
CREATE OR REPLACE AGENT analytics.sales.orders_agent
  FROM SPECIFICATION
  $$
  models:
    orchestration: auto
  tools:
    - tool_spec:
        type: "cortex_analyst_text_to_sql"
        name: "Analyst1"
        description: "Answers revenue questions from the orders semantic view"
    - tool_spec:
        type: "cortex_search"
        name: "Search1"
        description: "Searches redacted support transcripts"
  tool_resources:
    Analyst1:
      semantic_view: "analytics.sales.orders_sv"
    Search1:
      search_service: "support_db.public.transcripts_svc"
      max_results: "5"
  $$;

CREATE OR REPLACE MCP SERVER analytics.sales.orders_mcp
  FROM SPECIFICATION $$
  tools:
    - title: "Governed business data agent"
      name: "business_data_agent"
      type: "CORTEX_AGENT_RUN"
      identifier: "analytics.sales.orders_agent"
      description: "Use this agent for governed business data questions."
  $$;

CREATE ROLE ;

GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER TO ROLE ;

GRANT USAGE ON WAREHOUSE  TO ROLE ;
GRANT USAGE ON DATABASE  TO ROLE ;
GRANT USAGE ON SCHEMA . TO ROLE ;
GRANT USAGE ON MCP SERVER analytics.sales.orders_mcp TO ROLE ;
GRANT USAGE ON AGENT analytics.sales.orders_agent TO ROLE ;

GRANT ROLE  TO USER ;
ALTER USER  SET DEFAULT_ROLE = '' DEFAULT_WAREHOUSE = '';

-- Only the resources the agent uses: the semantic view, the tables it reads, and the search service.
GRANT SELECT ON SEMANTIC VIEW analytics.sales.orders_sv TO ROLE ;
GRANT SELECT ON TABLE analytics.sales.orders TO ROLE ;
GRANT SELECT ON TABLE analytics.sales.customers TO ROLE ;
GRANT USAGE ON DATABASE support_db TO ROLE ;
GRANT USAGE ON SCHEMA support_db.public TO ROLE ;
GRANT USAGE ON CORTEX SEARCH SERVICE support_db.public.transcripts_svc TO ROLE ;
```

Sources: [CREATE AGENT](https://docs.snowflake.com/en/sql-reference/sql/create-agent); [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).

### Trace and audit

[`GET_LINEAGE`](https://docs.snowflake.com/en/sql-reference/functions/get_lineage-snowflake-core) shows what sits downstream of a table, now including agents. The [2026-09-02 release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage) adds a catch: "an agent whose most recent version was committed before this change doesn't appear in lineage until you commit a new version." Semantic views have their own limit: per the [lineage docs](https://docs.snowflake.com/en/user-guide/ui-snowsight-lineage), lineage covers semantic views created from early February 2026 onward, at object level only, so recreate an older view to see it. [External lineage became GA on 2026-09-03](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-03-external-lineage-ga), so OpenLineage events from your transformation and orchestration tools join the same graph.

[`ACCESS_HISTORY`](https://docs.snowflake.com/en/user-guide/access-history) records which objects each query read, by user, and since [2026-08-03 its `agents_info` column](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-03-access-history-agents-info-column) names the Cortex Agent that read data on a user's behalf. The view can lag by up to 3 hours ([Account Usage](https://docs.snowflake.com/en/sql-reference/account-usage)), so check after that window. See [tracing AI answers to source](https://atlan.com/know/ai-agent/data-for-ai/data-lineage-for-ai/) and [AI-ready data lineage](https://atlan.com/know/ai-readiness/ai-ready-data-lineage/).

```sql
-- 7b. Verify lineage and access. From get_lineage-snowflake-core, access-history and the 2026-08-03 agents_info note.
SELECT DISTANCE, SOURCE_OBJECT_NAME, TARGET_OBJECT_DOMAIN, TARGET_OBJECT_NAME
FROM TABLE (SNOWFLAKE.CORE.GET_LINEAGE('analytics.sales.orders', 'TABLE', 'DOWNSTREAM', 2));

SELECT user_name, query_id, query_start_time, direct_objects_accessed, base_objects_accessed, agents_info
FROM snowflake.account_usage.access_history
ORDER BY 1, 3 desc;
```

Sources: [GET_LINEAGE](https://docs.snowflake.com/en/sql-reference/functions/get_lineage-snowflake-core); [Access History](https://docs.snowflake.com/en/user-guide/access-history); [agents_info release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-03-access-history-agents-info-column).

Check it: rerun the Step 1 evaluation set through the agent, then confirm the ACCESS_HISTORY rows whose agents_info names your agent show only in-scope objects.

---

## Why is your Snowflake agent giving wrong answers?

Each row pairs a symptom with the prep step and the Snowflake feature that addresses it.

| What you see | Prep step that is missing | Snowflake feature that fixes it | Source |
|---|---|---|---|
| Filter uses a value that isn't stored (asks for "Americas", column holds "AMER") | Representative values not declared | `SAMPLE_VALUES (...) IS_ENUM` on the dimension | "When IS_ENUM is set, Cortex Analyst only chooses from those values when filtering on the column." [2026-06-25 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-06-25-semantic-views-sample-values) |
| A loosely typed customer or product name never matches | Fuzzy text match not wired | `WITH CORTEX SEARCH SERVICE` on the dimension, for product, customer or company names over numeric or date columns | [SQL guide](https://docs.snowflake.com/en/user-guide/views-semantic/sql); [Best-practices guide](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) |
| A question that spans two tables fails or joins wrong | Relationships not declared | `RELATIONSHIPS (...)` in the semantic view | Joins happen only when relationships are defined explicitly: [Best-practices guide (Feb 3, 2026)](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) |
| Fiscal-year or rounding conventions ignored | Org conventions not written down for the model | `AI_SQL_GENERATION ''` | [2026-01-12 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-01-12-semantic-views-custom-instructions); guide example "Our fiscal year starts on February 1st, not January 1st". |
| Agent answers questions it should refuse or clarify | Question categorization not set | `AI_QUESTION_CATEGORIZATION ''` | "Reject all questions asking about users. Ask users to contact their admin." [SQL guide](https://docs.snowflake.com/en/user-guide/views-semantic/sql) |
| Answers to common questions drift between runs | Common questions not pinned to verified answers | `AI_VERIFIED_QUERIES (...)`; start with 10 to 20 | [2026-04-05 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-04-05-semantic-views-verified-queries); 10 to 20 from the [Best-practices guide](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/) |
| Column descriptions read "A column holding data of type ..." | AI descriptions saved without review | `AI_GENERATE_TABLE_DESC` output reviewed, then `COMMENT ON COLUMN` | "A column holding data of type DecimalType representing age values." [SQL descriptions](https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions) |
| Agent returns raw emails or names | Sensitive columns not classified and masked | Classification profile with `auto_tag` and a `tag_map`, plus a masking policy on the mapped tag | [Use SQL to set up sensitive data classification](https://docs.snowflake.com/en/user-guide/classify-auto); [Tag-based masking](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies) |
| PII appears in answers drawn from documents or transcripts | Unstructured text not redacted before indexing | `AI_REDACT` before `CREATE CORTEX SEARCH SERVICE` | "AI_REDACT performs detection and redaction in a best-effort manner using AI models." [AI_REDACT](https://docs.snowflake.com/en/sql-reference/functions/ai_redact) |
| Confident answer from a table that stopped loading | Freshness floor not set on a time-based schedule | `SNOWFLAKE.CORE.FRESHNESS` DMF with an `EXPECTATION`, and `DATA_METRIC_SCHEDULE = '5 MINUTE'` or a CRON schedule | [Expectations](https://docs.snowflake.com/en/user-guide/data-quality-expectations); [Use SQL to set up DMFs](https://docs.snowflake.com/en/user-guide/data-quality-working) |
| MCP client gets answers that ignore the semantic view | Raw SQL tool exposed next to the governed tool | Keep `SYSTEM_EXECUTE_SQL` on a separate MCP server with a least-privileged role | "Exposing SYSTEM_EXECUTE_SQL on the same server allows the MCP client to bypass the agent's semantic views, verified queries, and orchestration" [MCP server docs](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) |
| You cannot tell which tables an agent can reach | Agent missing from lineage | Commit a new agent version after 2026-09-02 | "an agent whose most recent version was committed before this change doesn't appear in lineage until you commit a new version." [2026-09-02 note](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage) |
| Nobody knows who to ask when an answer looks wrong | Owner not attached to the object | `CREATE CONTACT` + `SET CONTACT STEWARD`; `VERIFIED_BY '(STEWARD = data_stewards)'` | [Using Contacts](https://docs.snowflake.com/en/user-guide/contacts-using); [SQL guide](https://docs.snowflake.com/en/user-guide/views-semantic/sql) |

Prep built once decays as tables and owners change. Rerun the Step 1 evaluation set after every schema change, and use the symptom table as a triage list.

---

## What changed in Snowflake's AI data prep features in 2025 and 2026?

Between April 2025 and October 2026, Snowflake added the semantic view clauses, lineage and audit columns this page uses, and made Cortex Agents the recommended consumer. The run-order table carries the other dates.

| Date | Change | Why it matters for prep | Release note |
|---|---|---|---|
| 2025-04-17 | Semantic views (Preview) | Semantic models can be stored as schema-level objects | [2025-04-17](https://docs.snowflake.com/en/release-notes/2025/other/2025-04-17-semantic-views) |
| 2025-08-25 to 08-28 | Querying semantic views GA (release 9.25) | SELECT ... SEMANTIC_VIEW is production | [Release 9.25](https://docs.snowflake.com/en/release-notes/2025/9_25) |
| 2025-11-04 | Cortex Agents GA; Snowflake-managed MCP server GA | The consumer of all this prep, inside and outside Snowflake | [Agents](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents); [MCP](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents-mcp) |
| 2026-08-03 | `agents_info` column in ACCESS_HISTORY | Names the agent behind each access | [2026-08-03](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-03-access-history-agents-info-column) |
| 2026-08-28 | Snowflake recommends moving from Cortex Analyst to Cortex Agents | Prep targets the agent; "Your semantic views carry over unchanged." | [2026-08-28](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-28-cortex-analyst-transition-cortex-agents) |
| 2026-09-02 | Data lineage for Cortex Agents | Trace table to semantic view to agent | [2026-09-02](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage) |
| 2026-09-30 | Semantic Studio GA | Authoring and Git-backed versioning for semantic views | [2026-09-30](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-30-semantic-studio-ga) |
| 2026-10-12 | Horizon Context (Preview), APPLY COMMENT privilege | Horizon Catalog can browse external assets, trace column-level lineage across platforms, and manage tags and descriptions for 18 external sources | [2026-10-12](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-12-horizon-context-preview) |

The biggest shift is the 2026-08-28 recommendation. The [release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-28-cortex-analyst-transition-cortex-agents) says Cortex Agents "supports every Cortex Analyst capability with higher answer quality," and "Existing applications continue to work, and the Cortex Analyst REST API remains available." Prep you did for Cortex Analyst still counts.

[Snowflake Horizon Context](https://atlan.com/know/snowflake/snowflake-horizon-context/), in Preview since 2026-10-12, "extends Horizon Catalog beyond Snowflake." You can connect it to 18 sources, including BI tools and other databases, and manage their tags and descriptions in Horizon Catalog, per the [release note](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-12-horizon-context-preview). [How Horizon Context and the Atlan context layer work together](https://atlan.com/know/snowflake/snowflake-horizon-context-and-atlan-context-layer/) goes deeper.

---

## How Atlan keeps Snowflake AI prep in sync with the rest of your context

Atlan, the Context Layer for AI, reads the tags and descriptions you set in Snowflake, syncs tags in both directions, and connects them to context from your other systems.

Inside a single Snowflake account, Horizon Catalog and Horizon Context hold this metadata. The design question is where definitions live when agents and data span more than one platform, which is what an [enterprise context layer](https://atlan.com/know/what-is-the-enterprise-context-layer/) answers.

Per docs.atlan.com:

- [Atlan's Snowflake connector](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake) crawls Snowflake databases, schemas, tables, views and procedures, and "builds column-level lineage from query history automatically."
- "Atlan reads object tags from Horizon and synchronizes them bidirectionally between Snowflake and Atlan" ([crawl reference](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/references/what-does-atlan-crawl-from-snowflake)). [Reverse sync](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/how-tos/manage-snowflake-tags) updates tags that already exist in Snowflake, and tag sync relies on Enterprise Edition ACCOUNT_USAGE views.
- "Syncing Snowflake COMMENT fields into the Description field in Atlan is enabled by default," so Step 3 seeds Atlan's descriptions.
- Masking and row access policies stay defined in Snowflake and are enforced by its query engine: "Governance policies execute at the query engine layer, not the application layer" ([Horizon Catalog docs](https://docs.snowflake.com/en/user-guide/snowflake-horizon)).
- Atlan can "Monitor the quality of your Snowflake assets in Atlan using Snowflake's native data metric functions" ([Data Quality Studio docs](https://docs.atlan.com/product/capabilities/governance/data-quality/snowflake)). Configuring Snowflake DMFs for Atlan is labeled Private Preview on [docs.atlan.com](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/how-tos/configure-snowflake-data-metric-functions) as of 2026-11-02, and is supported only on Enterprise and Business Critical editions.
- The [Atlan MCP setup docs](https://docs.atlan.com/product/capabilities/atlan-ai/how-tos/remote-mcp-overview) list Snowflake: "Connect from the Snowflake UI so CoWork agents can use Atlan tools, or register the server with the Cortex Code CLI." Atlan MCP "is hosted and enabled for all Atlan tenants, with nothing to install or run." See what the [Atlan MCP server](https://atlan.com/know/what-is-atlan-mcp/) exposes.

For the architecture, see [how the context layer works with Snowflake's data plane](https://atlan.com/know/snowflake/atlan-snowflake-architecture/).

---

## FAQs about preparing Snowflake data for AI

### 1. What does AI-ready data mean in Snowflake?

Snowflake's AI-Ready Data Framework defines it with six factors, 62 measurable requirements and five workload profiles, as of the guide's Apr 7, 2026 update. The agents profile carries 37 of those requirements. In practice, AI-ready Snowflake data carries tags, masking, descriptions, owners, quality expectations and a semantic view an agent can generate SQL from.

### 2. Do you need Snowflake Enterprise Edition to prepare data for AI?

Tag-based masking, sensitive data classification, data metric functions, access history and lineage all require Enterprise Edition or higher, according to Snowflake's docs. Creating and setting tags is available to all accounts. For other features, check the edition banner on each docs page.

### 3. Should you prepare data for Cortex Analyst or Cortex Agents?

Prepare for Cortex Agents. On 2026-08-28 Snowflake recommended transitioning to Cortex Agents, which it says supports every Cortex Analyst capability with higher answer quality. Your semantic views carry over unchanged, and the Cortex Analyst REST API remains available.

### 4. Can Snowflake write table and column descriptions for you?

Yes. AI_GENERATE_TABLE_DESC drafts descriptions in SQL, generally available since 2025-09-29, and Snowsight generates them in bulk, 50 columns at a time. Review each draft before saving, because the saved text lands in the COMMENT property, which Semantic View Autopilot extracts when it drafts a semantic view.

### 5. How many verified queries should a semantic view start with?

Start with 10 to 20 verified queries for the most common questions, per Snowflake's best-practices guide for semantic views. Since 2026-04-05 they live in the AI_VERIFIED_QUERIES clause of the semantic view DDL, versioned with the view.

### 6. How do you keep PII out of answers from Snowflake agents?

Classify columns with a classification profile set to auto_tag, with a tag map that applies your own sensitivity tag, attach a masking policy to that tag, and run AI_REDACT on documents before indexing them in Cortex Search. Snowflake describes AI_REDACT as best-effort, so review a sample of its output.

### 7. When did Snowflake semantic views become generally available?

Querying semantic views became generally available in Snowflake release 9.25, in late August 2025. Semantic views entered Preview on 2025-04-17, and Semantic Studio, the authoring tool, became generally available on 2026-09-30.

---

## Sources

1. [AI-Ready Data Framework: Assess and Remediate Your Data for AI, Snowflake Developers](https://www.snowflake.com/en/developers/guides/ai-ready-data-framework-guide/)

2. [Best Practices for Creating Semantic Views for Cortex Analyst, Snowflake Developers](https://www.snowflake.com/en/developers/guides/best-practices-semantic-views-cortex-analyst/)

3. [CREATE SEMANTIC VIEW, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view)

4. [Using SQL commands to create and manage semantic views, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/views-semantic/sql)

5. [Overview of semantic views, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/views-semantic/overview)

6. [Semantic View Autopilot, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/views-semantic/autopilot)

7. [Tag-based masking policies, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/tag-based-masking-policies)

8. [Introduction to object tagging, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/object-tagging/introduction)

9. [CREATE TAG, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/create-tag)

10. [CREATE MASKING POLICY, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/create-masking-policy)

11. [Understanding row access policies, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/security-row-intro)

12. [Introduction to sensitive data classification, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/classify-intro)

13. [Use SQL to set up sensitive data classification, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/classify-auto)

14. [CREATE CLASSIFICATION_PROFILE, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/classes/classification_profile/commands/create-classification-profile)

15. [Introduction to data quality checks, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/data-quality-intro)

16. [Use SQL to set up data metric functions, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/data-quality-working)

17. [Use SQL to work with expectations, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/data-quality-expectations)

18. [System data metric functions, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/data-quality-system-dmfs)

19. [COMMENT, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/comment)

20. [Generate descriptions with Snowflake Cortex, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/ui-snowsight-cortex-descriptions)

21. [Using SQL to automatically generate object descriptions, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions)

22. [Using Contacts, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/contacts-using)

23. [CREATE CORTEX SEARCH SERVICE, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/create-cortex-search)

24. [Cortex Search, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)

25. [AI_REDACT, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/functions/ai_redact)

26. [Access History, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/access-history)

27. [Account Usage, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/account-usage)

28. [Data Lineage, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/ui-snowsight-lineage)

29. [GET_LINEAGE (SNOWFLAKE.CORE), Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/functions/get_lineage-snowflake-core)

30. [Snowflake Horizon Catalog, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/snowflake-horizon)

31. [Cortex Agents, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents)

32. [CREATE AGENT, Snowflake Documentation](https://docs.snowflake.com/en/sql-reference/sql/create-agent)

33. [Snowflake-managed MCP server, Snowflake Documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp)

34. [Apr 17, 2025: Semantic views (Preview), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-04-17-semantic-views)

35. [Aug 08, 2025: Contacts (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-08-08-contacts)

36. [9.25 Release notes: Aug 25, 2025-Aug 28, 2025, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/9_25)

37. [Sep 29, 2025: Using SQL for Cortex Powered Object Descriptions (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-09-29-sql-object-descriptions)

38. [Nov 04, 2025: Cortex Agents (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents)

39. [Nov 04, 2025: Snowflake-managed MCP server (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-11-04-cortex-agents-mcp)

40. [Dec 08, 2025: AI_REDACT for automated redaction of PII (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2025/other/2025-12-08-ai-redact-ga)

41. [Jan 12, 2026: Specifying custom instructions in semantic views, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-01-12-semantic-views-custom-instructions)

42. [Feb 23, 2026: Simplified setup for Data Quality Monitoring, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-02-23-data-quality-monitoring-setup)

43. [Mar 12, 2026: Recent Cortex Search updates (Generally Available), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-03-12-recent-cortex-search)

44. [Apr 05, 2026: Support for verified queries in semantic views, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-04-05-semantic-views-verified-queries)

45. [May 14, 2026: Cortex AI Guardrails support for Snowflake CoWork and Cortex Agents (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-05-14-cortex-ai-guardrails-si-cortex-agents)

46. [June 25, 2026: Support for sample values and enum indicators in semantic view DDL, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-06-25-semantic-views-sample-values)

47. [July 21, 2026: Tag-based data protection policies (Public Preview), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-07-21-tag-based-policies-preview)

48. [Jul 29, 2026: Data quality monitoring dashboard (Public preview), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-07-29-data-quality-monitoring-dashboard-pupr)

49. [Aug 3, 2026: ACCESS_HISTORY view: New agents_info column, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-03-access-history-agents-info-column)

50. [August 17, 2026: AI mode for sensitive data classification (Public Preview), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-17-sensitive-data-classification-ai-mode-preview)

51. [Aug 28, 2026: Snowflake recommends transitioning from Cortex Analyst to Cortex Agents, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-08-28-cortex-analyst-transition-cortex-agents)

52. [Sep 02, 2026: Data lineage for Cortex Agents, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-02-cortex-agent-lineage)

53. [Sep 03, 2026: External lineage (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-03-external-lineage-ga)

54. [Sep 30, 2026: Semantic Studio (General availability), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-09-30-semantic-studio-ga)

55. [Oct 6, 2026: Data lineage for storage integrations, external tables, model monitors, and Cortex Search services, Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-06-lineage-integrations-monitors-search)

56. [Oct 12, 2026: Horizon Context (Preview), Snowflake Release Notes](https://docs.snowflake.com/en/release-notes/2026/other/2026-10-12-horizon-context-preview)

57. [Snowflake, Atlan Documentation](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake)

58. [What does Atlan crawl from Snowflake?, Atlan Documentation](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/references/what-does-atlan-crawl-from-snowflake)

59. [Manage Snowflake tags, Atlan Documentation](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/how-tos/manage-snowflake-tags)

60. [Snowflake Data Quality Studio, Atlan Documentation](https://docs.atlan.com/product/capabilities/governance/data-quality/snowflake)

61. [Configure Snowflake data metric functions, Atlan Documentation](https://docs.atlan.com/apps/connectors/data-warehouses/snowflake/how-tos/configure-snowflake-data-metric-functions)

62. [Set up Atlan MCP, Atlan Documentation](https://docs.atlan.com/product/capabilities/atlan-ai/how-tos/remote-mcp-overview)