LangChain エラー処理とデバッグ
Agent開発ではさまざまなエラーに遭遇することは避けられません。この記事では、よくあるエラーの種類、デバッグ方法、ベストプラクティスを整理します。
よくあるエラーの種類
| エラーの種類 | 典型的な原因 | 解決策 |
|---|---|---|
| ImportError | プロバイダーパッケージが未インストール | pip install langchain-deepseek など |
| APIキーエラー | .env が未設定、またはキーが無効 | 環境変数とキーの有効性を確認 |
| タイムアウトエラー | ネットワークの問題、またはモデルの応答が遅い | timeout パラメータを設定 |
| Token 上限超過 | メッセージ履歴が長すぎる | trim_messages() で切り詰める |
| ツール呼び出しエラー | ツール内部の例外 | ToolException + handle_tool_errors を使用 |
| モデルが返す形式のエラー | モデル出力が期待どおりでない | 構造化出力 + handle_errors を使用 |
ModelRetryMiddleware——モデル呼び出しのリトライ
LangChain には組み込みのリトライミドルウェアが用意されています:
例
from langchain.agents.middleware import ModelRetryMiddleware
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
# 組み込みのモデルリトライミドルウェア
# モデル呼び出し失敗時に自動リトライ
agent = create_agent(
model=init_chat_model("deepseek:deepseek-v4-flash", timeout=30, max_retries=2),
middleware=[
ModelRetryMiddleware(
max_retries=3, # 最大3回リトライ
backoff_factor=2.0, # バックオフ係数(2s, 4s, 8s)
)
],
system_prompt="あなたは初心者向けチュートリアル サンプル のアシスタントです。",
)
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
# 組み込みのモデルリトライミドルウェア
# モデル呼び出し失敗時に自動リトライ
agent = create_agent(
model=init_chat_model("deepseek:deepseek-v4-flash", timeout=30, max_retries=2),
middleware=[
ModelRetryMiddleware(
max_retries=3, # 最大3回リトライ
backoff_factor=2.0, # バックオフ係数(2s, 4s, 8s)
)
],
system_prompt="あなたは初心者向けチュートリアル サンプル のアシスタントです。",
)
ToolRetryMiddleware——ツール呼び出しのリトライ
例
from langchain.agents.middleware import ToolRetryMiddleware
agent = create_agent(
model="deepseek:deepseek-v4-flash",
tools=[my_tool],
middleware=[
ToolRetryMiddleware(
max_retries=3,
backoff_factor=1.5,
)
],
)
agent = create_agent(
model="deepseek:deepseek-v4-flash",
tools=[my_tool],
middleware=[
ToolRetryMiddleware(
max_retries=3,
backoff_factor=1.5,
)
],
)
組み込みの RetryMiddleware とカスタムの @wrap_model_call / @wrap_tool_call は共存できます。組み込みミドルウェアは middleware リストの先頭に置き、最外層の保護として機能させます。
debug=True——詳細ログ
例
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
# debug モードを有効にし、詳細な実行ログを出力
agent = create_agent(
model=init_chat_model("deepseek:deepseek-v4-flash"),
debug=True, # デバッグログを有効化
system_prompt="あなたは初心者向けチュートリアル サンプル のアシスタントです。",
)
# 実行時に出力される内容:
# - 各ノードの入力状態
# - 各ノードの出力状態
# - エッジ(edge)の遷移判定
result = agent.invoke({
"messages": [HumanMessage(content="こんにちは")]
})
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
# debug モードを有効にし、詳細な実行ログを出力
agent = create_agent(
model=init_chat_model("deepseek:deepseek-v4-flash"),
debug=True, # デバッグログを有効化
system_prompt="あなたは初心者向けチュートリアル サンプル のアシスタントです。",
)
# 実行時に出力される内容:
# - 各ノードの入力状態
# - 各ノードの出力状態
# - エッジ(edge)の遷移判定
result = agent.invoke({
"messages": [HumanMessage(content="こんにちは")]
})
debug=True の出力例:
[DEBUG] Starting graph execution
[DEBUG] Executing node: model
[DEBUG] Node 'model' input: {'messages': [HumanMessage(content='你好')]}
[DEBUG] Node 'model' output: {'messages': [AIMessage(content='你好!...')]}
[DEBUG] Edge 'model' -> '__end__': routing to __end__
[DEBUG] Graph execution complete
stream_mode="debug"——最も詳細なデバッグ情報
例
# stream_mode="debug" で最も詳細な情報を取得
for event in agent.stream(
{"messages": [HumanMessage(content="こんにちは")]},
stream_mode="debug",
):
# event には:ノード名、入力、出力、タイムスタンプ、タスク情報などが含まれます
print(f"[{event['type']}] {event.get('name', '')}")
if 'input' in event:
print(f" 入力: {event['input']}")
if 'output' in event:
print(f" 出力: {event['output']}")
for event in agent.stream(
{"messages": [HumanMessage(content="こんにちは")]},
stream_mode="debug",
):
# event には:ノード名、入力、出力、タイムスタンプ、タスク情報などが含まれます
print(f"[{event['type']}] {event.get('name', '')}")
if 'input' in event:
print(f" 入力: {event['input']}")
if 'output' in event:
print(f" 出力: {event['output']}")
よくある問題のトラブルシューティング
問題1:モデルがツールを呼び出し続けて停止しない
考えられる原因:ツールが返す情報が十分でなく、モデルがタスク完了を判断できない。解決方法:
- ツールがより明確な情報(「タスク完了」など)を返すようにする
- system_prompt に停止条件を設定する
- after_model でループ回数を確認し、しきい値を超えたら jump_to="end" を使用する
問題2:モデルが誤ったツールやパラメータを呼び出した
考えられる原因:ツールの説明が不明確。解決方法:
- ツール関数のドキュメント文字列を改善する
- args_schema を使用してパラメータ範囲を制限する
- より高性能なモデルを使用する(例:deepseek-v4-flash の代わりに deepseek-v4-pro)
問題3:会話メモリが機能しない
チェックリスト:
- checkpointer パラメータを渡していますか?
- 毎回同じ thread_id を使用していますか?
- SqliteSaver を使用する場合、データベースファイルは存在し、書き込み可能ですか?