Agentを構築する際、「エラー」は行き止まりではなく、極めて価値のある**「コンテキスト入力」です。優れたAgent設計は、エラーを自己修正の手がかり(Self-Correction Cues)**へと昇華させます。
以下に、ツール呼び出しエラーの処理、階層的な戦略策定、および複数ツールの競合解決に関するエンジニアリング手法を解説します。
1. Agentのツール呼び出しが失敗した場合の対処法(閉ループメカニズム)
従来のソフトウェア開発では、例外(Exception)が発生するとクラッシュするかログを出力して終了しますが、Agentアーキテクチャでは**「観察 – 内省 – 修正(Observe-Reflect-Correct)」の閉ループを構築する必要があります。 核心原則: エラーのトレースバック(Traceback)を「観察結果(Observation)」**としてLLMにフィードバックすること。
標準的な処理フロー
- 例外の捕捉 (Catch):
- ツール実行層(Executor)ですべての例外をキャッチし、プログラムをクラッシュさせないようにします。
- エラーの整形 (Format):
- 長大なPythonのスタックトレースを、LLMが理解できる簡潔なヒントに変換します。
- Bad:
File "/lib/python...", line 40, in ... ValueError: ... - Good:
ToolExecutionError: 引数 'date' は 'YYYY-MM-DD' 形式である必要がありますが、'tomorrow' を受け取りました。
- コンテキストへのフィードバック (Feedback):
- 上記の “Good” なエラー情報を、System Message または User Message として再度Agentに送信します。
- 再推論 (Re-reasoning):
- Agentはエラー情報を見て、自身の論理能力を使ってパラメータを修正し、新たなツール呼び出しを生成します。
2. エラータイプに応じた戦略の調整方法(階層的ガバナンス)
エラーの種類によって「処方箋」は異なります。コードレベルで Error Handler Mapping を構築し、エラータイプごとに異なるプロンプトを注入したり、異なるロジックを実行したりすることを推奨します。
| エラータイプ | 典型的なシーン | 対応戦略 (Strategy) | システムプロンプト注入例 |
| 幻覚パラメータ (Hallucinated Args) | send_email 呼び出し時に、存在しない引数 priority=high を捏造した。 | Schema強化 | ツールのJSON Schema定義を再注入し、提示する。 「パラメータ priority は無効です。Schemaで定義されたフィールドのみを使用してください。」 |
| 解析エラー (Parsing Error) | LLMが出力したJSONに括弧が足りない、またはMarkdown記号が含まれている。 | フォーマット修復 | 軽量LLM (Output Parser) を呼び出して修復させるか、提示する。 「出力をJSONとして解析できません。Markdownを含めず、厳密にJSON文字列のみを出力してください。」 |
| ロジック検証エラー (Validation Error) | 日付に「来週の水曜」と入れたが、APIは "2026-02-11" を要求している。 | ルール提示 | Pydanticのバリデーションエラーをそのまま返す。 「日付フォーマットエラー。現在時刻は X です。具体的な日付を計算してください。」 |
| 実行時エラー (Runtime Error) | APIタイムアウト、または 500エラー。 | 指数バックオフ (Exponential Backoff) | すぐにLLMに問わない。コード層で自動リトライ(1秒, 2秒, 4秒間隔)を行う。全て失敗した場合のみ、LLMに「別のツールを使って」と通知する。 |
| 空の結果 (Empty Result) | データベース検索で [] が返ってきた。 | 戦略切り替え | Agentに提示する。 「データが見つかりませんでした。検索条件を緩めるか、keyword_search ツールに切り替えて試してください。」 |
3. 複数のツールが要件を満たす場合、どう最適解を選ぶか?(ツールの曖昧性解消)
ユーザーが「A社について調べて」と言った際、手元に Google Search、internal_wiki_search、stock_api の3つのツールがあると、Agentは迷ったり、不適切なツールを選んだりしがちです。
以下は、ツール選択を最適化する3つの戦略です。
1. 記述エンジニアリング (Description Engineering) – 最も基礎的
LLMのツール選択は主に docstring(関数への注釈)に依存します。記述が重複しているとLLMは混乱します。
- Bad:
search_wiki: “情報を検索する。”google: “インターネットを検索する。”
- Good:
search_wiki: “社内規定、従業員名簿、プロジェクトドキュメントの場合にのみ使用すること。”google: “公開ニュース、競合分析、外部市場データのために使用すること。”
- テクニック: 記述の中に Negative Constraints(負の制約) を含め、「いつこのツールを使ってはいけないか」を明示します。
2. ルーティング層 (The Router Pattern) – より高精度
Agentが具体的なタスクを実行する前に、専用の Router Chain(分類器) を挟みます。
- 原理: まず高速なプロンプトでユーザーの意図を分類します。
- Prompt: 「ユーザーの質問は以下のどのカテゴリに属しますか?[社内知識, 外部ニュース, 株価データ]。カテゴリ名のみを返してください。」
- ロジック:
- もし「社内知識」なら -> Agentには
internal_wiki_searchのみをマウントする。 - もし「外部ニュース」なら -> Agentには
Google Searchのみをマウントする。
- もし「社内知識」なら -> Agentには
- メリット: Agentの選択肢を絞り込むことで、幻覚(Hallucination)の確率を劇的に下げることができます。
3. コストとパフォーマンスの優先順位 (Cost/Latency Priority)
複数のツールで解決可能(例:どちらも検索機能を持っている)な場合、メタデータに基づいてコードレベルで優先順位をハードコーディングします。
- 戦略: **「より速く、より安く、より信頼できる」**ツールを優先的に使用します。
- ロジック例(擬似コード)
l
def select_best_tool(tools, query):
# 1. まずローカルキャッシュ/DBを試す (Cost: 0, Latency: low)
if local_db.has_data(query):
return local_db_tool
# 2. 次に社内APIを試す (Cost: low)
elif is_internal_query(query):
return internal_api_tool
# 3. 最後に高価な外部検索をフォールバックとして使う (Cost: high)
else:
return google_search_tool
まとめと推奨事項
- 耐障害性(Fault Tolerance):
- 例外を握りつぶさない(Never swallow exceptions)でください。Pythonのエラーを**「自然言語」**に翻訳し、Agentにフィードバックしましょう。
- 戦略の使い分け:
- 「システムダウン(リトライすべき)」と「Agentのミス(修正指示すべき)」を明確に区別しましょう。
- 選択の最適化:
- Agentに10個のツールから当てずっぽうに選ばせるよりも、まずRouterで2個に絞り込んでから選ばせる方が、賢明で確実です。