レック・テクノロジー・コンサルティング株式会社TECH BLOG

※自動翻訳 / Automated translation

dbt + DuckDB で学ぶ Spotify 式 Context Layer - 正確なKPI集計と自由なデータ探索を両立する Text-to-SQL 設計論

サムネイル画像

自然言語での分析(DWHへの問い合わせ)を実現する場合、必要なコンテキストを用意せずにスキーマやテーブル定義のみをプロンプトとして渡しただけのText-to-SQLでは、現場特有の業務ルールを反映できず誤集計が多発します。
本記事では、Spotify社内AI「Vedder」[^1] の設計思想を参考に、DuckDB + dbt-duckdb + Gemini 3.7 Flash を用いて、4つの検証パターン(素のDDL、Context Layer、Semantic Layer、および両者を統合したハイブリッド構成)の精度を実測した結果を比較します。


目次

  1. この記事のまとめ
  2. 検証環境と前提条件
  3. 1. データ構造と検証シナリオ(ERD)
  4. 2. 課題:マスタにフラグが存在してもLLMが誤る理由
  5. 3. Spotify社内AI「Vedder」の設計思想
  6. 4. 統合ハイブリッドの要:AI Router の仕組みと実装選択肢
  7. 5. dbtリポジトリでの定義ファイル構成
  8. 6. 実践検証:4パターンの精度実測と挙動比較
  9. 7. なぜ Semantic Layer だと計算ミスが起きないのか?
  10. 8. まとめとデータ組織向け導入ロードマップ
  11. 参考文献

この記事のまとめ

  • コンテキスト無しでの限界:
    マスタにフラグが存在しても、LLMは「ポッドキャスト除外」や「30秒未満スキップ除外」等の暗黙ルールを認識できず誤集計が発生(実測結果にてポッドキャストホストが1位に混入)。
  • 3つの単体パターンの特性:
    • Pattern A (素のDDL): 業務ルールを解釈できず全滅。
    • Pattern B (Context Layer): 業務ルールを注入して動的SQL生成。柔軟だが比率計算で推測に頼るリスクあり。
    • Pattern C (Semantic Layer): LLMにSQLを書かせず MetricFlow経由で決定的なSQLを生成し実行。比率計算ミスの発生を防げる。ただし柔軟性を求めらる非定型集計は不向き。
  • 結論(Pattern D:Routerを用いた統合的な活用):
    定型KPIは Semantic Layer、非定型探索は Context Layer へ自動ルーティングする AI Router により、全シナリオで高精度な正解とガバナンスを両立。

検証環境と前提条件

本検証は、ローカルPC上で DuckDB + dbt-duckdb + Gemini API の最小構成で実測を行っています。

  • データエンジン: DuckDB (v1.4+) + dbt-duckdb (v1.10+)
    ローカル上でスタースキーマ(マート層)およびセマンティック定義を構築・クエリ実行。
  • 推論モデル (LLM): Google Gemini 3.7 Flash API
    ユーザーの質問に対するSQL動的生成(Text-to-SQL)および意図判定(AI Router)を担当。
  • 検証データセット: Spotify模擬ログ(全2,500件)
    音楽・ポッドキャスト混在ログ、無料/有料プラン、30秒未満スキップ、ロイヤリティ許諾フラグ等を含むオリジナル(ダミー)検証データ。
  • 検証スクリプト: Pythonスクリプト
    同一の質問セットに対して4つのアプローチ(素のDDL / Context / Semantic / ハイブリッド)を順次実行し、実際の生成SQLと集計結果を測定。

1. データ構造と検証シナリオ(ERD)

本検証のテーブル設計です。生トランザクション層(raw_*)と集計マート層(fct_*)を分離しています。

Spotifyの再生ログとマート層のテーブル構造を示すER図。生データ層(raw_artists, raw_tracks, raw_streams, raw_users)と集計マート層(fct_daily_artist_streams)のエンティティ関係および主要カラム(30秒以上有効再生数 official_stream_count, ロイヤリティ対象再生数 official_royalty_streams 等)の定義。


2. 課題:マスタにフラグが存在してもLLMが誤る理由

対話型分析エージェントをリリースした場合、多くのエンドユーザーは「content_type = 'music' かつ play_duration_sec >= 30 で絞り込んで」とは指示せず、「再生数TOP5は?」などと質問します。
テーブル定義のみを渡した場合(Pattern A)、Gemini 3.7 Flashは以下の誤ったSQLを生成しました。

Pattern A(素のDDL)からLLMが生成したSQLクエリ。生ログテーブル(raw_streams)に対して単に COUNT(stream_id) を実行しており、ポッドキャスト除外や30秒未満スキップ除外の業務ルールが適用されていない誤ったクエリ例。

DuckDBでの実行結果

Pattern Aの誤集計実行結果。本来の音楽アーティスト(Ado, YOASOBI等)を押しのけて、ポッドキャスト番組ホストのJoe Roganが410件で1位に誤集計されているターミナル実行ログ。

誤集計の要因

  1. 概念と物理の乖離: ポッドキャスト配信者も raw_artists に存在するため区別ができない。
  2. 暗黙ルールの欠如: 「30秒未満のスキップを除外する」という音楽業界の標準ルールはDDLの型からは推測不能。
  3. フラグ文脈の欠如: ロイヤリティ計算フラグ(is_rcn)の適用条件をLLMが判断できない。

3. Spotify社内AI「Vedder」の設計思想

Spotifyのエンジニアリングチームが公開したブログ記事[^1] では、70,000超ものデータセットを抱える同社が直面した課題と、なぜ「Context Layer」が必要だったのかが率直に語られています。

1. なぜDDLだけでは破綻するのか?(公式ブログより引用)

*"To solve this problem, we started developing an AI data assistant, but with over 70,000 datasets at Spotify, amounting to petabytes of data, no single individual can claim knowledge of everything. Just putting all schemas into an LLM doesn't work at this scale...

Schemas do not convey all the information. If a column has the INT64 type, then it doesn't say anything about how those less than 100 are legacy test data and how they differ from actual data in terms of definitions or what is meant by 'active user.' ... We needed something in between. A layer that captures what actually matters about a slice of the warehouse, owned by people who own and understand the domain."*
---- Spotify Engineering Blog (2026-06-10) [^1]

2. 過去クエリログの87.5%はノイズだった(公式ブログより引用)

「データサイエンティストが過去に書いたクエリ履歴をLLMに学習させればスケールするのでは?」というアプローチに対し、Spotifyは実際に検証を行いました。

*"During our curation phase, we provided the questions and SQL for actual queries issued against the domain by the data scientists in our data warehouse, and we asked the cluster curators to pick which ones were good examples.

They accepted only 12.5% of the proposed pairs.

The other 87.5% were ad-hoc exploration, debugging sessions, one-off answers no one would ask again, queries that used the wrong table, or queries that were technically correct but taught the wrong pattern. Query history is rich. Most of it is noise. And the signal doesn't label itself."*

---- Spotify Engineering Blog (2026-06-10) [^1]

3. Vedderの主要アーキテクチャ

  • 3つのUI: Slack Bot(スレッド質問用)、MCPサーバー(IDE/エージェント用)、専用Web UI(対話探索用)。
  • ReActループ: 質問受領 ➔ 関連クラスタ選択 ➔ SQL生成 ➔ ウェアハウス実行 ➔ 回答作成。
  • 3層クラスタ:
    1. Datasets: スキーマ、代表値サンプル、パーティション情報。
    2. Pairs: ドメイン専門家が承認した12.5%の正統Q&Aお手本ペア。
    3. Docs: Gotchas(落とし穴)、用語集、推奨/非推奨カラムの指示。

4. 統合ハイブリッドの要:AI Router の仕組みと実装選択肢

定型KPIのガバナンスと非定型探索の柔軟性を両立するため、手前に AI Router を配置します。

Pattern D(統合ハイブリッド)におけるAI Routerの二段構えルーティング構成図。ユーザーの質問を判定し、定義済み定型KPIはハルシネーションを抑えたSemantic Layerルートへ、非定型探索は業務ルール注入のContext Layerルートへ自動振り分けする処理フロー。

1. フォールバック設計

質問が定義済みメトリクスに直接合致しない場合は、自動的に Context Layer(動的SQL)へ安全にフォールバック します。

2. 本検証(ローカル)での実装:LightweightContextEngine

本検証では、Spotify の社内AI「Vedder」の思想をローカル環境で再現するため、Python クラス LightweightContextEngine を実装しました。

  • メタデータの自動抽出: dbt の schema.ymlmeta.business_rules / meta.anti_patterns)や docs を解析し、ユーザーの質問キーワードに関連するテーブルや業務ルールを動的に検索・抽出します。
  • インテリジェントなルーティング:
    • 質問が semantic_models.yml で定義された定型KPIに合致する場合 ➔ Semantic Layer(確定クエリ) を直接実行。
    • 定義外の集計やアドホック探索の場合 ➔ 抽出した業務コンテキストをプロンプトに注入し、Gemini 3.7 Flash に動的SQLを生成 させます。

3. 実務導入での選択肢:dbt-wizard の活用

本検証のようなルーティングやコンテキスト注入を実務の dbt プロジェクトへ導入する場合、ゼロからスクリプトを自作する代わりに dbt-wizard [^10] のようなツールの活用が有効です。

  • dbt 定義のダイレクト活用: dbt の manifest.json や YAML 定義(schema.yml / semantic_models.yml)を直接読み込み、dbt で管理されているメタデータやビジネスルールをそのまま LLM のコンテキストとして活用できます。
  • 運用保守の効率化: モデル定義やルールの更新が即座に Text-to-SQL の挙動に反映されるため、手動のプロンプトメンテナンスを不要にし、安全でガバナンスの効いたデータ探索環境を構築できます。

4. 主要クラウドDWHにおけるルーターの選択肢

その他にも主要なDWHにおける実現方法は調べた限りでは以下の通りです。 このあたりは進化のスピードがとても速いので、最新の情報は公式ドキュメントをご確認ください。 主要DWH・データ基盤(Snowflake, Databricks, BigQuery, dbt+LLM)における Semantic Layer(Cortex Analyst, Unity Catalog Metric Views, Looker等)、Context Layer(Cortex Search, Dataplex, dbt docs等)、および AI Router(Cortex Agents, Genie, Vertex Agent等)の実装機能比較表。


5. dbtリポジトリでの定義ファイル構成

dbtプロジェクトのディレクトリ構成図。modelsディレクトリ配下のマートSQL、semantic_models.yml、schema.yml、およびdocsディレクトリ配下のコンテキスト定義Markdownファイルの配置ツリー。

レイヤー別の役割と設定項目

dbtプロジェクトにおけるSemantic Layer(semantic_models.yml / metricflow_time_spine.sql)とContext Layer(spotify_context.md / schema.yml)の配置ディレクトリ、役割、主な設定内容(measures, metrics, meta.business_rules, meta.anti_patterns)の対比表。

YAML定義コードスニペット

1. models/schema.yml (Context Layer の業務ルール注入)

models/schema.yml の設定コード。fct_daily_artist_streams に対するContext Layer定義として、meta.business_rules(適用ルール)や meta.anti_patterns(禁止クエリ例)を記述したYAMLファイル。

2. models/semantic_models.yml (Semantic Layer の比率メトリクス定義)

models/semantic_models.yml の設定コード。dbt Semantic Layerにおいて、エンティティ(artist_id)、ディメンション(stream_date)、メジャー(official_streams, total_streams)、および比率メトリクス(official_stream_ratio: official_streams / total_streams)を確定定義したYAMLファイル。


6. 実践検証:4パターンの精度実測と挙動比較

実測合否判定テーブル

4つの検証シナリオ(Q1:再生数ランキング、Q2:プラン別アクティブ数、Q3:ロイヤリティ計算、Q4:公式再生率)における4パターン(素のDDL、Context Layer、Semantic Layer、統合ハイブリッド)の精度実測結果比較マトリクス表。Pattern Dが全シナリオで高い正解率を達成していることを示す。

* Q4(公式再生率)における比率計算の留意点:
比率計算の Text-to-SQL では、LLM が「行ごとの比率の単純平均(AVG)」を誤用してしまうリスクが一般に存在します。今回の Pattern B(Context Layer)では LLM が正しく SUM(分子) / SUM(分母) を組み立てて *
77.02% の完全正解 を導出できましたが、Pattern C(Semantic Layer)では dbt 上で type: ratio として除算式が物理的に固定されるため、LLM の推論揺らぎに頼らない 100% 確実な集計がシステムレベルで保証されます。


【実測エビデンス】全検証パターン(Case 1〜Case 4)のターミナル実行ログキャプチャを表示


1. Case 1: 再生数ランキングTOP5

Case 1(再生数ランキング集計)の実際のAPI実行生ログとDuckDB実行結果エビデンス画像。

2. Case 2: プラン別アクティブリスナー数

Case 2(プラン別アクティブ数集計)の実際のAPI実行生ログとDuckDB実行結果エビデンス画像。

3. Case 3: Adoのロイヤリティ対象再生数

Case 3(ロイヤリティ計算)の実際のAPI実行生ログとDuckDB実行結果エビデンス画像。

4. Case 4: アーティスト別の公式再生率(比率計算)

Case 4(公式再生率・比率計算)の実際のAPI実行生ログとDuckDB実行結果エビデンス画像。


7. なぜ Semantic Layer だと計算ミスが起きないのか?

「LLMにSQLを書かせる方式」と「Semantic Layer」の違いは、SQLを組み立てる主体にあります。

比率計算におけるContext Layer(LLMが動的SQLを作文し割り算の分母推論で確率的リスクがある)とSemantic Layer(MetricFlowが数式を定義・固定し決定論的に計算する)の処理アプローチ比較図。

MetricFlow が生成する確定SQLの構造

code_09_metricflow_sql.png


8. まとめとデータ組織向け導入ロードマップ

セマンティック層とコンテキスト層について、これまでは違いがよく理解できていませんでしたが模擬的な実装を通じて理解が深まりました。
SpotifyのVedderでは。エージェントとの対話を重ねることで継続的にコンテキスト層をアップデートする仕組みも存在すると記載がありましたが、自社のデータ基盤でそれをどう実現するかについても考えていく必要がありそうです。

AIデータアシスタント構築のロードマップ(Step 1: スタースキーマ整備、Step 2: Semantic LayerによるKPI固定、Step 3: Context Layerによる暗黙知メタデータ化、Step 4: AI Routerによる自動振り分け)を示す4ステップのフロー図。

  1. Step 1: スタースキーマ(マート層)の整備:
    「30秒未満のスキップを除外する」といった音楽配信の標準集計ルールや除外フラグをあらかじめ織り込んだクリーンなマートテーブルを構築する。
  2. Step 2: 最重要KPIの Semantic Layer 化:
    経営指標や比率メトリクスなど、数字のブレが許されないKPIを semantic_models.yml に固定する。
  3. Step 3: 業務暗黙知のメタデータ化と AI Router の配備:
    現場特有のGotchas(落とし穴)を schema.ymlmeta に言語化し、AI Routerで自動分岐(+フォールバック)する体制を整える。

参考文献

この記事をシェアする

  • Facebook
  • X
  • Pocket
  • Line
  • Hatena
  • Linkedin

資料請求・お問い合わせはこちら

ページトップへ戻る