概要
生成AIとデータ基盤の融合により,専門知識をもたない利用者でも自然言語でデータに問い合わせられる環境が急速に整いつつある[1].私の所属する NTT 西日本でも,CoCo と CoWorkを用いることで,普段データ分析を行わないライトユーザに対しても「まずデータを触ってみる」という導入部分を提供できるようになってきた.
しかしながら,CoWork を実際に動かすうえで必要となる Cortex Agent と セマンティックビュー(Semantic View)を用意する工程には,依然として一定のハードルが残っている.そこで本記事では,作成したいテーブルを指定するだけで,対応するセマンティックビューと Cortex Agent を自動生成する Streamlit アプリを構築した取り組みについて述べる.あわせて,構築の過程で判明した Snowflake 側の仕様上のつまずきと,その回避策について述べる.
本記事は次の流れで構成される.はじめに背景と課題を実務の文脈から整理する.次に本ツールの全体アーキテクチャと4ステップの実装を示す.さらに,構築中に遭遇したエラーとその回避策をトラブルシューティングとしてまとめる.最後に,本アプローチの限界と今後の展望について考察する.なお,本ツールのソースコードは GitHub にて公開している[6].
背景(全社的なデータ活用推進と,その「次の一手」)
私の所属する NTT 西日本では,データ活用の裾野を全社的に広げる取り組みを進めている.その一環として,2026 年 6 月にはデータ活用基盤の大型アーキテクチャ刷新をリリースし,利用者にとって Snowflake をより使いやすい環境へとリニューアルした.
あわせて,2026 年 6 月中旬に社長を含む経営層に向けて,CoWork と CoCo を活用し,ライトユーザでも簡単にデータを活かせる様子を示すデモを実施した.その結果,全社員に向けてこの取り組みをプロモーションしていってほしい,という方針を経営層から得ることができた.なお,これら基盤の現在地については,2026 年 7 月 13 日の Snowflake ユーザコミュニティイベント「Snowvillage WEST」でも簡単に紹介している[3].
この方針を受け,全社展開の第一歩として,各組織のマネージャ向けのハンズオンを計画した.ハンズオンでは,あらかじめエージェントを作成した状態から始め,「データ活用がいかに手軽か」を体験してもらうことを狙いとした.
課題(ハンズオンは成立しても,実務で「自分で作れない」)
ハンズオンそのものは,あらかじめエージェントを用意しておけば成立する.しかしながら,本当の課題は,各部が実務で「自分たちのデータに対してエージェントを作る」段階で顕在化する.
CoWork を実際に動かすためには,その裏側で Cortex Agent と セマンティックビュー(Semantic View)を準備する必要がある.そして,この準備工程こそが,ライトユーザにとっての次のハードルになっている.
私個人の実感としても,Snowflake におけるセマンティックビューやエージェントの実装は,1年前と比較すればかなり容易になった(この点は別記事にまとめている[4]).しかしながら,Snowflake を触ったことのないライトユーザ層からすると,そのハードルは依然として一定程度高い.
具体的には,次のような点が障壁として挙げられる.
- セマンティックビューを定義するには,テーブルの各カラムを ディメンション(分析軸)/メジャー(集計対象)/時間軸 に分類し,YAML として記述する必要がある.
- Cortex Agent を作成するには,ツール仕様(
tool_spec)やツールリソース(tool_resources)の構造,プロファイル設定など,独特の記法を理解しなければならない. - これらは,エンジニアにとっては「以前よりかなり手軽になった」ものの,ライトユーザからすると依然として学習コストの高い作業である.
このため,ハンズオンは実施できても,各部の実務では活かされないという事態になりかねない.「入口」は用意できたが,その先へ進むための Agent/セマンティックビューの構築が,普段データを扱わない利用者には難しい,という構造的な課題が残っているのである.要件が少し違うだけで書くべき定義も変わるため,一度エンジニアが作って終わりにできないことも,この課題を根深いものにしている.
アプローチ(「テーブルを選ぶだけ」で Agent が立ち上がるツール)
上述の課題に対し,各部が準備したデータや,データ活用基盤内に既に存在するデータを指定するだけで,関連するエージェントを自動で構築できるツールを Streamlit で実装した.方針は次のとおりである.
ライトユーザは「どのテーブルを使いたいか」を選ぶだけでよい.セマンティックビューの YAML 生成,Agent の仕様記述,作成,動作確認までをツールが自動で肩代わりする.
実装は Streamlit アプリ(Streamlit in Snowflake 上で動作)として構築した.利用者の操作は次の4ステップに集約される.
- テーブル選択 — データベース → スキーマ → テーブル(複数可)を選ぶ.
- Agent 設定 — Agent 名,セマンティックビュー名,作成先スキーマ,最大カラム数を指定する.
- 作成実行 — ボタン一つでセマンティックビューと Agent を自動構築する.
- Agent テスト — 作成した(または既存の)Agent にチャット形式で質問し,実行された SQL と結果をその場で確認する.
全体アーキテクチャ
前提条件と必要な権限
本ツールは,テーブルのメタデータ取得,Semantic View と Cortex Agent の作成,そして Agent の呼び出しという,比較的強い操作を伴う.そのため,実行するロールには次の権限が必要になる.
-
ウェアハウス:クエリ実行のための
USAGE. -
データベース/スキーマ:対象および作成先の
USAGE,作成先スキーマに対する Semantic View と Agent の作成権限. -
テーブル:分析対象テーブルへの
SELECT(INFORMATION_SCHEMAはロールに応じて参照可能). -
Cortex 関連:Cortex Agents(
SNOWFLAKE.CORTEX.DATA_AGENT_RUN等)を利用するための権限.Snowflake では Cortex 機能の利用可否がロール(例:SNOWFLAKE.CORTEX_USERデータベースロール)で制御されるため,これが付与されている必要がある.
参考として,作成用ロールへの付与例を示す.権限名・スコープは Snowflake のエディション・リージョン・バージョンにより異なるため,実際の付与は各環境に応じて適切なものを設定していただきたい.
-- 例: 作成用ロール app_creator_role への付与(環境に合わせて調整すること)
GRANT USAGE ON WAREHOUSE <YOUR_WAREHOUSE> TO ROLE app_creator_role;
GRANT USAGE ON DATABASE <DB> TO ROLE app_creator_role;
GRANT USAGE ON SCHEMA <DB>.<SCHEMA> TO ROLE app_creator_role;
GRANT SELECT ON ALL TABLES IN SCHEMA <DB>.<SCHEMA> TO ROLE app_creator_role;
-- Semantic View / Agent の作成権限(オブジェクト作成権限)
GRANT CREATE SEMANTIC VIEW ON SCHEMA <DB>.<SCHEMA> TO ROLE app_creator_role; -- [要確認:権限名]
GRANT CREATE AGENT ON SCHEMA <DB>.<SCHEMA> TO ROLE app_creator_role; -- [要確認:権限名]
-- Cortex 利用
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE app_creator_role; -- [要確認:対象ロール名]
とくに Cortex 関連の権限が付与されていない場合,Agent の作成や呼び出しが失敗する点に注意されたい.失敗は internal error のような形で現れ,原因の特定が難しいことがあるため,まず権限まわりを確認することを勧める.
実装の詳細
以降,4つのステップに分けて実装の要点を述べる.コードの全体像は末尾に示す streamlit_app.py を参照されたい.
Step 1: セマンティックビュー YAML の自動生成
まず,選択されたテーブルのカラム情報を INFORMATION_SCHEMA.COLUMNS から取得する.
SELECT COLUMN_NAME, DATA_TYPE, COMMENT
FROM {database}.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '{schema}' AND TABLE_NAME = '{table}'
ORDER BY ORDINAL_POSITION
取得したカラムを,データ型にもとづいて次のように自動分類する.
| DATA_TYPE | 分類 | 備考 |
|---|---|---|
DATE,TIMESTAMP*,DATETIME
|
time_dimensions | 時間軸 |
NUMBER,FLOAT,INT* 等 |
measures | 集計対象(default_aggregation: sum) |
その他(VARCHAR 等) |
dimensions | 分析軸 |
この工程で判明した実装上の要点は次のとおりである.
-
データ型はパラメータ付きで返る.
DATA_TYPEはNUMBER(38,0)のように精度・スケール付きで返るため,split("(")[0]で基本型を取り出してから判定する必要がある. -
小文字カラム名はダブルクォートが必須.
is_defaultのような小文字を含むカラムは,exprフィールドで"is_default"とクォートしなければ,参照時に大文字化されてinvalid identifierとなる. -
各カラムに3フィールドが必須. セマンティックビューの各列には
name,expr,data_typeの3つが必要である. -
カラム数の上限を設ける. カラムが多すぎると後段の Agent 呼び出しで
internal errorとなる場合があったため,1テーブルあたりの最大カラム数を制限(既定30,推奨30以下)できるようにした.
生成される YAML は次の形式となる.
name: MY_SEMANTIC_VIEW
tables:
- name: TABLE_NAME
base_table:
database: DB
schema: SCHEMA
table: TABLE_NAME
dimensions:
- name: COL1
expr: COL1
data_type: VARCHAR(16777216)
time_dimensions:
- name: START_TIME
expr: START_TIME
data_type: TIMESTAMP_LTZ(9)
measures:
- name: AMOUNT
expr: AMOUNT
data_type: NUMBER(38,0)
default_aggregation: sum
Step 2: セマンティックビューの作成
生成した YAML から,SYSTEM$CREATE_SEMANTIC_VIEW_FROM_YAML を用いてセマンティックビューを作成する.
CALL SYSTEM$CREATE_SEMANTIC_VIEW_FROM_YAML(
'{database}.{schema}', -- 作成先スキーマの FQN
$$ {yaml_content} $$, -- YAML 本体($$ で囲む)
FALSE, -- FALSE=作成/TRUE=検証のみ
FALSE -- FALSE=作成/TRUE=検証のみ
)
判明した要点は次のとおりである.
-
CREATE SEMANTIC VIEW ... AS $$ ... $$という構文は存在しない.YAML から作成する場合は上記のシステムプロシージャを用いる. - YAML 本体はドルクォート(
$$)で囲む. - ビュー名は SQL 側ではなく YAML 内の
nameフィールドで決まる. - 第3・第4引数を
TRUE, TRUEにすると「検証のみ」で実体が作られない.実際に作成するにはFALSE, FALSEを指定する必要がある(これは当初,検証だけが走って「オブジェクトが作られない」現象として現れた).
Step 3: Cortex Agent の作成
セマンティックビューをツールとして組み込んだ Cortex Agent を作成する.正しい構文は CREATE AGENT ... FROM SPECIFICATION である.
CREATE OR REPLACE AGENT {db}.{schema}.{agent_name}
FROM SPECIFICATION
$$
models:
orchestration: auto
orchestration: {}
tools:
- tool_spec:
type: cortex_analyst_text_to_sql
name: {tool_name}
description: "説明文"
tool_resources:
{tool_name}: # ← tools[].name と一致させる
execution_environment:
type: warehouse
warehouse: ""
semantic_view: {sv_fqn} # ← semantic_view_fqn ではなく semantic_view
$$
ここが最もつまずいた工程であった.判明した要点を挙げる.
-
CREATE CORTEX AGENTではなくCREATE AGENT. 前者はunexpected 'AGENT'の構文エラーになる. -
SPEC = $$...$$ではなくFROM SPECIFICATION $$...$$. 前者はコンパイルこそ通るが,スペックが保存されず空になるという分かりにくい挙動を示した. -
tool_resourcesのキーはツール名(tool_spec.name)と一致させる. 型名であるcortex_analyst_text_to_sqlをキーにするとエラーになる. -
リソースは
semantic_view_fqnではなくsemantic_viewで指定し,execution_environmentを含める. これは,正しく動作している既存 Agent のスペックと突き合わせて初めて判明した. models.orchestration: autoとorchestration: {}が必要.
さらに,Agent 作成後には次の2手順が必須であった.
-- プロファイル設定(display_name がないと DATA_AGENT_RUN が internal error を返す)
ALTER AGENT {fqn} SET PROFILE = '{"display_name": "agent_name"}';
-- バージョンのコミット
ALTER AGENT {fqn} COMMIT;
とくに プロファイル(display_name)未設定が internal error の主因であった点は,エラーメッセージからは特定しにくく,正常に動く既存 Agent との差分比較によってようやく突き止められた.
Step 4: Agent のテスト(動作確認)
作成した Agent は,SNOWFLAKE.CORTEX.DATA_AGENT_RUN で呼び出して動作確認する.
SELECT SNOWFLAKE.CORTEX.DATA_AGENT_RUN(
'{agent_fqn}',
'{"messages": [{"role": "user", "content": [{"type": "text", "text": "質問"}]}]}'
) AS RESPONSE
レスポンスは v2 スキーマで返り,content 配列の中に text(回答),tool_use,tool_result(実行 SQL と結果セット),suggested_queries などが含まれる.
{
"content": [
{"type": "text", "text": "回答テキスト"},
{"type": "tool_use", "tool_use": { }},
{"type": "tool_result", "content": [
{"type": "json", "json": {"sql": "SELECT ...", "result_set": { }}}
]},
{"type": "suggested_queries", "suggested_queries": []}
],
"role": "assistant",
"status": "completed"
}
注意点として,リクエスト本文に "stream": false を含めるとエラーになる(SQL 関数からの呼び出しは常に非ストリーミングのため).また,エラー時は {"message": "internal error", "code": "..."} の形式で返るため,アプリ側でこの形を検出し,利用者にエラー内容を明示するようにした.
Streamlit 固有の注意点
Streamlit in Snowflake 上での実装では,実行方法の使い分けが重要であった.
| 操作 | 方法 | 理由 |
|---|---|---|
SHOW コマンド |
session.sql().collect() |
conn.query() は fetch_pandas_all でエラーになる |
| DDL 実行 | session.connection.cursor().execute() |
session.sql() は Snowpark のエイリアスエラーを起こす |
SELECT 実行 |
session.sql().collect() |
安全に取得できる |
| 接続 | st.connection("snowflake", ttl=os.getenv("SNOWFLAKE_CONNECTION_TTL")) |
定番パターン |
つまずいた点とその回避策(トラブルシューティング)
本ツールは一発では完成せず,多くのエラーを踏みながら組み上げた.同様の構築を試みる方の一助となるよう,発生したエラーと対策を一覧で共有する.
| エラー | 原因 | 対策 |
|---|---|---|
internal error |
プロファイル未設定,またはスペック不正 |
ALTER AGENT ... SET PROFILE + 正しいスペック形式 |
invalid identifier 'xxx' |
小文字カラム名の未クォート |
expr を "col_name" とダブルクォート |
Duplicate expression name |
カラム重複,または expr 未指定 |
重複排除(seen_cols)+ expr を明示 |
fetch_pandas_all NotSupported |
SHOW 結果の取得方法 |
session.sql().collect() を使う |
aliases for Columns |
session.sql() で DDL を実行 |
session.connection.cursor().execute() を使う |
unexpected 'AGENT' |
CREATE CORTEX AGENT は不正 |
CREATE AGENT を使う |
SPECIFICATION 関連エラー |
キーワード誤り |
FROM SPECIFICATION を使う |
| YAML は valid だが作成されない | 引数が TRUE, TRUE
|
FALSE, FALSE で実際に作成 |
これらの多くは,公式ドキュメントの記述と実際の挙動の差分,あるいはエラーメッセージからは原因が読み取りにくい類のものであった.とくに Agent 作成まわりは,正常に動作している既存 Agent のスペックを DESCRIBE で確認し,自作 Agent との差分を突き合わせる手法が有効であった.
考察
本ツールにより,ライトユーザは「どのテーブルを使いたいか」を選ぶだけで,セマンティックビューと Cortex Agent の動作するたたき台をその場で得られるようになった.これまでエンジニアが手書きしていた YAML やスペック定義を介さずに,対話可能な Agent の入口まで到達できる点は,冒頭に述べた課題に対する一定の前進といえる.
一方で,本アプローチには次の限界がある点も正直に記しておきたい.
-
カラム分類は発見的(ヒューリスティック)である. データ型のみで分類しているため,たとえば
DATABASE_IDのような ID 列が数値型ゆえに「合計を取るメジャー」として分類されるなど,意味的に不適切な分類が生じうる.実運用では生成後の手直しが望ましい. - 生成されるセマンティックビューは簡易なものである. 同義語(synonyms),検証済みクエリ,テーブル間のリレーションなどは付与しておらず,あくまで自動生成の初期版という位置づけである.
- カラム数の多いテーブルには制限が要る. 90 列規模のテーブルでは Agent 呼び出しが不安定になったため,カラム数の上限を設けている.広いテーブルをそのまま扱うには,列の絞り込みや設計の工夫が必要になる.
- CoWork の自動起動は未達である. Streamlit からの外部アプリ起動制御ができなかったため,アプリ内テストで代替している.
以上より,本ツールは「ライトユーザが Agent 構築の最初のハードルを越えるための入口」を提供するものであり,本格的な分析用途では生成物の見直しを前提とすることが望ましいと考えられる.とはいえ,手書きのゼロからの構築を,テーブル選択という一操作にまで圧縮できたことの実務的な意義は小さくないと思われる.今後は,カラム分類の精度向上(列名パターンやコメントの活用),同義語・関係定義の自動付与,そして CoWork との連携強化を進めることで,より実践的なツールへ育てていきたい.
まとめ
- CoCo・CoWork によってライトユーザ向けのデータ活用の「入口」は整ってきたが,その先の Cortex Agent・セマンティックビュー構築には依然ハードルが残る.
- 本記事では,テーブルを選ぶだけでセマンティックビューと Cortex Agent を自動生成する Streamlit アプリを構築し,その入口を一操作にまで圧縮した.
- 構築を通じて,
FROM SPECIFICATION構文,tool_resourcesの記法,プロファイル設定の必須性など,Snowflake 側の仕様上の要点を明らかにした. - 生成物はあくまで初期版であり,カラム分類の精度や意味定義には改善の余地が残る.今後の継続的な改良を予定している.
おまけ:ユーザに権限を渡さずに実行する(所有者の権限モデル)
前節で述べたとおり,本ツールをユーザ自身のロールで動かす場合,そのロールに Cortex や DDL の権限を付与する必要がある.しかしながら,実運用では,ライトユーザに対してこれらの強い権限を直接渡すことが望ましくない,あるいは渡せない場合もある.
このような場合には,Streamlit in Snowflake の「所有者の権限(owner's rights)」モデルを用いることで,ユーザに権限を渡さずに本ツールを実行させることができる.要点は次のとおりである.
- Streamlit in Snowflake のアプリは,既定で 呼び出し元(閲覧者)ではなく,アプリ所有者の権限で実行される[2].
- したがって,必要な権限(Cortex/DDL/
SELECT)を持つロールでアプリを作成・所有しておけば,閲覧者にはアプリへのUSAGEを付与するだけでよい.閲覧者自身はCREATE AGENTなどの権限を持つ必要がない. - アプリは所有者がプロビジョニングしたウェアハウスで動作し,アプリが作成された DB/スキーマ上で実行される.
具体的な設定手順(作成用ロールの用意,アプリのデプロイ,閲覧用ロールへの USAGE 付与など)は,別記事に詳しくまとめている[5].
本ツールで反映すべき箇所
本ツールを所有者の権限モデルで動かす場合,アプリのロジックそのものはほぼ変更不要であるが,次の点に注意・修正が必要である.
-
デプロイ/所有ロール(最重要) — アプリを,Cortex・Semantic View 作成・Agent 作成・対象テーブル
SELECTの各権限を持つ専用ロールで作成・所有する.閲覧ユーザには当該アプリへのUSAGEのみを付与する.すなわち変更点は「誰がアプリを所有するか」であり,コードではなく 運用・デプロイ設計の部分である. -
SHOW/DESCRIBE系の置き換え — 所有者の権限(ウェアハウスランタイム)で動くアプリは,所有者権限ストアドプロシージャと同じ制限を受け,SHOW/DESCRIBE/LISTなどのコマンドが制限される.本ツールのget_databases/get_schemas/get_tables/get_table_columnsはSHOW系に依存しているため,INFORMATION_SCHEMA(またはACCOUNT_USAGE)を用いたSELECTベースの取得に置き換える必要がある.なお,YAML 生成部(generate_semantic_view_yaml)は既にINFORMATION_SCHEMA.COLUMNSを用いているため,この部分は変更不要である.また,これらの制限を受けない コンテナランタイムでアプリを動かすという選択肢もある. -
コンテキスト/セッション — 所有者の権限アプリは,閲覧者ではなくアプリ所有者のコンテキストで動作する.
CURRENT_USERなどのコンテキスト関数を用いる場合は,所有者ロールへREAD SESSION権限の付与が必要になる点にも留意する.
なお,本記事の趣旨は,あくまで「テーブルを指定すると,対応する Cortex Agent が自動で作成される」点にある. 本節は,その仕組みを権限管理の観点から実運用に載せるための補足(おまけ)である.
ソースコード(GitHub)
本ツールの全ソースコードは,以下の GitHub リポジトリで公開している[6].セットアップ手順・実装メモ・制限事項も README にまとめている.
リポジトリ構成は次のとおりである.
auto-cortex-agent-creator/
├── streamlit_app.py # メインアプリ(全機能)
├── requirements.txt # 依存パッケージ
├── snowflake.yml # Streamlit in Snowflake デプロイ定義(要編集)
├── .streamlit/
│ └── config.toml # Streamlit 設定
├── .gitignore
├── LICENSE # MIT License
└── README.md
参考
Snowflake(公式ドキュメント)
[1]はじめての Snowflake Intelligence: https://www.snowflake.com/ja/developers/guides/getting-started-with-snowflake-intelligence-ja/
[2]所有者の権限と Streamlit in Snowflake アプリの理解: https://docs.snowflake.com/ja/developer-guide/streamlit/object-management/owners-rights
関連する発表・記事(@mshdtksk)
[3]「NTT西日本のデータ活用基盤Polarisの歴史〜「使える人しか使わない基盤」から「誰もが経営に活かせる基盤」へ〜」の営みの中で経営層に対して6分デモ実演をした話(Docswell): https://www.docswell.com/s/3324212129/KWRL2D-2026-07-18-193407
[4]Snowflake Intelligenceへの進化の軌跡 - データカタログの苦労からAI-readyな世界まで(Qiita): https://qiita.com/mshdtksk/items/d9c3d133964dc21a30cd
[5]MFA導入後でも別ユーザーの権限で実行できるStreamlitアプリを作る(Qiita): https://qiita.com/mshdtksk/items/41872814bb8542a6e84e
本稿の実装
[6]本稿のソースコード(GitHub): https://github.com/mshdtksk/auto-cortex-agent-creator





