RAGシステムの基本設計:Claudeとベクター検索で社内文書を活用する
この記事の要点
RAG(Retrieval-Augmented Generation)の仕組みとClaudeを使った実装方法を解説。ベクターDBの選定・チャンキング戦略・検索精度の改善・ハルシネーション防止まで、社内文書Q&Aシステムの設計を実践的に紹介します。
結論
RAG(検索拡張生成)は、Claudeが学習データに含まれない社内情報・最新情報・専門知識を使って回答できるようにする設計パターンです。ユーザーの質問に関連する文書を検索し、その内容をコンテキストとしてClaudeに渡すことで、根拠のある正確な回答が得られます。
社内規程・製品マニュアル・過去の提案書・会議録のような情報を「Claudeに聞けば答えてくれるナレッジベース」に変えられます。
RAGが必要になる場面
Claudeは学習データから知識を持っていますが、2つの限界があります。
- 学習データのカットオフ以降の情報は知らない(最新の法改正・今年の社内規程改訂など)
- 社内固有の情報は学習されていない(自社の製品仕様・顧客情報・内部手順書など)
RAGはこの限界を補います。Claudeに「社内の規程集」「製品マニュアル」「過去の議事録」を検索する能力を与えることで、これらの質問にも正確に答えられるようになります。
| 用途 | 具体例 |
|---|---|
| 社内規程Q&A | 「育休取得の手続きを教えて」→ 人事規程を検索して回答 |
| 製品サポート | 「エラーコード503の対処法は?」→ 製品マニュアルを検索 |
| 過去事例の活用 | 「同様の案件で過去どんな提案をしたか?」→ 提案書を検索 |
| 法令対応 | 「改正個人情報保護法で変わった点は?」→ 最新ガイドラインを検索 |
RAGシステムの3つのコンポーネント
コンポーネント1: 文書の前処理とベクター化
文書をAIが検索できる形式に変換します。
元の文書 → チャンク分割 → ベクター埋め込み → ベクターDB保存
チャンク分割: 長い文書を適切な大きさに分割します。チャンクが大きすぎると関係のない情報が混入し、小さすぎると文脈が失われます。
| チャンクサイズ | 適した文書 |
|---|---|
| 500〜800文字 | FAQ・規程・手順書 |
| 1,000〜2,000文字 | 技術文書・レポート |
| セクション単位 | 構造化された仕様書 |
ベクター埋め込み: テキストを数値ベクトルに変換します。意味的に近いテキスト同士が近い位置に配置されます。これによって「経費精算の方法」という質問に「旅費・出張費の申請手順」という文書がヒットするような意味検索が可能になります。
コンポーネント2: 検索エンジン(ベクターDB)
ユーザーの質問に意味的に近い文書チャンクを高速に返します。
主なベクターDB:
| ツール | 特徴 | 向いているシーン |
|---|---|---|
| Chroma | 軽量・Python親和性が高い | プロトタイプ・小規模 |
| FAISS | 高速・Meta開発 | 大規模データのローカル処理 |
| Pinecone | マネージドサービス | 本番環境・スケーラブル |
| pgvector | PostgreSQL拡張 | 既存DBを活用したい場合 |
コンポーネント3: 生成(Claude)
検索で見つかった文書をコンテキストとしてClaudeに渡し、回答を生成します。
RAGパイプラインの実装例
import anthropic
from your_vector_db import VectorDB
client = anthropic.Anthropic()
db = VectorDB()
def answer_question(user_question: str) -> str:
# ステップ1: 関連文書を検索
relevant_chunks = db.search(
query=user_question,
top_k=5, # 上位5件を取得
threshold=0.75 # 類似度の閾値
)
# ステップ2: 検索結果をコンテキストとして整形
context = "\n\n---\n\n".join([
f"【出典: {chunk.source}】\n{chunk.text}"
for chunk in relevant_chunks
])
# ステップ3: Claudeに質問と文書を渡す
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="""あなたは社内文書に基づいて質問に答えるアシスタントです。
回答の原則:
- 提供された文書の情報のみを使って回答してください
- 文書に情報がない場合は「この文書からは確認できません」と回答してください
- 回答には必ず出典を示してください""",
messages=[{
"role": "user",
"content": f"""以下の社内文書を参考に質問に答えてください。
【参考文書】
{context}
【質問】
{user_question}"""
}]
)
return response.content[0].text
検索精度を上げる3つのテクニック
テクニック1: ハイブリッド検索
ベクター検索(意味的な類似性)とキーワード検索(BM25などの単語一致)を組み合わせます。
ベクター検索は「経費の申請方法」→「旅費の手続き」のような言葉が異なっても意味が近い文書を見つけますが、「第3条第2項」のような固有の語句・コードは弱いです。キーワード検索と組み合わせることで両方の弱点を補えます。
テクニック2: 質問の書き換え
ユーザーの短い質問をそのまま検索クエリにするより、Claudeに「検索に適した形に書き換え」させてから検索します。
# ユーザーの質問を検索クエリに変換
search_query = client.messages.create(
model="claude-haiku-4-5-20251001", # 安価なモデルで処理
messages=[{
"role": "user",
"content": f"""次の質問を、文書検索に適したキーワードに書き換えてください。
質問: {user_question}
キーワードのみを返してください。"""
}]
).content[0].text
# 書き換えたクエリで検索
results = db.search(query=search_query, top_k=5)
「育休どのくらい取れる?」→「育児休業 取得期間 日数 条件」のように展開することで、より適切な文書がヒットします。
テクニック3: 検索結果の再ランキング
上位N件を取得した後、さらにClaudeに「どれが最も関連性が高いか」を評価させます。ベクター検索で上位に来た文書が必ずしも最適とは限らないためです。
チャンキング戦略の詳細
文書の種類によって最適なチャンク分割の方法が変わります。
構造に沿ったチャンキング
章・節・条項などの構造を尊重した分割です。「第5条(育児休業)」の内容は第5条全体をひとまとまりにします。条の途中で切ると文脈が失われます。
オーバーラップチャンキング
隣接するチャンク間で100〜200文字程度を重複させます。チャンクの境界で文脈が切れる問題を防げます。
チャンク1: A...B[境界100文字]C
チャンク2: [境界100文字]C...D
親子チャンキング
大きなチャンク(段落・節)と小さなチャンク(文)の両方を保存します。検索は小さいチャンクで行い、ヒットしたチャンクの親(大きいチャンク)をコンテキストとしてClaudeに渡します。詳細すぎず粗すぎない情報量を確保できます。
ハルシネーション防止の設計
RAGを使ってもハルシネーション(根拠のない回答)はゼロにはなりません。抑制するための設計を組み合わせます。
出典を必ず含める
Claudeへの指示:
「回答の各文に、使用した文書の出典(文書名・ページ・条項)を示してください。
出典を確認できない情報は回答に含めないでください。」
「わからない」と言える状態にする
「提供された文書に情報がない場合は、
『この質問については提供された文書から確認できません。
担当部署(〇〇部)に直接お問い合わせください』
と回答してください。推測や一般的な知識で補完しないでください。」
検索結果の品質をチェックする
検索で見つかった文書の類似度スコアが低い場合(例: 0.6未満)は、「関連する文書が見つかりませんでした」として処理します。低品質な検索結果をそのままClaudeに渡すと、関係のない情報から無理やり回答を作ることがあります。
文書の更新と管理
RAGシステムは文書が最新の状態に保たれていないと、古い情報に基づく回答が出てしまいます。
更新検知の仕組み
def update_document(doc_id: str, new_content: str):
# 古いチャンクを削除
db.delete_by_doc_id(doc_id)
# 新しいコンテンツをチャンク化してベクター化
new_chunks = chunk_document(new_content)
embeddings = embed_chunks(new_chunks)
# ベクターDBに保存
db.insert(chunks=new_chunks, embeddings=embeddings, doc_id=doc_id)
メタデータで鮮度を管理する
{
"content": "育児休業は最長1年取得できます...",
"source": "人事規程2026年版",
"updated_at": "2026-04-01",
"valid_until": "2027-03-31",
"department": "人事部"
}
検索結果にこのメタデータを含めると、Claudeが「2024年版の規程に基づく情報です(最新版を確認してください)」のように情報の鮮度を示した回答ができます。
マルチエージェント設計と組み合わせて「最初に文書を検索するエージェント」「検索結果を整理するエージェント」「回答を生成するエージェント」に分けることで、より精度が上がります。詳細はマルチエージェント設計の実践パターンを参照してください。
まとめ
RAGシステム設計の実践ポイントをまとめます。
- RAGは社内文書・最新情報・専門知識への質問に答えるための設計パターン
- 文書の前処理(チャンキング)→ ベクター検索 → Claudeでの生成の3ステップが基本構造
- ハイブリッド検索・質問の書き換え・再ランキングで検索精度を上げる
- 「提供した文書の情報のみ使う」「出典を示す」「わからない場合は認める」の指示でハルシネーションを抑制する
- 文書の更新・削除の仕組みを最初から設計に含めて情報の鮮度を保つ
RAGを正しく設計することで、社内の散在した情報を「Claudeに聞けば答えてくれるシステム」に変えられます。
よくある質問
RAGとは何ですか?
Retrieval-Augmented Generation の略で、AIが回答を生成する前に関連する文書を検索して取得(Retrieval)し、その情報を使って回答を生成(Generation)する仕組みです。学習データに含まれない社内情報や最新情報を活用できます。
RAGを使うとハルシネーション(幻覚)を防げますか?
完全には防げませんが、大幅に減らせます。「提供した文書の情報のみを使って回答し、情報がない場合は『この文書からは確認できません』と回答してください」という指示と組み合わせることで、根拠のない回答を抑制できます。
どんなベクターDBを使えばよいですか?
小規模(文書数万件以下)はChromaやFAISSのような軽量なものが適しています。大規模(数十万件以上)や本番環境ではPineconeやWeaviateが信頼性が高いです。Supabaseを使っている場合はpgvectorも選択肢です。