👨‍🦱

関西のおばちゃんがSnowflake Intelligenceでおばちゃんチャットボットを作ってみる

に公開

はじめに

関西のおばちゃんのm.fujitaやで。
この記事は、hikariさんが以前作ってくれはった「おばちゃんチャットボット」をSnowflake Intelligenceで動かしてみよう!というブログになるんよ。

せっかく関西在住歴が長かった関西弁のおばちゃんが記事を書くので、なるだけネイティブな関西弁でブログを書こうと思うねん。どうぞよろしゅうお願いします。

今日伝えたいこと

  • Cortex Analyst
  • Cortex Agent

この2つの設定だけでSnowflake Intelligenceで関西弁のおばちゃんが登場するで。
最終形はこんな感じになるねん。



おおお、関西弁のおばちゃんがメール送れるんやて?なんやて?!すごいやん。

構成図

今回の動きのイメージはこんな風になってるで。

Cortex Analyst(Cortex分析)

さてさて、その前にCortex Analystってなんやねんっちゅー話を解説せなあかんね。
あんな、Snowflake が出してる新しい仕組みでな、
「SQL わからんわ~」って人でも 自然な言葉でデータに聞けるんや。
たとえばやで、
「去年の売上どないやったん?」って入力したら、
勝手に SQL に変えて結果を出してくれるんやわ。

だから、エンジニアやなくてもデータ分析できるようになる、
いわば「データの通訳さん」みたいなもんやな。

Cortex Analyst(Cortex分析、Cortexアナリスト)は、この後で使う用語として統一するわ。

Cortex Agent(エージェント)

Cortex Analyst が「SQL 聞き屋さん」やったら、
Cortex Agent は“お手伝いロボ”みたいなもんや。

ユーザーの自然な会話を理解して、
必要ならデータベースに聞きに行ったり
外のサービス呼び出したり
その結果まとめて返してくれるっていう感じやねん。

手順

Snowflake Intelligenceを使ったチャットボットはこんな手順でできるんや。

  1. 環境設定
    • Snowflake Intelligenceを使うためのロール・スキーマ作成
    • データベース/スキーマ作成
    • ステージ作成
    • ディレクトリテーブルを有効化
    • Email送信用のインテグレーションとプロシージャ作成
    • Cortex のクロスリージョン利用を AWS_US リージョンに対して有効化
  2. Snowflake Marketplaceから飲食店データをGet
  3. Cortex Analystの作成
  4. Cortex Agentの作成
  5. Snowflake Intelligence起動

1.環境設定

今回は、メールを送ってみたいからインテグレーションとプロシージャも作るで。
SQLワークシートを起動して、実行するんやで。

Agentの初期設定とかあるからSQLは長いけど、全部コピペして実行したらあっという間や!試してみてな。

Agentを使うための初期設定
-- 1.環境設定 | 1.Snowflake Intelligenceを使うためのロール・スキーマ作成
-- ACCOUNTADMIN ロールに切り替え
-- (最上位の管理者ロール。アカウント全体に対する権限を持つ)
use role accountadmin;

-- Snowflake Intelligence 用の管理ロールを作成
create role if not exists snowflake_intelligence_admin;

-- アカウント全体で Integration オブジェクトを作成する権限を付与
-- (API Integration や Storage Integration などを作れるようになる)
grant create integration on account to role snowflake_intelligence_admin;

-- アカウント全体で Database を作成する権限を付与
grant create database on account to role snowflake_intelligence_admin;

-- 指定した Warehouse(ここでは compute_wh)を利用できる権限を付与
grant usage on warehouse compute_wh 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;

-- 作成したロールをアクティブに切り替え
use role snowflake_intelligence_admin;

-- Snowflake Intelligence 用のデータベースを作成
-- すでに存在していれば新規作成はされない
create database if not exists snowflake_intelligence;

-- データベース内に schema "agents" を作成
create schema if not exists snowflake_intelligence.agents;

-- schema "agents" 上で Agent オブジェクトを作成できる権限を付与
-- (Snowflake Native Apps の Agent 機能を利用するため)
grant create agent on schema snowflake_intelligence.agents to role snowflake_intelligence_admin;

-- Cortex のクロスリージョン利用を AWS_US リージョンに対して有効化
ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'AWS_US';

-- 1.環境設定 | 2.データベース・スキーマ作成 
CREATE DATABASE if not exists KANSAI_OBACHAN_DB;
CREATE SCHEMA if not exists KANSAI_OBACHAN_DB.KANSAI_OBACHAN_SCH;

-- 1.環境設定 | 3.ステージ作成
CREATE STAGE if not exists KANSAI_OBACHAN_DB.KANSAI_OBACHAN_SCH.SEMANTIC_MODEL;

-- 1.環境設定 | 4.ディレクトリテーブルを有効化
ALTER STAGE KANSAI_OBACHAN_DB.KANSAI_OBACHAN_SCH.SEMANTIC_MODEL
  SET DIRECTORY = ( ENABLE = TRUE );

-- 1.環境設定 | 5.Email送信用のインテグレーション作成
CREATE OR REPLACE NOTIFICATION INTEGRATION EMAIL_INTEGRATION
  TYPE=EMAIL
  ENABLED=TRUE
  DEFAULT_SUBJECT = 'Snowflake Intelligence';

-- 1.環境設定 | 6.Email送信用のプロシージャ作成
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'
EXECUTE AS OWNER
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}''
            )
        """).collect()
        
        return "Email sent successfully"
    except Exception as e:
        return f"Error sending email: {str(e)}"
';

SQLを貼り付けて実行してもらったらうまく行くんやけど、後述する「Cortex Agent」を作るためにはデータベース・スキーマが「snowflake_intelligence.agents」である必要があるんや。記憶の片隅に入れといて。

2.Snowflake Marketplaceから飲食店データをGet!

Snowflake Marketplaceいうのは、スマホでいう「Google Play」とか「App Store」みたいなもんで、Snowflakeからサンプルデータを取ってこれるんやで。
Snowflake Marketplaceの検索画面から「飲食店」を検索するんや。

矢印通りにFood Establishment Set in Japanいうやつをゲットするんや。
このデータはな、「全国の飲食店データ」が公開されてるんや。
サンプルは、東京都渋谷区と大阪市中央区のデータやねんで。
なんと、このデータ「週次」で更新されとるんや。めっちゃ新しいデータが毎週出てくるから活用するのに持って来いやで。

3.Cortex Analystの設定

Cortex Analyst作るで。

ちょっと分かりにくいねんけど、2個目の「新しいセマンティックビューを作成」を押すんや。
なんでかいうとな、
1個目は「セマンティックビューを作るやつ」
2個目は「セマンティックモデル(yaml)を作るやつ」って裏側では区別があるからやねん。

こんな感じで、下記のデータベース・スキーマ・ステージを選んで名前を設定するんやで

  • データベース:KANSAI_OBACHAN_DB
  • スキーマ:KANSAI_OBACHAN_SCH
  • ステージ:SEMANTIC_MODEL
  • 名前:OSAKA_RESTAURANT_INFO
    そしたら、自動でyamlファイルのファイル名が提案されるからそのまま進むんや。

次に行ったらな、さっきGetした飲食店データのうちの

  • データベース:FOOD_ESTABLISHMENTS_DATA_SET_IN_JAPAN
  • スキーマ:MART
  • ビュー:FOOD_SAMPLE_OSAKA_CHUO
    を選択するんや。

カラムは一旦全部選択してええで。

ほんで、yamlを編集っておしたらな

こんな感じで自動的にyamlを作ってくれるんやけど(いやぁSnowflakeさんかしこいわぁ)

その自動的に作られたyamlはいったん消して、下記のCortex Analystに貼り付けるyamlを貼り付けるんや。
このyamlは、元記事と一緒やで。↓

Cortex Analystに貼り付けるyaml
name: osaka_restaurant_info
tables:
  - name: FOOD_SAMPLE_OSAKA_CHUO
    base_table:
      database: FOOD_ESTABLISHMENTS_DATA_SET_IN_JAPAN
      schema: MART
      table: FOOD_SAMPLE_OSAKA_CHUO
    dimensions:
      - name: BRAND_ID
        description: ブランドコード
        expr: BRAND_ID
        data_type: VARCHAR(16777216)
        sample_values:
          - '797'
          - '1861'
      - name: BRAND_NAME
        description: ブランド名
        expr: BRAND_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 白木屋
          - 大阪王将
          - ミスタードーナツ
      - name: BRAND_OWNER
        description: オーナー会社の法人番号
        expr: BRAND_OWNER
        data_type: VARCHAR(16777216)
        sample_values:
          - '4120001168969'
          - '2120001168995'
      - name: GENRE_MAJOR_NAME
        description: ジャンル大分類
        expr: GENRE_MAJOR_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 飲食業
      - name: GENRE_MEDIUM_NAME
        description: ジャンル中分類
        expr: GENRE_MEDIUM_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 配達・持ち帰り
          - 飲食店
      - name: GENRE_SUB_NAME
        description: ジャンル小分類
        expr: GENRE_SUB_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 飲み屋・居酒屋
          - 専門料理店
          - 寿司店
          - ステーキ
          - その他配達・持ち帰り
          - 各国料理
          - 肉調理店(焼肉・焼鳥・ステーキ除く)
          - バー
          - 焼肉
          - キャバレー・ナイトクラブ・ラウンジ
          - カレー店
          - 持ち帰り飲食サービス業
          - 料亭
          - 麺類(そば)
          - 分類できない飲食店
          - 丼・定食
          - 鍋料理
          - 和食・郷土料理
          - ファーストフード
          - カフェ・喫茶店
          - ラーメン
          - 焼き鳥
          - 中華料理
          - 麺類(うどん)
          - 一般レストラン
          - お菓子・スイーツ
          - 配達飲食サービス業
          - その他飲食店
          - お好み焼き・たこ焼き・焼きそば等
      - name: STORE_ADDRESS
        description: 店舗住所
        expr: STORE_ADDRESS
        data_type: VARCHAR(16777216)
        sample_values:
          - 大阪府大阪市中央区高麗橋4ー2ー7
          - 大阪府大阪市中央区東心斎橋2丁目5ー22
          - 大阪府大阪市中央区心斎橋筋2ー2ー3
      - name: STORE_BUILDING_NAME
        description: 店舗ビル名
        expr: STORE_BUILDING_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - ヴィラ日本橋ビル 1F
          - 中西ビル 1F
      - name: STORE_CITY_NAME
        description: 店舗市町村
        expr: STORE_CITY_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 大阪市中央区
      - name: STORE_FACEBOOK
        description: 店舗Facebook
        expr: STORE_FACEBOOK
        data_type: VARCHAR(16777216)
        sample_values:
          - https://www.facebook.com/ebisuhub/
          - https://www.facebook.com/people/BISTROT-LE-CANON/100054318979844/
      - name: STORE_INSTAGRAM
        description: 店舗instagram
        expr: STORE_INSTAGRAM
        data_type: VARCHAR(16777216)
        sample_values:
          - https://www.instagram.com/teppan_osaka/
          - https://www.instagram.com/cafegarb/
      - name: STORE_NAME
        description: 店舗名
        expr: STORE_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 神戸牛牛・本町店
          - Bar Reiche
          - DOPE
      - name: STORE_OTHER_SITE
        description: 店舗_他site
        expr: STORE_OTHER_SITE
        data_type: VARCHAR(16777216)
        sample_values:
          - '[''https://tabelog.com/osaka/A2701/A270107/27075875/'', ''https://www.ekiten.jp/shop_6851905/'']'
          - '[''https://tabelog.com/osaka/A2701/A270201/27074686/'', ''https://www.ekiten.jp/shop_6525173/'', ''https://place.line.me/businesses/35063080'']'
      - name: STORE_PHONE_NUMBER
        description: 店舗電話番号
        expr: STORE_PHONE_NUMBER
        data_type: VARCHAR(16777216)
        sample_values:
          - 080-5696-6988
          - 06-6121-6588
      - name: STORE_PREF_NAME
        description: 店舗都道府県
        expr: STORE_PREF_NAME
        data_type: VARCHAR(16777216)
        sample_values:
          - 大阪府
      - name: STORE_URL
        description: 店舗URL
        expr: STORE_URL
        data_type: VARCHAR(16777216)
        sample_values:
          - https://tabelog.com/osaka/A2701/A270204/27112287/
          - https://s.tabelog.com/osaka/A2701/A270201/27078266/
      - name: STORE_X
        description: 店舗X
        expr: STORE_X
        data_type: VARCHAR(16777216)
        sample_values:
          - https://twitter.com/MixBarSLY
          - https://twitter.com/miyazakikan
      - name: STORE_ZIPCODE
        description: 店舗郵便番号
        expr: STORE_ZIPCODE
        data_type: VARCHAR(16777216)
        sample_values:
          - '5420076'
          - '5410041'
          - '5420083'
      - name: UPDATE_DATE
        description: データ取得日
        expr: UPDATE_DATE
        data_type: VARCHAR(16777216)
        sample_values:
          - '20250408'
      - name: UUID
        description: 店舗ID
        expr: UUID
        data_type: VARCHAR(16777216)
        sample_values:
          - 71b87932-e132-43e4-9583-96bfdd3d2b8e
          - ab7abad2-390c-4eac-8004-231d427ca34e
          - d0f9e27d-8ccf-4175-9312-cbf8ff3f9585
    time_dimensions:
      - name: CLOSED_DATE
        description: 閉店推定日
        expr: CLOSED_DATE
        data_type: DATE
        sample_values:
          - '2024-05-27'
          - '2024-02-09'
      - name: OPEN_DATE
        description: 開業推定日
        expr: OPEN_DATE
        data_type: DATE
        sample_values:
          - '2016-07-08'
          - '2017-02-01'
          - '2006-04-01'
    facts:
      - name: CLOSED_FLAG
        description: 閉店フラグ
        expr: CLOSED_FLAG
        data_type: NUMBER(38,0)
        sample_values:
          - '1'
          - '0'
          - '2'
      - name: SEATS
        description: 店舗座席数
        expr: SEATS
        data_type: NUMBER(38,0)
      - name: STORE_LAT
        description: 緯度
        expr: STORE_LAT
        data_type: NUMBER(10,7)
        sample_values:
          - '34.6675624'
          - '34.6897922'
          - '34.6732392'
      - name: STORE_LON
        description: 経度
        expr: STORE_LON
        data_type: NUMBER(10,7)
        sample_values:
          - '135.5007200'
          - '135.5053260'
          - '135.5006608'
verified_queries:
  - name: ラーメン
    question: ラーメン食べたい。一番新しいお店の名前と電話番号教えて
    use_as_onboarding_question: true
    sql: SELECT store_name, store_phone_number FROM food_sample_osaka_chuo WHERE genre_sub_name = 'ラーメン' ORDER BY open_date DESC NULLS LAST LIMIT 1 /* Generated by Cortex Analyst */
    verified_by: 〇〇〇
    verified_at: 1747702367

最後にディレクトリテーブルを更新しておくで
カタログ→データベースエクスプローラー→
KANSAI_OBACHAN_DB-KANSAI_OBACHAN_SCH-ステージ-SEMANTIC_MODEL を選択。
右上のリフレッシュボタンを押すんや。

ほんなら、さっき追加したyamlファイルが出てきたわ。良かったやん!

4.Cortex Agentの設定

Cortex Agentは元記事のおばちゃんチャットボットに出てきてないところやからよぉきいてや
Agentを使うためにはsnowflake_intelligence_adminロールの作成と設定が必要やで
今回は、1番の環境設定のSQLに設定済みやからここで、新たなSQLを実行せんでもええんやで。

ここでな、自分のロールをsnowflake_intelligence_adminロールに変更するんや。
Agentを作るスキーマにCreate agentロールがないとうまく動かへんで。

AI&ML→エージェントっていうメニューを選択するんやで

さぁ「エージェントを作成」を押して作ってみよう!

プラットフォーム統合の所、エージェントの作成対象 Snowflake Intelligenceのフラグは付けとかなあかんで。Cortex AgentとSnowflake Intelligenceが繋がらなくなるからフラグをオンにすることは大事。データベースとスキーマは必ず「snowflake_intelligence.agents」にしておく必要があるんやで。
名前は「KANSAI_OBACHAN_AGENT」にするで。

でけた!

Cortex Agentには設定箇所がいくつかあるんや。これから設定方法を説明するで。

  • 概要:Agentの概要説明、例文の質問
  • ツール:Agentで使うツール Cortex Analyst・Cortex Searchなど検索で使うツール・メール送信に使うカスタムツールを設定
  • オーケストレーション:どう返事してほしいかの設定
  • アクセス:ロール設定が可能

概要:質問例を記入

でけたので、編集してみるで。
KANSAI_OBACHAN_AGENTをクリックして編集や。

「ラーメン食べたい。一番新しいお店の名前と電話番号教えて」を質問例に入れるんやで。


こまめにセーブしたほうがええから、セーブしぃや。

ツール:Cortex Analystの設定

ツールを選択すると、エージェントで使うオブジェクトを決めることができるんや。
今回は、Cortex Analystで登録した、セマンティックモデルを選択するんやで。

ファイルが出てきたらOSAKA_RESTAURANT_INFO.yamlを選択して、ツール詳細に名称「OSAKA_RESTAURANT_INFO」・説明「大阪の飲食店情報」を入れて追加を押すで。

ドラクエみたいに、こまめにセーブしたほうがええから、セーブしぃや。

ツール:メール送信ツール設定

ツール:カスタムツールを選択して追加するねん。

データベース・スキーマを下記のように設定するんやで。

  • データベース:KANSAI_OBACHAN_DB
  • スキーマ:KANSAI_OBACHAN_SCH
  • カスタムツール識別子:KANSAI_OBACHAN_DB.KANSAI_OBACHAN_SCH.SEND_EMAIL


    名前は「KANSAI_OBACHAN_SEND_EMAIL」やで。
    こまめにセーブしときや、知らんけど。

オーケストレーションの設定

ここがいっちゃん大事や!
ここで関西弁のおばちゃんが返事するように設定が必要やねん。

Response Instructionsにこれ入れてみてな。

関西弁のおばちゃんの返答スクリプト
  あなたは、とても元気なやかましい大阪のおばちゃんです。
    注意:
    - 分析結果は、下記の「関西弁説明」を学習し、関西弁で回答してください。
    - 敬語は使わないでください。
    - 質問に関連する面白い話を加えてください。
    - 最後に「知らんけど」か「飴ちゃんやるわ」と言ってください。

    -関西弁説明
        -語彙
            -ありがとう:標準語では「ありがとう」ですが、関西弁では「おおきに」と言います。
            -とても:標準語の「とても」は、関西弁では「めっちゃ」や「ほんまに」と言います。
            -疲れた:標準語の「疲れた」は、関西弁では「しんどい」と言います。
            -だめ:標準語の「だめ」は、関西弁では「あかん」と言います。
            -すごい:標準語の「すごい」は、関西弁では「えらい」と言います。
        -文法
            -標準語の「〜している」は、関西弁では「〜しとる」と言います。
            -標準語の「〜していない」は、関西弁では「〜してへん」と言います。
            -標準語の「〜だ」は、関西弁では「〜や」と言います。例えば、「これは本だ」は「これは本や」となります。
            -標準語の「〜でしょう」は、関西弁では「〜やろ」と言います。例えば、「明日は雨でしょう」は「明日は雨やろ」となります。
            -標準語の「〜ない」は、関西弁では「〜へん」と言います。例えば、「行かない」は「行かへん」となります。 

最後にセーブ忘れなや、知らんけど。

Agent設定完了や!

右側の所に質問を入れたら、おばちゃんが返事してくれたで。

Snowflake Intelligenceで動かす

AI&ML→Snowflakeインテリジェンスを起動するんや。

そしたらな、別タブで表示される。
ログイン画面が出てくるからな、元のアカウントのログインと同じアイパスいれるんやで。

おおおおお!さっき設定したCortex Agentと同じ内容が出てきたで。やったやん!

ホンマ嬉しいわ。あめちゃんあげるわ。

質問例、押してみるわな。
やった答えてくれたで。

メール送ってみよか。
ちょっと分からんかったみたいやけど、私に送ってって言うたら、うまいこと送れたみたいや。

さぁ届いてるか見てみよか。
無事に届いとったわ。Snowflake便利やなぁ。知らんけど。

まとめ

ついにできたなぁ、みんなも試してみてな。
こんな手順でできるんやで。

  1. 環境設定
    • Snowflake Intelligenceを使うためのロール・スキーマ作成
    • データベース/スキーマ作成
    • ステージ作成
    • ディレクトリテーブルを有効化
    • Email送信用のインテグレーションとプロシージャ作成
    • Cortex のクロスリージョン利用を AWS_US リージョンに対して有効化
  2. Snowflake Marketplaceから飲食店データをGet
  3. Cortex Analystの作成
  4. Cortex Agentの作成
  5. Snowflake Intelligence起動

何かいっぱい設定が必要そうに見えるけど、実際やってみたら30分もかからんので試してみてな。
あめちゃんあげるわ!

参考元

元記事はこっちやで。
https://blog.truestar.co.jp/snowflake/20250520/62623/

hikariさんの資料もめっちゃわかりやすいから見てなぁ~

https://speakerdeck.com/truestar_marketing/da-ban-kai-cui-guan-xi-bian-tiyatutobotutowozuo-tuteti-gan-chu-xin-zhe-karaxue-berustreamlitxsnowflakehuo-yong-and-shi-li-setusiyon-snonwflake-westyuzahui-ee4cad7a-4ffb-4dea-a713-b0fa586f9c74?slide=13

truestarテックブログ
設定によりコメント欄が無効化されています