【RAG 構築 手順 LangChain Python】デファクトスタンダードで始めるRAGシステム開発
ヨミアゲAI編集部
AI音声・動画制作に関する情報をお届けします
2026年Q2時点のRAG構築動向とLangChainの役割
2026年Q2時点において、RAG(Retrieval-Augmented Generation)は、大規模言語モデル(LLM)が持つ幻覚(Hallucination)の問題を緩和し、最新情報や企業固有のデータに基づいた正確な回答を生成するための標準的なアプローチとして確立されています。特にLangChainは、そのモジュール性と豊富な統合機能により、RAGシステム構築のデファクトスタンダードツールの一つとなっています。PythonエコシステムにおけるLangChainのバージョンは0.2.x系が安定しており、多くのLLMプロバイダー(OpenAI, Anthropic, Googleなど)やベクトルデータベース(ChromaDB, Pinecone, Qdrantなど)との連携が強化されています。
💡 ポイント: 2026年現在、RAGは単なる情報検索と生成の組み合わせに留まらず、エージェント機能やセルフリフレクションメカニズムと統合され、より複雑なタスクに対応可能な高度なAIシステムへと進化しています。
LangChainとPythonによるRAG構築のステップバイステップ
LangChainとPython 3.10以降を使用してRAGシステムを構築する基本的な手順を以下に示します。
1. 環境準備とライブラリのインストール
まず、必要なライブラリをインストールします。
pip install langchain langchain-community openai chromadb tiktoken
⚠️ 注意:
langchain-communityは、多くの統合機能(ドキュメントローダー、ベクトルストアなど)を提供するパッケージです。LangChain 0.2.x以降では、コアパッケージから分離されています。
2. ドキュメントのロードと分割(チャンキング)
RAGシステムの基盤となる知識データを用意します。ここでは、テキストファイルからデータを読み込み、LLMが処理しやすいように分割します。
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# ドキュメントのロード (例: sample.txt)
# 実際のユースケースでは、PDFLoader, CSVLoaderなども利用可能
loader = TextLoader("sample.txt")
documents = loader.load()
# ドキュメントの分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 1チャンクあたり約1000文字
chunk_overlap=200 # 前後のチャンクと200文字重複させる
)
split_documents = text_splitter.split_documents(documents)
print(f"元のドキュメント数: {len(documents)}")
print(f"分割後のチャンク数: {len(split_documents)}")
💡 ポイント:
chunk_sizeとchunk_overlapの調整はRAGの性能に大きく影響します。小さいチャンクは詳細な情報を捉えやすいですが、コンテキストが失われがちです。大きいチャンクはコンテキストを保持しやすいですが、関連性の低い情報も含まれる可能性があります。最適な値はデータセットとLLMの特性によって異なります。
3. Embeddingモデルの選択とベクトルデータベースへの保存
分割されたテキストチャンクをベクトル化し、ベクトルデータベースに保存します。ここでは、OpenAIのEmbeddingモデルとローカルで手軽に利用できるChromaDBを使用します。
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
import os
# APIキーの設定 (環境変数から取得することを推奨)
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
# Embeddingモデルの初期化
# 2026年Q2時点では、text-embedding-3-small (512次元) や text-embedding-3-large (3072次元) が主流です。
# 小規模なRAGではtext-embedding-3-smallで十分な性能を発揮します。
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# ベクトルデータベースの構築と保存
# persist_directoryを指定すると、データベースがディスクに保存され、再利用可能になります。
vectorstore = Chroma.from_documents(
documents=split_documents,
embedding=embeddings,
persist_directory="./chroma_db"
)
# データベースを永続化
vectorstore.persist()
print("ベクトルデータベースが構築され、保存されました。")
| Embeddingモデル | 次元数 | 特徴(2026年Q2時点) | 料金(参考: 1Mトークンあたり) |
|---|---|---|---|
| text-embedding-3-small | 512 | 高性能と低コストのバランスが良い | 約$0.02 |
| text-embedding-3-large | 3072 | 最高性能、より高コスト | 約$0.13 |
⚠️ 注意: OpenAI APIキーは公開リポジトリにコミットしないよう、環境変数で管理してください。ChromaDBはローカルで手軽に利用できますが、大規模なプロダクション環境ではPineconeやQdrantなどのマネージドサービスを検討することも重要です。
4. RetrieverとLLMの準備、RAGチェーンの構築
ベクトルデータベースから関連情報を取得するRetrieverと、回答生成を行うLLMを準備し、これらを結合してRAGチェーンを構築します。
from langchain_openai import ChatOpenAI
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
# 保存したベクトルデータベースをロード
# embedding_functionを再度渡すことで、正しくロードされます。
vectorstore = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
# Retrieverの準備
# search_kwargsで検索パラメータを設定できます。ここでは上位3件の関連ドキュメントを取得します。
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# LLMの初期化
# 2026年Q2時点では、gpt-4oやgpt-4-turboが推奨される高性能モデルです。
# temperatureを低く設定することで、より一貫性のある回答を促します。
llm = ChatOpenAI(model="gpt-4o", temperature=0.1)
# プロンプトテンプレートの定義
# LLMに与える指示と、検索で取得したコンテキスト、ユーザーの質問を埋め込みます。
prompt = ChatPromptTemplate.from_template("""
あなたはユーザーの質問に答えるAIアシスタントです。
提供されたコンテキストのみに基づいて、質問に正確に答えてください。
コンテキストに情報がない場合は、「情報が見つかりませんでした。」と答えてください。
コンテキスト:
{context}
質問: {input}
""")
# ドキュメントを結合するチェーン (StuffDocumentsChain)
# 検索で取得したドキュメントをプロンプトに詰め込む役割を担います。
document_combiner = create_stuff_documents_chain(llm, prompt)
# Retrieverとドキュメント結合チェーンを組み合わせたRAGチェーンの作成
rag_chain = create_retrieval_chain(retriever, document_combiner)
print("RAGチェーンが構築されました。")
5. RAGチェーンの実行と評価
構築したRAGチェーンに質問を投入し、回答を取得します。
# 質問の実行
question = "LangChainとは何ですか?"
response = rag_chain.invoke({"input": question})
print(f"\n質問: {question}")
print(f"回答: {response['answer']}")
# 質問の実行 (コンテキストにない情報)
question_no_context = "宇宙の起源について教えてください。"
response_no_context = rag_chain.invoke({"input": question_no_context})
print(f"\n質問: {question_no_context}")
print(f"回答: {response_no_context['answer']}")
💡 ポイント: RAGシステムの性能評価には、回答の正確性、関連性、網羅性などが重要です。LangChainはLangSmithのようなツールと連携し、トレース、デバッグ、評価を効率的に行うことができます。2026年Q2時点では、評価フレームワークとしてRAGASなども広く利用されています。
RAG構築における最適化と考慮事項
RAGシステムの効果を最大化するためには、いくつかの考慮事項があります。
- データ品質と前処理: ドキュメントのクリーンさ、重複排除、メタデータの付与は検索精度に直結します。定期的なデータ更新と品質管理が不可欠です。
- チャンキング戦略: ドメイン固有の知識やドキュメント構造に応じたチャンキング(例: Markdownヘッダーに基づく分割、セマンティックチャンキング)を検討します。
- Retrieverの高度化: 単純な類似度検索だけでなく、ハイブリッド検索(キーワード検索とベクトル検索の組み合わせ)、Reranking、Multi-query Retriever、Self-query Retrieverなどの高度なRetriever戦略を導入することで、検索精度を大幅に向上させることが可能です。2026年Q2時点では、これらの技術はLangChainで容易に実装できます。
- LLMの選定: 生成する回答の品質、コスト、レイテンシーを考慮して最適なLLM(例: GPT-4o, Claude 3.5 Sonnet, Llama 3など)を選択します。
- プロンプトエンジニアリング: LLMへの指示(プロンプト)を最適化することで、より質の高い回答を引き出せます。Few-shot学習やCoT(Chain-of-Thought)プロンプティングも有効です。
これらの要素を継続的に改善することで、より堅牢で高性能なRAGシステムを構築できます。