diff --git a/site/sfguides/src/from-zero-to-agents/assets/engagementclicks.png b/site/sfguides/src/from-zero-to-agents/assets/engagementclicks.png new file mode 100644 index 0000000000..534f45f4bb Binary files /dev/null and b/site/sfguides/src/from-zero-to-agents/assets/engagementclicks.png differ diff --git a/site/sfguides/src/from-zero-to-agents/assets/metricsproduct.png b/site/sfguides/src/from-zero-to-agents/assets/metricsproduct.png index 0731d31ea8..dd08ddec22 100644 Binary files a/site/sfguides/src/from-zero-to-agents/assets/metricsproduct.png and b/site/sfguides/src/from-zero-to-agents/assets/metricsproduct.png differ diff --git a/site/sfguides/src/from-zero-to-agents/assets/setup.sql b/site/sfguides/src/from-zero-to-agents/assets/setup.sql new file mode 100644 index 0000000000..b2b0fcf98d --- /dev/null +++ b/site/sfguides/src/from-zero-to-agents/assets/setup.sql @@ -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; diff --git a/site/sfguides/src/from-zero-to-agents/assets/zeroclicks.png b/site/sfguides/src/from-zero-to-agents/assets/zeroclicks.png new file mode 100644 index 0000000000..cecb6ec2ab Binary files /dev/null and b/site/sfguides/src/from-zero-to-agents/assets/zeroclicks.png differ diff --git a/site/sfguides/src/from-zero-to-agents/from-zero-to-agents.md b/site/sfguides/src/from-zero-to-agents/from-zero-to-agents.md index d508acf707..e1ebca1165 100644 --- a/site/sfguides/src/from-zero-to-agents/from-zero-to-agents.md +++ b/site/sfguides/src/from-zero-to-agents/from-zero-to-agents.md @@ -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 @@ -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, @@ -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) @@ -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 @@ -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) @@ -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 @@ -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); ``` @@ -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