AIコーディング 2026.05.16

LangChain×ChromaDB×FAISSエラー解決|ImportError・メモリ不足・デプロイ失敗の原因と対策

タグ:LangChain / ChromaDB / RAG / エラー対処 / ベクトルDB

LangChainのRetrievalQA廃止問題とは

AIコーディングツール(Claude Code・ChatGPT・Cursor)が生成したコードで、以下のエラーが発生することが多くなっています。

ImportError: cannot import name 'RetrievalQA' from 'langchain.chains'

このエラーは、LangChainのバージョンアップに伴い、RetrievalQAクラスが廃止されたことが原因です。特にAIが生成したコードは古い情報に基づいていることが多いため、このエラーは月に数百件の検索ボリュームがあり、開発が一時停止する深刻な問題となっています。

本記事では、このエラーが発生する正確な原因、そして2026年時点での推奨される代替実装方法をステップバイステップで解説します。


1. RetrievalQAのImportError:バージョン互換性の問題

症状

ImportError: cannot import name 'RetrievalQA' from 'langchain.chains' in Python project

または

ModuleNotFoundError: No module named 'langchain_community'

または

DeprecationWarning: RetrievalQA is deprecated

このエラーは、LangChainのバージョンアップデートでRetrievalQAが廃止されたり、パッケージ構成が変わったときに発生します。月間800回以上の検索需要があることから、移行に困るエンジニアが多いのが現状です。

RetrievalQAが廃止された理由

LangChainのlangchain.chainsモジュールに含まれていたRetrievalQAクラスは、LangChain 0.2.0以降で削除されました。廃止された理由は以下のとおりです。

  • 柔軟性の低さ: 固定的なチェーン構造で、カスタマイズが難しい
  • メンテナンスの負担: 複数のバリエーション(RetrievalQA、RetrievalQAWithSourcesAnswerなど)の維持が困難
  • モダン設計への移行: LangChainがLCEL(LangChain Expression Language)に統一するため

LCELを使うことでより柔軟で拡張可能なRAGパイプラインを構築できるようになり、ベクトルデータベース検索、LLMへのプロンプト送信、出力の解析が細かく制御できるようになります。

すなわちLangChainが「魔法のようなラッパークラス」よりも「明示的で組み立て可能なコンポーネント」を重視する設計方針に変わったためでもあります。これにより開発者はRAGパイプラインの各ステップを詳細に制御でき、デバッグや機能追加が容易になりました。

現在、RetrievalQAを使用するコードは以下のようなエラーで失敗します:

from langchain.chains import RetrievalQA
# ImportError: cannot import name 'RetrievalQA' from 'langchain.chains'

このエラーで何が起きているか

LangChainは2023年以降、大きなアーキテクチャ変更を実施しました。過去は単一のlangchainパッケージにすべての機能が含まれていましたが、現在は以下のように分割されています。

  • langchain: コア機能のみ
  • langchain-community: 外部APIやツール統合
  • langchain-openai: OpenAI特化機能
  • langchain-anthropic: Anthropic(Claude)特化機能

これまでのコード(古いバージョン向けに書かれたコード)をそのまま実行しようとすると、分割されたモジュールが見つからず、このエラーが発生します。

想定される原因

LangChainは頻繁にAPIを変更しており、古いドキュメントやサンプルコードの多くは現在の最新バージョンに対応していません。特に0.2.0以降のバージョンでは、チェーン周りの大規模なリファクタリングが行われています。コードが古いバージョンを想定しているか、依存関係の競合が生じている可能性があります。

廃止された理由は具体的には以下の3点です:

  1. モジュール再編langchain.chainsからRetrievalQAが削除された
  2. LCELへの統合:単純なクラスベースから、より表現力のあるLCELベースの設計に変更
  3. 柔軟性の向上:従来はchain_typeで限定的な選択肢のみだったが、LCELではカスタム処理が容易に

現在のLangChain体系

2024年以降、LangChainは以下の3層構造になっています。

パッケージ役割インポート例
langchain-core基本インターフェース、ベースクラスfrom langchain_core.language_models import LLM
langchain-community統合機能(Vector DB、LLM、ツール)from langchain_community.vectorstores import Chroma
langchainワークフロー、チェーン、エージェントfrom langchain.chains import create_retrieval_chain

RetrievalQAはこの再編で廃止され、新しいチェーン実装パターンに置き換わりました。

前提環境・必要なもの

  • Python 3.9以上(3.8以上でも動作するが3.9以上を推奨)
  • LangChain 0.2.0以降(推奨:0.2.0以上)
  • OpenAI APIキー(またはほかのLLM)
  • ベクトル化機能(OpenAI Embeddings、Hugging Face Embeddings など)
  • ベクトルデータベース(FAISS、Chroma、Weaviateなど)

以下のコマンドでLangChainと依存パッケージをインストールしてください:

pip install langchain langchain-core langchain-community langchain-openai faiss-cpu python-dotenv

注記: langchain-communitylangchain-openaiは独立したパッケージとなりました。別途インストールが必要です。

切り分け手順

  1. インストール済みのLangChainバージョンを確認する

    pip show langchain
    pip show langchain-community
    
  2. 利用可能なクラスを確認する

    import langchain.chains
    print(dir(langchain.chains))
    
  3. 別の場所からインポートされていないか確認

    # LangChainの新バージョンでの正しいインポート方法を試す
    from langchain_core.runnables import RunnablePassthrough
    from langchain.chains import create_retrieval_chain
    

エラーメッセージ別の原因と解決策

ModuleNotFoundError: No module named ‘langchain_community’

原因:langchain-communityパッケージをインストールしていない

LangChain 0.2以降、機能がモジュール分割され、langchain_communityがメインパッケージに含まれなくなりました。最も一般的な原因です。

確認手順

現在インストールされているLangChain関連パッケージを確認します。

pip list | grep langchain

出力例(エラーが発生する状態):

langchain               0.2.0

出力例(正常な状態):

langchain               0.2.0
langchain-community    0.2.0

解決策

pip install langchain-community

なお、pipでインストールする際はハイフン(langchain-community)を使いますが、Pythonのコード内でインポートする際はアンダースコア(langchain_community)を使う点に注意してください。

文脈表記
pipコマンドpip install langchain-community
Pythonコードfrom langchain_community import ...

ImportError: cannot import name ‘RetrievalQA’

原因:廃止されたRetrievalQAクラスを直接インポートしようとしている

従来の間違った書き方

from langchain.chains import RetrievalQA  # ❌ これは動作しません

新しい正しい書き方

from langchain.chains import create_retrieval_chain  # ✅ 2024年以降推奨
from langchain.chains.combine_documents import create_stuff_documents_chain

古いコードパターンのインポート方法変更についても注意が必要です。

古いコード(LangChain 0.0.x向け)

from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter

新しいコード(LangChain 0.2以降向け)

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter

TypeError: issubclass() arg 1 must be a class

原因:新旧のLangChainバージョンが混在している、またはimportの順序が不適切

LangChainとlangchain_communityのバージョンが一致していない場合にも発生します。LangChainの公式ドキュメントでは、バージョン0.2以降、両パッケージのメジャーバージョンを統一することが推奨されています。

解決策

pip uninstall langchain langchain-community -y
pip install --upgrade langchain langchain-community langchain-core

または、特定のバージョンを指定してインストールします。

pip install langchain==0.2.5 langchain-community==0.2.5

ERROR: pip’s dependency resolver does not currently take into account…

原因:バージョン間の依存関係に不整合がある

解決策

pip install --upgrade --force-reinstall langchain langchain-community

対処方法(優先度順)

1. LCELによる新しい実装に移行する(推奨)

最新のLangChainでは、LangChain Expression Language(LCEL)を使ったパイプライン構築が標準です。以下が基本的なパターンです:

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 1. 文書をロードしてベクトル化
loader = TextLoader("document.txt")
docs = loader.load()

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.from_documents(splits, embeddings)

# 2. Retrieverを作成(上位4件を返す)
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# 3. ドキュメントのフォーマット関数
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# 4. プロンプトテンプレート定義
template = """以下の文脈を踏まえて質問に答えてください:

{context}

質問: {question}
答え:"""

prompt = ChatPromptTemplate.from_template(template)

# 5. LLMを定義
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# 6. チェーン構築(LCEL)
chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 7. 実行
result = chain.invoke("質問内容ここに入力")
print(result)

重要なポイントは以下の通りです:

  • retriever = vectorstore.as_retriever() でRetrieverオブジェクトを作成
  • | パイプ演算子でコンポーネントを連結
  • RunnablePassthrough() で質問を次のステップに受け渡す
  • 各ステップが明示的で、途中で加工や条件分岐を追加するのが容易

また、精度向上のためにベクトル検索とフルテキスト検索を組み合わせる方法も有効です:

from langchain.retrievers import BM25Retriever  # フルテキスト検索
from langchain.retrievers import EnsembleRetriever

# ベクトル検索用
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# フルテキスト検索用(BM25アルゴリズム)
bm25_retriever = BM25Retriever.from_documents(docs)
bm25_retriever.k = 4

# 両者を結合(重み付け可能)
ensemble_retriever = EnsembleRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    weights=[0.7, 0.3]  # ベクトル検索を70%、フルテキスト30%
)

# LCELチェーンに統合
chain = (
    {"context": ensemble_retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

この併用手法では、ベクトル検索が意味的な関連性の高い文書を取得し、BM25がキーワード一致による確実な取得を担うことで、漏れ落としを削減し回答品質を向上させられます。

2. ソースドキュメントを含めた実装

旧バージョンのRetrievalQAではreturn_source_documents=Trueオプションで参考文献を返していました。新しい方式ではRunnableParallelを使って明示的に指定します:

from langchain_core.runnables import RunnableParallel

# チェーン構築(出力にソースドキュメント含む)
rag_chain = RunnableParallel(
    {"response": chain, "source_documents": retriever}
)

result = rag_chain.invoke("質問内容")
print("回答:", result["response"])
print("参考文献:")
for doc in result["source_documents"]:
    print(f"  - {doc.metadata.get('source', 'Unknown')}: {doc.page_content[:100]}...")

さらに、クラスベースで回答とソースを両方返す実装も可能です:

class RAGWithSources:
    def __init__(self, retriever, llm, prompt):
        self.retriever = retriever
        self.llm = llm
        self.prompt = prompt
    
    def invoke(self, query):
        # 関連ドキュメント取得
        docs = self.retriever.get_relevant_documents(query)
        
        # 回答生成
        context = format_docs(docs)
        response = self.prompt.format_prompt(
            context=context,
            question=query
        )
        answer = self.llm.invoke(response).content
        
        # 回答とソースを返す
        return {
            "answer": answer,
            "sources": [{"content": doc.page_content, "metadata": doc.metadata} for doc in docs]
        }

# 使用例
rag = RAGWithSources(retriever, llm, prompt)
result = rag.invoke("質問文")
print(result["answer"])
print(result["sources"])

3. create_retrieval_chainを使う方法

from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("""以下の文脈を使って質問に答えてください。

<context>
{context}
</context>

質問: {input}""")

document_chain = create_stuff_documents_chain(llm, prompt)
retrieval_chain = create_retrieval_chain(retriever, document_chain)

result = retrieval_chain.invoke({"input": "What is LangChain?"})
print(result["answer"])

4. 依存関係を明確にする

requirements.txtで明示的にバージョンを指定してください。複数のパッケージが異なるLangChainバージョンに依存していることが原因になることがあります:

langchain==0.2.5
langchain-core==0.2.5
langchain-community==0.2.5
langchain-openai==0.1.6

モジュールのインポート先が変わっている点にも注意してください:

旧バージョン新バージョン
from langchain import OpenAIfrom langchain_openai import OpenAI
from langchain.embeddings import OpenAIEmbeddingsfrom langchain_openai import OpenAIEmbeddings
from langchain.vectorstores import Chromafrom langchain_community.vectorstores import Chroma
from langchain.document_loaders import TextLoaderfrom langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitterfrom langchain_text_splitters import CharacterTextSplitter
from langchain.chains import RetrievalQALCELで直接構築(インポート不要)

5. 仮想環境を再構築する

複数のプロジェクトがあり、仮想環境を使い分けている場合、別の仮想環境にインストールされたパッケージを参照している可能性があります。正しい仮想環境をアクティブにしてからインストールを実行してください。

python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install --upgrade langchain langchain-openai langchain-community

動作確認として、以下のテストスクリプトを実行するとよいでしょう。

# test_langchain.py
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter

print("✓ langchain_community インポート成功")
print("✓ langchain_text_splitters インポート成功")
print("LangChain セットアップ完了")

旧コードの移行チェックリスト

既存のRetrievalQAを使ったコードを新しい方式に移行する場合、以下を確認してください:

項目旧パターン(RetrievalQA)新パターン(create_retrieval_chain)移行済み
インポートfrom langchain.chains import RetrievalQAfrom langchain.chains import create_retrieval_chain
チェーン構築qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)chain = create_retrieval_chain(retriever, combine_chain)
プロンプト設定chain_type_kwargs={"prompt": ...} で指定ChatPromptTemplate.from_template() で明示的に指定
実行方法qa({"query": "..."})chain.invoke({"input": "..."})
出力の取り出しresult["result"]result["answer"]

また、以下のポイントも合わせて確認してください:

  • LangChainバージョンが0.2以降であるか確認
  • from langchain.chains import RetrievalQA を削除
  • 各モジュールのインポート先を新体系に変更
  • Retriever、プロンプト、LLMを分離して定義
  • LCELのパイプ演算子で連結
  • テンプレート変数({context}など)をプロンプトに明示
  • ソースドキュメントが必要な場合はRunnableParallelまたはRAGWithSourcesクラスを使用
  • チャット履歴が必要な場合はメモリコンポーネントを追加

つまずきやすいポイントと解決策

OpenAI APIキーが設定されていない

エラーメッセージ:

openai.error.AuthenticationError: Incorrect API key provided

解決方法:

OpenAI APIキーを環境変数に設定します。

export OPENAI_API_KEY="sk-..."  # Macの場合
set OPENAI_API_KEY=sk-...       # Windowsの場合

Pythonコード内での設定:

import os
os.environ["OPENAI_API_KEY"] = "sk-..."

ベクトル化に失敗する(RateLimitError)

エラーメッセージ:

openai.error.RateLimitError: Rate limit exceeded

APIのレート制限に達しています。以下の対処をします。

import time
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()
# 少量ずつ処理
for doc in docs:
    embedding = embeddings.embed_query(doc.page_content)
    time.sleep(0.5)  # 0.5秒待機

オープンソースの埋め込みモデルを使う方法も有効です:

from langchain_community.embeddings import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# APIキー不要で、ローカルで実行可能

ベクトルストアが見つからないエラー

ValueError: Could not construct vectorstore from the search_index_args

このエラーは、ベクトルストアが正しく初期化されていない場合に発生します。解決策:

# インデックスをローカルに保存・読み込む
vectorstore = FAISS.load_local(
    "vectorstore_index",
    embeddings,
    allow_dangerous_deserialization=True
)

# または、新規作成する場合は必ずドキュメントを先に準備
if not os.path.exists("vectorstore_index"):
    vectorstore = FAISS.from_documents(docs, embeddings)
    vectorstore.save_local("vectorstore_index")

レトリーバーが関連ドキュメントを返さない

精度が低い場合は、以下を試してください:

# 検索結果を確認
query = "LangChainについて説明してください"
retrieved_docs = retriever.invoke(query)
for doc in retrieved_docs:
    print(doc.page_content)

# 検索数を増やす
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 8}  # デフォルトの4から8に
)

# MMRによる多様性を確保した検索
retriever = vectorstore.as_retriever(
    search_type="mmr",  # Maximum Marginal Relevance
    search_kwargs={"k": 4, "fetch_k": 20}
)

# さらに、チャンキングサイズを調整
splitter = CharacterTextSplitter(
    chunk_size=500,  # より小さく
    chunk_overlap=100
)

出力が長すぎる、または不要な詳細を含む

プロンプトテンプレートで出力形式を指定することで対処できます:

template = """以下の文脈を使って質問に答えてください。
簡潔に、200字以内で答えてください。

文脈:
{context}

質問:{question}

答え:"""

requirements.txt 内のバージョン指定が古い

チーム開発時に、requirements.txt に古いバージョンが固定されていないか確認します。

cat requirements.txt

以下のような指定がある場合は更新が必要です。

# 古い指定例
langchain==0.0.352

新しいバージョンに更新します。

langchain==0.2.5
langchain-community==0.2.5

または、最新版を自動選択させる場合:

langchain>=0.1.0
langchain-community>=0.1.0

それでも解決しないとき

  • LangChainのGitHubリポジトリでIssueを検索し、同じエラーが報告されていないか確認してください
  • ドキュメントのバージョンセレクタで、インストール済みバージョンに合わせた説明を読む(公式ドキュメント: https://python.langchain.com)
  • Stack Overflowで見つけた解決策は、回答の投稿日を確認(2024年以降の情報が目安)し、LangChainの公式ドキュメントと比較確認してください
  • 最後の手段として、古いバージョンをピン留めするのではなく、コードを新しいAPIに合わせることを強くお勧めします

2. RAGでのチャット履歴の不具合:メモリ管理とコンテキスト

症状

会話をしているのに、前のメッセージの内容を認識していない
新しい質問をするたびに、チャット履歴が失われたように見える

RAGシステムでは、会話を続けるのに必要なメモリ(チャット履歴)の管理が重要です。

想定される原因

RetrievalQAの基本形は単一の質問に対する回答を返すだけで、デフォルトではチャット履歴を保持しません。会話の文脈を保つには、明示的にメモリコンポーネントを追加する必要があります。また、単純にチャット履歴をプロンプトに追加するだけでは、RAG検索の精度が低下するという問題があります。前の質問との関連性を考慮しない検索が行われるためで、質問の前処理(Question Reformulation)が必要になります。

切り分け手順

  1. 現在のメモリ設定を確認する

    # ConversationalRetrievalChainを使っているか?
    # 明示的なメモリオブジェクトは設定されているか?
    print(chain.memory)  # Noneなら未設定
    
  2. プロンプトテンプレートの内容を確認する

    print(chain.llm_chain.prompt.template)
    # chat_historyや{history}が含まれているか?
    
  3. テスト実行してログを見る

    # 2つの会話を順番に実行し、2番目の回答に1番目の文脈が反映されているか確認
    result1 = chain({"question": "私の名前はTaroです"})
    result2 = chain({"question": "私の名前は?"})
    print(result2["answer"])  # "Taro"と回答するか?
    

対処方法(優先度順)

1. LCE


あわせて読みたい

参考ソース