Snowflake AI_COMPLETE 関数で動画と音声を直接分析
はじめに
Snowflake の非構造化データ分析がまた一つ大きな進化を遂げました。これまで画像、ドキュメント、音声と段階的に対応してきた Cortex AI ですが、ついに AI_COMPLETE 関数 が 動画と音声をそのまま入力 として受け付けられるようになりました!
今回ご紹介する AI_COMPLETE 関数のマルチモーダル拡張 は、Snowflake Cortex AI Functions の中でも個人的にはかなりインパクトの大きいアップデートで、Public Preview としてリリースされました。動画ファイルや音声ファイルを SQL からそのまま AI に渡し、要約・分類・感情分析・構造化抽出までを一気通貫で行えるようになります。
これまで音声データの分析は AI_TRANSCRIBE 関数でテキスト化してから他の関数で処理する 2 段構成が基本でした。動画データに至っては、Python の動画処理ライブラリでフレーム抽出や音声トラック分離をする前処理を組むか、Snowpark Container Services (SPCS) で専用の処理基盤を構築するか、というアーキテクチャを取る必要がありました。今回のアップデートで、これらの前処理を介さずに 音声のトーンや間合い、動画の映像情報まで含めて AI に直接理解させる ことができるようになったため、これまで踏み込めなかった領域の分析にもチャレンジしやすくなります。
非構造化データの世界で、画像、ドキュメント、音声、そして動画と、ビジネスで扱う主要なデータ形式すべてが SQL から扱えるようになったことで、よりマルチモーダルなデータ分析をシンプルに構成できる ようになったと言えるのではないでしょうか。
本記事では、AI_COMPLETE 関数の動画・音声対応の概要から基本的な使い方、AI_TRANSCRIBE 関数とのコスト・品質比較、そしてビジネス活用まで実例を交えて詳しく解説していきます。最後には Streamlit in Snowflake で動画をアップロードしてその場で分析する、シンプルで体感的なサンプルアプリもご紹介しますので是非最後までご覧ください!
AI_COMPLETE 関数のマルチモーダル拡張とは
AI_COMPLETE 関数 は Snowflake Cortex AI Functions の中核を担う汎用 LLM 呼び出し関数です。これまでもテキスト、画像、ドキュメントといったマルチモーダル入力に対応してきましたが、今回のアップデートで 動画ファイル・音声ファイルを直接入力 として渡せるようになりました。
これまでの音声分析は「AI_TRANSCRIBE で文字起こし → AI_COMPLETE でテキスト分析」という 2 段構成が主流でした。動画分析については、Python の動画処理ライブラリでフレームを画像として切り出し AI_COMPLETE の画像入力に流し込んだり、SPCS でフレーム抽出と推論を行う処理基盤を組んだりするアプローチが必要でした。今回のマルチモーダル拡張では、こうした前処理を介さず 音声・動画ファイルそのものを AI_COMPLETE に渡して 要約や感情分析、構造化抽出までできるようになります。
主な特徴
- SQL ネイティブ: 既存の AI_COMPLETE 関数と同じ呼び出し方で動画・音声をそのまま扱える
- 音声と映像の同時理解: 動画の場合、映像と音声の両面から内容を解析できる
- マルチモーダル統合: テキストプロンプトと組み合わせた条件付き分析や JSON 構造化出力に対応
- 対応形式の広さ: 動画・音声ともに主要な汎用フォーマットに対応
- セキュアな処理: ステージ上のファイルを Snowflake 内で完結して処理
Cortex AI Functions ファミリーの一員として
AI_COMPLETE のマルチモーダル拡張は、AI_COMPLETE で抽出した結果を 後工程の AI Functions にそのまま流し込む ことで、より分析の幅が広がります。例えば動画から要約テキストを取り出した後段で、以下のような AI Functions と組み合わせるパターンが王道です。
- AI_CLASSIFY: AI_COMPLETE で取り出した要約を業種カテゴリやリスクレベルに分類
- AI_SENTIMENT: 抽出したテキストの感情を多角的にスコア化
- AI_AGG: 大量のメディアから抽出した結果を集約してインサイトを得る
- AI_EMBED: 抽出テキストや画像をベクトル化して横断検索を可能に
- AI_TRANSCRIBE: 文字起こしに特化した関数。タイムスタンプや話者ラベル付きで音声を構造化テキストに変換したいときに最適
基本的な使い方
AI_COMPLETE 関数で動画・音声を直接渡す構文は、画像入力と同様にシンプルです。
AI_COMPLETE(
<model>,
<prompt>,
<file>
)
パラメータ
-
model: 動画・音声に対応した LLM モデル名 (現時点では
gemini-3.1-proとgemini-3.5-flashが公式に動画・音声入力対応として案内されています。今後の対応モデル拡大が期待されます) - prompt: AI に依頼する内容を自然言語で記述
-
file:
TO_FILE関数で参照するステージ上のファイル (動画または音声)
使用例1: 動画ファイルの要約
最もシンプルな使い方として、動画ファイルをそのまま渡して要約を生成するパターンです。映像と音声の両方を踏まえた要約が一発で取得できます。
本記事ではサンプル動画として Pexels: Pouring Fresh Coffee into Ceramic Mug (Pexels License) を使用しています。
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'この動画の内容を 200 文字程度で日本語で要約してください。映っているもの、雰囲気、想定されるシーンを含めてお願いします。',
TO_FILE('@media_stage', 'pouring_coffee.mp4')
) AS summary;
実際の出力例は以下のようになりました。
白いテーブルの上で、ガラス製のコーヒーサーバーからユニークな青いキャラクター型の小さなマグカップに、淹れたてのコーヒーがゆっくりと注がれる様子が映っています。カップの可愛らしいデザインと、コーヒーが満たされていく静かな動きが、ホッと一息つくような温かみのあるリラックスした雰囲気を醸し出しています。自宅での穏やかな朝のコーヒータイムや、午後のほっとする休憩シーンが想定される動画です。
同じパターンは音声ファイルでも全く同じ書き方で動作します。例えば英語朗読の音声を渡して日本語で要約してもらうと、声のトーンや雰囲気まで含めた要約が返ってきます。
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'この音声の内容を 150 文字程度で日本語で要約してください。話者の感情や雰囲気も踏まえてお願いします。',
TO_FILE('@media_stage', 'english_narration.m4a')
) AS summary;
シャーロック・ホームズにとって、彼女(アイリーン・アドラー)は常に「あの女性」という唯一無二の特別な存在です。話者であるワトソンは、ホームズが彼女を他の名前で呼ぶのをほとんど聞いたことがないと語っています。ワトソンの落ち着いた回想めいた語り口からは、ホームズが彼女に対して抱く深い敬意や、彼女の圧倒的な存在感が静かに伝わってきます。
日本語音声でも同様に動作します。コールセンター応対のような場面想定の音声ファイル (本記事では再現性のため macOS の say コマンドで合成した日本語音声を利用しています。同じパターンを試すには Mozilla Common Voice 日本語データセット (CC0) や VOICEVOX で生成した音声でも代用可能です) を渡したところ、用件と感情トーンを的確にまとめてくれました。
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'この音声の内容を日本語で要約し、話者の用件と感情トーンを 1〜2 文で返してください。',
TO_FILE('@media_stage', 'business_call_jp.m4a')
) AS summary;
話者は、購入した商品の配送が遅れているため、現在の状況を確認したいという用件で連絡しています。感情トーンは、非常に丁寧で落ち着いた印象を受けます。
使用例2: 音声のトーン・ピッチまで踏み込んだ分析
ここからが AI_TRANSCRIBE と決定的に異なる点です。AI_COMPLETE は 音声の文字情報だけでなく、声のピッチ・話す速度・音量・トーン (vocal delivery) までモデルに評価させる ことができます (公式ドキュメントのコールセンター分析の例でも明示されています)。「こんにちは」という同じセリフでも、明るく弾むようなトーンと、重く沈んだトーンとではビジネス上の意味は全く違ってきますよね。テキスト化してしまうと失われるこのニュアンスを、AI_COMPLETE はそのまま捉えられるわけです。
試しに、まったく同じ日本語のセリフ (「こんにちは。本日もよろしくお願いいたします。」) を、明るく速いトーンと、暗く落ち着いたトーンの 2 パターンで合成し、それぞれを AI_COMPLETE に渡してみました。
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'You are an acoustic analyzer. Listen to the attached audio and evaluate the vocal delivery (pitch, pace, tone, volume). Return a Japanese description of the vocal delivery only (do not transcribe content). 出力は日本語で短く。',
TO_FILE('@media_stage', 'tone_bright.m4a')
) AS bright_analysis;
明るいトーンの音声に対する出力。
非常に高いピッチと速いペースで話されています。トーンは明るくやや人工的(早送りや加工されたような声)で、ボリュームは適度です。
暗いトーンの音声に対する出力。
ピッチは中程度で安定しており、ペースは落ち着いて聞き取りやすいです。トーンは丁寧かつ穏やかで、音量は適度で一定に保たれています。
言葉の内容は同じなのに、声の出し方を読み取ってまるで別の評価が返ってきました。これは AI_TRANSCRIBE では絶対に取り出せない情報なので、コールセンター品質スコアリング・面接評価・問い合わせの緊急度判定など、「言葉の中身ではなく、声の出し方そのものが意味を持つ」ユースケース で大きな威力を発揮します。
使用例3: 動画ファイルの構造化分析
JSON Schema を指定して構造化された結果を取得する例です。ダッシュボードや他システム連携で使いやすい出力が一発で手に入ります。
同じサンプル動画を使って、シーン要約・登場物体・雰囲気を構造化して取得してみます。
SELECT TO_JSON(AI_COMPLETE(
'gemini-3.1-pro',
'この動画を分析し、シーンの要約・登場物体・全体の雰囲気を JSON で返してください。',
TO_FILE('@media_stage', 'pouring_coffee.mp4'),
{},
{
'type': 'json',
'schema': {
'type': 'object',
'properties': {
'summary': {'type': 'string'},
'objects': {'type': 'array', 'items': {'type': 'string'}},
'mood': {'type': 'string'}
},
'required': ['summary', 'objects', 'mood']
}
}
)) AS analysis;
実際の出力例は以下のようになりました。
{
"mood": "落ち着いた、リラックスした",
"objects": ["コーヒーポット", "マグカップ", "コーヒー"],
"summary": "黒いコーヒーポットから、青い鳥の顔がデザインされたユニークなマグカップにコーヒーが注がれている様子。"
}
Schema で指定したキーと型を守った JSON が返ってくるため、データパイプラインの次工程にそのまま渡しやすいのがうれしいところです。
同じパターンを使って、シーン要約・推測される話題ジャンル・全体トーンを すべて日本語で 構造化して取得してみます。プロンプトで「すべての値を日本語で」と明示するのがポイントです。
SELECT TO_JSON(AI_COMPLETE(
'gemini-3.1-pro',
'この音声を分析し、すべての値を日本語で記述した JSON で返してください。要約・推測される話題ジャンル・全体トーンを含めてください。',
TO_FILE('@media_stage', 'business_call_jp.m4a'),
{},
{
'type': 'json',
'schema': {
'type': 'object',
'properties': {
'summary': {'type': 'string'},
'genre': {'type': 'string'},
'tone': {'type': 'string'}
},
'required': ['summary', 'genre', 'tone']
}
}
)) AS analysis;
{
"genre": "ビジネス",
"summary": "挨拶と本日の協力をお願いしている。",
"tone": "丁寧"
}
値まできれいに日本語で返ってくるので、日本語ダッシュボードや日本語レポート生成にもそのまま使えます。
使用例4: テキストプロンプトと条件付き分析
「特定の観点だけ抽出してほしい」というケースもプロンプトの工夫で実現できます。該当が無いときに勝手に推測されたら困るので、「該当が無ければなしと返してください」という指示も含めています。
本記事ではサンプル動画として Pexels: Person Having an Interview (Pexels License) を使用しています。この動画には製品名は登場しないため、期待される出力は「なし」です。
SELECT AI_COMPLETE(
'gemini-3.1-pro',
'動画内で製品名 (ブランド名) が出てきた箇所のみを抽出し、製品名と出現タイミングを箇条書きで列挙してください。該当が無ければ「なし」とだけ返してください。',
TO_FILE('@media_stage', 'interview.mp4')
) AS extracted;
実際の出力は なし とシンプルに返り、プロンプトの指示に忠実に従っていることが確認できました。
対応モデルとフォーマット
対応モデル
公式ドキュメント上、現時点で動画・音声を直接入力できるモデルとして案内されているのは gemini-3.1-pro と gemini-3.5-flash です。当初は gemini-3.1-pro のみでしたが、より軽量・高速な gemini-3.5-flash も追加され、選択肢が広がりました。どちらもコンテキストウィンドウは 100 万トークンで、対応フォーマットやファイルサイズ上限も同等です。Snowflake は様々なモデルプロバイダーとパートナーシップを結んでおり、今後さらにマルチモーダル対応モデルのラインナップ拡充が期待できます。
| モデル | コンテキストウィンドウ | 用途の目安 |
|---|---|---|
gemini-3.1-pro |
1,000,000 トークン | 高い分析品質を重視したいケース |
gemini-3.5-flash |
1,000,000 トークン | より高速・軽量に処理したいケース |
また、AI_COMPLETE の使いやすいところは どのモデルが背後で使われているかが明示されている 点です。テキスト処理を担う他社のマネージドサービスでは「内部のモデルが知らないうちに切り替わる」ことがありますが、AI_COMPLETE では関数の第 1 引数で必ずモデル名を指定するため、どのモデルが使われているか/コストや特性がどうなっているかをコントロールしながらアプリを設計できます。
対応フォーマット
非常に幅広いフォーマットに対応しているため、世の中で使われている多くの動画・音声ファイルをそのまま扱えます。
| 種類 | 対応フォーマット |
|---|---|
| 動画 | mp4, mpeg, mov, avi, flv, mpg, webm, wmv, 3gpp |
| 音声 | wav, mp3, aiff, aac, ogg, flac, m4a, mp4, pcm, webm |
リクエスト上限
1 リクエストあたりの上限は次の通りです。検証や PoC では十分な範囲ですし、上限についても今後拡張されていくことが期待されます。
| 項目 | 上限 |
|---|---|
| 1 リクエストの合計サイズ | 100 MB |
| 動画ファイル数 / リクエスト | 最大 10 本 |
| 音声ファイル数 / リクエスト | 最大 10 本 |
長尺の動画を扱いたい場合は、シーンや時間で分割してから渡すことで、現状の上限内でも幅広い分析が可能です。
リージョン対応状況
動画・音声入力に対応しているモデル (gemini-3.1-pro / gemini-3.5-flash) のネイティブ提供リージョンは Cortex LLM の Regional availability でご確認ください。お使いのリージョンで利用できない場合でも、クロスリージョン推論 を有効化することで同等の機能をご利用いただけます。設定はワンライナーで完了します。
ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';
クロスリージョン推論を経由する場合は若干レイテンシが増える可能性はありますが、機能としては同様にご利用いただけます。
AI_TRANSCRIBE との使い分け (コストと品質)
「音声を扱うなら AI_TRANSCRIBE と AI_COMPLETE のどちらを使うべきか?」は、新機能を試すうえで多くの方が気になるポイントだと思います。
そもそも AI_TRANSCRIBE は「音声をテキスト化する」という目的特化型の専用 AI Function です。出力形式は (テキスト + タイムスタンプ + 話者ラベル) に固定されており、自由度は低い反面、目的が明確なときにシンプルに使えてコストも秒単位で予測しやすい という強みがあります。一方の AI_COMPLETE は汎用 LLM のため、プロンプトでやりたいことを自由に表現でき、声のトーンや映像情報まで踏まえた解釈ができます。両者は競合するというよりは、目的が明確なときは AI_TRANSCRIBE、自由な解釈が必要なときは AI_COMPLETE という形で補完的に使い分けるのが基本方針です。
機能の違い
| 観点 | AI_TRANSCRIBE | AI_COMPLETE (音声直接入力) |
|---|---|---|
| 主な目的 | 音声 → テキストの構造化変換 | 音声内容の要約・分類・抽出など自由度の高い分析 |
| 出力 | テキスト + タイムスタンプ + 話者ラベル | プロンプトに応じた自由な出力 (JSON 構造化も可) |
| 話者分離 | 話者ラベル (SPEAKER_00 等) を自動付与 | プロンプトで「話者ごとに整理してください」と指示する形 |
| タイムスタンプ | 単語・話者単位で取得可能 | プロンプトで指定すれば取得可能 (構造化出力との組み合わせが推奨) |
| 声のトーンや感情 | テキスト変換のみ | 声のトーンや間合いまで踏まえた分析が可能 |
| 多言語対応 | 多言語に幅広く対応 | LLM ベースのため幅広い言語に柔軟に対応 |
コスト面の比較
| 関数 | 課金単位の特徴 |
|---|---|
| AI_TRANSCRIBE | 音声 1 秒 = 50 トークン (一律)。1 時間で 180,000 トークン |
| AI_COMPLETE (音声直接) | LLM のトークン課金。入力サイズと出力長に応じて変動 |
AI_TRANSCRIBE は音声長に対してリニアに課金されるシンプルなモデルなので、「とにかく文字起こししたい」「大量バッチ処理のコストを安定させたい」 というケースで強みを発揮します。一方、AI_COMPLETE は LLM ベースの課金のため、長文プロンプトや構造化出力を組み合わせる場合は内容に応じてコストが上下します。その代わり、使うモデルを第 1 引数で明示的に選択できる ため、コストと分析品質のトレードオフをアプリ側でコントロールしやすいのがメリットです。
品質面の比較
両者は得意分野が異なるため、シナリオごとに使い分けるのが効果的です。
| シナリオ | 推奨 |
|---|---|
| 議事録のドラフト作成 (誰が何を話したか正確に残したい) | AI_TRANSCRIBE → AI_COMPLETE のチェーン |
| コールセンターの感情分析 (声のトーン込み) | AI_COMPLETE 直接 |
| 大量音声の高速バッチ文字起こし | AI_TRANSCRIBE |
| 動画 (映像+音声) の要約・モデレーション | AI_COMPLETE 直接 |
| 音声から JSON 構造化抽出 | AI_COMPLETE 直接 |
ビジネス活用シーン
AI_COMPLETE 関数の動画・音声対応によって広がるビジネス活用シーンをご紹介します。
1. コールセンターの品質スコアリング
通話音声を AI_COMPLETE に直接渡し、「対応のプロフェッショナリズム」「顧客の怒りレベル」「エスカレーションの兆候」などを 声のトーンも含めた多次元スコア として一括取得できます。
- 声のトーン込みの感情分析: 文字起こしでは取りこぼす微妙なニュアンスをカバー
- 構造化出力との連携: JSON で各指標を返してダッシュボード化
- オペレーター教育: ハイパフォーマー音声と比較した改善ポイントの抽出
2. 会議動画からの構造化議事録生成
長時間の会議動画を渡し、議題ごと・参加者ごとに要約・決定事項・アクションアイテムを構造化して取得できます。
- 議題分割: プロンプトで「議題ごとに章立てしてください」と指示
- アクションアイテムの抽出: 担当者と期限を JSON で取得
- 資料の連携: ホワイトボードや投影資料の文字情報も AI が拾える
3. プロモーション動画のコンプライアンスチェック
マーケティング動画について「景表法に抵触しそうな表現」「社内ガイドライン違反」を公開前にチェックするパターンです。
- NG ワード検出: プロンプトで条件を指定
- 映像と音声の整合性: 表示テロップと発話内容の矛盾を発見
- 多言語展開時の品質保証: 各言語版動画のチェックを SQL で一括実行
4. 教育・研修動画の章立て自動生成
オンライン教材を AI_COMPLETE で解析し、視聴者向けの章立て・要約・タイムスタンプ付きインデックスを自動生成できます。
- 章タイトルの自動抽出: 内容の切り替わりを AI が検出
- 学習者向け要約: レベル別に複数の要約を生成
- 検索可能化: 抽出した内容を AI_EMBED でベクトル化し横断検索
5. ソーシャル / UGC のモデレーション
UGC (User Generated Content / ユーザー生成コンテンツ) とは、SNS や動画投稿サイトに一般ユーザーが投稿した動画・音声・画像などのコンテンツのことです。これらに対して、有害コンテンツや違反コンテンツの検出を SQL ワークフローで実装できます。
- バッチモデレーション: ステージに到着した動画を Streams + Tasks で自動分析
- レポート連携: 結果を Snowflake Notification でレビュー担当者へ
- 多軸スコアリング: 暴力性・差別表現・著作権懸念などを並行評価
Streamlit in Snowflake で動画分析アプリ
AI_COMPLETE の動画対応を体感しやすいよう、Streamlit in Snowflake で動画をアップロードして即座に AI に分析してもらうシンプルなサンプルアプリを作ってみました。
アプリケーションの概要
このアプリでは以下の体験ができます。
- 動画アップロード: ブラウザから動画ファイルをアップロードし、ステージへ自動保存
- 動画プレビュー: アップロードした動画をその場で再生可能
- AI 分析: AI_COMPLETE の動画入力で要約・抽出・分類などの分析を実行
- プロンプト編集: サイドバーから分析プロンプトを自由に編集
前提条件
- Streamlit in Snowflake が利用可能なアカウント
- gemini-3.1-pro が利用可能なリージョン (またはクロスリージョン推論が有効)
- 100 MB 以下の動画ファイル
-
Streamlit のバージョンは
1.52.2を指定 (st.file_uploaderなどを利用するため、1.26.0 以上が必須)。本記事では Streamlit in Snowflake で利用可能な最新バージョンとして1.52.2を指定しています。
Streamlit バージョンの指定方法 (重要)
Streamlit in Snowflake のデフォルトバージョンは古いことがあるため、明示的に最新バージョンを指定することをおすすめします。アプリのファイル群と同じステージに environment.yml を配置するだけで反映されます。
# environment.yml
name: app_environment
channels:
- snowflake
dependencies:
- streamlit=1.52.2
Snowsight 上で SiS を作る場合は、エディタ右上の 「Packages」 から streamlit の version を 1.52.2 に変更すれば同じ効果が得られます。
実装手順
1. Streamlit in Snowflake のアプリを作成
Snowsight の左ペインから『Streamlit』を開き、『+ Streamlit App』ボタンから新規アプリを作成します。
2. サンプルコードの貼り付け
下記のサンプルコードをそのままコピー&ペーストします。ステージは初回起動時に自動作成されます。
3. アプリの実行
右上の「実行」ボタンをクリックしてアプリを起動し、動画をアップロードして「AI で動画を分析」ボタンを押すだけで分析結果が返ってきます。
サンプルコード
import streamlit as st
import io
import os
import re
import uuid
from datetime import datetime
from snowflake.snowpark.context import get_active_session
session = get_active_session()
STAGE_NAME = "VIDEO_ANALYSIS_STAGE"
# 現在の DB / Schema を取得してフルパスを組み立てる
db = session.get_current_database().strip('"')
schema = session.get_current_schema().strip('"')
STAGE_FQN = f"{db}.{schema}.{STAGE_NAME}"
st.set_page_config(layout="wide")
st.title("🎬 動画分析アプリ")
st.caption("AI_COMPLETE × gemini-3.1-pro で動画をその場で分析します")
st.sidebar.title("⚙️ 設定")
st.sidebar.info("動画分析に対応するモデル: gemini-3.1-pro")
prompt_template = st.sidebar.text_area(
"📝 分析プロンプト",
value=(
"この動画の内容を 300 文字程度で要約してください。"
"登場人物・主なシーン・音声から読み取れる感情を含めて、日本語で説明してください。"
),
height=180
)
@st.cache_resource
def setup_stage():
try:
session.sql(f"DESC STAGE {STAGE_FQN}").collect()
except Exception:
session.sql(f"""
CREATE STAGE IF NOT EXISTS {STAGE_FQN}
ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')
DIRECTORY = (ENABLE = TRUE)
""").collect()
setup_stage()
def clean_ai_response(text):
"""AI 応答の前後ダブルクォートとエスケープ済み改行を整える"""
if not isinstance(text, str):
return text
text = text.strip()
if len(text) >= 2 and text.startswith('"') and text.endswith('"'):
text = text[1:-1]
text = text.replace("\\n", "\n").replace('\\"', '"')
return text
uploaded_file = st.file_uploader(
"動画ファイルをアップロードしてください (合計 100MB 以下)",
type=["mp4", "mov", "webm", "avi", "mpeg", "mpg", "flv", "wmv"]
)
if uploaded_file is not None:
st.subheader("▶️ 動画プレビュー")
st.video(uploaded_file)
if st.button("🤖 AI で動画を分析", use_container_width=True, type="primary"):
try:
# 安全なファイル名に変換 (日本語・記号を排除)
ext = os.path.splitext(uploaded_file.name)[1].lower() or ".mp4"
safe_ext = ext if re.fullmatch(r"\.[a-z0-9]{2,5}", ext) else ".mp4"
video_filename = (
f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}_"
f"{uuid.uuid4().hex[:8]}{safe_ext}"
)
with st.spinner("動画をステージにアップロード中..."):
video_stream = io.BytesIO(uploaded_file.getvalue())
session.file.put_stream(
video_stream,
f"@{STAGE_FQN}/{video_filename}",
auto_compress=False,
overwrite=True
)
with st.spinner("AI が動画を分析中..."):
# バインド変数で SQL エスケープ問題を回避
query = f"""
SELECT AI_COMPLETE(
'gemini-3.1-pro',
?,
TO_FILE('@{STAGE_FQN}', ?)
) AS analysis
"""
result = session.sql(
query,
params=[prompt_template, video_filename]
).collect()
st.subheader("📊 分析結果")
if result and len(result) > 0 and result[0]["ANALYSIS"]:
st.markdown(clean_ai_response(result[0]["ANALYSIS"]))
else:
st.warning("分析結果が取得できませんでした。プロンプトや動画を変えて再度お試しください。")
except Exception as e:
st.error(f"エラーが発生しました: {str(e)}")
else:
st.info("👆 動画ファイルをアップロードすると、ここで分析を実行できます。")
実装のポイント
- 追加パッケージ不要: Streamlit in Snowflake の標準パッケージのみで動作
- ステージは自動作成: 初回起動時に Server Side Encryption + Directory Table 付きで作成
- プロンプトは自由編集: 用途に応じてサイドバーから即座に変更可能
-
動画プレビュー:
st.videoでアップロード直後にブラウザ上で再生確認
動作確認
アプリの中核となる「session.file.put_stream でステージにファイルを送る → AI_COMPLETE で分析する」のロジックは、Snowpark Python セッション経由で実機動作を確認済みです。Streamlit in Snowflake にコードをそのまま貼り付ければ、UI 越しに同じフローが動きます。
アプリケーション画面
デモ動画には Pixabay: Meadow, Grass, Spring Meadow, Wind (Pixabay Content License) を使用しています。
以下にアプリのスクリーンショットを 3 枚配置します (撮影後に差し替え)。
-
動画アップロード直後の画面

-
AI 分析実行直後の画面

-
サイドバーのプロンプト編集画面

コストについて
AI_COMPLETE 関数の課金は他の AI Functions と同様、トークン消費に基づいています。動画・音声を直接入力する場合は、以下の点を踏まえてコスト試算を行うのが安全です。
- 入力トークン: ファイルの長さや内容に応じて変動
- 出力トークン: プロンプトで指定した出力サイズに応じて変動
-
モデル単価:
gemini-3.1-proのクレジット単価が適用
最新のクレジット消費単価は Snowflake Service Consumption Table で確認できます。
本記事で利用したサンプル素材の出典
本記事で利用したフリー素材の一覧と出典です。読者の方が手元で再現できるよう、すべて商用利用可能なライセンスのものを選定しています。
- 動画: Pexels: Pouring Fresh Coffee into Ceramic Mug (Pexels License)
- 動画: Pexels: Person Having an Interview (Pexels License)
- 動画: Pixabay: Meadow, Grass, Spring Meadow, Wind (Pixabay Content License)
- 音声: LibriVox: The Adventures of Sherlock Holmes (Arthur Conan Doyle) (パブリックドメイン)
- 音声: LibriVox: A Christmas Carol (Charles Dickens) (パブリックドメイン)
- 音声: Mozilla Common Voice 日本語データセット (CC0)
まとめ
AI_COMPLETE 関数の動画・音声対応は、Snowflake のマルチモーダル分析をよりシンプルに構成できるようにする重要な一手 です。これまで段階的に拡張されてきた画像・ドキュメント・音声に動画が加わり、ビジネスで扱う主要な非構造化データのほぼ全てが SQL からそのまま扱えるようになりました。
主要なメリット
- メディアデータをそのまま AI に渡せる: 文字起こしを介さず、声のトーンや映像も理解できる
- 既存の AI Functions と組み合わせやすい: AI_TRANSCRIBE / AI_CLASSIFY / AI_AGG などとの連携で柔軟なパイプラインが構築可能
- ガバナンスを保ったまま分析: ステージ上のメディアデータが Snowflake の外に出ない
- SQL ネイティブ: 既存のデータパイプラインへの組み込みがスムーズ
対応モデルや上限値はこれから順次広がっていくことが期待され、今後ますます多くのユースケースで使えるようになっていきます。コールセンター、会議分析、コンテンツモデレーション、教育、マーケティングなど、幅広いビジネスシーンで AI_COMPLETE の動画・音声対応を活用し、これまで踏み込めなかった非構造化データから新たな価値を引き出していきましょう!
宣伝
SNOWFLAKE BUILD JAPAN ONLINE で登壇しました!
2025/12/11-12に開催されました『SNOWFLAKE BUILD JAPAN ONLINE 2025』において『Snowflakeで実現するデータ活用の未来: Snowflake IntelligenceとSnowflake Managed MCP Serverによるエージェント型分析』という内容のセッションを配信させていただきました。注目機能である Snowflake Intelligence 及び Snowflake Managed MCP Server の概要と利用方法についてデモを交えて可能な限り分かりやすお伝えしておりますので、是非ご視聴いただければ幸いです!
以下リンクでご登録いただけるとオンデマンドですぐにご視聴いただくことが可能です。
SNOWFLAKE DISCOVER でバーチャルハンズオンをデリバリしました!
2025/7/8-9に開催されました Snowflake のエンジニア向け大規模ウェビナー『SNOWFLAKE DISCOVER 第2弾』において『Snowflake Cortex AI で実現する次世代の VoC (顧客の声) 分析』という実践的なバーチャルハンズオンをデリバリさせていただきました。多くの業種で関連する顧客の声を Snowflake の最新機能を用いて分析する方法を体感いただけますので、是非非構造化データの分析のヒントを得たい方はご視聴いただければ幸いです!
以下リンクでご登録いただけるとオンデマンドですぐにご視聴いただくことが可能です。
SNOWFLAKE DISCOVER で登壇しました!
2025/4/24-25に開催されました Snowflake のエンジニア向け大規模ウェビナー『SNOWFLAKE DISCOVER』において『ゼロから始めるSnowflake:モダンなデータ&AIプラットフォームの構築』という一番最初のセッションで登壇しました。Snowflake の概要から最新状況まで可能な限り分かりやすく説明しておりますので是非キャッチアップにご活用いただければ嬉しいです!
以下リンクでご登録いただけるとオンデマンドですぐにご視聴いただくことが可能です。

X で Snowflake の What's new の配信してます
X で Snowflake の What's new の更新情報を配信しておりますので、是非お気軽にフォローしていただければ嬉しいです。
日本語版
Snowflake の What's New Bot (日本語版)
English Version
Snowflake What's New Bot (English Version)
変更履歴
(20260606) 動画・音声入力の対応モデルに gemini-3.5-flash が追加されたため、対応モデルの記載を更新
(20260517) 新規投稿


Discussion
コストが気になります
コメントありがとうございます!主に発生してくるコストは他のSnowflake AI Functionsと同様に (A.トークン数) * (B.モデル毎のクレジット単価) * (C.Snowflakeのエディション毎の単価) というトークン数ベースの料金となります。
B.モデル毎のクレジット単価は以下のCredit Consumption TableのTable 6(a)をご参照ください。
C.Snowflakeのエディション毎の単価は以下をご参照ください。
A.トークン数については、入力トークン数についてはLLMのモデル毎に異なって参ります。本記事の通りGemini 3.1 Proの場合、手元で動画で検証したところ1秒あたり数十 - 数百トークンほどになりましたのでご参考になれば幸いです。
また一度AI_COMPLETE関数を動かしてみていただいた後で、以下のビューで確認することで実際のコストが確認できますので、より正確な試算が可能かと存じますのでこちらもご参考になれば幸いです。