Tech Waves

produced by Hakuhodo DY ONE

本ブログは、株式会社Hakuhodo DY ONEの開発チームによるエンジニアブログです。
それぞれのメンバーが業務を通して得た技術情報や、各種セミナーの参加レポート、またその他トピックについて情報発信を行っています。

検索の常識が変わる?Snowflake Cortex Search を使って、3ステップで「意味で探す」検索エンジンを作ってみる


こんにちは、one_inaです❄️。

前回は自然言語で SQL を生成する「Cortex Analyst」を紹介しましたが、
今回はもう一つの強力な AI 機能「Cortex Search」を取り上げます。

「マニュアルのどこに書いてあるか分からない…」
「キーワードが少し違うだけで検索にヒットしない…」

そんな悩みを、「自然言語で検索」する「Cortex Search」で解決してみましょう。

 

1. Cortex Search とは何か?

Cortex Search は、Snowflake 内のデータに対して 高性能な検索エンジンを数分で構築できるフルマネージドなサービスです。

最大の特徴は、単なる「キーワード一致」ではなく、
「言葉の意味」を理解して検索する(ベクトル検索)点にあります。

一般的な検索と Cortex Search の違い

項目 従来のキーワード検索 (LIKE等) Cortex Search
検索ロジック 文字列の完全/部分一致 ベクトル化による意味の類似度
表記揺れ 「PC」と「パソコン」は別物 同じ意味として処理
インフラ 自分でインデックス管理が必要 インフラ・計算リソースは Snowflake 任せ
精度向上 複雑な辞書登録が必要 自動で埋め込み(Embedding)モデルを適用

RAG(検索拡張生成)の基盤として、LLM に最新知識や社内ドキュメントを渡す際の「検索部分」として非常に重宝されます。

 

2. 【事前準備】サンプルデータを用意しておく

今回は、仮に「10件の請求書(帳票)PDF」があったらと仮定して、 これを自然言語で検索する題材にします。

仮に、下記のようなフォーマットのPDFが10個存在しているとします。
※あくまでサンプルで作成しているデータなので架空の請求書です

 

3. Cortex Search サービスを作成する

それでは、3ステップでCortex Searchを作成しましょう。

ステップ1:PDFファイルの取り込み(Storage)

まず、PDFファイルをSnowflake内に保存します。

  1. Stage(ステージ)の作成: PDFをアップロードするための場所を作ります。

    CREATE STAGE TEST.PUBLIC.MY_FILES_STAGE
      ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')
      DIRECTORY = (ENABLE = true);

    具体的には、以下の3つのことを行っています。

    1. CREATE STAGE TEST.PUBLIC.MY_FILES_STAGE

    「TESTデータベース」の「PUBLICスキーマ」の中に、「MY_FILES_STAGE」という名前のステージを作ります。

    • ステージとは: CSVやPDF、画像などのファイルを一時的にアップロードしたり、置いておいたりするためのストレージ領域です。
    • この記述では、Snowflakeが内部で管理する「内部ステージ(Internal Stage)」が作成されます。

    2. ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')

    「Snowflakeによるサーバーサイド暗号化」を設定しています。

    • SNOWFLAKE_SSE (Server-Side Encryption) とは、Snowflake側が自動的にファイルを暗号化して保存し、管理してくれる設定です。
    • ユーザーが複雑な鍵管理をすることなく、安全にファイルを保管できます。

    3. DIRECTORY = (ENABLE = true)

    「ディレクトリテーブル」という機能を有効にしています。

    • これが有効になっていると、ステージにどんなファイルがあるかをSQLで検索(SELECT)できるようになります。
    • 通常、ステージ内のファイルを見るには LIST @stage_name という特殊なコマンドが必要ですが、これを true にすると、「ファイル名」「サイズ」「最終更新日」などのメタデータをテーブルのように扱えるため、非常に便利です。



  2. ファイルのアップロード: Snowsight(管理画面)から、作成したステージに10件のPDFファイルをアップロードします。 管理画面で先ほど作成した ステージオブジェクトを開き「+ファイル」ボタンを押すことで、 ファイルを簡単にアップロードできます。

 

ステップ2:テキスト抽出とテーブル化(Parsing)

Cortex Searchはテーブル(またはビュー)のデータを検索対象とするため、PDFからテキストを抽出してテーブルに格納します。

  1. テーブルの作成:

    CREATE OR REPLACE TABLE TEST.PUBLIC.PARSED_PDFS AS
    SELECT
      RELATIVE_PATH AS file_name,
      AI_PARSE_DOCUMENT(
        TO_FILE('@TEST.PUBLIC.MY_FILES_STAGE', RELATIVE_PATH),
        {'mode': 'LAYOUT', 'page_split': true}
      ) AS parsed_content
    FROM DIRECTORY(@TEST.PUBLIC.MY_FILES_STAGE)
    WHERE RELATIVE_PATH LIKE '%.pdf';

このコマンドは、「ステージに置いたPDFファイルをAIで読み取って(解析して)、その結果を新しいテーブルに保存する」 という処理を行っています。

Snowflakeの最新機能である Cortex AI(Document AI/Document Parsing) を活用したデータ準備ステップです。

各部分の意味を詳しく解説します。

1. CREATE OR REPLACE TABLE ... AS

TEST.PUBLIC.PARSED_PDFS という名前のテーブルを作成する」という意味です。 すでに同じ名前のテーブルがある場合は、上書き(Replace)します。

2. AI_PARSE_DOCUMENT(...) 👈 ここが最重要

SnowflakeのAI(Cortex)を使って、PDFを解析する関数です。

  • TO_FILE(...): 解析対象のファイルを指定しています。先ほど作成したステージ(MY_FILES_STAGE)にあるファイルを指定しています。
  • 'mode': 'LAYOUT': 文書の構造(タイトル、見出し、段落、表など)を維持したままテキストを抽出します。
  • 'page_split': true: PDFを「ページ単位」で分割して解析します。これにより、長い文書でも「〇ページ目の内容」として扱いやすくなります。

3. FROM DIRECTORY(@...)

先ほどのコマンドで DIRECTORY = (ENABLE = true) と設定したおかげで使える書き方です。 ステージにあるファイルの一覧を、あたかも「テーブル」のように読み込んでいます。

4. WHERE RELATIVE_PATH LIKE '%.pdf'

ステージ内にあるファイルのうち、拡張子が「.pdf」のものだけを処理対象にするというフィルターです。


💡 何が起きるのか?(結果)

このコマンドを実行すると、以下のような中身のテーブルができあがります。

 


ステップ3:Cortex Search Serviceの作成(Indexing)

ここがCortex Searchの肝です。テーブルのデータに対して検索エンジンを作成します。

CREATE OR REPLACE CORTEX SEARCH SERVICE TEST.PUBLIC.PARSED_PDFS_SEARCH
  ON content
  ATTRIBUTES file_name
  WAREHOUSE = COMPUTE_WH
  TARGET_LAG = '1 hour'
AS (
  SELECT
    p.FILE_NAME AS file_name,
    page.value:content::VARCHAR AS content
  FROM TEST.PUBLIC.PARSED_PDFS p,
  LATERAL FLATTEN(input => p.PARSED_CONTENT:pages) page
);

これまでの工程で解析したPDFのテキストデータを、AIが検索できる「インデックス」として登録しています。

各項目の意味を詳しく解説します。

1. CREATE OR REPLACE CORTEX SEARCH SERVICE ...

「Cortex Search サービス」を新規作成(または上書き)します。 名前は PARSED_PDFS_SEARCH と名付けられています。これが検索エンジンの「エンドポイント(APIの窓口)」になります。

2. ON content

どのカラムを「検索対象」にするかを指定しています。 ここでは、PDFから抽出されたテキストが入っている content カラムを、AI(ベクトル検索)の対象に設定しています。

3. ATTRIBUTES file_name

検索結果と一緒に返したい「追加情報(メタデータ)」を指定します。「見つかったテキストが、どのファイル(file_name)のものか」をフィルタリングしたり、結果に表示したりするために使います。

4. WAREHOUSE = COMPUTE_WH

この検索エンジンを構築・更新するために使用するコンピューティングリソース(仮想ウェアハウス)を指定しています。

5. TARGET_LAG = '1 hour'

データの更新頻度です。「元のテーブル(PARSED_PDFS)が更新されてから、最大1時間以内に検索エンジンに反映させる」という設定です。

6. AS ( SELECT ... FROM ... ) 👈 データの整形

  • LATERAL FLATTEN(...): 前のステップで作ったテーブルの PARSED_CONTENT は、1行に全ページの解析結果が「配列(リスト)」として入っています。これを 「1ページ = 1行」になるようにバラバラに展開(フラット化) しています。
  • page.value:content::VARCHAR: バラバラにしたデータの中から、純粋な「テキスト本文(content)」だけを抜き出し、文字列型(VARCHAR)に変換しています。


4. Snowflake Intelligence から試してみる

先ほど作成したCortex Searchオブジェクトをエージェントに登録すれば、 Snowflake Intelligenceから自然言語で対話をしながら帳票データを検索することができます。 ※agent登録はまた別の記事で記載します。

ここでは、利用のイメージだけお伝えして終わりたいと思います。

1.Snowflake Intelligenceを開き 質問をしてみる

「いくつの帳票が収められていますか?」という問いかけに自然言語と表形式で回答をしてくれます。

2.INV-20260110-001 この中身をみたいですとPDFの中身を質問

PDFの中身について質問しても、ステージに入れたPDFファイルの中身を表示してくれます。

3.請求書の合計金額を質問

格納した請求書の合計金額についても、計算して利用した情報も表形式で教えてくれます。 聞いてもいないですが、一番大きい金額と小さい金額の月と金額も補足で教えてくれました。


5. まとめ

Cortex Search を使ってみて感じたメリットは以下の 3 点です。

準備が圧倒的に楽: ベクトルDBの構築やEmbeddingモデルの選定が一切不要。
データの鮮度: TARGET_LAG を設定するだけで、基のテーブルが更新されれば自動で検索インデックスも更新される。
セキュア: データは Snowflake から一歩も外に出ない。


Cortex Analyst が

「構造化データ(数字)の翻訳者」なら、
Cortex Search は「非構造化データ(文章)の案内人」です。


この2つを組み合わせれば、「売上データを確認しながら、その背景にある営業報告書を検索する」といった、より高度な AI アプリケーションが作れそうですね。


最後までお読みいただきありがとうございました!


 

この記事を書いた人

One_ina (one_ina)

プロジェクトマネージメントやAI関連の記事を書いていければと思います。