概要
ChatGPTに自社マニュアルを読ませたい。
そんなときによく使われるのが RAG(Retrieval-Augmented Generation)です。
RAGは「AIに知識を覚えさせる」のではなく、「必要な文書を検索してから回答する」仕組みです。
本記事では、DIY・家電修理まとめサイトで実装したRAGを例に、ベクトルDBを使った検索の流れを紹介します。
その検索によく使われるのが、文章をEmbedding(ベクトル)へ変換し、そのベクトルを保存・検索できるベクトルDBです。
DIY・家電修理まとめサイト(以下、まとめサイト)では、修理ガイドをベクトルとして保存し、意味検索で候補を出し、チャットではその候補が表示されるように、修理相談チャットとして実装しています。
RAGとは
「文書を探してから答える」 手法となります。
| 英語 | 意味 | 役割 |
|---|---|---|
| Retrieval | 取り出す・検索する | 関連する文書を探す(ここが主役) |
| Augmented | 補強する | 探した文書を回答の材料にする |
| Generation | 生成する | LLMが文章を組み立てる |
この3つのうち、最も重要なのは Retrieval(検索)です。Generation(生成)は検索結果を自然な文章にまとめる役割です。
よくある誤解と正しいイメージ
| 誤解 | 実際 |
|---|---|
| RAG = すごいチャットボットそのもの | 中心は 文書検索。チャットはその上に乗る |
| AIが全部の文書を暗記している | 暗記ではなく、都度検索して取りに行く |
| ベクトルDBがあれば完成 | ベクトルDBは「意味で探すための倉庫」。入れ方・探し方が大事 |
たとえば:
- 普通のキーワード検索 … 本棚で「バッテリー」と書いてある本だけ探す
- ベクトル検索 … 「すぐ電源が切れる」と質問すると、意味検索でバッテリー関連の本を連想して探す
- RAG … その本を開いてから、「このページが参考になりそうです」と案内する
なぜベクトルDBを使うのか
文章をそのまま比較するのは難しいので、いったん 数値の列(ベクトル / embedding) に変換します。
OpenAI の Embeddings APIを使うことでテキストをベクトル化することができます。
「画面が真っ暗」 → [0.12, -0.44, 0.87, …]
「液晶が映らない」 → [0.11, -0.41, 0.90, …] ← ベクトル同士の距離が近い
「バッテリー交換」 → [-0.55, 0.22, 0.03, …] ← 遠い
この「意味の近い/遠い」を高速に探すのが ベクトルDB(またはベクトル検索機能付きDB) の機能です。
代表サービス:
- Pinecone / Qdrant / Weaviate などの専用ベクトルDB
- MongoDB Atlas の Vector Search(既存MongoDB上でベクトル検索)
「ベクトルDBを使う = RAG」ではありませんが、意味で文書を探すRAGではほぼ必須の部品です。
なぜ必要か
| LLM単体の課題 | RAG(文書検索)でできること |
|---|---|
| 自社ガイドを知らない | 自前の文書を検索対象にできる |
| 情報が古くなりやすい | 文書を更新してベクトルを作り直せば最新情報を反映できる |
| 根拠のない回答が出やすい | 「このページが根拠」と示せる/無ければ断れる |
一般的なパイプライン
【事前準備:文書をベクトルDBへ】
文書 → テキスト整形 / 分割 → 埋め込み(embedding) → ベクトルDBに保存
【質問が来たとき】
質問 → 埋め込み → ベクトルDBで類似検索 → 近い文書を取得
→ (任意)その文書を渡して LLM が回答を生成
流れを覚えるならこの3語だけで足ります。
- 入れる(文書をベクトル化して保存)
- 探す(質問に近い文書をベクトルDBから取得)
- 答える(見つかった文書をもとに案内・生成)
まとめサイトでの使い方
まとめサイトでは、 チャットで修理ガイドの文書検索 を行っています。
構成は次のようになっています。
チャットに質問
│
▼
意味検索API
│
▼
Vector Search
│
▼
修理ガイド一覧
│
▼
Chat API
│
▼
LLM(100文字だけ生成)
│
▼
回答を表示
基本のデータはMongoDB Atlasに登録しています。
ベクトル検索用のデータは、MongoDB Atlas の Vector Search を使っています。
チャットでは2段階でAPIを呼び出しています。
| 機能 | 役割 | エンドポイント / UI |
|---|---|---|
| 意味検索 | 質問文に近い修理ガイド一覧を返す | GET /api/search/repair-semantic |
| 回答内容生成 | 修理ガイド一覧を基に、短い補足文を生成 | POST /api/chat/repair |
ポイントは、チャットでも「手順の全文をLLMに書かせない」設計にしていることです。
一般的なRAGでは検索結果をそのままLLMへ渡して長文回答を生成する例が多く見られます。しかし今回は、修理手順そのものはガイドページへ誘導し、LLMには「なぜこのガイドが参考になるのか」という100文字程度の補足だけを生成させています。
詳細はガイドページと元動画へ誘導し、LLMは「なぜそのガイドが参考になるか」の短い補足に留めます。
= 検索が主役、生成は脇役。
なぜMongoDB Atlasを選んだか
今回はMongoDBを既に利用していたため、
新たにPineconeやQdrantを導入せず、
Atlas Vector Searchを利用しました。
メリット
- 既存コレクションをそのまま使える
- インフラが増えない
- 集約パイプラインで完結する
デメリット
- ベクトル検索専用DBほど高機能ではない
- 高度な検索チューニングは限定的
RAGパイプライン
入れる → 探す → 答える
【入れる】修理ガイド文書をベクトル化して保存
repair_pages(MongoDB)
↓ 埋め込み用テキストを作成
↓ OpenAI Embeddings(text-embedding-3-small)
repair_page_embeddings へ保存
↓ Atlas Vector Search(ベクトル検索インデックス)
【探す】質問に近いガイドをベクトルDBで検索
ユーザー質問(文章)
「画面が真っ暗で映らない」
↓ 埋め込み(OpenAI Embeddings API)
[0.12, -0.44, 0.87, …] ← これがベクトル
↓ $vectorSearch
あらかじめ同じ方法でベクトル化したガイドと「近さ」を比較
【答える】
意味検索API(ガイド一覧を返す)
修理チャット(短い補足 + ガイド一覧 + 免責)
入れる
OpenAIで、既存のデータをベクトル化して、ベクトルDBに登録します。
探す
制限を設けています
- 質問のレート制限(IPあたり 20 req / 分)(乱用を防ぐため)
- メッセージ長上限 500 文字まで受け付ける
- 関連するガイドを取得(既定最大5件、上限10)
答える
関連するガイドの有無で内容が変わります
- ガイドなし
- 定型文「見つかりませんでした…」を返す
- ガイドあり
- 導入文 + LLMによる短い補足(100字以内)+ 「下記のガイドをご確認ください」
プロンプト上の制約
- 作業手順の詳細は書かない
- 「見つかりませんでした」など否定は書かない(ヒット時のみ補足生成)
- 詳細はガイドページ側で確認するよう促す
これは「RAGで長文回答を生成する」のではなく、検索結果の案内をLLMで少しだけ自然にする形です。誤情報リスクと責任範囲を抑えるための判断です。
まとめ
まとめサイトでは、検索結果をLLMで補足するシンプルな構成ですが、十分に実用的なチャットを構築できました。
修理サイトのように誤情報がリスクとなるサービスでは、LLMに手順を書かせるのではなく、検索結果への案内役に限定する設計が有効だと思います。
また、実装してみて、「RAGの主役はLLMではなく検索」だと感じました。
ベクトルDBが対応しているデータベースの選定も大事で、今回は既にMongoDB Atlasを利用していたため、Vector Searchをそのまま利用でき、追加でベクトルDBを構築する必要がありませんでした。
この仕組みは修理サイトだけではなく、社内文書検索やFAQ、製品マニュアル検索などにも応用できます。文書を適切にテキスト化し、Embeddingを作成してベクトルDBへ登録すれば、同じ考え方でRAGを構築できます。
おわりに
今回はDIY・家電修理まとめサイトのRAG実装を紹介しました。
AIを活用したWebシステムやRAG、OpenAI APIを利用した機能開発にも取り組んでいます。同様のシステム開発に興味がありましたら、プロフィールからお気軽にご相談ください。
実際の動作はこちらから確認できます。