メインコンテンツへスキップ
見出し画像

【前編】BigQuery ベクトル検索で作る「類似稟議2,000件の検出 & 稟議起案ガイド生成」基盤 ― 分析はDWHに任せる①(データ整備&BQML最適化編)


    はじめに:「10件のサンプルでは見えない『表記ゆれ』と『44秒タイムアウトの壁』をどう突破するか?」


    Geminiとその周辺技術を扱えるようになり、どうしても触って実検証しておきたかったテーマとして、

    ・過去の事案や事象で類似するものを抽出し、アイディアや企画に活かす

    です。そしてもう少し業務という括りに踏み込み、そこでの要件としてよーく聞くのが、

    ・”過去の稟議起案を元に、新規で起案する起案文書のベースを作成したい”
    ・”過去の類似分析や実験結果を元に、新規製品開発や企画ネタを発案”

    といったものです。これらは平易に ”似たもの検索” という言葉で片付けられますが、システム的には手間かかる課題だったりします。その辺りはぜひ当ブログのこちらのテーマを参照いただければと。

    また、以前のブログ(ServiceNow × Databricksで作る類似インシデント検索― 分析はData Lakeに任せる① および 後半の自動クローズ編②)では、外部のデータ基盤上でテキストをベクトル(768次元の数値配列)に変換し、コサイン類似度(`cosine_similarity`)を使って類似案件を見つけ出すアーキテクチャーを公開しました。

    多くの反響をいただいた一方で、当時の検証を振り返ると、実運用(本番システム)に乗せるには 、2つの大きな課題 が残っていました。

    • 課題①:サーバーレス起動+ライブラリ導入による「44秒タイムアウトの壁」

      • 前回の Databricks Free Edition 構成では、Notebook ジョブが起動するたびに `%pip install sentence-transformers` が走り、Python の `for` ループでコサイン類似度を計算していたため、実行完了まで約44秒 かかっていました。その結果、呼び出し側(当時の上限22秒)がタイムアウトしてしまい、後半の記事では泣く泣く GAS(Google Apps Script)でレスポンスをエミュレートする構成をとらざるを得ませんでした・・💦

    • 課題②:10件のトイデータでは「本当の類似性(識別力)」が見極められない

      • 前回は `INC001`〜`INC010` のわずか10件での検証でした。しかし実際の企業システムには 数千件規模の過去データ が眠っています。母集団が 2,000件 を超えてくると、同じ部署名や同じ金額、同じバズワード(「AI」「CRM」「クラウド」など)を含む紛らわしい別案件(ハードネガティブ)が大量に混ざり込むため、素朴に件名だけをベクトル化しても使い物になりません。

    そこで今回から 前半・後半の2部構成 でお届けするのが、分析・ベクトル検索エンジンを Google Cloud の BigQuery(Data Warehouse) に全面刷新し、フロントの Gemini Enterprise(旧 Google Agentspace) と直結させる次世代アーキテクチャーです!

    これで、以前のブログの残課題を、ここで解消したいと思います!

    しかも今回の業務テーマは、単なる問い合わせ検索よりもさらに実業務での利用価値が高い 「稟議決裁ワークフローにおける過去類似案件の検出 & 稟議入力ガイドの自動生成」 に設定しました。

    企業で新しいツールやシステムを導入するとき、起案者が毎回必ず悩むのが以下の3点ですよね。

    1. 「この稟議、どの勘定科目(販管費のクラウド利用料?それとも無形固定資産のソフトウェア計上?)で申請すべきなんだろう?」

    2. 「部門長決裁だけでいいの?情報セキュリティ審査やAIガバナンス委員会もルートに入れる必要があるの?」

    3. 「過去に似た案件を出した人が、審査部門からどんな理由で差し戻されているのか(何を添付すれば一発承認されるのか)を起案前に知りたい!」

    画像


    結論を先に言います。

    BigQuery のネイティブ関数 `AI.GENERATE_EMBEDDING`(最新GAモデル `gemini-embedding-001`)と `VECTOR_SEARCH` を使うことで、前回の200倍にあたる「2,000件の過去稟議データ」を一括ベクトル化しても経過時間はわずか約11秒(11秒189ミリ秒)!さらに、2,000件の中から意味的に類似する過去稟議を抽出し、勘定科目・決裁ルート・審査指摘事項を取り出す検索クエリは「約1〜2秒」でリアルタイム応答させることができました!

    いやー、これには正直感動しました。

    画像

    ただし!実際に BigQuery に 2,000件の稟議データを入れて BigQuery ML(BQML)を組み込んでみると、「旧モデルの2027年廃止問題」「件名だけベクトル化すると精度が出ない罠」「BigQuery特有のコサイン距離(0が一致)と類似度(1が一致)の逆転」「テーブル関数(TVF)内で `VECTOR_SEARCH` の `top_k` に引数を渡すとエラーになる仕様」 など、実機で検証しないと絶対にハマる落とし穴(勘所)がいくつもありました・・💦

    そこで本シリーズは、以下のように役割を明確に分けて解説してゆきます。

    • 【前半版(本記事)】:BigQuery 内にベクトル検出に向けた足元データ(2,000件)の整備 & BigQuery ML の組み込みと最適化

    • 【後半版(次回記事)】:Gemini Enterprise から BigQuery のベクトル検索へ接続し、類似案件を根拠に「稟議入力ガイド」を生成する本番運用のユースケース実装

      • ※なお、今回は「BigQuery × Gemini Enterprise」のコア設計を深く掘り下げるため、ServiceNow 等の外部ワークフロー製品との連携はこのブログのテーマからは除外しています(将来、稟議決裁WFとの実連携が必要になった際の続編ネタとして温存しておきます!)。

    まずは本記事(前半版)で、BigQuery の中に「2,000件の過去稟議から1秒で真の類似案件を射抜くベクトル検索エンジン」を一気通貫で構築してゆきましょう!


    1.全体アーキテクチャーと、前回(Databricks編)からの進化ポイント

    具体的な SQL 実装に入る前に、前半・後半を通じた全体アーキテクチャーと、前回の Databricks 編から何がどう進化するのかを整理しておきます。

    画像
    全体アーキテクチャー:前半版(BigQuery データ整備2,000件&ML最適化)と後半版(Gemini Enterprise 本番接続)の全体像

    上のアーキテクチャー図の通り、今回の設計思想は極めてシンプルです。
    「2,000件の過去稟議データの保持・Embedding生成・コサイン類似度検索はすべて BigQuery(Data Warehouse)側のサーバーレスSQLで完結させ、後半版の Gemini Enterprise からはテーブル関数(TVF)を1行呼び出すだけにする」 という責務分離をとっています。

    テキスト図で処理フローを表すと、以下のようになります。

    画像

    さらに、前回の Databricks Free Edition 編と今回の BigQuery Vector Search 編の違い、および今回押さえるべき 「5つの技術的勘所」 を1枚の図解にまとめました。

    画像
    前回ブログ(Databricks 編)との徹底比較 & BigQuery ML 組み込み「5つの技術的勘所」

    特に注目していただきたい比較ポイントは以下の5点です。

    • 対象業務とデータボリューム

      • 前回(Databricks編):ITインシデント 10件(`INC001`〜`INC010` のサンプル配列)

      • 今回(BigQuery編):稟議決裁データ 2,000件(8カテゴリ×9部門。表記ゆれの正解ペアと、同じ部署・金額・単語を含むハードネガティブ案件を混在させた実戦データ)

    • Embedding(埋め込み)モデル

      • 前回(Databricks編):OSS の `paraphrase-multilingual-mpnet-base-v2`(768次元)。Notebook 起動のたびに `%pip install sentence-transformers` が必要

      • 今回(BigQuery編):Vertex AI の最新GAモデル `gemini-embedding-001`(MRL 768次元出力対応)。パッケージインストールは一切不要で、SQLの `AI.GENERATE_EMBEDDING` から直接呼び出し可能

    • 類似検索エンジン

      • 前回(Databricks編):Python(Pandas + scikit-learn)の `for` ループによる総当たり計算

      • 今回(BigQuery編):BigQuery ネイティブの `VECTOR_SEARCH` 関数による分散並列検索

    • 実行時間とタイムアウト問題

      • 前回(Databricks編):サーバーレスのコールドスタート+pip導入で 約44秒(呼び出し側の22秒制限に引っかかりタイムアウト)

      • 今回(BigQuery編):常時ウォームなサーバーレスSQLにより、2,000件の母集団に対するベクトル検索が 約1〜2秒 で完了

    • 外部AIエージェント(Gemini Enterprise)との連携性

      • 前回(Databricks編):Jobs API の非同期ポーリングが必要

      • 今回(BigQuery編):TVF(テーブル値関数) としてカプセル化することで、`SELECT * FROM fn_search_similar_ringi('...')` の1行で同期取得が可能

    今回は ”圧倒的な実務向けスケールと構成で検証してます”  ということです。


    2.【勘所の解剖】BigQuery で高精度ベクトル検索を組むとき「どのMLモデル・どういった設計」を選ぶべきか?


    さて、ユーザー様からもよくご質問をいただく 「BigQuery内でベクトル検索をするとき、どのMLモデルを選び、どうパラメータを組むのが正解なのか?」 という勘所を、最新仕様に基づいて5つに整理しておきます。

    勘所①:モデルは最新の安定版GA「`gemini-embedding-001`」× 新構文「`AI.GENERATE_EMBEDDING`」を選ぶ

    今回の要件として「最新モデルを使うメリットが高ければ最新、不具合などを考慮すべきなら安定したモデルを採用したい」という重要なポイントがあります。
    2026年現在の Google Cloud(Vertex AI / BigQuery ML)におけるテキスト埋め込みモデルのライフサイクルを整理すると、結論は迷う余地なく `gemini-embedding-001` の一択になります。

    • 旧モデル `text-multilingual-embedding-002` / `text-embedding-005`(非推奨・廃止予定)

      • 過去のブログ記事や古いサンプルコードでよく使われていますが、すでにレガシーモデル扱いとなっており、2027年4月1日にシャットダウン(廃止) されるスケジュールが公式発表されています。新規構築で採用するのは移行リスクが伴います。

    • プレビュー系マルチモーダルモデル `gemini-embedding-2-preview`(今回は不採用)

      • 画像・音声・動画・PDFまで同一ベクトル空間に埋め込める次世代モデルですが、現時点では Preview 表記やリージョン制約があり、今回のような「構造化された日本語テキスト稟議テーブル(2,000件)」に対してはオーバースペックです。

    • 最新テキスト埋め込みGAモデル `gemini-embedding-001`(★今回の採用モデル)

      • Google の多言語・英語テキスト埋め込みモデルが統合された 最新の一般提供(GA・本番安定稼働)モデル です。

      • 日本語のビジネス文書(稟議書・契約書・技術仕様)の文脈理解精度が旧モデルから大幅に向上しているだけでなく、後述する `task_type`(非対称検索タスク指定) と MRL(Matryoshka Representation Learning:次元数圧縮) に完全対応しています。

      • また、BigQuery 側の呼び出し関数も、従来の `ML.GENERATE_EMBEDDING`(出力列名が `ml_generate_embedding_result` と冗長だった旧構文)から、よりシンプルで直感的な新構文 `AI.GENERATE_EMBEDDING`(出力列名がそのまま `embedding` になる最新構文)へ進化しています。

    勘所②:稟議の「件名」だけをベクトル化せず、「合成コンテキスト列(`search_content`)」を作る

    稟議データの類似検索で一番やってしまいがちな失敗が、`title`(稟議件名)の1列だけを Embedding にかけることです。
    たとえば起案者が 「営業部門で商談の議事録作成やCRM入力を自動化する生成AIツールを導入したい」 と検索したとき、過去の承認稟議の件名が 「フィールドセールス向けSFA自動連携SaaS契約」 だった場合、件名だけだと「議事録」も「生成AI」も入っていないため類似度が伸び悩みます。

    ところが、稟議書の本質は 「どんな業務課題を解決するために(起案背景・目的)、どんな定量効果を狙うのか(ROI)」 にあります。
    そこで今回は、ベクトル化の対象列(`content`)として以下の4項目を構造化テキストとして結合した 合成コンテキスト列(`search_content`) を生成します。

    • `【カテゴリ】` + `【起案部門】` + `【稟議件名】` + `【起案背景・目的】` + `【定量効果・ROI】`

    一方、検索結果として一緒に返却する `account_item`(勘定科目)、`approval_route`(必須決裁ルート)、`reviewer_guidance`(審査部門からの指摘事項・差戻し理由) は、ベクトル化の対象には混ぜず、「類似案件が見つかった後に起案ガイドを生成するための構造化ペイロード(正解ラベル)」 としてテーブルに保持しておくのがプロの設計です!

    勘所③:非対称 `task_type`(`RETRIEVAL_DOCUMENT` vs `RETRIEVAL_QUERY`)と 768次元 MRL 圧縮

    `gemini-embedding-001` の真価を引き出す最大のパラメータが `task_type` です。
    稟議の類似検索では、「検索される側の過去稟議レコード(長文の背景・ROIを含む文書)」と、「検索する側の起案者の質問文(1〜2行の短い相談文)」で文章の長さも構造も非対称になります。

    • 2,000件の過去稟議テーブルをバッチでベクトル化するとき:

      • `STRUCT('RETRIEVAL_DOCUMENT' AS task_type, 768 AS output_dimensionality)` を指定します。

    • 起案者の入力テキストをリアルタイムにベクトル化して検索するとき:

      • `STRUCT('RETRIEVAL_QUERY' AS task_type, 768 AS output_dimensionality)` を指定します。

    このように `RETRIEVAL_DOCUMENT` と `RETRIEVAL_QUERY` をペアで使い分けることで、「短い起案相談文」と「詳細な過去稟議書」がベクトル空間上でピタッと重なるように最適化されます。
    また、`gemini-embedding-001` のデフォルト次元数は `3072` 次元ですが、MRL(マトリョーシカ表現学習)によって重要な意味情報が先頭の次元に凝縮されているため、`768 AS output_dimensionality` を指定することで 検索精度をほぼ維持したまま、ベクトルストレージ容量と `VECTOR_SEARCH` のスキャン演算量を4分の1に高速化 できます(しかも `distance_type => 'COSINE'` を使えば BigQuery が自動的に長さを正規化して計算してくれます)。

    勘所④:BigQuery の `COSINE` 距離(`distance`)を類似度スコア(`1 - distance`)に変換する

    ここも前回の Databricks(Python `scikit-learn`)編から移行する際の重要な注意点です。

    • Python の `cosine_similarity` は 「コサイン類似度(`1.0` が完全一致、`0.80` 以上が高類似)」 を返します。

    • 一方、BigQuery の `VECTOR_SEARCH(..., distance_type => 'COSINE')` が返す `distance` 列は 「コサイン距離(`0.0` が完全一致、値が小さいほど類似)」 です。

    そのまま `distance`(例:`0.2041`)を画面や AI エージェントに渡すと、「スコアが 0.2 しかないから似ていない」と誤判定してしまいます。そのため、SQL 側で必ず `ROUND(1 - distance, 4) AS similarity_score` に変換し、`0.7959` のような直感的な類似度スコアとして出力するように設計します。

    勘所⑤:2,000件規模なら `VECTOR INDEX` 不要の Exact Search(完全検索)が最速&再現率100%!

    「ベクトル検索をするなら `CREATE VECTOR INDEX`(`IVF` や `TreeAH`)を張らなくていいの?」と思われる方も多いかなと。
    実は、BigQuery の `CREATE VECTOR INDEX` は デフォルトで最低 5,000行以上 のテーブルが対象となっており、2,000件のテーブルに対してインデックス作成を叩くと行数不足エラーになります。

    そして何より、2,000件〜数万件規模であればベクトルインデックスは一切不要 です!
    インデックスを張らずに `VECTOR_SEARCH` を実行すると、BigQuery は大規模並列エンジンを使って全2,000件との総当たり計算(Exact Search / Brute Force)を一瞬(約1秒)で実行します。近似検索(ANN)による取りこぼしがゼロ(Recall=再現率100%)であり、データの追加・更新時にもインデックス再構築待ちが発生しないため、数千件規模の業務ワークフローでは Exact Search が最も合理的です。

    ①から⑤をまとめると以下図解イメージです。

    画像

    3.【Step by Step 実機構築①】BigQuery に足元データ「過去稟議 2,000件」を整備する

    それでは、Google Cloud(Argolis 環境:`gemini-demo01`)の BigQuery Studio を開いて、実際にテーブルとデータを構築してゆきましょう!

    Step 1-1. データセット `ringi_ai_demo` の作成

    まずは BigQuery Studio のクエリエディタで、今回の検証用データセット `ringi_ai_demo` を `US` マルチリージョンに作成します。

    1)BigQuey プロダクトメニューを起動

    画像
    BigQueryプロダクトの選択

    2)Studioメニューの対象プロジェクト(例:gemini-demo01)の3点メニューから[データセットを作成]を選択

    画像

    3)以下のように定義します
      ・プロジェクトID:デフォルト値
      ・データセットID:ringi_ai_demo
           ・リージョン:USリージョン

    画像
    データセットの作成定義

    入力終えたら、[データセットの作成]を押下します。

    画像
    BigQuery・データセットの作成

    4)続いて、この作成されたデータセットへスキーマを作成します。
      ・クエリビューを開き以下のSQLをコピペ。
      ・実行

    画像
    クエリの作成と実行
    CREATE SCHEMA IF NOT EXISTS `gemini-demo01.ringi_ai_demo`
    OPTIONS (
      location = 'US',
      description = '稟議決裁ワークフロー 類似案件ベクトル検索&起案ガイド生成デモ(2,000件)'
    );

    5)クエリが実行され、スキーマが作成されます。

    画像
    スキーマとデータセットの作成完了

    Step 1-2. 類似性の識別力を極限テストする「2,000件の過去稟議データ」設計と一括投入

    ここが今回のデータ整備のハイライトです。
    単なるランダム文字列を 2,000件入れても意味がありません。

    今回は 「ベクトル検索が本当に表記ゆれを吸収し、かつ紛らわしいノイズ案件を弾けるのか?」 を厳密に検証できるよう、以下の 2層構造で合計 2,000件 の過去稟議テーブル(`past_ringi_records`)を構築します。

    • ① ベンチマーク検証用の代表10案件(`RNG-2026-0001` 〜 `RNG-2026-0010`)

      • 今回のテスト起案文 「営業部門で商談の議事録作成やCRM入力を自動化する生成AIツールを導入したい。月額150万円想定」 に対する識別力を測るためのゴールデンデータです。

      • 【表記ゆれの真の類似案件:4件(`RNG-2026-0001`〜`0004`)】:

        • `RNG-2026-0001`:『フィールドセールス向けAI音声文字起こし・SFA自動連携SaaS契約』(※「議事録」「生成AI」「CRM」という単語を使わず、「AI音声文字起こし」「SFA」「LLM」と表現した承認済案件)

        • `RNG-2026-0002`:『インサイドセールス商談要約LLMアシスタントおよびCRM自動起票ツール導入』(※経理・情シスから「SaaS月額はクラウド利用料、初期設定費は業務委託費に分けて起票せよ」とガイドされた承認済案件)

        • `RNG-2026-0003`:『営業トーク解析・自動CRM記録クラウドサービス利用申請』(※情シスから「SSO連携とPIIマスキング有効化」を条件に承認された条件付承認案件)

        • `RNG-2026-0004`:『全社営業部員向け生成AI議事録・案件サマリー自動生成ツール導入(差戻し・再起案事例)』(※初回起案時に誤って「ソフトウェア資産(固定資産)」で申請し、さらに「AIガバナンス委員会の学習オプトアウト確認」を漏らして差し戻された超重要ナレッジ案件!)

      • 【紛らわしいハードネガティブ(ノイズ)案件:6件(`RNG-2026-0005`〜`0010`)】:

        • `RNG-2026-0005`:『第一営業本部 商談会議室向け大型モニター・防音ブースおよびオフィス什器刷新』(※同じ「第一営業本部」、同じ「商談」、同じ予算「150万円」だが、勘定科目は「器具備品(有形固定資産)」の別案件!)

        • `RNG-2026-0006`:『基幹CRMデータベースサーバー老朽化に伴うOracle DB保守ライセンス更新』(※「CRM」と「150万円」を含むが、勘定科目は「システム保守運用費」のインフラ保守案件!)

        • `RNG-2026-0007`:『工場製造ライン外観検査AIカメラおよびエッジ推論用GPU端末の調達』(※「AI」を含むが、製造原価のハードウェア固定資産案件!)

        • `RNG-2026-0008`〜`0010`:営業モバイル端末のゼロトラストEDR増設、DX・AI展示会出展(150万円)、営業プロセスBPRコンサル委託(150万円)。

    • ② 全社8カテゴリ × 9部門 × 多様な業務テーマで展開する 1,990件(`RNG-2024-0011` 〜 `RNG-2026-2000`)

      • `01_生成AI・SaaS導入`、`02_クラウド基盤・インフラ増強`、`03_セキュリティ・ゼロトラスト`、`04_基幹システム・ERP改修`、`05_マーケティング・展示会・広告`、`06_オフィス環境・ファシリティ・什器`、`07_外部コンサル・業務委託契約`、`08_研究開発・PoC・ハードウェア調達` の8カテゴリにわたり、各約250件ずつ(合計2,000件)の過去稟議レコードを生成します。

    上記要件を図解すると以下のイメージです。

    画像
    類似検索において、紛らわしいノイズが含まれるデータ構成要件

    外部の Python 環境や CSV ファイルを用意しなくても、BigQuery Studio に以下の SQL をコピペして実行するだけで、誰でも3秒で 2,000件の過去稟議テーブルを完全再現 できます!

    -- ============================================================================
    -- Step 1: 稟議決裁ワークフロー過去案件テーブル(2,000件)の作成とデータ投入
    -- ============================================================================
    CREATE OR REPLACE TABLE `gemini-demo01.ringi_ai_demo.past_ringi_records` AS
    WITH
    -- ① ベンチマーク検証用の代表10案件(表記ゆれの真の類似案件4件 + 紛らわしいハードネガティブ6件)
    golden_records AS (
      SELECT * FROM UNNEST([
        STRUCT(
          'RNG-2026-0001' AS ringi_id,
          '01_生成AI・SaaS導入' AS category,
          '第一営業本部' AS department,
          DATE '2026-09-15' AS applied_date,
          'フィールドセールス向けAI音声文字起こし・SFA自動連携SaaS契約' AS title,
          '外勤営業担当者が訪問商談後に毎回1時間かけて手入力している商談記録およびSFA(顧客管理)への活動履歴登録を、音声認識と大規模言語モデル(LLM)による自動要約で省力化する。' AS background_purpose,
          '営業部員120名の商談後事務作業を1日45分削減(月間1,800時間相当)。データ入力漏れゼロ化による案件受注率3%向上、投資回収期間4.5ヶ月。' AS expected_roi,
          1500000 AS budget_amount_jpy,
          'クラウドサービス利用料(販管費・ソフトウェア / OPEX)' AS account_item,
          '部門長決裁 + 情報セキュリティ審査 + AIガバナンス委員会' AS approval_route,
          '承認済' AS final_status,
          '【AIガバナンス・法務審査ガイド】顧客の商談音声データを外部LLMへ送信するため、「入力データのAIモデル学習オプトアウト条項(Zero Data Retention)」の契約書明記と、クラウドセキュリティチェックシート(別紙3)の添付が必須。' AS reviewer_guidance
        ),
        STRUCT(
          'RNG-2026-0002',
          '01_生成AI・SaaS導入',
          'インサイドセールス部',
          DATE '2026-08-22',
          'インサイドセールス商談要約LLMアシスタントおよびCRM自動起票ツール導入',
          'オンライン商談(Google Meet / Zoom)の録画・発話データから顧客の課題・BANT情報・ネクストアクションをAIが自動抽出し、CRMの商談オブジェクトへ自動反映するSaaSを導入したい。',
          'インサイドセールス60名の架電・オンライン商談後の記録作成工数を70%削減。1日あたりの有効商談数を1.4倍へ引き上げ。',
          1450000,
          'クラウドサービス利用料(販管費・ソフトウェア / OPEX)',
          '部門長決裁 + 情報セキュリティ審査 + AIガバナンス委員会',
          '承認済',
          '【経理・情シス審査ガイド】SaaS月額利用料(120万円)は「クラウドサービス利用料(販管費)」、初期プロンプト調整・CRM連携設定費(25万円)は「業務委託費」に科目を分けて明細起票すること。'
        ),
        STRUCT(
          'RNG-2026-0003',
          '01_生成AI・SaaS導入',
          '第二営業本部',
          DATE '2026-07-10',
          '営業トーク解析・自動CRM記録クラウドサービス利用申請(エンタープライズ営業向け)',
          '法人営業の商談内容テキスト化および顧客管理システムへの議事メモ転記を自動化するクラウドAIアシスタントを契約し、営業現場の残業時間削減とナレッジ共有を実現する。',
          '営業担当者100名あたり月間1,500時間の報告書作成工数を削減。ハイパフォーマーの商談トーク可視化による成約率向上。',
          1600000,
          'クラウドサービス利用料(販管費・ソフトウェア / OPEX)',
          '部門長決裁 + 情報セキュリティ審査 + AIガバナンス委員会',
          '条件付承認',
          '【情報セキュリティ条件付承認ガイド】SSO(SAML 2.0)連携および監査ログ保存期間1年以上のプラン選択を条件として承認。個人情報(PII)マスキング機能の有効化画面キャプチャを検収時に提出すること。'
        ),
        STRUCT(
          'RNG-2026-0004',
          '01_生成AI・SaaS導入',
          '第一営業本部',
          DATE '2026-05-18',
          '全社営業部員向け生成AI議事録・案件サマリー自動生成ツール導入(差戻し・再起案事例)',
          '商談後の議事録作成とCRM入力負荷が高いため、生成AIによる自動文字起こし・要約SaaSを導入して営業生産性を高めたい。',
          '営業1名あたり週3時間の事務工数削減を見込む。',
          1500000,
          'クラウドサービス利用料(販管費・ソフトウェア / OPEX)',
          '部門長決裁 + 情報セキュリティ審査 + AIガバナンス委員会',
          '差戻し(再起案で承認)',
          '【初回差戻し理由(要注意)】①初回起案時に「ソフトウェア資産(無形固定資産)」で申請されたが、SaaS利用契約のため「クラウドサービス利用料(販管費)」へ修正が必要。②AIガバナンス委員会の事前審査(外部送信データの学習非利用確認)が未添付のため差戻し。'
        ),
        -- ▼ ここから紛らわしいハードネガティブ(キーワードは重複するが意味・勘定科目が異なる案件)
        STRUCT(
          'RNG-2026-0005',
          '06_オフィス環境・ファシリティ・什器',
          '第一営業本部',
          DATE '2026-09-01',
          '第一営業本部 商談会議室向け大型モニター・防音ブースおよびオフィス什器刷新',
          '営業部門のオンライン商談増加に伴い、周囲の雑音を防ぐ個室型防音フォンブース2台および会議室用65インチ4Kモニター・エルゴノミクスチェアを整備する。',
          'オンライン商談時の音声品質向上および営業フロアの会議室不足解消。耐用年数5年での減価償却。',
          1500000,
          '器具備品(有形固定資産 / CAPEX・減価償却対象)',
          '部門長決裁 + 総務ファシリティ審査 + 経理固定資産登録',
          '承認済',
          '【経理固定資産ガイド】1点20万円以上の防音ブースおよび大型モニターは「器具備品(有形固定資産)」として資産計上が必須。3社相見積書およびオフィスレイアウト変更届を添付すること。'
        ),
        STRUCT(
          'RNG-2026-0006',
          '04_基幹システム・ERP改修',
          '情報システム部',
          DATE '2026-08-12',
          '基幹CRMデータベースサーバー老朽化に伴うOracle DB保守ライセンス更新およびストレージ増設',
          '全社営業部門が利用するオンプレミス連携用CRM中継データベースサーバーの保守期限到来に伴い、年間サポート契約の更新とSSDストレージ増設を実施する。',
          '基幹CRMシステムの稼働率99.95%維持および月末バッチ処理の遅延防止。',
          1500000,
          'システム保守運用費(販管費・保守料)',
          '情報システム部長決裁 + 購買部ベンダ審査',
          '承認済',
          '【購買審査ガイド】既存ベンダとの年間保守契約更新のため単独随意契約理由書を添付。前回契約単価からの値上げ率(3%以内)の妥当性確認表を添えること。'
        ),
        STRUCT(
          'RNG-2026-0007',
          '08_研究開発・PoC・ハードウェア調達',
          '製造技術部',
          DATE '2026-07-25',
          '工場製造ライン外観検査AIカメラおよびエッジ推論用GPU端末の調達',
          '精密部品組立ラインにおける微細な傷・打痕検査を自動化するため、高解像度産業用カメラとエッジAI画像推論ボックス(NVIDIA Jetson搭載)をラインへ設置する。',
          '目視検査員の工数を年間2,400時間削減し、不良品流出率を0.01%以下に抑制。',
          1550000,
          '機械装置・工具器具備品(製造原価・有形固定資産 / CAPEX)',
          '工場長決裁 + 生産技術審査 + 安全衛生委員会',
          '承認済',
          '【製造経理ガイド】工場ラインへの物理組み込み機器のため販管費ではなく「製造原価(機械装置)」での固定資産計上となる。工場レイアウト図と検収テスト基準書を添付すること。'
        ),
        STRUCT(
          'RNG-2026-0008',
          '03_セキュリティ・ゼロトラスト',
          '情報システム部',
          DATE '2026-06-30',
          '全社営業モバイル端末向けゼロトラストEDR・SASEセキュリティライセンス増設',
          '営業部門の社外リモートワーク拡大に伴い、貸与ノートPCおよびスマートフォンからの社内CRMアクセスを保護するSASE/EDRエージェントを追加調達する。',
          'マルウェア感染および不正アクセスによる顧客情報漏洩リスクの極小化、SOC監視工数の40%削減。',
          1480000,
          '通信費・セキュリティ利用料(販管費)',
          'CISO(最高情報セキュリティ責任者)決裁 + 情報システム部長承認',
          '承認済',
          '【CISO審査ガイド】全社セキュリティ標準ポリシー準拠案件。契約期間(年間一括払い)に応じた前払費用計上スケジュールを経理部へ共有すること。'
        ),
        STRUCT(
          'RNG-2026-0009',
          '05_マーケティング・展示会・広告',
          'マーケティング本部',
          DATE '2026-09-05',
          '秋のDX・AIEXPO展示会ブース出展および営業リード獲得デジタル広告キャンペーン',
          '新規エンタープライズ顧客の商談リードを獲得するため、大型展示会への小間出展および連動するWebターゲティング広告を実施し、CRMへ見込み客リストを供給する。',
          '有効名刺・MQLリード獲得600件、うち商談化60件(想定パイプライン売上9,000万円)。',
          1500000,
          '広告宣伝費(販管費)',
          'マーケティング本部長決裁 + 法務景表法チェック',
          '承認済',
          '【マーケ・法務ガイド】配布パンフレットおよび広告バナー内の「No.1」「業界初」等の表記について根拠データの法務審査を完了させること。勘定科目は「広告宣伝費」。'
        ),
        STRUCT(
          'RNG-2026-0010',
          '07_外部コンサル・業務委託契約',
          'DX推進部',
          DATE '2026-08-01',
          '営業プロセス標準化および次世代CRM定着化に向けた業務改革(BPR)コンサルティング委託',
          '営業本部ごとの商談管理ルールのバラつきを解消するため、外部コンサルティングファームに業務フロー棚卸しとKPI設計支援を3ヶ月間業務委託する。',
          '全社営業KPIの統一および案件フォーキャスト精度の25%向上。',
          1500000,
          '支払手数料・業務委託費(販管費)',
          'DX推進部長決裁 + 法務準委任契約審査 + 購買相見積審査',
          '承認済',
          '【法務・購買ガイド】準委任契約(善管注意義務)のため、成果物定義ではなく「月間稼働時間幅(精算幅140〜180h)」と「業務完了報告書の検収基準」を契約書に明記すること。偽装請負防止チェックリスト必須。'
        )
      ])
    ),
    -- ② 8カテゴリ×多様な業務テーマの組み合わせで生成する1,990件のリアルな過去稟議データ
    categories AS (
      SELECT * FROM UNNEST([
        STRUCT(0 AS cat_idx, '01_生成AI・SaaS導入' AS category, 'クラウドサービス利用料(販管費・ソフトウェア / OPEX)' AS account_item, '部門長決裁 + 情報セキュリティ審査 + AIガバナンス委員会' AS approval_route,
          ['カスタマーサポート問い合わせ自動回答RAGチャットボット導入', '法務契約書レビューAIアシスタントSaaSライセンス契約', '社内規程・マニュアル横断検索エンタープライズAI基盤導入', 'エンジニア向けAIコーディング支援ツール(コード補完)導入', '人事採用面接スケジュール調整・候補者スカウトAIツール契約'] AS titles,
          ['問い合わせ対応やドキュメント確認にかかる手作業工数を削減し、生成AIによる一次回答ドラフト生成で業務スピードを向上させる。', '属人化している専門文書チェックやナレッジ検索をAIアシスタントで標準化し、担当者の残業時間削減と品質均一化を図る。', '複数システムに散在する社内データを横断検索・要約できるクラウドSaaSを導入し、情報探索時間を大幅に短縮する。'] AS purposes,
          ['担当部門40名の月間作業時間を320時間削減。初期導入後5ヶ月での投資回収を見込む。', '一次対応リードタイムを平均4時間から15分へ短縮し、顧客満足度(CSAT)を12ポイント改善。', '外注費および残業代の削減により年間480万円のコスト削減効果を試算。'] AS rois,
          ['【AIガバナンス・情シス審査ガイド】外部クラウドAIへ社内データを送信するため、学習オプトアウト(Zero Data Retention)設定の確認証跡とセキュリティチェックシート(別紙3)を必ず添付すること。', '【経理審査ガイド】月額・年額のSaaSサブスクリプション利用料は「クラウドサービス利用料(販管費)」で起票し、初期導入コンサル費用が含まれる場合は「業務委託費」と明細を分けること。'] AS guidances
        ),
        STRUCT(1, '02_クラウド基盤・インフラ増強', 'クラウドインフラ利用料・通信費(販管費 / 原価)', '情報システム部長決裁 + クラウドCoEアーキテクチャ審査',
          ['Google Cloud BigQueryデータウェアハウス分析基盤の予約スロット増強', '本番Kubernetesクラスタ増設およびマルチリージョンDR構成構築', '全社データレイクハウス移行に伴うCloud Storage・ETLパイプライン整備', 'Webサービス負荷増大に対応するCDNキャッシュおよびロードバランサ増強', '開発・検証環境向けクラウドサンドボックス自動払い出し基盤の構築'],
          ['データ分析クエリおよびバッチ処理の増加に伴い、ピーク時のスロット競合を解消してリアルタイム分析のSLAを確保する。', '事業拡大に伴うトラフィック増加とBCP(事業継続計画)要件に対応するため、クラウドインフラの冗長化とキャパシティ拡張を行う。', '老朽化したオンプレミスDWHからフルマネージドクラウド基盤へ移行し、インフラ運用保守工数とハードウェア更改コストを削減する。'],
          ['夜間バッチ処理時間を4時間から35分へ短縮。コミットメント割引(CUD)適用によりオンデマンド比28%の単価削減。', 'システム目標復旧時間(RTO)を24時間から1時間以内へ短縮し、重大障害時の機会損失リスクを回避。', 'インフラ運用エンジニアの保守工数を月間120時間削減し、新規サービス開発へのシフトを実現。'],
          ['【クラウドCoE審査ガイド】1年または3年のコミットメント割引(CUD)を適用する場合は、解約不可期間のリスク試算表と月次予算配賦計画を添付すること。', '【情シス・経理ガイド】本番環境インフラ費はサービス原価、社内分析基盤は販管費(システム利用料)へ按分比率を明記して起票すること。']
        ),
        STRUCT(2, '03_セキュリティ・ゼロトラスト', '通信費・セキュリティ利用料(販管費)', 'CISO(最高情報セキュリティ責任者)決裁 + 情報システム部長承認',
          ['全社ID管理基盤(IdP)のパスキー・多要素認証(MFA)強化ライセンス更新', 'クラウド設定ミス検知(CSPM)および脆弱性自動スキャンツール導入', '特権ID管理(PAM)および本番環境アクセス監査ログ保全システム導入', 'サプライチェーン攻撃対策に向けた外部公開資産(ASM)継続監視サービス契約', '標的型メール攻撃訓練および従業員セキュリティeラーニング基盤の年間契約'],
          ['高度化するフィッシング攻撃および認証情報窃取に対抗するため、ゼロトラスト原則に基づく常時検証とエンドポイント保護を強化する。', 'マルチクラウド環境の権限設定ミスや公開設定リスクを自動検知し、インシデント発生前のプロアクティブな是正体制を構築する。', '金融・エンタープライズ顧客からのセキュリティ監査要件(SOC2 / ISO27001)に対応するため、特権操作ログの改ざん防止と証跡管理を徹底する。'],
          ['セキュリティインシデント調査の初動時間(MTTR)を75%短縮。外部監査対応の証跡収集工数を年間400時間削減。', '不正ログイン試行のブロック率99.9%達成およびアカウント乗っ取り被害ゼロの継続。', '脆弱性診断の手動実施コストを年間300万円圧縮し、日次自動スキャンによる常時監視へ移行。'],
          ['【CISO審査ガイド】全社セキュリティポリシー第4条に基づく必須統制案件。SOC監視チームとのアラート連携フロー図を添付すること。', '【法務・情シスガイド】セキュリティログの海外リージョン保管有無を確認し、国内リージョン(東京/大阪)指定オプションを選択していることを明記すること。']
        ),
        STRUCT(3, '04_基幹システム・ERP改修', 'ソフトウェア資産計上(無形固定資産 / CAPEX)またはシステム改修費', '経営会議(または管掌役員)決裁 + 情報システム部アーキテクチャ審査 + 経理部資産判定',
          ['会計ERPシステム インボイス・電子帳簿保存法ワークフロー連携モジュール改修', '販売管理システムと倉庫管理システム(WMS)のリアルタイム出荷API連携開発', '購買稟議ワークフローシステムにおける予算実績自動突合・アラート機能追加開発', '人事給与システムと勤怠管理SaaSのマスターデータ自動同期バッチ改修', 'サブスクリプション契約管理システムの従量課金自動請求エンジン追加開発'],
          ['法改正対応および手作業によるCSVエクスポート・二重入力を廃止し、基幹システム間のデータ連携を完全自動化して決算早期化を実現する。', '事業モデルの拡大に伴い既存ERPの標準機能では対応できない特殊計上ロジックをアドオン改修し、経理・営業事務の手戻りをなくす。', '月次決算時の伝票突合および予算超過チェックをシステム制御に組み込み、内部統制(J-SOX)上の統制不備リスクを排除する。'],
          ['月次決算の締め日数を5営業日から3営業日へ短縮。経理・営業事務のCSV手作業工数を年間1,800時間削減。', '請求書発行ミスおよび出荷指示遅延をゼロ化し、監査法人からのIT統制指摘事項を100%解消。', 'システム耐用年数5年での償却を前提とし、3年累計で投資額の180%の業務工数削減効果を達成。'],
          ['【経理固定資産・J-SOXガイド】新機能追加(自社利用ソフトウェアの価値増加)に該当するため、100万円以上は「ソフトウェア仮勘定(無形固定資産 / CAPEX)」として起票すること(単なるバグ修正・保守のみ販管費)。要件定義書と検収基準書が必須。', '【情シス審査ガイド】基幹ERPへのアドオン改修は将来のバージョンアップ影響度を評価したFIT&GAP分析表を添付すること。']
        ),
        STRUCT(4, '05_マーケティング・展示会・広告', '広告宣伝費(販管費)', 'マーケティング本部長決裁 + 法務景表法・商標チェック',
          ['業界特化型カンファレンス協賛(プラチナスポンサー)および基調講演登壇', '製造・金融業界ターゲット向けアカウントベースドマーケティング(ABM)Web広告出稿', '導入事例ホワイトペーパー制作およびビジネスメディアタイアップ記事掲載', '既存顧客向けユーザー会(年次フォーラム)会場手配・ライブ配信運営委託', '製品紹介3Dプロモーション動画制作およびYouTube・タクシー広告配信'],
          ['重点ターゲット業界の決裁者層(CxO・DX推進部門長)に対するブランド認知度向上と、エンタープライズ商談パイプラインの創出を図る。', '競合他社との差別化ポイントを実際の顧客成功事例を通じて訴求し、資料請求(MQL)から有効商談(SQL)への転換率を引き上げる。', '展示会・オンラインウェビナーを連動させたオムニチャネル施策により、四半期リード獲得目標を達成する。'],
          ['獲得リード450件、有効商談化45件、想定受注金額6,750万円(CPA単価およびROAS 450%目標)。', '指名検索数(ブランド検索ボリューム)の前年同期比135%達成および商談成約リードタイムの15%短縮。', '既存顧客のチャーンレート(解約率)1.2%低減およびアップセル案件20件の創出。'],
          ['【法務・広報審査ガイド】広告クリエイティブおよび講演資料に含まれる市場シェア・効果数値には必ず出典・調査期間を明記し、景品表示法チェック完了証跡を添付すること。', '【経理審査ガイド】イベント開催日または広告掲載完了月が費用計上基準(発生主義)となるため、前払金と検収月のスケジュールを明記すること。']
        ),
        STRUCT(5, '06_オフィス環境・ファシリティ・什器', '器具備品(有形固定資産 / CAPEX)または消耗品費', '部門長決裁 + 総務ファシリティ審査 + 経理固定資産登録',
          ['ハイブリッドワーク対応フリーアドレス執務デスク・高機能チェア増設', '役員会議室およびセミナールーム向けWeb会議用マイクスピーカー・大型ディスプレイ導入', '社員リフレッシュエリア兼集中ワークブースの造作および内装レイアウト改修', '研究開発フロア向け入退室生体認証セキュリティゲートおよび防犯カメラ増設', '拠点サテライトオフィス新設に伴う複合機・Wi-Fiアクセスポイント・什器一式調達'],
          ['出社とリモートワークを併用するハイブリッド勤務体制において、Web会議の音漏れ防止と部門横断コラボレーションの活性化を両立するオフィス環境を整備する。', '人員増加に伴う座席不足を解消するとともに、人間工学に基づいた什器導入により従業員の健康維持とエンゲージメント向上を図る。', '物理セキュリティ基準の引き上げに伴い、機密エリアへの入退室履歴の厳格管理と老朽設備の更新を実施する。'],
          ['会議室予約の取りづらさを解消し、従業員エンゲージメント調査の「職場環境満足度」を18ポイント改善。', 'サテライト拠点活用による営業移動時間の月間300時間削減。5年定額法での減価償却。', '設備故障による業務停止リスクの解消および省エネ機器への更新による電力コスト15%削減。'],
          ['【経理・総務ガイド】取得価額が1単位20万円以上の什器・機器は「器具備品(有形固定資産)」、内装工事は「建物附属設備」として資産計上すること。必ず3社以上の相見積書を添付すること。', '【総務ファシリティガイド】ビル管理会社への工事届出および消防法上の通路幅・感知器移設有無の事前確認シートを添付すること。']
        ),
        STRUCT(6, '07_外部コンサル・業務委託契約', '支払手数料・業務委託費(販管費)', '部門長決裁 + 法務準委任/請負契約審査 + 購買部相見積審査',
          ['中長期DX戦略策定およびAI活用ロードマップ設計アドバイザリー業務委託', '新規事業立ち上げに伴う市場調査・競合ベンチマーク分析レポート作成委託', 'データガバナンス体制構築および個人情報保護規程改定に向けた専門コンサル委託', 'グローバル拠点展開に向けた現地法規制・税務コンプライアンス調査委託', 'クラウドネイティブ開発標準化およびSRE内製化支援に伴う技術アドバイザリー契約'],
          ['社内だけでは知見が不足している専門領域について、外部の専門コンサルタント・有識者の知見を活用し、プロジェクトの立ち上げ期間を大幅に短縮する。', '客観的な第三者視点での業務プロセス診断とベンチマーク評価を取り入れ、投資対効果の高い施策へ経営資源を集中させる。', '法規制対応や高度なアーキテクチャ設計における手戻りリスクを防ぎ、社内メンバーへのスキルトランスファー(内製化)を並行して進める。'],
          ['社内独力での調査・設計と比較してプロジェクト期間を6ヶ月から2ヶ月へ短縮。手戻り防止による想定コスト回避効果1,200万円。', '社内コアメンバーへのナレッジ移管により、次年度以降の外部委託コストを50%削減。', '経営会議への意思決定インプット精度向上および新規事業の初期立ち上げ成功率の改善。'],
          ['【法務・購買ガイド】「請負契約(成果物完成責任)」か「準委任契約(稼働・善管注意義務)」かを明確に区分し、業務仕様書(SOW)に検収条件と指揮命令系統(偽装請負防止)を明記すること。', '【購買審査ガイド】100万円以上の外部委託は原則3社コンペ(相見積)が必要。特命発注(1社単独)の場合は「単独随意契約理由書(様式B)」を必ず添付すること。']
        ),
        STRUCT(7, '08_研究開発・PoC・ハードウェア調達', '研究開発費(販管費)または機械装置・工具器具備品(CAPEX)', 'R&D部門長決裁 + 知財法務審査 + 安全環境審査',
          ['次世代マルチモーダルAIモデル検証用GPUワークステーションおよび検証機材調達', 'スマートファクトリーIoTセンサーネットワーク実証実験(PoC)機器およびゲートウェイ調達', '自律走行AMR(協働搬送ロボット)倉庫内導線テスト用試作機レンタルおよび計測器導入', '高精度3Dスキャナおよびデジタルツインシミュレーション検証用ハードウェア調達', '新素材耐久性テスト向け恒温恒湿試験チャンバーおよび自動計測ロガー導入'],
          ['次期主力製品・新規技術の実用化に向け、実環境に近いラボ環境でアルゴリズムの推論速度・精度およびハードウェア耐久性の実証実験(PoC)を行う。', '本格量産・全社展開の前に小規模なプロトタイプ検証を実施し、技術的ボトルネックの早期特定と特許出願に向けた実験データを取得する。', '従来手作業で行っていた計測・データ収集プロセスを自動化し、研究開発サイクル(仮説・実験・評価)のスループットを倍増させる。'],
          ['PoC検証期間を従来の3ヶ月から4週間へ短縮。量産移行後の設計手戻りコスト(想定2,500万円)を未然に防止。', '新規技術に関する特許出願2件の実験データ取得および製品化リードタイムの30%短縮。', '試験データの自動収集による研究員の計測工数月間160時間削減。'],
          ['【経理・R&D審査ガイド】試作・実験専用で他用途へ転用できない機材やPoC委託費は「研究開発費」、1年以上継続使用する汎用測定器・サーバーは「工具器具備品(固定資産)」として区分計上すること。', '【知財・法務ガイド】外部大学や共同研究先と実験データを共有する場合は、共同研究契約書(NDAおよび知的財産帰属条項)の締結番号を稟議書に記載すること。']
        )
      ])
    ),
    departments AS (
      SELECT dept_name, dept_idx FROM UNNEST([
        '第一営業本部', '第二営業本部', 'DX推進部', '情報システム部',
        'マーケティング本部', '経理財務部', '人事総務部', '製造技術部', 'カスタマーサクセス部'
      ]) AS dept_name WITH OFFSET AS dept_idx
    ),
    statuses AS (
      SELECT status_name, st_idx FROM UNNEST([
        '承認済', '承認済', '承認済', '条件付承認', '差戻し(再起案で承認)'
      ]) AS status_name WITH OFFSET AS st_idx
    ),
    generated_1990 AS (
      SELECT
        FORMAT('RNG-%d-%04d', 2024 + MOD(n, 3), n) AS ringi_id,
        c.category,
        d.dept_name AS department,
        DATE_ADD(DATE '2024-04-01', INTERVAL MOD(n * 17, 940) DAY) AS applied_date,
        CONCAT(
          c.titles[OFFSET(MOD(n, 5))],
          '(', d.dept_name, '・第', CAST(MOD(n, 4) + 1 AS STRING), '四半期案件 #', CAST(n AS STRING), ')'
        ) AS title,
        CONCAT(
          '【', d.dept_name, ' 起案背景】',
          c.purposes[OFFSET(MOD(n, 3))],
          ' 対象拠点・スコープ:拠点コード-', CAST(MOD(n, 12) + 1 AS STRING),
          '、対象ユーザー数:約', CAST((MOD(n, 15) + 2) * 10 AS STRING), '名規模。'
        ) AS background_purpose,
        CONCAT(
          c.rois[OFFSET(MOD(n, 3))],
          '(試算ケースID: ROI-', CAST(n AS STRING), ')'
        ) AS expected_roi,
        (30 + MOD(n * 37, 470)) * 10000 AS budget_amount_jpy,
        c.account_item,
        c.approval_route,
        s.status_name AS final_status,
        CONCAT(
          c.guidances[OFFSET(MOD(n, 2))],
          CASE
            WHEN s.status_name = '差戻し(再起案で承認)' THEN ' ※初回申請時に添付証跡および費用按分明細の記載漏れがあり差戻し、修正後に再起案で承認。'
            WHEN s.status_name = '条件付承認' THEN ' ※四半期ごとの効果測定レポート提出を条件として承認。'
            ELSE ' ※事前審査チェックリスト完備によりストレート承認。'
          END
        ) AS reviewer_guidance
      FROM UNNEST(GENERATE_ARRAY(11, 2000)) AS n
      JOIN categories c ON c.cat_idx = MOD(n, 8)
      JOIN departments d ON d.dept_idx = MOD(n * 3, 9)
      JOIN statuses s ON s.st_idx = MOD(n * 7, 5)
    )
    SELECT * FROM golden_records
    UNION ALL
    SELECT * FROM generated_1990;

    1)上記のSQLをクエリビューにコピペし実行

    画像
    テーブル&レコードデータ作成用SQLの実行

    2)実行すると、以下のように、わずか2〜3秒で `past_ringi_records`(2,000件)が作成されます!

     ・作成されたテーブルのフィールド

    画像
    フィールド

    ・足元用レコードデータ

    画像
    投入された足元用レコードデータ
    画像
    ringi_ai_demo データセットと過去稟議 2,000件テーブル(past_ringi_records)の作成



    4.【Step by Step 実機構築②】`gemini-embedding-001` リモートモデル作成と 2,000件一括ベクトル化


    足元の 2,000件データが揃ったら、次は BigQuery から Vertex AI の最新埋め込みモデル `gemini-embedding-001` を呼び出すリモートモデルを作成し、2,000件すべてを一括でベクトル化します。

    画像
    類似性検出の仕組み構築のステップ

    Step 2-1. `REMOTE WITH CONNECTION DEFAULT` によるリモートモデル作成

    現在の BigQuery では、`REMOTE WITH CONNECTION DEFAULT` を指定するだけで、プロジェクトのデフォルト Cloud リソース接続を使って非常にシンプルに Vertex AI のリモートモデルを作成できます。

    1)コピペ用クエリでモデルを登録
      ※ GUIからの設定でもMLの登録は行えます。

    -- ============================================================================
    -- Step 2: Vertex AI 最新GAモデル gemini-embedding-001 のリモートモデル登録
    -- ============================================================================
    CREATE OR REPLACE MODEL `gemini-demo01.ringi_ai_demo.gemini_embedding_model`
    REMOTE WITH CONNECTION DEFAULT
    OPTIONS (
      endpoint = 'gemini-embedding-001'
    );

    2)クエリの実行

    画像

    3)モデルが登録

    画像
    登録されたモデル

    いかに今回の作業のハマりどこを追記しておきます。

    ⚠️ ハマりどころ①:プロジェクト初回実行時のサービスアカウント伝播ラグに注意!
    その Google Cloud プロジェクトで初めて `REMOTE WITH CONNECTION DEFAULT`(または新規 Cloud リソース接続)を実行した直後は、裏側で自動生成されるサービスアカウント(`bqcx-[MASKED_PROJECT_NUMBER]-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com`)の IAM 伝播に数十秒ほどかかる場合があります。

    実際、今回の検証でも初回クリック直後には `Service account bqcx-... does not exist` というエラーが1回出ましたが、約30〜60秒待ってから再実行(または外部接続のサービスアカウントに IAM で `Vertex AI ユーザー` ロールを付与)したところ、すんなりモデル作成が完了しました!

    初回だけ起きる挙動なので慌てなくて大丈夫です。

    Step 2-2. `AI.GENERATE_EMBEDDING` で 2,000件を一括ベクトル化する(経過時間わずか 11.2秒!)

    モデルが登録できたら、いよいよ 勘所②(合成コンテキスト列 `content` の構築) と 勘所③(`task_type => 'RETRIEVAL_DOCUMENT'` & `output_dimensionality => 768`) を組み込んだ SQL を実行し、2,000件の過去稟議をベクトル化したテーブル `past_ringi_embeddings` を作成します!

    クエリへ以下の2000件レコードデータのエンべッディング生成用SQLをコピペして実行します。

    画像
    ベクトル化実行用のクエリ
    -- ============================================================================
    -- Step 3: 合成コンテキスト列(content)の構築と2,000件一括Embedding生成
    -- ============================================================================
    CREATE OR REPLACE TABLE `gemini-demo01.ringi_ai_demo.past_ringi_embeddings` AS
    SELECT
      ringi_id,
      category,
      department,
      applied_date,
      title,
      background_purpose,
      expected_roi,
      budget_amount_jpy,
      account_item,
      approval_route,
      final_status,
      reviewer_guidance,
      content AS search_content,
      embedding,
      ARRAY_LENGTH(embedding) AS embedding_dims,
      status AS embedding_status
    FROM AI.GENERATE_EMBEDDING(
      MODEL `gemini-demo01.ringi_ai_demo.gemini_embedding_model`,
      (
        SELECT
          *,
          CONCAT(
            '【カテゴリ】', category, '\n',
            '【起案部門】', department, '\n',
            '【稟議件名】', title, '\n',
            '【起案背景・目的】', background_purpose, '\n',
            '【定量効果・ROI】', expected_roi
          ) AS content
        FROM `gemini-demo01.ringi_ai_demo.past_ringi_records`
      ),
      STRUCT(
        'RETRIEVAL_DOCUMENT' AS task_type,
        768 AS output_dimensionality
      )
    );

    ・AI.GENERATE_EMBEDDING:
    BigQueryに組み込まれた Vertex AI 連携機能(BigQuery ML)を使って、実際にベクトルを生成しています。

    ・MODEL `gemini-demo01.ringi_ai_demo.gemini_embedding_model`:
    事前にBigQuery内に定義されているEmbeddingモデル(通常はVertex AIの text-embedding-004 などに紐づいています)を指定しています。

    ・ 'RETRIEVAL_DOCUMENT' AS task_type:
    ベクトル検索における**「検索対象(データベース側)の文書」**として最適化された手法でベクトル化することを指定しています。(ちなみに、検索するユーザー側の質問文をベクトル化するときは RETRIEVAL_QUERY を指定します)。

    BigQuery Studio で実行したときの結果画面(`実行の詳細` タブ)が以下の画像です!

    画像
    AI.GENERATE_EMBEDDING(gemini-embedding-001)による 2,000件一括ベクトル化(経過時間 11秒189ミリ秒))

    赤枠の数値をご覧いただくとわかる通り、なんと 2,000件の日本語稟議テキストのベクトル生成が「経過時間:11秒189ミリ秒」で完了 しています!

    裏側では BigQuery が自動的にリクエストを分散並列化し、「消費したスロット時間:1分54秒」分の処理をわずか 11.2秒の壁時計時間(Wall-clock time)に圧縮 してくれているのです。

    前回 Databricks Free Edition で 10件に 44秒かかっていたことを思うと、まさに次元が違うスピードですよね。

    Step 2-3. 全8カテゴリ・2,000件のベクトル生成結果とメタデータの確認

    念のため、2,000件すべてに欠損なく 768次元ベクトル(`embedding_dims = 768`)が入っているか、カテゴリ別に集計して確認してみましょう。

    クエリビューに、検証用のSQLをコピペし実行します。

    画像
    検証用クエリの実行
    -- ============================================================================
    -- 検証クエリ①:投入した2,000件の稟議データ&768次元Embedding生成結果のカテゴリ別集計
    -- ============================================================================
    SELECT
      category,
      COUNT(*) AS record_count,
      COUNTIF(embedding_dims = 768) AS valid_768d_vectors,
      FORMAT("¥%'d", CAST(AVG(budget_amount_jpy) AS INT64)) AS avg_budget_jpy,
      ANY_VALUE(account_item) AS standard_account_item,
      ANY_VALUE(approval_route) AS required_approval_route
    FROM `gemini-demo01.ringi_ai_demo.past_ringi_embeddings`
    GROUP BY category
    ORDER BY category;

    検証クエリの実行結果が応答されます。

    画像
    実行結果

    上の実機結果より、、`01_生成AI・SaaS導入`(253件)から `08_研究開発・PoC・ハードウェア調達`(250件)まで、全8カテゴリ・合計 2,000件すべてに 768次元の Embedding ベクトルが1件のエラーもなく生成 され、各カテゴリの「標準勘定科目」と「必須決裁ルート」が綺麗に紐付いています!

    画像
    8カテゴリ×約250件=合計 2,000件の768次元ベクトル生成

    これで、全レコードデータのベクトル化がバッチリ整備されました!


    5.【Step by Step 実機構築③】`VECTOR_SEARCH` のテーブル関数(TVF)化と「表記ゆれ vs ハードネガティブ」識別検証

    それでは前半版の仕上げとして、2,000件のベクトルテーブルに対してリアルタイムに類似検索を行う `VECTOR_SEARCH` を組み込み、後半版の Gemini Enterprise から1行で呼び出せる TVF(テーブル値関数:`fn_search_similar_ringi`) にカプセル化してゆきます。

    画像

    Step 3-1. テーブル値関数 `fn_search_similar_ringi` の作成と `top_k` の勘所

    ここで実機検証中に判明した 超重要なハマりどころ を共有します。

    ⚠️ ハマりどころ②:TVF(テーブル関数)の中で `VECTOR_SEARCH` の `top_k` に関数引数を渡すとエラーになる!
    最初はテーブル関数の引数を `(query_text STRING, top_k INT64)` の2つにして、`VECTOR_SEARCH(..., top_k => top_k)` と書いたのですが、BigQuery で実行すると `Invalid top_k argument of VECTOR_SEARCH, should be a literal value or query parameter` というエラーで弾かれました・・💦
    BigQuery の仕様上、`VECTOR_SEARCH` の `top_k` には リテラル整数(例:`top_k => 10`) を直接書く必要があります。そのため、TVF 内部では `top_k => 10`(上位10件取得)のリテラル定数にしておき、呼び出し側の `SELECT * FROM fn_search_similar_ringi('...') LIMIT 5` で必要な件数に絞る のが正解の設計パターンです!

    この仕様を踏まえて作成した、本番対応のテーブル値関数(TVF)がこちらです。

    -- ============================================================================
    -- Step 4: VECTOR_SEARCH とコサイン類似度変換をカプセル化したテーブル関数(TVF)の作成
    -- ※ VECTOR_SEARCH の top_k にはリテラル定数(10)を指定し、呼び出し側で LIMIT 制御する
    -- ============================================================================
    CREATE OR REPLACE TABLE FUNCTION `gemini-demo01.ringi_ai_demo.fn_search_similar_ringi`(
      query_text STRING
    ) AS (
      SELECT
        ROUND(1 - distance, 4) AS similarity_score,
        ROUND(distance, 4) AS cosine_distance,
        base.ringi_id,
        base.category,
        base.department,
        base.applied_date,
        base.title,
        base.budget_amount_jpy,
        base.account_item,
        base.approval_route,
        base.final_status,
        base.reviewer_guidance,
        base.background_purpose,
        base.expected_roi
      FROM VECTOR_SEARCH(
        TABLE `gemini-demo01.ringi_ai_demo.past_ringi_embeddings`,
        'embedding',
        (
          SELECT embedding
          FROM AI.GENERATE_EMBEDDING(
            MODEL `gemini-demo01.ringi_ai_demo.gemini_embedding_model`,
            (SELECT query_text AS content),
            STRUCT(
              'RETRIEVAL_QUERY' AS task_type,
              768 AS output_dimensionality
            )
          )
        ),
        top_k => 10,
        distance_type => 'COSINE'
      )
    );

    ご覧の通り、この TVF の中に以下の処理がすべてカプセル化されています。

    1. 起案者の入力テキスト(`query_text`)を `task_type => 'RETRIEVAL_QUERY'` でリアルタイムに 768次元ベクトルへ変換

    2. `past_ringi_embeddings`(2,000件)に対して `distance_type => 'COSINE'` で Exact Search を実行

    3. コサイン距離(`distance`)を `ROUND(1 - distance, 4) AS similarity_score`(コサイン類似度)に変換し、稟議起案ガイドに必要な `account_item`、`approval_route`、`final_status`、`reviewer_guidance` をセットで返却

    Step 3-2. 2,000件の中から1行のSQLで類似稟議 Top 5 を射抜く!

    さっそく、起案者がこれから申請しようとしている相談文

    ・「営業部門で商談の議事録作成やCRM入力を自動化する生成AIツールを導入したい。月額150万円想定」 

    を自然言語文で  `fn_search_similar_ringi`  に渡して検索してみましょう!

    以下のクエリをコピペして、実行します。

    画像
    -- ============================================================================
    -- 検証クエリ②:2,000件の過去稟議から類似案件をリアルタイム検索(TVF 1行呼び出し)
    -- ============================================================================
    SELECT
      similarity_score,
      ringi_id,
      final_status,
      title,
      account_item,
      approval_route,
      SUBSTR(reviewer_guidance, 1, 52) AS reviewer_guidance_head
    FROM `gemini-demo01.ringi_ai_demo.fn_search_similar_ringi`(
      '営業部門で商談の議事録作成やCRM入力を自動化する生成AIツールを導入したい。月額150万円想定'
    )
    ORDER BY similarity_score DESC
    LIMIT 5;

    実行時間はわずか 約1.5秒!
    そして返ってきた Top 5 の実機画面が以下の画像です!

    画像
    テーブル関数 fn_search_similar_ringi の1行呼び出しによる 2,000件からの類似稟議 Top 5 検索

    2,000件の母集団の中から抽出された上位5件の内訳を見てください。

    • 第1位(類似度 `0.7959`):`RNG-2026-0004`|`差戻し(再起案で承認)`

      • 件名:全社営業部員向け生成AI議事録・案件サマリー自動生成ツール導入(差戻し・再起案事例)

      • 抽出されたガイド情報:初回起案時に誤って「ソフトウェア資産(無形固定資産)」で申請して差し戻され、「クラウドサービス利用料(販管費)」へ修正した実績+AIガバナンス委員会の事前審査が必要という決定的な注意喚起!

    • 第2位(類似度 `0.7917`):`RNG-2026-0002`|`承認済`

      • 件名:インサイドセールス商談要約LLMアシスタントおよびCRM自動起票ツール導入

      • 抽出されたガイド情報:SaaS月額利用料(120万円)は「クラウドサービス利用料」、初期設定費(25万円)は「業務委託費」に科目を分けて明細起票すべきという経理・情シス審査ガイド!

    • 第3位(類似度 `0.7839`):`RNG-2026-0001`|`承認済`

      • 件名:フィールドセールス向けAI音声文字起こし・SFA自動連携SaaS契約

      • 注目ポイント:検索文にある 「議事録」「CRM」「生成AIツール」という単語が件名に1つも含まれていない(代わりに「AI音声文字起こし」「SFA」と書かれている)にもかかわらず、類似度 `0.7839` で堂々の第3位にヒット しています!

    • 第4位(類似度 `0.7822`):`RNG-2026-0003`|`条件付承認`

      • 件名:営業トーク解析・自動CRM記録クラウドサービス利用申請(エンタープライズ営業向け)

      • 抽出されたガイド情報:SSO連携と監査ログ1年以上保存、PIIマスキング有効化キャプチャ提出という情報セキュリティ条件!

    • 第5位(類似度 `0.7439`):`RNG-2024-0864`|`条件付承認`

      • 1,990件の自動生成レコードの中から、同じ生成AI・SaaS導入カテゴリの「人事採用面接スケジュール調整・候補者スカウトAIツール契約」が `0.7439` で5位に入っています。

    画像

    Step 3-3. 「表記ゆれの真の類似案件(4件)」vs「キーワード重複ノイズ(6件)」のスコア差を検証する

    さらに、「同じ営業本部や同じ金額(150万円)、同じ『CRM』『AI』という単語を含んでいるけれど、まったく別カテゴリの紛らわしい案件(ハードネガティブ6件:`RNG-2026-0005`〜`0010`)」との間に、どれくらい明確なスコア差がついているのかを検証したクエリを実行してみましょう!

    クエリに、以下SQLをコピペして実行します。

    画像
    -- ============================================================================
    -- 検証クエリ③:「表記ゆれの類似案件(正解4件)」vs「キーワード重複ノイズ(6件)」の識別検証
    -- ============================================================================
    SELECT
      CASE
        WHEN base.ringi_id IN ('RNG-2026-0001', 'RNG-2026-0002', 'RNG-2026-0003', 'RNG-2026-0004')
          THEN '✅ 正解(表記ゆれ類似)'
        ELSE '❌ ノイズ(同部門・同金額の別案件)'
      END AS judge,
      ROUND(1 - distance, 4) AS similarity_score,
      ROUND(distance, 4) AS cosine_distance,
      base.ringi_id,
      base.category,
      base.title,
      base.account_item
    FROM VECTOR_SEARCH(
      (
        SELECT * FROM `gemini-demo01.ringi_ai_demo.past_ringi_embeddings`
        WHERE ringi_id BETWEEN 'RNG-2026-0001' AND 'RNG-2026-0010'
      ),
      'embedding',
      (
        SELECT embedding
        FROM AI.GENERATE_EMBEDDING(
          MODEL `gemini-demo01.ringi_ai_demo.gemini_embedding_model`,
          (SELECT '営業部門で商談の議事録作成やCRM入力を自動化する生成AIツールを導入したい。月額150万円想定' AS content),
          STRUCT('RETRIEVAL_QUERY' AS task_type, 768 AS output_dimensionality)
        )
      ),
      top_k => 10,
      distance_type => 'COSINE'
    )
    ORDER BY similarity_score DESC;

    結果が応答されました!

    画像
    「表記ゆれの真の類似案件(正解4件)」vs「キーワード重複ノイズ(6件)」の識別検証)

    この結果(画像07)は、実務でベクトル検索の閾値(Threshold)を設計する上で非常に重要な示唆を与えてくれます。

    • 緑枠:`✅ 正解(表記ゆれ類似案件 4件)` の類似度スコア

      • `RNG-2026-0004`(生成AI議事録・差戻し事例):`0.7959`(コサイン距離 `0.2041`)

      • `RNG-2026-0002`(商談要約LLM・CRM自動起票):`0.7917`(コサイン距離 `0.2083`)

      • `RNG-2026-0001`(AI音声文字起こし・SFA連携):`0.7839`(コサイン距離 `0.2161`)

      • `RNG-2026-0003`(営業トーク解析・自動CRM記録):`0.7822`(コサイン距離 `0.2178`)

      • ➔ 4件ともすべて `0.78` 以上(`0.7822`〜`0.7959`)の高スコア帯に密集 しています!

    • 赤枠:`❌ ノイズ(同部門・同金額・同キーワードの別案件 6件)` の類似度スコア

      • `RNG-2026-0010`(営業プロセス標準化・CRM定着化BPRコンサル委託 / 150万円):`0.6845`

      • `RNG-2026-0005`(第一営業本部 商談会議室モニター・防音ブース什器刷新 / 150万円):`0.6671`

      • `RNG-2026-0007`(工場製造ライン外観検査AIカメラ・GPU端末調達 / 155万円):`0.6626`

      • `RNG-2026-0009`(秋のDX・AIEXPO展示会ブース出展・営業リード獲得広告 / 150万円):`0.6614`

      • `RNG-2026-0008`(全社営業モバイル端末ゼロトラストEDR・SASE増設 / 148万円):`0.6586`

      • `RNG-2026-0006`(基幹CRMデータベースサーバーOracle DB保守更新 / 150万円):`0.6545`

      • ➔ 「第一営業本部」「商談」「150万円」「CRM」「AI」といったキーワードがどれだけ入っていても、業務目的と性質が異なる案件は すべて `0.68` 以下(`0.6545`〜`0.6845`)に綺麗に引き離されています!

    つまり、「合成コンテキスト列(カテゴリ+件名+背景+ROI)」×「`gemini-embedding-001` の非対称 `task_type`」 を使うことで、真の類似案件とノイズ案件の間に 約 `0.10`(10ポイント)もの明確なスコアギャップ が生まれ、`similarity_score >= 0.75` を目安にするだけで迷いなく真の類似稟議だけを抽出できることが実証できました!


    6.本番設計で押さえるべき注意点・落とし穴まとめ(保存版チートシート)

    今回の前半版(BigQuery データ整備2,000件 & BQML ベクトル検索最適化)の実機検証で判明した 4大ハマりどころと解決策 を1枚のチートシートにまとめました。

    画像
    BigQuery ベクトル検索(2,000件)実機検証で判明した4大ハマりどころと解決策
    1. 初回 `REMOTE` モデル作成時のサービスアカウント伝播ラグ

      • プロジェクトで初めて `REMOTE WITH CONNECTION DEFAULT`(または外部接続)を実行した直後は、`bqcx-...` サービスアカウントの IAM 伝播に30〜60秒ほどかかる場合があります。エラーが出たら外部接続のサービスアカウントに `Vertex AI ユーザー` ロールを付与するか、数十秒待ってから再実行すれば OK です。

    2. 2,000件規模では `CREATE VECTOR INDEX` を叩かない(Exact Search が最適)

      • BigQuery のベクトルインデックスは 5,000行以上が対象です。数千件規模の業務データではインデックス無しの `VECTOR_SEARCH`(並列 Exact Search)を使うことで、インデックス管理コストゼロ・再現率100%・約1秒の高速応答が得られます。

    3. `COSINE` 距離(`distance`)は必ず `ROUND(1 - distance, 4) AS similarity_score` に変換する

      • BigQuery の `distance` は `0.0` が完全一致です。AI エージェントや業務ユーザーが直感的に判断できるよう、`1 - distance` でコサイン類似度(`1.0` が完全一致)に変換してから返却しましょう。

    4. TVF(テーブル関数)化の際は `VECTOR_SEARCH` の `top_k` をリテラル定数にする

      • `VECTOR_SEARCH` の `top_k` には TVF の関数引数を渡せないため、TVF 内では `top_k => 10` のようにリテラル整数を指定し、呼び出し側の `SELECT ... LIMIT 5` で件数を制御するのが鉄則です。


    7.参考リンク(公式ドキュメント一次情報)& 最後に(まとめ)

    今回使用した BigQuery Vector Search および `gemini-embedding-001` の公式ドキュメント一次情報はこちらです。

    最後に(まとめ)

    如何でしたでしょうか?

    前回の Databricks 編(10件・Python ループ・44秒タイムアウト)でぶつかった壁をバネにして、今回は Google Cloud の BigQuery Vector Search × `gemini-embedding-001` を使い、200倍の「2,000件」の過去稟議データをわずか約11秒で一括ベクトル化し、約1.5秒で真の類似稟議を射抜くデータ基盤 を構築しました。

    今回の前半版から得られた本質的な学びは以下の3点かなと。

    1. 「分析とベクトル検索は Data Warehouse(BigQuery)に任せる」ことで、Python ライブラリ起動待ち(44秒)の壁が消滅し、数千件の類似検索が1秒台のサーバーレスSQLで完結する。

    2. 稟議の「件名」だけでなく「カテゴリ+起案背景+定量効果(ROI)」を合成コンテキスト化し、`gemini-embedding-001` の非対称 `task_type`(`RETRIEVAL_DOCUMENT` / `RETRIEVAL_QUERY`)を使うことで、単語が全く違う表記ゆれ案件を高精度に検出しつつ、同部門・同金額のノイズ案件を `0.10` 以上のスコア差で綺麗に分離できる。

    3. さらに「勘定科目」「必須決裁ルート」「過去の差戻し理由(審査ガイド)」を構造化カラムとして保持し、TVF(`fn_search_similar_ringi`)にカプセル化しておくことで、AIエージェントが即座に「生きた稟議入力ガイド」を生成できる土台が整う。

    さて、これで BigQuery 側の「2,000件類似稟議検索エンジン(`fn_search_similar_ringi`)」は完璧に仕上がりました!

    次回の 【後半版】 では、いよいよ社員が普段使うフロントAIエージェント 「Gemini Enterprise」からこの BigQuery ベクトル検索へ本番接続し、チャットで起案内容を相談するだけで「推奨勘定科目・必須決裁ルート・差戻し防止チェックリスト・稟議ドラフト文面」を自動生成する一気通貫のユースケース実装 をお届けします!

    次回以降も、Gemini Enterpriseのさらなる深掘りにどんどんチャレンジしてゆきますので、次のブログにも乞うご期待ください!では。

     
     
    東京都在住/自動化(テスト・RPAなど)大好き/LLMへAPI接続して遊ぶことが趣味/外資系SaaSの導入向け技術職/中学受験向け我が家塾の経験/Gemini Enterprise / Google ADK / マルチエージェント(A2A・MCP)× エンタープライズ業務実装

    あなたへのおすすめ