Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified site/sfguides/src/from-zero-to-agents/assets/metricsproduct.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
214 changes: 214 additions & 0 deletions site/sfguides/src/from-zero-to-agents/assets/setup.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
-- Summary of objects created in this script:
--
-- Roles:
-- - snowflake_intelligence_admin
--
-- Warehouses:
-- - dash_wh_si
--
-- Databases:
-- - dash_db_si
-- - snowflake_intelligence
--
-- Schemas:
-- - dash_db_si.retail
-- - snowflake_intelligence.agents
--
-- File Format:
-- - swt_csvformat
--
-- Stages:
-- - swt_marketing_data_stage
-- - swt_products_data_stage
-- - swt_sales_data_stage
-- - swt_social_media_data_stage
-- - swt_support_data_stage
-- - semantic_models
--
-- Git Integration:
-- - snowflake_labs_si_git_api_integration
--
-- Git Repository:
-- - snowflake_labs_sfguide_si_repo
--
-- Tables:
-- - marketing_campaign_metrics
-- - products
-- - sales
-- - social_media
-- - support_cases
--
-- Notification Integration:
-- - email_integration
--
-- Stored Procedure:
-- - send_email


use role accountadmin;

create or replace role snowflake_intelligence_admin;
grant create warehouse on account to role snowflake_intelligence_admin;
grant create database on account to role snowflake_intelligence_admin;
grant create integration on account to role snowflake_intelligence_admin;

set current_user = (select current_user());
grant role snowflake_intelligence_admin to user identifier($current_user);
alter user set default_role = snowflake_intelligence_admin;
alter user set default_warehouse = dash_wh_si;

use role snowflake_intelligence_admin;
create or replace database dash_db_si;
create or replace schema retail;
create or replace warehouse dash_wh_si with warehouse_size='large';

create database if not exists snowflake_intelligence;
create schema if not exists snowflake_intelligence.agents;

grant create agent on schema snowflake_intelligence.agents to role snowflake_intelligence_admin;

use database dash_db_si;
use schema retail;
use warehouse dash_wh_si;

create or replace file format swt_csvformat
skip_header = 1
field_optionally_enclosed_by = '"'
type = 'csv';

-- create table marketing_campaign_metrics and load data from s3 bucket
create or replace stage swt_marketing_data_stage
file_format = swt_csvformat
url = 's3://sfquickstarts/sfguide_getting_started_with_snowflake_intelligence/marketing/';

create or replace table marketing_campaign_metrics (
date date,
category varchar(16777216),
campaign_name varchar(16777216),
impressions number(38,0),
clicks number(38,0)
);

copy into marketing_campaign_metrics
from @swt_marketing_data_stage;

-- create table products and load data from s3 bucket
create or replace stage swt_products_data_stage
file_format = swt_csvformat
url = 's3://sfquickstarts/sfguide_getting_started_with_snowflake_intelligence/product/';

create or replace table products (
product_id number(38,0),
product_name varchar(16777216),
category varchar(16777216)
);

copy into products
from @swt_products_data_stage;

-- create table sales and load data from s3 bucket
create or replace stage swt_sales_data_stage
file_format = swt_csvformat
url = 's3://sfquickstarts/sfguide_getting_started_with_snowflake_intelligence/sales/';

create or replace table sales (
date date,
region varchar(16777216),
product_id number(38,0),
units_sold number(38,0),
sales_amount number(38,2)
);

copy into sales
from @swt_sales_data_stage;

-- create table social_media and load data from s3 bucket
create or replace stage swt_social_media_data_stage
file_format = swt_csvformat
url = 's3://sfquickstarts/sfguide_getting_started_with_snowflake_intelligence/social_media/';

create or replace table social_media (
date date,
category varchar(16777216),
platform varchar(16777216),
influencer varchar(16777216),
mentions number(38,0)
);

copy into social_media
from @swt_social_media_data_stage;

-- create table support_cases and load data from s3 bucket
create or replace stage swt_support_data_stage
file_format = swt_csvformat
url = 's3://sfquickstarts/sfguide_getting_started_with_snowflake_intelligence/support/';

create or replace table support_cases (
id varchar(16777216),
title varchar(16777216),
product varchar(16777216),
transcript varchar(16777216),
date date
);

copy into support_cases
from @swt_support_data_stage;

create or replace stage semantic_models encryption = (type = 'snowflake_sse') directory = ( enable = true );

-- create git api integration and repository
create or replace api integration snowflake_labs_si_git_api_integration
api_provider = git_https_api
api_allowed_prefixes = ('https://github.com/Snowflake-Labs')
enabled = true;

create or replace git repository snowflake_labs_sfguide_si_repo
api_integration = snowflake_labs_si_git_api_integration
origin = 'https://github.com/Snowflake-Labs/sfguide-getting-started-with-snowflake-intelligence';

-- copy semantic model from git repo to stage
copy files into @semantic_models
from @snowflake_labs_sfguide_si_repo/branches/main/
files = ('marketing_campaigns.yaml');

create or replace notification integration email_integration
type=email
enabled=true
default_subject = 'snowflake intelligence';

create or replace procedure send_email(
recipient_email varchar,
subject varchar,
body varchar
)
returns varchar
language python
runtime_version = '3.12'
packages = ('snowflake-snowpark-python')
handler = 'send_email'
as
$$
def send_email(session, recipient_email, subject, body):
try:
# Escape single quotes in the body
escaped_body = body.replace("'", "''")

# Execute the system procedure call
session.sql(f"""
CALL SYSTEM$SEND_EMAIL(
'email_integration',
'{recipient_email}',
'{subject}',
'{escaped_body}',
'text/html'
)
""").collect()

return "Email sent successfully"
except Exception as e:
return f"Error sending email: {str(e)}"
$$;

ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'AWS_US';

select 'Congratulations! Snowflake Intelligence setup has completed successfully!' as status;
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 56 additions & 13 deletions site/sfguides/src/from-zero-to-agents/from-zero-to-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,24 @@ This hands-on lab guides you through transforming raw data into actionable insig

## Environment and Data Loading

Establish the secure foundation using the provided `setup.sql` script. This script automates the creation of roles, warehouses, and the ingestion of marketing data from public S3 buckets.
Imagine you are on a marketing team at a fictional retail company selling sports and outdoor gear. The company has plenty of data from campaign performance from paid ads to customer feedback.

The problem the team faces:
1. Campaign performance data is siloed from customer feedback
2. Customer feedback is unstructured and unanalyzed
3. Analysts can’t self-serve insights from these data

What you’ll build to solve these issues:
1. Cortex AI turns raw transcripts into structured sentiment scores
2. Dynamic Tables automate so that data stays current as new feedback arrives
3. Semantic View bridges campaign metrics and customer feedback into one model
4. Snowflake Intelligence that allows analysts to ask natural language questions


### Setup Instructions
Establish the secure foundation using the provided `setup.sql` script. This script automates the creation of roles, warehouses, and the ingestion of marketing data from public S3 buckets.

Run [setup.sql](https://github.com/Snowflake-Labs/sfguide-getting-started-with-snowflake-intelligence/blob/main/setup.sql) in a Snowsight SQL Worksheet.
Run [setup.sql](https://github.com/Snowflake-Labs/sfquickstarts/blob/master/site/sfguides/src/from-zero-to-agents/assets/setup.sql) in a Snowsight SQL Worksheet.

### What Gets Provisioned

Expand Down Expand Up @@ -91,6 +104,8 @@ AI Enrichment is the "Preprocessing" step. By enriching your data first:
Transform "dark data" (raw transcripts) into analytical trends using Cortex AI Functions. Run sentiment analysis on customer feedback to create measurable features:

```sql
USE DATABASE DASH_DB_SI;
USE SCHEMA RETAIL;
UPDATE support_cases SET product = 'Fitness Wear' WHERE product = 'ThermoJacket Pro';
SELECT
title,
Expand All @@ -107,7 +122,7 @@ Confirm that the role is set to `SNOWFLAKE_INTELLIGENCE_ADMIN` by clicking on yo
2. Navigate to `Catalog` > `Database Explorer`
3. Open `DASH_DB_SI.RETAIL.Tables.MARKETING_CAMPAIGN_METRICS`. If you do not see the database, refresh the data.
4. Click on `Load Data` in the top right hand corner
5. Upload the marketing_data.csv and click `next` then load
5. Upload the marketing_data.csv and click `next` then `load`
6. Click `View table detail` to see the new data uploaded

![Updating marketing data](assets/updatingmarketing.png)
Expand All @@ -128,6 +143,8 @@ Instead of running a one-time enrichment, you define a **Dynamic Table**. This t
Create a Dynamic Table that automatically joins campaign metrics with AI-generated sentiment scores:

```sql
USE DATABASE DASH_DB_SI;
USE SCHEMA RETAIL;
CREATE OR REPLACE DYNAMIC TABLE enriched_marketing_intelligence
TARGET_LAG = '1 hours'
WAREHOUSE = dash_wh_si
Expand Down Expand Up @@ -189,7 +206,7 @@ This tool allows the agent to search and retrieve information from unstructured
- **Select Data:** `marketing_campaign_metrics`
- **Select search column:** `campaign name`
- **Select attribute columns:** `Select all`
- **Warehouse for indexing:** `DASH_DB_SI`
- **Warehouse for indexing:** `DASH_WH_SI`
5. Click `create` and click the refresh icon in the top right corner. `Serving` will update from `INITALIZING` to `ACTIVE`

![Active Cortex Search](assets/servingactive.png)
Expand Down Expand Up @@ -321,11 +338,37 @@ For lab participants, the Trace is the most critical UI interaction. It allows y

Apply **Dynamic Data Masking** to specific metrics to ensure the agent respects **RBAC** (Role-Based Access Control).

### Create the Marketing Role
### Create the Marketing Role and Granting Access

If you ran the `setup.sql` exactly as provided in the GitHub repo, it created `snowflake_intelligence_admin`. Let's create the `marketing_intelligence_role` to represent your "Restricted Team" and give it the necessary access.
If you ran the `setup.sql` exactly as provided in the GitHub repo, it created `snowflake_intelligence_admin`. Let's create the `marketing_intelligence_role` to represent your "Restricted Team" and give it the necessary access. Be sure to have your role set to `snowflake_intelligence_admin` and warehouse to `DASH_WH_SI`.

```sql
USE DATABASE DASH_DB_SI;
USE SCHEMA RETAIL;

-- Create the Semantic View
CREATE OR REPLACE SECURE VIEW marketing_intelligence_view AS
SELECT
campaign_name AS "Ad Campaign",
category AS "Product Category",
clicks AS "Engagement Clicks",
-- avg_sentiment will come from the Dynamic Table
0 AS "Customer Sentiment Score"
FROM marketing_campaign_metrics;

-- Check which roles have access to your database and schema
SHOW GRANTS ON DATABASE dash_db_si;
SHOW GRANTS ON SCHEMA dash_db_si.retail;

-- Check specifically for your Semantic View
SHOW GRANTS ON VIEW marketing_intelligence_view;

USE ROLE snowflake_intelligence_admin;
USE WAREHOUSE dash_wh_si;

-- You should see the actual budget/click numbers
SELECT * FROM marketing_intelligence_view LIMIT 5;

USE ROLE ACCOUNTADMIN;

-- Create the role
Expand All @@ -341,6 +384,7 @@ GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE marketing_intelligence_role;
GRANT SELECT ON VIEW dash_db_si.retail.marketing_intelligence_view TO ROLE marketing_intelligence_role;

-- Assign to yourself for testing
SET current_user = CURRENT_USER();
GRANT ROLE marketing_intelligence_role TO USER IDENTIFIER($CURRENT_USER);
```

Expand Down Expand Up @@ -383,26 +427,25 @@ SELECT
FROM marketing_campaign_metrics;

USE ROLE snowflake_intelligence_admin;
USE SCHEMA dash_db_si.retail;
-- You should see numbers like 11103
SELECT "Ad Campaign", "Engagement Clicks" FROM marketing_intelligence_view;
```
![Admin Role](assets/engagementclicks.png)


### Verify as Marketing Role

```sql
USE ROLE marketing_intelligence_role;
USE SCHEMA dash_db_si.retail;
-- You should see 0 for all clicks
SELECT "Ad Campaign", "Engagement Clicks" FROM marketing_intelligence_view;
```
![Marketing Role](assets/zeroclicks.png)

### Agent Interaction Verification

Now that the data is masked at the source, the **Agent** will automatically respect it.
By applying Dynamic Data Masking alongside RBAC, you ensured that the data serves different teams with appropriate access — admins see real click data while the marketing role sees masked values.

1. Switch your UI role to `marketing_intelligence_role`
2. Ask the Agent: *"How many clicks did the Summer Fitness campaign get?"*
3. The Agent will query the view, receive `0` from the database engine, and reply: *"The Summer Fitness campaign received 0 clicks."*
4. **Show Reasoning:** Open the trace to prove the SQL was correct, but the **Data Engine** protected the values

<!-- ------------------------ -->

Expand Down
Loading