結論
結論: RAG(検索拡張生成)は、LLMの幻覚(ハルシネーション)を抑制し、自社データに基づく正確な回答を実現する技術。2026年はハイブリッド検索とGraphRAGの組み合わせが主流になりつつある。
この記事の要点:
- 要点1: RAGは「検索(Retrieval)→ 拡張(Augmented)→ 生成(Generation)」の3ステップで、LLMに社内データを参照させる仕組み
- 要点2: PoCにはChromaDB(無料・ローカル完結)、本番にはPineconeやpgvectorが定番
- 要点3: 2026年のベストプラクティスは「ハイブリッド検索 + リランキング + ファインチューニング」の併用
対象読者: 社内データを活用したAIチャットボットを構築したいエンジニア
読了後にできること: PythonでRAGパイプラインを構築し、自社ドキュメントに基づくQ&Aシステムを実装できる
はじめに
ChatGPTに社内の就業規則について質問したら、もっともらしいウソを返された——そんな経験はありませんか?
LLM(大規模言語モデル)は汎用的な知識を持っていますが、自社固有の情報は知りません。しかも「知らない」と言わずに、それっぽい回答を生成してしまう(ハルシネーション)。この問題を解決するのがRAG(Retrieval-Augmented Generation:検索拡張生成)です。
RAGを使えば、LLMが回答を生成する前に関連する社内ドキュメントを検索し、その内容に基づいて回答します。2026年現在、エンタープライズAIシステムの53%がRAGパイプラインを採用しており、「AIを実業務で使う」ための必須技術となっています。
まず試したい「5分即効」セットアップ3選
即効1: ChromaDBで最小構成のRAG
# 動作環境: Python 3.10+
# pip install chromadb openai
import chromadb
from openai import OpenAI
# 1. ベクトルDBにドキュメントを格納
chroma = chromadb.Client()
collection = chroma.create_collection("company_docs")
# 社内ドキュメントを登録(実際はPDF/Notion/Confluenceから取得)
documents = [
"有給休暇は入社6ヶ月後に10日付与されます。勤続年数に応じて最大20日まで増加します。",
"リモートワークは週3日まで可能です。事前に上長の承認が必要です。申請はSlackの#remote-workチャンネルで。",
"経費精算の上限は月5万円です。5万円を超える場合は事前に経理部の承認が必要です。",
"育児休業は子が1歳になるまで取得可能。保育所に入れない場合は最長2歳まで延長できます。",
]
collection.add(
documents=documents,
ids=[f"doc_{i}" for i in range(len(documents))]
)
# 2. 質問に対して関連ドキュメントを検索
query = "リモートワークのルールを教えてください"
results = collection.query(query_texts=[query], n_results=2)
# 3. 検索結果をコンテキストとしてLLMに渡す
context = "n".join(results["documents"][0])
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4.1-nano", # 低コスト
messages=[
{"role": "system", "content": f"以下の社内ドキュメントに基づいて回答してください。ドキュメントに情報がない場合は「確認が必要です」と回答してください。nn{context}"},
{"role": "user", "content": query}
]
)
print(response.choices[0].message.content)
ポイント: ChromaDBはpip install chromadbだけで使えるベクトルDB。OpenAI Embeddingsを内部で自動呼び出しするため、明示的なエンベディング生成コードが不要です。
即効2: PDF文書をRAGに取り込む
# pip install chromadb openai pymupdf langchain-text-splitters
import fitz # PyMuPDF
from langchain_text_splitters import RecursiveCharacterTextSplitter
# PDFからテキスト抽出
def extract_pdf(path):
doc = fitz.open(path)
return "n".join(page.get_text() for page in doc)
text = extract_pdf("company_rules.pdf")
# チャンク分割(日本語に適した設定)
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 日本語は1文字≒1トークンなので500文字
chunk_overlap=50, # 前後50文字を重複させて文脈を保持
separators=["nn", "n", "。", "、", " "]
)
chunks = splitter.split_text(text)
# ChromaDBに格納
collection.add(
documents=chunks,
ids=[f"chunk_{i}" for i in range(len(chunks))]
)
print(f"{len(chunks)}チャンクを登録完了")
ポイント: チャンクサイズは日本語の場合300-500文字が最適。大きすぎると検索精度が下がり、小さすぎると文脈が失われます。chunk_overlapで段落境界のコンテキスト切れを防ぎます。
即効3: Claudeで高品質な回答を生成
# pip install anthropic
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_API_KEY環境変数を設定
# 検索結果をXMLタグで構造化して渡す(Claude推奨パターン)
context_docs = results["documents"][0]
context_xml = "n".join(
f"<document index="{i+1}">n{doc}n</document>"
for i, doc in enumerate(context_docs)
)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=f"""以下の社内ドキュメントに基づいて、正確に回答してください。
ドキュメントに記載がない情報は「社内規定で確認が必要です」と回答してください。
回答にはどのドキュメントを参照したかを明記してください。
<documents>
{context_xml}
</documents>""",
messages=[{"role": "user", "content": query}]
)
print(response.content[0].text)
ポイント: ClaudeはXMLタグで構造化された入力を正確に処理します。<document index="1">のように番号付きで渡すと、「ドキュメント2より」のように出典を明示した回答が得られます。
RAGアーキテクチャの全体像
【RAGパイプライン】
[ドキュメント] → [チャンク分割] → [エンベディング] → [ベクトルDB]
↓
[ユーザー質問] → [エンベディング] → [類似検索] → [リランキング]
↓
[プロンプト構築]
↓
[LLM生成]
↓
[回答]
| ステップ | 処理内容 | 2026年のベストプラクティス |
|---|---|---|
| チャンク分割 | 文書を検索単位に分割 | セマンティック分割(意味の切れ目で分割) |
| エンベディング | テキストをベクトルに変換 | OpenAI text-embedding-3-large / Cohere embed-v4 |
| ベクトルDB | ベクトルを格納・検索 | PoC: ChromaDB、本番: Pinecone / pgvector |
| 検索 | 類似ドキュメントを取得 | ハイブリッド検索(ベクトル + キーワード) |
| リランキング | 検索結果を再順位付け | Cohere Rerank / Cross-Encoder |
| 生成 | コンテキスト付きで回答 | 出典明示 + ハルシネーション検出 |
ベクトルDB選定ガイド
| DB | 特徴 | コスト | 推奨シーン |
|---|---|---|---|
| ChromaDB | ローカル完結、pip install可 | 無料(OSS) | PoC・個人開発 |
| Pinecone | マネージド、スケーラブル | $0〜(Free Tier) | 本番SaaS |
| pgvector | PostgreSQL拡張、SQLで操作 | 無料(OSS) | 既存PostgreSQL環境 |
| Qdrant | Rust製高速、フィルタリング強い | 無料(OSS) | 大規模・高速要件 |
| Weaviate | GraphQL API、マルチモーダル | 無料(OSS) | 画像+テキスト混在 |
2026年の選定基準: 「PoCならChroma、SQLが使いたいならpgvector、マネージドが良いならPinecone」が鉄則。既存のPostgreSQLがある企業はpgvectorが最もROIが高いです。
【要注意】よくある失敗パターンと回避策
失敗1: チャンクサイズが不適切
❌ 1000文字以上の大きなチャンクで検索精度が低下。関係ない情報が混入
✅ 日本語は300-500文字。セマンティック分割(段落・見出し単位)を併用
失敗2: 「RAGの精度が悪い」のに生成側を調整する
❌ プロンプトを何度変えても回答が改善しない
✅ RAGの精度問題の80%は検索側の問題。まずリランキングを導入し、検索結果の上位3件が本当に関連しているか確認
失敗3: エンベディングモデルの選定ミス
❌ 英語向けモデルで日本語ドキュメントをエンベディングし、検索精度が壊滅
✅ 日本語対応モデルを選択: OpenAI text-embedding-3-large(多言語対応)、Cohere embed-v4(多言語特化)
失敗4: ドキュメントの更新を忘れる
❌ 就業規則が改訂されたのに古い情報が返される
✅ ドキュメント更新のWebhookをトリガーに、ベクトルDBを自動再インデックス(n8nと連携すると効果的)
参考・出典
- Retrieval-Augmented Generation (RAG) — Pinecone(参照日: 2026-03-04)
- RAG in 2026: A Practical Blueprint — DEV Community(参照日: 2026-03-04)
- RAG Best Practices — Redwerk(参照日: 2026-03-04)
- ベクトルデータベース&RAG爆速入門 — Qiita(参照日: 2026-03-04)
- RAG in 2026: Bridging Knowledge and Generative AI — Squirro(参照日: 2026-03-04)
あわせて読みたい:
- Claude Agent SDKとは?AIエージェント開発の実装ガイド
- Difyとは?ノーコードでAIアプリを作れるプラットフォームを徹底解説
- OpenAI API × Responses APIで業務自動化
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。
100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』(SBクリエイティブ)。
SoftBank IT連載7回執筆(NewsPicks最大1,125ピックス)。
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。
あわせて読みたい
AIエージェントの導入・活用についてのご相談は、Uravationのサービス一覧をご覧ください。
あわせて読みたい
- 関連記事: AIエージェントのメモリ設計パターン