AI Ready Data Analysis Platform 〜 text2SQLツールの精度向上への取り組み table tag systemの導入
ミツモア データマネージャの古田 @crazysrot です ミツモアでは、日々自身の生産性向上に努めるよう全社を挙げて生成AIを日常的に活用しまくっています。 データグループでも生成AIを最大限活用し、分析にまつわる業務全てを置き換える活動を行っています。 今回はその一環でtext2SQLの精度向上のためのTopicを1つお話しします
はじめに
データ基盤を活用する上で、エンジニアやビジネスアナリストが直面する大きな課題の一つは「どのテーブルを使えばよいか」という選択です。特に、生成AIを使用したtext2SQLツールの精度向上において、適切なテーブル選択は極めて重要です。
また、弊社データ基盤では
クロスセルを含む売上 / 売上 の違い (このパターンのみなら簡単ですが他にも複数の要素が絡んだ売上の指標が多数あるケース)
個人向けサービス / 法人向けサービス (各プロダクトが入り混じったデータ基盤、requests/productB_requestsといったようなネーミングだが、誤って参照してしまう確率は一定発生)
のような、全tableを一緒くたに取り扱っていては精度が悪化するといった現象が起きてしまうため、とても悩ましい技術課題でした。
本記事では、私たちがtext2SQLツールの精度を向上させるためにdbt環境で実装したテーブルタグシステムと、それがどのようにLLMによるデータ分析を支援しているかについて紹介します。
なぜタグシステムが必要か
2025年9月現在、生成AIはlong contextであればあるほど精度は下がり、費用も増える。そのような構造になっています。そのため、inputする情報量をいかに削ぎ落とすのかと言うことはとても重要な機能として組み込まねばなりません。ただでさえミツモアBigQueryには千弱のテーブルが存在し、プロダクト別にそれぞれが異なる目的や重要度を持っています。
text2SQLツールでLLMがユーザーのクエリを理解し、適切なSQLを生成するためには、以下の情報が必要です: 1. テーブルの内容:何のデータが格納されているか 2. ビジネスドメイン:どの事業領域に関連するか 3. データの重要度:どの程度信頼でき、活用すべきか
これらの情報を構造化して提供することで、text2SQLツールはより精度の高いテーブル選択とSQL生成が可能になります。
2系統のタグシステム
私たちは、各dbtモデルのdescriptionに2種類のタグを付与しています:
description: | [Payment][Tier2] **English:** Table managing billing and payment information. **日本語:** 請求と支払い情報を管理するテーブル。
1. 種別タグ(ビジネスドメイン)
最初のタグは、テーブルがどのビジネス領域に属するかを示します:
- [IM] - Individual MarketPlace:個人向けサービス
- [BM] - Business MarketPlace:法人向けサービス
- [Payment] - 決済関連データ
- [Ad] - 広告・マーケティングデータ
- [PV] - ページビュー・アクセスログ
- [Log] - システムログ・イベントログ
- [Other] - プラットフォーム共通機能
複数の領域にまたがる場合は、パイプで区切って複合タグとします: - [IM|Payment] - 個人向けサービスの決済データ - [PV|Log] - ページビューのログデータ
2. Tierタグ(重要度・活用度)
2つ目のタグは、テーブルの重要度と活用頻度を5段階で表します:
Tier 1 - ビジネスクリティカル
- 売上、ユーザー、取引など、ビジネスの中核となるデータ
- データ品質が最も高く、頻繁に参照される
- 例:
revenue(売上)、users(ユーザー)、requests(依頼)
Tier 2 - 重要な運用データ
- 日常的な分析や運用で使用される重要データ
- 決済、広告、レビューなど、ビジネス運営に不可欠
- 例:
stripe_sales(Stripe決済)、adwords_costs(広告費用)
Tier 3 - サポート・集計データ
- 派生データや集計テーブル、分析用のマート
- MLモデル用データ、集計メトリクスなど
- 例:
ML_train(ML学習用)、pro_aggregate(事業者集計)
Tier 4 - 一時的・開発データ
- ソースデータ、ステージング、開発中のテーブル
- データ連携ツール(Stitch、Airbyte)からの生データ
- 例:
source___stitch_*、_temp_*
Tier 5 - 非推奨・旧データ
- 廃止予定または既に使用されていないテーブル
- 移行のために一時的に残されているデータ
- 例
services_old、products_old
タグシステムの実装
標準フォーマット
すべてのテーブルdescriptionは以下のフォーマットに従います:
description: | [分類][Tier番号] **English:** 英語での説明文 **日本語:** 日本語での説明文
実装例
models: - name: stripe_sales description: | [IM|Payment][Tier2] **English:** Sales data from the individual service platform via Stripe payment processing. **日本語:** サービスプラットフォーム(個人領域)、stripe経由での売上。
多言語対応
英語と日本語の両方で説明を記載することで: - グローバルチームメンバーのアクセシビリティ向上 - text2SQLツールが異なる言語のクエリに対応可能 - 用語の一貫性と理解の共有
text2SQLツールでの活用
このタグシステムにより、text2SQLツールは以下のような判断が可能になります:
クエリの意図理解
- ユーザーが「売上データを見たい」→ [Payment]タグのテーブルを優先
- 「広告効果を分析したい」→ [Ad]タグのテーブルを選択
データの信頼性判断
- 重要な分析にはTier1-2のテーブルを使用
- 探索的分析ではTier3-4も活用
- Tier5は除外または警告表示
効率的なテーブル探索
- タグによる絞り込みで、検索対象を大幅に削減
- 複合タグで、より精密なマッチング
成果と今後の展望
このタグシステムの導入により:
- text2SQLの精度向上:適切なテーブル選択率が大幅に改善
- 分析時間の短縮:ユーザーが自力でテーブルを探す時間を削減
- データガバナンスの強化:重要度による自動的な利用制御
今後は、以下の拡張を検討しています:
- 自動タグ付け:テーブルの利用頻度やクエリパターンからのタグ自動生成
- 動的Tier調整:実際の利用状況に基づくTierの自動更新
- より細かい分類:サブカテゴリの追加による、さらに精密な分類
- dbt外への対応 : 現在はdbtのみにしか対応しておらず、delyさんのように対応させるtableの範囲を広げる。記事の中では、アドホックで作成されたtableの取り扱いなども記載されており利用範囲が広かったです。
まとめ
データ基盤の価値を最大化するには、データへのアクセシビリティが重要です。私たちのタグシステムは、text2SQLツールとそのユーザーの両方がデータを理解し、活用するための共通言語として機能しています。
このアプローチは、特に大規模なデータ基盤を持つ組織において、データの民主化とセルフサービス分析の実現に貢献します。適切なメタデータ管理は、単なる整理整頓ではなく、ビジネス価値を生み出すための重要な投資なのです。
参考
Tier情報を記載したmd
# テーブル description 表記ルール
このドキュメントでは、dbt モデルのテーブル description における統一的な表記ルールを定義します。
## 基本フォーマット
すべてのテーブル description は以下のフォーマットに従って記載してください:
```yaml
description: |
[分類][Tier番号]
**English:** 英語での説明文
**日本語:** 日本語での説明文
```
### フォーマット詳細
1. **複数行記述**: `|` を使用して複数行での記述を行う
2. **分類とTier**: `[IM][Tier1]` のような形式でプロダクト分類とTier番号を記載
- **分類が不明確な場合**: `[Tier番号]` のみ記載し、分類は省略する
3. **言語別説明**: 英語と日本語の両方で説明を記載
4. **行末スペース**: 各行の末尾には半角スペース2つを必ず追加する
## 分類一覧
現在のコードベースで使用されている分類は以下の通りです:
### 基本分類
- `[IM]` - Individual Market(個人領域)- サービスプラットフォームの個人向けサービス
- `[BM]` - Business Market(法人領域)- サービスプラットフォームの法人向けサービス
- `[Other]` - その他 - プラットフォーム共通機能や設定関連
- `[Ad]` - 広告関連 - 各種広告プラットフォームのコストデータ
- `[Payment]` - 決済関連 - Stripe等の決済システム関連データ
- `[PV]` - Page View関連 - サイト訪問・ページビュー関連データ
- `[Log]` - ログ関連 - システムログやイベントログ
- `[HU]` - ハッチュー
### 複合分類
複数の領域にまたがるテーブルには、パイプ(|)で区切って複数の分類を記載:
- `[IM|Payment]` - 個人領域の決済関連
- `[IM|Log]` - 個人領域のログ関連
- `[PV|Log]` - ページビューのログ関連
- `[IM|BM]` - 個人・法人領域共通
## 説明文の作成方針
### 内容の一致性
**English** と **日本語** の説明内容は必ず一致するようにしてください:
- 英語と日本語で同じ情報を伝える
- 一方の言語にのみ記載されている情報がないようにする
- 翻訳の際は意味の一貫性を保つ
### 既存の詳細な説明がある場合
既存の日本語説明が十分に詳細で適切な場合:
- **日本語:** 既存の説明文をそのまま使用
- **English:** 既存の日本語説明を英訳して記載
### 説明が未記載または不十分な場合
description が未記載、または説明が不十分な場合:
1. LLM(AI)を使用して適切な説明文を生成
2. AI生成であることを明示するため `**AI Generated**` の印を追加
3. 生成された説明文の品質を確認し、必要に応じて修正
```yaml
description: |
[IM][Tier1]
**AI Generated**
**English:** AI-generated description in English
**日本語:** AIが生成した日本語の説明文
```
## 実装例
### 例1: 既存説明がある場合
```yaml
- name: requests
description: |
[IM][Tier1]
**English:** Table of requests generated on the quotation platform of the service platform (individual area). Contains information on request details (questions and answers) and sales data.
**日本語:** サービスプラットフォーム(個人領域)の見積りプラットフォーム上で発生した依頼のtable。依頼内容(質問と回答)や売上などの情報を保持している。
```
### 例2: AI生成の場合
```yaml
- name: example_table
description: |
[IM][Tier2]
**AI Generated**
**English:** User activity tracking table containing login sessions and page view data for analytics purposes.
**日本語:** ユーザーアクティビティを追跡するテーブル。ログインセッションとページビューデータを分析目的で保持。
```
### 例3: 複合分類の場合
```yaml
- name: stripe_sales
description: |
[IM|Payment][Tier2]
**English:** Sales data from the individual service platform via Stripe payment processing.
**日本語:** サービスプラットフォーム(個人領域)、stripe経由での売上。
```
### 例4: 分類が不明確な場合
```yaml
- name: _temp_xxxxx_request
description: |
[Tier4]
**English:** Temporary intermediate table for business segment analysis for mid_requests.
**日本語:** requests用ビジネスセグメント分析中間テーブル。
```
## 注意事項
1. **一貫性の維持**: すべてのテーブルで同じフォーマットを使用する
2. **内容の一致**: **English** と **日本語** の説明内容は必ず一致させる
3. **品質管理**: AI生成の説明文は人間がレビューし、必要に応じて修正する
4. **分類の正確性**: `[分類][Tier番号]` は既存のルールに従って正確に記載する
- **分類が不明確な場合は省略**: 明確な分類ができない場合は、無理に分類を付与せず `[Tier番号]` のみ記載する
5. **行末スペース**: 各行末の半角スペース2つを忘れずに追加する