ALBACONNECT
Insights

LangChain × RAGの実装パターン比較 — 2026年版ベストプラクティス

紅谷 颯杜監修・更新: 2026-04-16

要点

RAGの実装パターンをBasic(LCEL標準型)・Advanced(検索強化型)・Agentic(LangGraph型)の3つに分類し、レイテンシー・精度・コストの定量比較とユースケース別の選定基準を共有。LangChain vs LlamaIndexの選定理由、チャンキング改善でRetrieval Precisionが58%→82%に改善した実例、RAGAS評価パイプラインの実践まで、受託開発の現場知見を凝縮。

RAGの実装パターンには明確な使い分けがあり、選択を間違えると本番で破綻する

これが、私たちが複数の受託プロジェクトでRAGシステムを構築してきた結論だ。

RAGは2024年のブームから2年が経ち、「とりあえず動くPoC」の時代から「運用環境で精度と信頼性を保つ」フェーズに移行している。LangChain自体も大きく変わった。2024年後半にLegacy Chains(RetrievalQA等)が非推奨となり、LCEL(LangChain Expression Language)とcreate_retrieval_chainベースのパイプラインが標準になった。2025年にはLangGraphが安定版となり、エージェント型RAGのパターンが確立された。

本記事では、LangChainの現行アーキテクチャに基づく3つの実装パターンを比較し、ユースケース別の選定基準とハマりどころを共有する。

なぜLangChainか — LlamaIndexを選ばなかった理由

RAGフレームワークの選定で、私たちはLlamaIndexも検証した。LlamaIndexはRAGに特化しており、インデックス構築やクエリエンジンの抽象度が高い。ドキュメントQAに限定するならLlamaIndexの方が立ち上がりは速い。

しかし、私たちの受託案件では「RAG+既存業務ロジック+外部API連携」が複合的に求められる。LangChainはRAG以外のチェーン構築(ツール呼び出し、マルチステップ推論、ワークフロー制御)との統合が容易で、LangGraphとの連続性がある。RAG単機能の最適さより、プロジェクト全体の拡張性を優先した。

3つの実装パターン

パターン1: Basic RAG(LCEL標準型)

最もシンプルな構成。ドキュメントをチャンクに分割し、ベクトル化して格納。クエリに対して類似度検索でチャンクを取得し、LLMに渡す。2026年現在、create_retrieval_chainがLangChain公式の推奨パターンだ。

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import TiDBVectorStore
from langchain.chains.retrieval import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = TiDBVectorStore(
    embedding_function=embeddings,
    connection_string=TIDB_CONNECTION,
    table_name="documents",
    distance_strategy="cosine",
)

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "以下の文脈に基づいて質問に回答せよ。文脈にない情報は「分かりません」と答えよ。\n\n{context}"),
    ("human", "{input}"),
])

combine_docs_chain = create_stuff_documents_chain(llm, prompt)
chain = create_retrieval_chain(
    vectorstore.as_retriever(search_kwargs={"k": 5}),
    combine_docs_chain,
)

response = chain.invoke({"input": "直近のチャーンレートの傾向は?"})

適するケース: FAQ対応、社内Wiki検索など質問と回答が1対1で対応する領域。ドキュメント数千件程度。PoC・初期プロトタイプ。

適さないケース: 複数ドキュメントの横断推論、曖昧・複合クエリ、回答精度へのビジネス要求が高い場合。

パターン2: Advanced RAG(検索強化型)

Basic RAGの検索精度を改善するパターン。ハイブリッド検索(ベクトル+BM25キーワード検索)にクロスエンコーダーのリランキングを組み合わせる。

from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain.retrievers import ContextualCompressionRetriever

bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 10

vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 10})

ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, vector_retriever],
    weights=[0.4, 0.6],
)

model = HuggingFaceCrossEncoder(model_name="cross-encoder/ms-marco-MiniLM-L-6-v2")
reranker = CrossEncoderReranker(model=model, top_n=5)
compression_retriever = ContextualCompressionRetriever(
    base_retriever=ensemble_retriever,
    base_compressor=reranker,
)

chain = create_retrieval_chain(compression_retriever, combine_docs_chain)

適するケース: 稼働環境で検索精度が求められるシステム。専門用語が多くベクトル検索だけでは取りこぼしが発生する領域。ドキュメント数万件規模。

適さないケース: リランキングのレイテンシー(+200-500ms)が許容できないリアルタイム用途。インフラコストを最小限に抑えたい場合。

パターン3: Agentic RAG(LangGraph型)

LLMがクエリの意図を分析し、検索戦略を自律的に決定するパターン。LangGraphのステートマシンとして実装する。LangGraphが2025年に安定版になったことで、このパターンが実用域に入った。

from langgraph.graph import StateGraph, END
from typing import TypedDict

class RAGState(TypedDict):
    query: str
    search_strategy: str
    retrieved_docs: list
    answer: str
    needs_refinement: bool

def analyze_query(state: RAGState) -> RAGState:
    # LLMにクエリ分類を依頼(省略: gpt-4o-miniでquery→strategy分類)
    state["search_strategy"] = classify_query(state["query"])
    return state

def retrieve(state: RAGState) -> RAGState:
    strategy = state["search_strategy"]
    if strategy == "multi_query":
        docs = multi_query_retrieve(state["query"], vectorstore)
    elif strategy == "decompose":
        docs = decomposed_retrieve(state["query"], vectorstore)
    else:
        docs = vectorstore.similarity_search(state["query"], k=5)
    state["retrieved_docs"] = docs
    return state

def evaluate_and_answer(state: RAGState) -> RAGState:
    # 省略: LLMで検索結果の網羅性を判定
    state["answer"] = generate_answer(state)
    state["needs_refinement"] = check_sufficiency(state)
    return state

graph = StateGraph(RAGState)
graph.add_node("analyze", analyze_query)
graph.add_node("retrieve", retrieve)
graph.add_node("answer", evaluate_and_answer)
graph.set_entry_point("analyze")
graph.add_edge("analyze", "retrieve")
graph.add_edge("retrieve", "answer")
graph.add_conditional_edges(
    "answer",
    lambda s: "retrieve" if s["needs_refinement"] else END,
)
app = graph.compile()

適するケース: 複合的な分析質問。複数データソースの横断検索。検索→評価→再検索の反復が必要な調査型タスク。

適さないケース: シンプルなFAQ(オーバーエンジニアリング)。レイテンシー制約が厳しい場合(LLM呼び出しが3-5回に増える)。LLMコストの管理が厳しい場合。

3パターンの定量比較

私たちがドキュメント数千〜数万件規模の案件で計測した実績値に基づく目安:

指標

Basic RAG

Advanced RAG

Agentic RAG

レイテンシー(P95)

1-2秒

2-4秒

5-15秒

LLM呼び出し回数/クエリ

1回

1回

3-5回

Retrieval Precision

60-70%

80-90%

85-95%

月間コスト目安(1,000クエリ/日)

$50-100

$80-150

$200-500

実装工数

1-2日

3-5日

1-2週間

※Retrieval PrecisionはRAGAS準拠の評価指標で計測。コストはGPT-4o-mini + text-embedding-3-small、2026年4月時点の価格ベース。

選定フローチャート

クエリの複雑さに応じて選択する:

  • 単純(FAQ、1対1対応) → Basic RAG
  • 中程度(専門用語多い、精度要求あり) → Advanced RAG
  • 複合的(横断検索、分析型、反復推論) → Agentic RAG

ただし、私たちのプロジェクトでは最初は必ずBasic RAGから始める。理由は3つ。

  1. ベースラインの確立。 Basic RAGの精度を測定しないと、Advanced/Agenticの改善幅を定量評価できない
  2. チャンキングとエンベディングの品質が全てに効く。 検索の土台が悪ければ、上のレイヤーで何をやっても改善幅は限定的だ
  3. コストとレイテンシーの見積もり。 最もシンプルな構成での数値がないと、稼働環境のインフラ設計ができない

ハマりどころ — 私たちの経験から

1. チャンキング戦略の過小評価

私たちの経験上、RAGの精度に最も影響が大きかったのは、LLMの性能でも検索アルゴリズムでもなく、チャンキングの品質だった。

あるプロジェクトで、一律500トークンで分割した結果、表の途中で切れる、手順の3ステップ目が別チャンクに飛ぶ、前提条件と結論が別チャンクになる問題が頻発した。セマンティックチャンキングに切り替え、メタデータ(ドキュメントタイトル、セクション見出し、作成日)をチャンクに埋め込んだところ、Retrieval Precisionが58%から82%に改善した。

2. 評価パイプラインの不在

「RAGを作った、動いた、デモで見せた、良さそうだ」で終わるプロジェクトが多い。しかし稼働環境で最も重要なのは定量的な評価パイプラインだ。

私たちはRAGAS(Retrieval Augmented Generation Assessment)をベースに、以下の3指標で評価している:

  • Retrieval Precision: 取得したチャンクのうち、回答に実際に使われた割合
  • Faithfulness: 生成された回答が、取得したチャンクの内容に忠実か
  • Answer Relevancy: 生成された回答が、元のクエリに対して的確か

これをCI/CDに組み込み、モデル変更やチャンキング変更のたびに自動実行する。評価パイプラインなしにRAGを稼働環境で運用するのは、テストなしにコードをデプロイするのと変わらない。

3. ベクトルDB選定の罠

私たちはTiDB Serverless(MySQL互換 + ベクトル検索)を採用している。選定理由は、既存のRDBワークロードとベクトル検索を同一インフラで扱えること、そしてサーバーレスのスケーリング特性だ。

選ばなかったものと、その理由:

  • Pinecone: マネージドで立ち上がりは速いが、データがベクトルDBに閉じる。RDBとのJOINが必要な業務要件では追加のデータ同期が発生する
  • pgvector: PostgreSQLエコシステムとの親和性は高いが、大規模ベクトルインデックスでの運用チューニングにコストがかかる。ただし2025年以降の改善(HNSW indexの高速化)で選択肢としての魅力は上がっている
  • Chroma: プロトタイプには最適だが、稼働環境のスケーラビリティと永続性に懸念が残る

ベクトルDB単体の性能で選ぶと、「あのデータと結合したいのにできない」問題に直面する。RDBワークロードとの共存を前提に選定すべきだ。

まだ解決できていないこと

チャンクの鮮度管理。 ドキュメントが更新されたとき、対応するチャンクのベクトルを効率的に更新する仕組みは、まだ力技に頼っている。差分更新の自動化は今後の課題だ。

マルチモーダル対応。 表や図を含むドキュメントのRAGは、テキストのみの場合と比べて精度が大きく落ちる。画像をテキストに変換してからチャンク化するアプローチを試しているが、情報の欠落が避けられない。

評価の自動化精度。 RAGAS自体がLLMに依存しているため、評価の精度にもばらつきがある。人手での抜き取り検証を定期的に行っているが、スケールしない。

まとめ

RAGの実装パターンは、ユースケースの複雑さに応じてBasic → Advanced → Agenticと段階的に選択するのが最も合理的だ。最初からAgenticに飛びつくのではなく、Basic RAGでベースラインを確立してから、必要に応じて検索の強化やエージェント化を検討する。

パターン選定よりも重要なのは、チャンキングの設計と評価パイプラインの整備だ。この2つが欠けたRAGは、デモでは動くが運用環境では壊れる。


関連記事

テーマ

記事

Semantic SIの全体像

Semantic SI完全ガイド 2026

データの前提のズレとRAG

DXの失敗は"意味のズレ"から始まる

Discovery商品化の思想

なぜ要件定義を"買う"べきなのか