はじめに
社内の情報は、さまざまな場所に分散しています。
マニュアルは社内Wiki、過去の対応履歴はスプレッドシート、商品情報は別のシステム。
これらを横断して検索できないことが、業務効率を下げる大きな原因になっています。
この記事では、複数のデータソースを1つのデータベースに統合し、
「1回の検索で全データを横断できる」仕組みを構築した方法を解説します。
分散データの課題
情報が見つからない問題
それぞれのツールで検索する必要があり、
「どこに書いてあるか分からない」「検索しても見つからない」という問題が発生します。
統合のメリット
これらを1つのデータベースに統合すると、以下のメリットがあります。
- 1回の検索で全データを横断:質問に関連する情報を、ソースを問わず取得
- 意味による検索:「返金」で検索しても「払い戻し」「キャンセル」がヒット
- 参照元の明示:どのデータソースから取得したかを表示
データソースの統合設計
統一スキーマの設計
複数のデータソースを統合するには、**共通のデータ構造(スキーマ)**が必要です。
データソースごとの変換
各データソースは形式が異なるため、統一スキーマへの変換処理が必要です。
Markdown形式
行ごとのデータ
文書ファイル
content + source_type + metadata + embedding
横断検索が可能に
各データソースの取り込み
FAQマニュアル(JSON形式)
手動で整備した対応マニュアルは、JSON形式で管理しています。
{
"id": "FAQ-001",
"question": "返金の手続きはどうすればいいですか?",
"answer": "返金のご依頼を承りました...",
"category": "決済",
"tags": ["返金", "キャンセル"]
}
これを統一スキーマに変換する際、質問と回答を結合してcontentとします。
対応履歴(スプレッドシート)
過去の対応履歴は、スプレッドシートに蓄積されています。
これらを1行ずつ取り込み、問い合わせ内容と対応内容を結合してcontentとします。
見積データ・商品マスタ
見積データや商品マスタは、検索時に補足情報として使われます。
「この修理の見積もりはいくらくらい?」
→ 見積データから関連情報を取得
→ 「〇〇の修理は△△円〜□□円が目安です」と回答
Embedding処理の実装
OpenAI Embedding APIの利用
テキストをベクトルに変換するには、OpenAIのEmbedding APIを使用します。
このプロジェクトでは、コストと精度のバランスからtext-embedding-3-smallを採用しています。
バッチ処理
数千件のデータを処理する場合、1件ずつAPIを呼ぶと時間がかかります。そこで、バッチ処理で効率化しています。
各データソースからデータを読み込み
前回と変更があるかチェック
変更があるものだけをまとめてEmbedding
ベクトルとメタデータをDBに保存
横断検索の実装
ソースタイプによるフィルタリング
必要に応じて、特定のデータソースのみを検索することも可能です。
-- FAQのみを検索
WHERE source_type = 'faq'
-- FAQと対応履歴を検索
WHERE source_type IN ('faq', 'ticket')
検索結果の活用
検索結果は、AIへの入力として使われます。
【検索結果】
1. [FAQ] 返金の手続きについて
返金のご依頼は、以下の手順でお受けしています...
2. [対応履歴] 2024/01/10の対応事例
同様のケースでは、〇〇の方法で対応しました...
3. [見積] △△の料金表
この作業の目安価格は□□円です...
AIは、これらの情報を元に回答を生成します。
なぜ同じテーブルに入れるのか
別テーブル vs 同じテーブル
データソースごとに別テーブルを作る方法もありますが、このプロジェクトでは同じテーブルに統合しました。
統合の利点
同じテーブルに入れることで、以下の利点があります。
-
質問の意図を推測しなくていい
- 「マニュアルを見たいのか」「過去事例を見たいのか」をユーザーが指定しなくていい
- 質問内容に応じて、最適な情報が自動で選ばれる
-
検索ロジックがシンプル
- 1回のクエリで完結
- 複数テーブルをUNIONする必要がない
-
類似度の比較が正確
- 同じEmbeddingモデルで変換されているため、類似度が比較可能
データ品質の確保
重複データの排除
同じ内容が複数回取り込まれないよう、source_idによる重複チェックを行います。
既存データがある場合:
- content_hashが同じ → スキップ
- content_hashが異なる → 更新
欠損データの処理
必須フィールドが欠けているデータは、取り込み時にスキップまたは補完します。
まとめ
分散データを統合することで、以下を実現しました。
- 1回の検索で全データを横断:質問に最適な情報がソースを問わず見つかる
- 意味ベースの検索:キーワードの揺れに対応
- 参照元の明示:どのデータソースから取得したかが分かる
データ統合は初期構築に手間がかかりますが、一度仕組みを作れば、新しいデータソースの追加も容易になります。