RAGの作り方|Python実装サンプル付き・社内ナレッジ検索の構築手順【2026年版】
目次 [非表示]
この記事でわかること
- Python50行で動く最小構成RAGの実装サンプル(コピペで動作)
- 2026年7月時点の技術スタック主流構成(embedding / ベクトルDB / LLM の3社並列)
- 自社SaaS『PigeonCloud』で本番運用中の3ヶ月段階的拡張ログと設計判断4つ
2026年7月14日更新: LLMラインナップ・フレームワーク・ベクトルDBの情報を7月時点に更新し、仕組み図解とフレームワーク比較表を追加しました。
社内の議事録・マニュアル・仕様書が増えすぎて、どこに何が書いてあるか誰も把握できない。Q&Aチャットボットを作ってみたがハルシネーション(もっともらしい嘘)が多くて使い物にならない。こうした課題を解く現実解が RAG(Retrieval-Augmented Generation、検索拡張生成) です。本記事ではPython50行の動くサンプルを出発点に、チャンク分割・embedding・ベクトルDB・LLM呼び出しまでの実装手順を、自社SaaS『PigeonCloud』(300社導入)で本番運用しているAIファイル検索の3ヶ月拡張ログ付きで解説します。
費用相場やベンダー選定基準は AI受託開発の費用相場2026年版 で詳説しています。外注のメリット・進行フローは AI開発外注ガイド をあわせてご覧ください。本記事はエンジニア向けの技術how-toに振り切って解説します。
RAG(検索拡張生成)とは?社内ナレッジ検索の仕組み
RAGは 「検索」と「生成」を組み合わせた仕組み です。3行で言えば次の通り。
- ユーザーの質問文を embedding(ベクトル) に変換する
- ベクトルDBで 類似度の高い社内文書を検索 する(top-k件)
- 検索結果を LLMのプロンプトに埋め込み、その文脈の範囲内で回答を生成させる
RAGの処理フロー(質問から回答まで)
回答根拠を検索結果に限定するため、LLM単体より創作(ハルシネーション)の余地を大きく減らせる
LLM単体との違い3点
- ハルシネーション抑制 — 回答根拠を検索結果に限定するため、LLMが勝手に創作する余地が減る
- 最新情報への追従 — ベクトルDBを更新するだけで反映。LLM再学習が不要
- ドメイン特化 — 自社の議事録・契約書・製品マニュアル等を外部漏洩させずに扱える
最小構成で動くRAGを作る|Python 50行サンプル
まずは コピペで動く最小RAG を載せます。PostgreSQLにpgvector拡張を入れた前提で、ドキュメント読み込み→チャンク分割→embedding生成→ベクトル検索→LLM呼び出しまで50行前後で書き切ります。2026年7月時点のOpenAI SDKとAnthropic SDKを使用(コード中のモデルは現行ラインナップのまま動きます)。
必要ライブラリ
pip install openai anthropic psycopg2-binary pgvector tiktoken
事前準備:PostgreSQLにCREATE EXTENSION vector;を実行し、以下のテーブルを作っておきます。
CREATE TABLE docs (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding VECTOR(1536)
);
CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists=100);
実装コード(50行)
import os
import psycopg2
from openai import OpenAI
from anthropic import Anthropic
oai = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
claude = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
conn = psycopg2.connect(os.environ["DATABASE_URL"])
def chunk_text(text: str, size: int = 500) -> list[str]:
"""固定長チャンク分割(500字)。本番ではセマンティック分割も検討"""
return [text[i:i+size] for i in range(0, len(text), size)]
def embed(text: str) -> list[float]:
"""text-embedding-3-small で1536次元ベクトルに変換"""
resp = oai.embeddings.create(model="text-embedding-3-small", input=text)
return resp.data[0].embedding
def ingest(docs_dir: str):
"""ディレクトリ内の.txtを読み込んでベクトルDBに格納"""
cur = conn.cursor()
for fname in os.listdir(docs_dir):
if not fname.endswith(".txt"): continue
with open(f"{docs_dir}/{fname}") as f:
for chunk in chunk_text(f.read()):
vec = embed(chunk)
cur.execute(
"INSERT INTO docs (content, embedding) VALUES (%s, %s)",
(chunk, vec)
)
conn.commit()
def retrieve(query: str, k: int = 5) -> list[str]:
"""cos類似度 top-k件を取得"""
qvec = embed(query)
cur = conn.cursor()
cur.execute(
"SELECT content FROM docs ORDER BY embedding <=> %s::vector LIMIT %s",
(qvec, k)
)
return [row[0] for row in cur.fetchall()]
def answer(query: str) -> str:
"""検索結果を文脈としてClaudeに回答させる"""
context = "\n---\n".join(retrieve(query))
prompt = f"以下の社内文書のみを根拠に回答してください。\n\n{context}\n\n質問: {query}"
resp = claude.messages.create(
model="claude-haiku-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
)
return resp.content[0].text
if __name__ == "__main__":
ingest("./docs")
print(answer("有給休暇の申請方法は?"))
コードの要点
- embedding モデル:
text-embedding-3-small(1536次元)を採用。精度とコストのバランス型で、日本語社内文書の検索では実用水準 - 類似度演算子: pgvectorの
<=>はcos距離。距離が小さいほど類似度が高く、ORDER BY ASC で top-k が取れる - ivfflat インデックス: 1万件超のドキュメントでは必須。
listsはデータ件数の平方根が目安 - LLMは文脈内限定回答: プロンプトで「社内文書のみを根拠に」と明示し、LLMの外部知識による創作を抑制する
このサンプルはあくまで出発点です。実運用では次章の「8ステップ」で評価パイプラインと運用監視を足していきます。
RAG実装の技術ステップ8つ(エンジニア向け)
最小構成から本番運用レベルまでの流れを、エンジニアが手を動かす順番で並べます。
ドキュメント収集
pypdf、Wordはpython-docxが定番。ファイル単位にメタデータ(部署・作成日・権限)を付けるチャンク分割
embedding生成
text-embedding-3-small(1536次元)、Cohere Embed v4、Google gemini-embedding-001から選定。日本語なら3社とも実用水準。バッチAPIでコスト圧縮可能ベクトルDB格納
類似検索処理
LLM呼び出し
評価パイプライン
運用監視
RAG設計で最初に決める4つの判断
RAGの精度は コードの巧拙よりも設計判断 で8割決まります。2026年7月時点でプロジェクト着手前に決めておく4点を整理しました。
チャンク分割戦略
固定長 vs セマンティックの判断。議事録・Slackログのように文脈が短い文書は固定長500字で十分、契約書・仕様書のように論理構造がある文書はセマンティック分割(句点・章見出し基準)が向く。
オーバーラップ50〜100字を入れると文脈の分断が減り、ヒット率が3〜5%改善する
embedding モデル選定
候補は後述の表の4モデル。いずれも日本語対応で実用水準にあり、切り替え自体はAPI差し替えのみで済む。
ベクトル次元数が変わると既存データを全て再生成する必要があるため、初期選定が効く
ベクトルDB選定
下記比較表を参考に、既存インフラとスケール要件で決める。弊社では pgvector を採用。既存PostgreSQL基盤に追加できた点が決め手で、権限・バックアップ・監視が既存の仕組みで完結する。
検索スコア閾値
top-k=5・cos類似度 0.7 以上を基準に。閾値未満はLLMに渡さず「関連文書なし」と返す設計にすると、無関係文書を根拠にした誤回答を防げる。
kとthresholdは評価パイプラインで月次調整する前提で決める
ベクトルDB比較表
| 製品 | 形態 | 適した規模 | 特徴 |
|---|---|---|---|
| pgvector | PostgreSQL拡張 | 〜1000万件 | 既存PostgreSQL資産を活用可。運用ノウハウ流用 |
| Pinecone | マネージドSaaS | 1000万〜10億件 | フルマネージド・スケール自動・運用負荷最小 |
| Qdrant | OSS / Cloud両対応 | 〜1億件 | Rust製で高速。セルフホスト可 |
| Weaviate | OSS / Cloud両対応 | 〜1億件 | GraphQL対応・ハイブリッド検索が標準実装 |
▶ ポイント:どのDBを選んでも2026年時点でcos類似度+メタデータフィルタは全製品が対応。差がつくのは運用コスト・既存基盤との統合性・チームのスキルセットです。pgvectorは0.8系でフィルタ付き検索の取りこぼし(overfiltering)が解消され、メタデータフィルタ併用時の実用性が一段上がりました。
実装に使う技術スタック(2026年7月時点の主流構成)
RAG実装で採用されている技術スタックを、LLM・embedding・フレームワークの3軸で整理します。2026年7月時点の情報です。実際、本記事の4月公開からの3ヶ月で3社とも主力モデルが入れ替わりました。この節は入れ替わりに合わせて更新しています。
LLMの選び方(3社×3軸)
回答生成に使うLLMは Claude・OpenAI・Google の3社を要件で使い分け るのが2026年時点の主流です。費用相場や総合比較は AI受託開発の費用相場2026年版 を参照してください。
- Claude Fable 5 (Anthropic)
- GPT-5.6 Sol (OpenAI)
- Gemini 3.1 Pro (Google・プレビュー)
契約書の論点抽出・多段推論・長文要約に強い
- Claude Sonnet 5
- GPT-5.6 Terra
- Gemini 3.5 Flash
RAGの主力帯。日次数万クエリまで経済的に回せる
- Claude Haiku 4.5
- GPT-5.6 Luna
- Gemini 3.1 Flash-Lite
クエリ書換え・軽量ルーティング・ラベリング向き
embeddingモデル
検索精度の土台になるembeddingモデルは、2026年時点で以下が実用水準です。
| モデル | 次元数 | 特徴 |
|---|---|---|
| OpenAI text-embedding-3-small | 1536 | コストと精度のバランス型。RAGのデフォルト選択肢 |
| OpenAI text-embedding-3-large | 3072 | 精度優先。日本語の複雑な文書に強い |
| Cohere Embed v4 | 256〜1536可変 | Matryoshka構造で次元数を可変調整可能 |
| Google gemini-embedding-001 | 最大3072 | Google Cloud基盤との親和性が高い |
▶ 日本語特化のローカルembeddingという選択肢:データを外部APIに出せない案件では、名古屋大学発の Ruri v3(Apache 2.0)が有力です。日本語embeddingベンチマークJMTEBで平均77.24を記録し、text-embedding-3-large(73.97)を上回ります。SentenceTransformers経由でembed関数を差し替えるだけで試せます(次元数が変わるためベクトルDBスキーマの再定義は必要)。推論環境を自前で持つ手間はかかりますが、データを社外に出さずに精度を確保できます。
フレームワーク選び(LangChain / LlamaIndex / 自前実装)
実装フレームワークは3択です。2026年7月時点の状況を比較表にまとめました。
| 選択肢 | 2026年7月時点 | 学習コスト | 向くケース |
|---|---|---|---|
| LangChain | 1.x系(1.0でcreate_agent中心に再設計・現行1.3系) | 中〜高 | エコシステム最大。検索API・メモリ・Agent連携を足していく前提のプロジェクト |
| LlamaIndex | 0.14系(依然0.x系) | 低 | RAGとドキュメントインデックスに特化。社内ナレッジ検索の単機能なら最短 |
| 自前実装 | 本記事の50行サンプルの延長 | 低(コード量次第) | ブラックボックス回避・チューニング余地の最大化・モデル切替の自由度重視 |
弊社では 自前実装 で回しています。フレームワークの抽象化が新モデル対応で足枷になるケースが増え、薄いコードのほうが3社LLM切り替えや評価パイプライン追加が速いと判断したためです。
コードを書かない選択肢との棲み分け:DifyやGoogle NotebookLMのようなノーコードツールでもRAGは試せます。少人数チームがマニュアル数十ファイルを検索する程度なら十分実用です。一方で、部署単位の権限制御・精度の定量評価・既存システム連携が要件に入る社内ナレッジ検索では、本記事のようなコードベースの構成が必要になります。
自社SaaS PigeonCloud の RAG 運用ログ|3ヶ月で辿った段階的拡張
自社SaaS『PigeonCloud』(ロフタル運営・300社導入)にはAIファイル検索機能がRAGで組まれており、本番トラフィックで運用中です。着手から3ヶ月でどう拡張したか、時系列で残します。いわゆる完成形を一発で作ったわけではなく、評価パイプラインの数値を見て次の打ち手を決めていった記録です(ログ中のモデル名・数値は検証当時のものです)。
3ヶ月の段階的拡張タイムライン
Month 1 — PoC段階(社内10名評価)
- チャンクサイズ: 固定長800字・オーバーラップなし
- embedding:
text-embedding-3-small - ベクトルDB: pgvector(既存PostgreSQL基盤に相乗り)
- LLM: Claude Sonnet 4.6 単独
- 評価: 社内10名に質問30件を投げてもらい、正答率を目視判定
得られた知見は2つ。固定長800字だと社内議事録のように短文の集まりではチャンク境界が悪く、質問と関連する文が半分に割れるケースが散見された。もうひとつは「わかりません」の返し方で、閾値設定せずに top-5 を必ず渡す実装にしていたため、関係ない文書でも無理やり回答を作ってしまう挙動が出た。
Month 2 — 本番展開(対外公開)
- チャンクサイズ: 文書種別ごとに500〜800字の可変に変更(議事録500字 / マニュアル800字)
- オーバーラップ: 50字を追加
- 検索閾値: cos類似度0.7未満は「関連文書なし」としてLLMに渡さない設計に
- 評価パイプライン: 質問100件×正解文書のペアを整備しRecall@5を週次計測
top-5ヒット率が Month 1末の72%から85%へ改善。閾値を入れたことで「わかりません」回答が全体の約8%発生するようになったが、ユーザー評価では 嘘の回答より"わからない"のほうが信頼できる というフィードバックが多数で、採用を維持している。
Month 3 — 継続改善(3社LLM動的ルーティング)
- LLM動的ルーティング: 質問の難易度で Haiku 4.5 / Sonnet 4.6 / Opus 4.7 を切り替え
- 分類器: GPT-4.1 nano に「単純検索 / 複雑推論 / 要約」の3分類を判定させる軽量前処理
- メタデータフィルタ: 部署・権限による検索範囲制御を実装
- 監視: 応答時間・API失敗率・ヒット率・わかりません率 の4指標をGrafanaに集約
単純検索の7割がHaiku 4.5で捌けるようになり、応答時間の中央値が3.2秒から2.1秒に短縮。筆者の経験では、3社LLMルーティングは 運用初月に入れるより、評価パイプラインが整ってから入れる ほうが判断根拠が明確になります。
2026年7月時点の補足:ルーティング先の各モデルは検証当時から世代が進んでいます(Sonnet 4.6→Sonnet 5 等)。それでも、評価パイプラインで Recall@5 と正答率の回帰を確認してから切り替えるという手順自体は変わりません。評価データさえ整備してあれば、新モデルが出ても「数値を見て入れ替えるかどうか決めるだけ」の作業になります。ここまでの改善はすべてPython薄い実装で通しています。
裏を返すと、この規模の改善サイクルを回し続けるには評価データの整備とチューニングに継続的なリソースが要ります。社内に割ける人員がいない場合は、生成AIの受託開発のように外部の運用ノウハウごと借りる進め方も現実的です。
RAGの精度を上げる実践テクニック5選
最小構成で動いたあと、精度を継続的に上げる打ち手を5つ紹介します。どれも 評価パイプラインの数値で効果を測れる範囲 で導入します。
- ハイブリッド検索 — ベクトル検索にBM25(キーワード検索)を足す。固有名詞・型番・コード片のように「文字列そのもの」を検索したい場面で強い。RRF(Reciprocal Rank Fusion)で結果をマージする手法が2026年時点では定番。米企業調査(VentureBeat・2026年Q1)でも採用意向が1四半期で約3倍に伸びており、本番RAGの標準装備になりつつある
- リランキング — top-20を取って Cohere Rerank API で再スコアリングし top-5に絞る。embeddingだけの検索より精度が5〜15%改善するケースが多い
- クエリ書き換え(HyDE) — 質問文から 仮想的な回答 をLLMに先に作らせて、その仮想回答でベクトル検索する手法。質問文が短すぎる場合に特に効果がある
- メタデータフィルタリング — 部署・権限・作成日でスコープを絞る。検索結果に「他部署の文書」が混入する事故を防ぐ意味でも必須
- フィードバックループ — 回答採用率(ユーザーがコピペしたか)・クリック率・low quality報告を蓄積し、ダメな回答パターンからプロンプト・チャンク・embeddingの見直しにつなげる
2026年のトレンドとしては、検索を1回で終える固定パイプラインではなく、LLMが必要に応じて検索を繰り返す Agentic RAG 構成への移行が進んでいます。ただし評価パイプラインなしにエージェント化しても精度改善の判断ができないため、本記事の8ステップを固めてからの発展形と捉えるのが現実的です。
よくある質問(FAQ)
まとめ|RAG構築は最小構成から始めて段階的に拡張する
RAGはPython50行の最小構成で動作確認し、評価パイプラインの数値を見ながらチャンク・embedding・LLMを順に触って精度を上げる流れが現実解です。いきなり完成形を目指すとチューニングすべき変数が多すぎて収束しません。
本記事で扱った設計判断4つ(チャンク分割戦略・embeddingモデル・ベクトルDB・検索閾値)を先に決め、3社LLMのどれを主力にするかは評価パイプラインの数値が出てから選ぶ。この順序だけ守れば、PoCから本番運用までの道筋が見えます。
次に読む
PigeonCloud / SASENAI / dotomachi を自社開発・運用中。自社SaaSで本番運用しているRAG・AIエージェントのノウハウをそのまま受託開発として提供しています。
最終更新: 2026年7月14日
データ管理、もっと簡単に。
Excel・Access・スプレッドシートの課題を、ノーコードのWebデータベース「PigeonCloud」が解決します。
月額5,500円〜(5ユーザー)、30日間無料でお試しいただけます。