❌ 問題症状
LangChain Agentを実行すると以下のエラーが発生:
ValueError: Could not parse LLM output: `Assistant, how can I help you today?`
- 非OpenAIモデル(Flan-T5、Bloomなど)使用時に頻発
- GPT-3.5-turboでも発生することがある
- GitHub Issue: 124👍 | 82💬 - LangChainで最も議論されたエラー
- エラーが出ても実際には正しいレスポンスが生成されている
🔍 問題の背景:なぜこのエラーが発生するのか
1. LangChain Agentが期待する出力フォーマット
LangChain の conversational-react-description Agentは、LLMに対して以下の形式での出力を期待しています:
Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [tool_names]
Action Input: the input to the action
Observation: the result of the action
Thought: Do I need to use a tool? No
AI: [your response here]
2. 非OpenAIモデルが失敗する理由
💡 核心的な違い
- Flan-T5やBloom:言語モデリング用に学習されている(指令追従能力が低い)
- GPT-3.5/GPT-4:指令追従(Instruction Following)に特化して微調整されている
- 非OpenAIモデルは期待される形式で出力を生成できず、パース処理が失敗する
3. エラー発生のメカニズム
LangChainの内部処理:
- LLMに対してプロンプトを送信
- LLMが応答を返す(例:
"Assistant, how can I help you today?") - Agentが応答から
"Action:"または"AI:"を探す - どちらも見つからない → ValueError が発生
# LangChain内部のパース処理(簡略版)
if "Action:" in llm_output:
# ツールを使用するケース
action = extract_action(llm_output)
elif "AI:" in llm_output:
# 直接応答するケース
return extract_response(llm_output)
else:
# どちらも見つからない
raise ValueError(f"Could not parse LLM output: `{llm_output}`")
✅ 解決策一覧
💡 推奨度別の対処法
| 方法 | 推奨度 | 難易度 | 適用ケース |
|---|---|---|---|
| ① OpenAI系モデル使用 | ⭐⭐⭐⭐⭐ | 簡単 | 本番環境 |
| ② try-except で処理 | ⭐⭐⭐ | 簡単 | 応急処置 |
| ③ カスタムOutputParser | ⭐⭐⭐⭐ | 中級 | 非OpenAIモデル使用時 |
| ④ リトライ機構 | ⭐⭐⭐⭐ | 中級 | 信頼性向上 |
| ⑤ Few-shot プロンプト | ⭐⭐⭐ | 中級 | 非OpenAIモデル最適化 |
📋 解決策① OpenAI系モデルの使用(最も確実)
最もシンプルで確実な解決方法は、指令追従に特化したモデルを使用することです。
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.agents import initialize_agent
from langchain.memory import ConversationBufferMemory
# ❌ 問題が発生するコード
llm = HuggingFaceHub(repo_id="google/flan-t5-xl")
# ✅ 解決策:OpenAI系モデルを使用
llm = ChatOpenAI(
model_name="gpt-3.5-turbo", # または gpt-4
temperature=0
)
agent = initialize_agent(
tools=tools,
llm=llm,
agent="conversational-react-description",
memory=ConversationBufferMemory(memory_key="chat_history"),
verbose=True
)
💰 コスト最適化のヒント
gpt-3.5-turbo: 高速・低コスト(推奨)gpt-4: 高精度だがコスト高gpt-4o-mini: 2026年新モデル、コストパフォーマンス最高
📋 解決策② try-except で応答を抽出(応急処置)
エラーメッセージ内に実際の応答が含まれているため、それを抽出する方法:
try:
response = agent_chain.run(input=query)
except ValueError as e:
response = str(e)
if not response.startswith("Could not parse LLM output: `"):
raise e # 別のエラーの場合は再度raise
# エラーメッセージから実際の応答を抽出
response = response.removeprefix("Could not parse LLM output: `").removesuffix("`")
print(response) # "Assistant, how can I help you today?"
⚠️ 注意:この方法は一時的な対処法です。本番環境では他の解決策を強く推奨します。
📋 解決策③ カスタムOutputParserの実装
独自のパーサーを実装することで、様々な出力形式に対応できます:
import re
from langchain.schema import BaseOutputParser
from typing import Any
class FlexibleAgentOutputParser(BaseOutputParser):
"""柔軟な出力形式に対応するカスタムパーサー"""
def get_format_instructions(self) -> str:
return """Output format:
{
"action": "tool_name",
"action_input": "input_for_tool"
}
OR
{
"final_answer": "your response"
}"""
def parse(self, text: str) -> Any:
cleaned_output = text.strip()
# JSON形式を試みる
action_pattern = r'"action":\s*"([^"]*)"'
action_input_pattern = r'"action_input":\s*"([^"]*)"'
action_match = re.search(action_pattern, cleaned_output)
action_input_match = re.search(action_input_pattern, cleaned_output)
if action_match and action_input_match:
return {
"action": action_match.group(1),
"action_input": action_input_match.group(1)
}
# final_answerを試みる
final_answer_pattern = r'"final_answer":\s*"([^"]*)"'
final_answer_match = re.search(final_answer_pattern, cleaned_output)
if final_answer_match:
return {"output": final_answer_match.group(1)}
# フォールバック:テキスト全体を返す
return {"output": cleaned_output}
# 使用例
from langchain.agents import AgentExecutor, LLMSingleActionAgent
output_parser = FlexibleAgentOutputParser()
# Agentにカスタムパーサーを設定
agent = LLMSingleActionAgent(
llm_chain=llm_chain,
output_parser=output_parser,
stop=["\nObservation:"],
allowed_tools=[tool.name for tool in tools]
)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
verbose=True
)
📋 解決策④ リトライ機構の実装
パースエラー時にLLMを再呼び出しする方法:
from langchain.callbacks.base import BaseCallbackHandler
class RetryOnParseErrorCallback(BaseCallbackHandler):
"""パースエラー時に再試行するコールバック"""
def __init__(self, max_retries=3):
self.max_retries = max_retries
self.retry_count = 0
def on_agent_action(self, action, **kwargs):
self.retry_count = 0 # 成功時にリセット
def on_tool_error(self, error, **kwargs):
if "Could not parse LLM output" in str(error):
if self.retry_count < self.max_retries:
self.retry_count += 1
print(f"⚠️ パースエラー検出。リトライ {self.retry_count}/{self.max_retries}")
return True # リトライ
else:
print(f"❌ 最大リトライ回数に達しました")
raise error
raise error
# 使用例
callback = RetryOnParseErrorCallback(max_retries=3)
agent = initialize_agent(
tools=tools,
llm=llm,
agent="conversational-react-description",
callbacks=[callback],
verbose=True
)
📋 解決策⑤ Few-shot プロンプトの最適化
非OpenAIモデルに正しい出力形式を学習させる方法:
from langchain.prompts import PromptTemplate
# Few-shot 例を含むプロンプトテンプレート
few_shot_template = """You are a helpful AI assistant.
When you need to use a tool, respond in this exact format:
Example 1:
Human: What's the weather today?
Thought: I need to use the weather tool
Action: get_weather
Action Input: today
Example 2:
Human: Hello!
Thought: This is a greeting, no tool needed
AI: Hello! How can I help you today?
Now, respond to the following:
Human: {input}
"""
prompt = PromptTemplate(
input_variables=["input"],
template=few_shot_template
)
llm_chain = LLMChain(llm=llm, prompt=prompt)
📊 各解決策の比較
| 解決策 | 成功率 | 実装工数 | ランニングコスト |
|---|---|---|---|
| ① OpenAIモデル | 95-99% | 5分 | 中〜高 |
| ② try-except | 60-70% | 5分 | 変動なし |
| ③ カスタムParser | 80-90% | 2-4時間 | 変動なし |
| ④ リトライ機構 | 85-95% | 1-2時間 | やや増加 |
| ⑤ Few-shot | 70-80% | 30分-1時間 | 変動なし |
🎓 まとめ
✅ 推奨アプローチ
本番環境の場合:
- 第一選択:OpenAIモデル(gpt-4o-mini または gpt-3.5-turbo)を使用
- 信頼性向上:リトライ機構を併用
- コスト削減が必須:カスタムOutputParser + 非OpenAIモデル
開発・テスト環境の場合:
- try-except で応急処置しつつ、他の解決策を検討
- Few-shot プロンプトで非OpenAIモデルの挙動を改善
🔗 参考リンク
- GitHub Issue #1358 - Could not parse LLM output (124👍)
- LangChain 公式ドキュメント - Agents
- LangChain Output Parsers ガイド
💡 この記事が役立ちましたか?
AI実装解決ナビでは、LangChain、Dify、AutoGPTなどAIエージェント開発の最新情報と実践的な解決策を発信しています。