AIエージェント活用実践編 / 単一エージェント実装 — ReAct ループの基本
エラー時の回復処理
無料公開レッスン / 読了目安 8 分
レッスン: エラー時の回復処理
学習のねらい
LLMエージェントは外部ツールの失敗や予期せぬ応答に直面することがあります。本レッスンでは、エラー発生時にエージェントが適切に対応し、タスクを中断したり回復を試みたりする仕組みを学びます。具体的には、ツール実行失敗時のリトライ、無限ループを防ぐ早期停止、ユーザーへの再質問について解説します。
ツール実行失敗時のリトライ
外部ツールは、ネットワーク問題、API障害、LLMが生成した引数の誤りなど、様々な理由で失敗します。このような場合、すぐに諦めるのではなく、リトライ (Retry) を試みることで回復できる可能性があります。
- リトライの戦略:
- 回数制限: 無限リトライを防ぐため、最大リトライ回数を設定します(例: 3回)。
- 指数バックオフ (Exponential Backoff): リトライ間隔を徐々に長くすることで、ツールやネットワークへの負荷を軽減し、回復のチャンスを増やします(例: 1秒後、3秒後、9秒後…)。
- エラー内容の分析: エラーメッセージをLLMにObservationとして渡し、LLM自身に原因を推論させ、引数を修正してリトライさせることも有効です。
リトライは一時的な問題に対応する重要な戦略ですが、永続的なエラーには効果が薄いため、適切な回数と戦略を設定することが重要です。
ループ無限化を防ぐ early stop
ReActループは、タスクが完了しない場合に無限にThought-Action-Observationを繰り返す可能性があります。これはコスト増大やリソース消費、ユーザーを待たせる原因となるため、早期停止 (Early Stop) の仕組みを導入します。
max_iterations(最大繰り返し回数): 最も基本的な早期停止の仕組みです。設定した回数を超えたら強制的にループを終了させます。- 時間制限: タスクにかけられる最大実行時間を設定し、その時間を超えたらループを終了させます。
- 進捗の停滞: エージェントが一定回数以上同じThoughtを繰り返している、または同じObservationを受け取っているなど、進捗が見られない場合にループを終了させます。
早期停止の条件に達した場合、エージェントはこれまでの作業を破棄するか、途中までの結果を報告するか、ユーザーに再質問するなどの次のアクションを検討します。
ユーザーに再質問する条件
エージェントがタスクを解決できない、または追加情報が必要な場合に、ユーザーに再質問することは、エージェントの有用性を高める重要な回復処理です。
- 再質問のトリガー:
- 情報不足: ツール実行に必要な引数がプロンプトから読み取れない場合。
- 曖昧な指示: ユーザーの指示が曖昧で、複数の解釈が可能な場合。
- ツール実行の失敗と回復不能: リトライを試みたが、すべて失敗し、これ以上進めない場合。
ユーザーに再質問する際は、単に「分かりません」と伝えるのではなく、何が分からないのか、どのような情報が必要なのか を具体的に伝えることが重要です。例えば、「どの都市の天気予報を知りたいですか?」や「『影響』とは、経済的な影響のことですか、それとも社会的な影響のことですか?」のように、ユーザーが回答しやすいように促しましょう。
エラーハンドリングの実装パターン
これらの回復処理は、コード上で以下のようなパターンで実装されることが多いです。
def run_agent_loop(max_iterations=5):
current_iteration = 0
while current_iteration < max_iterations:
try:
thought, action = llm_call(current_context)
if action.is_final_answer:
return action.answer
observation = None
for retry_count in range(MAX_TOOL_RETRY):
try:
observation = execute_tool(action.tool_name, action.tool_args)
break # 成功したらリトライループを抜ける
except ToolExecutionError as e:
print(f"Tool execution failed: {e}. Retrying...")
time.sleep(2 ** retry_count) # 指数バックオフ
if observation is None:
# リトライしても失敗した場合
print("Tool execution failed permanently. Asking user for clarification.")
return ask_user_for_clarification(current_context)
current_context.add(thought, action, observation)
current_iteration += 1
except Exception as e:
print(f"An unexpected error occurred: {e}. Stopping agent.")
return handle_unexpected_error(e)
print("Max iterations reached. Stopping agent.")
return report_partial_results(current_context)
このコード例は、max_iterations によるループ制御、try-except ブロックでのツール実行エラーハンドリング、そしてリトライロジックの概念を示しています。
まとめ
堅牢なLLMエージェントを構築するには、エラー時の回復処理が不可欠です。ツール実行失敗時にはリトライ戦略を導入し、max_iterations や時間制限で無限ループを防ぐ早期停止を実装しましょう。また、タスクを解決できない場合には、ユーザーに具体的で分かりやすい再質問をすることで、エージェントの有用性を高めることができます。