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="あなたは初心者向けチュートリアル サンプル のアシスタントです。",
)

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,
        )
    ],
)

組み込みの 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="こんにちは")]
})

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']}")

よくある問題のトラブルシューティング

問題1:モデルがツールを呼び出し続けて停止しない

考えられる原因:ツールが返す情報が十分でなく、モデルがタスク完了を判断できない。解決方法:

  • ツールがより明確な情報(「タスク完了」など)を返すようにする
  • system_prompt に停止条件を設定する
  • after_model でループ回数を確認し、しきい値を超えたら jump_to="end" を使用する

問題2:モデルが誤ったツールやパラメータを呼び出した

考えられる原因:ツールの説明が不明確。解決方法:

  • ツール関数のドキュメント文字列を改善する
  • args_schema を使用してパラメータ範囲を制限する
  • より高性能なモデルを使用する(例:deepseek-v4-flash の代わりに deepseek-v4-pro)

問題3:会話メモリが機能しない

チェックリスト:

  • checkpointer パラメータを渡していますか?
  • 毎回同じ thread_id を使用していますか?
  • SqliteSaver を使用する場合、データベースファイルは存在し、書き込み可能ですか?
その他の拡張