大規模言語モデル(LLM)を活用したAIエージェントは、単なる一問一答のチャットボットから、外部ツールを操作し複数ステップの計画を立てて実行する自律的なシステムへと進化しています。本記事では、AIエージェントを実務で構築する際に押さえておきたい3つの柱――ツール呼び出し(Function Calling)、マルチステップ推論、エラーハンドリング――について、設計パターンとベストプラクティスを解説します。これからエージェント型アプリケーションを設計するエンジニアの参考になる内容です。

1. ツール呼び出し(Tool Calling)の設計パターン

AIエージェントの実用性は、外部APIやデータベース、計算ツールなどをどれだけ正確に呼び出せるかに大きく依存します。

1.1 スキーマ駆動のツール定義

ツールはJSON Schemaなどで入出力の型を厳密に定義し、モデルが解釈しやすい形で提供することが重要です。パラメータ名や説明文を具体的に書くことで、誤った引数生成を減らせます。

{
  "name": "search_inventory",
  "description": "商品名から在庫数を検索する",
  "parameters": {
    "type": "object",
    "properties": {
      "product_name": { "type": "string" }
    },
    "required": ["product_name"]
  }
}

1.2 ツールの粒度設計

1.3 ツール選択のガードレール

利用可能なツール数が増えると誤選択のリスクも高まります。カテゴリ分けやRAGによる動的なツール絞り込みを行い、プロンプトに含めるツール一覧を必要最小限にすることが有効です。

2. マルチステップ推論の設計パターン

複雑なタスクは単一の呼び出しでは完結しません。計画立案と実行を繰り返す構造が求められます。

2.1 ReActパターン

「Reasoning(推論)」と「Acting(行動)」を交互に行うReActパターンは、エージェントが思考過程を言語化しながらツールを呼び出す代表的な手法です。

Thought: 在庫を確認する必要がある
Action: search_inventory(product_name="ノートPC")
Observation: 在庫数は5個
Thought: 発注の必要はない
Final Answer: 在庫は十分にあります

2.2 プランナー・エグゼキューター分離

タスクが長大な場合、全体計画を立てる「プランナー」と、個々のステップを実行する「エグゼキューター」を分離する設計が有効です。プランナーがサブタスクのリストを生成し、エグゼキューターが1つずつ実行結果を報告、プランナーが再計画する流れにより、長期タスクでも一貫性を保ちやすくなります。

2.3 状態管理とメモリ

3. エラーハンドリングのベストプラクティス

エージェントは外部環境との接続が多いため、失敗を前提とした設計が不可欠です。

3.1 リトライとフォールバック

ツール呼び出し失敗時は、指数バックオフによるリトライを行い、一定回数失敗した場合は代替ツールやユーザーへの確認に切り替えるフォールバック戦略を組み込みます。

3.2 自己検証(Self-Critique)

実行結果をそのまま最終回答に使わず、モデル自身に結果の妥当性を検証させるステップを挟むことで、ハルシネーションや誤った引数によるエラーを早期に検出できます。

「この結果はユーザーの質問に対して十分か?」を自問させるプロンプトを挟むだけでも精度は大きく向上します。

3.3 エラーメッセージの構造化

ツールからのエラーは、人間可読な文章ではなく構造化された情報(エラーコード、原因、再試行可否)として返すことで、モデルが次のアクションを判断しやすくなります。

{
  "error": true,
  "code": "RATE_LIMIT",
  "retryable": true,
  "message": "APIレート制限に達しました"
}

3.4 タイムアウトとサーキットブレーカー

無限ループや長時間の処理停滞を防ぐため、ステップ数上限やタイムアウトを設定し、閾値を超えた場合は処理を中断してユーザーに状況を報告する仕組みを用意しましょう。

まとめ

AIエージェントの設計では、ツール呼び出しの正確性、マルチステップ推論の一貫性、そして失敗を前提としたエラーハンドリングの3点を統合的に設計することが成功の鍵となります。小さく始めてログを観察しながら、プロンプトとアーキテクチャの両面で改善を重ねていくことが、信頼性の高いエージェント構築への近道です。