AIエージェントオーケストレーションのベストプラクティス:障害、承認、リトライへの対処

このガイドでは、AIエージェントオーケストレーションの仕組みを解説し、集中型、分散型、階層型のアーキテクチャを比較したうえで、本番環境で障害、承認、リトライに対処するための7つのベストプラクティスを紹介します。

Diagram of AI agent orchestration: a user's multi-step goal goes to an orchestrator, which routes work to agents, models, and tools to produce a final output, while breaking down tasks, tracking dependencies, delegating execution, managing shared context, and combining outputs.

複数のエージェントが同じプロジェクトに取り組むのは、非常に効率的に聞こえます。1つが作業を計画し、別の1つがデザインを担当し、3つ目がコードを書く。ただし、それはうまくいっている間だけの話です。そして、失敗は思っている以上に頻繁に起こります。

こうした失敗を防ぐには、慎重なワークフロー設計が必要です。そこで、オーケストレーションされたワークフローが不安定になる原因を掘り下げ、本番環境での信頼性を高めるオーケストレーションのベストプラクティスを探っていきましょう。

AI エージェントオーケストレーションとは?

AI エージェントオーケストレーションは、複数の AI エージェント、モデル、ツールを連携させて、複数ステップのタスクを完了させる仕組みです。しかし、どのエージェントを最初に実行するか、どの情報を渡すか、完了後に何が起こるかは、誰か、あるいは何かが決める必要があります。これがオーケストレーターの役割です。オーケストレーターとは、マネージャーとして機能する AI エージェント、またはソフトウェアで制御される実行レイヤーのことです。

簡単に言えば、オーケストレーションレイヤーは目標を小さなタスクに分解し、依存関係を追跡し、適切なエージェントに実行を委任し、共有コンテキストを管理し、出力をまとめ上げます。

AI エージェントオーケストレーションの仕組み:実行エンジンの内部

オーケストレーターにタスクを与えた後に何が起こるのかを見てみましょう。

Perplexity の Computer ワークショップの例を考えてみましょう。Salesforce、Snowflake、メール、カレンダー、最新ニュースの情報を使って、アカウントインテリジェンスダッシュボードを構築するというものです。

  1. 目標を理解し、作業を計画する。オーケストレーターは、求められている成果から出発し、それを明示的な依存関係を持つタスクに分解します。ダッシュボードの例では、さまざまなソースから情報を収集し、それを完成した成果物に仕上げる作業が含まれます。プランナーは、どのステップが他のステップに依存し、どのステップが独立して実行できるかを確定します。
  2. タスクを適切なエージェントにルーティングする。オーケストレーターは、依存関係が満たされたタスクを特定し、専門のエージェントやモデルに作業を委任します。依存するタスクは、前提となるタスクの完了を待ちます。Perplexity Computer は複数のフロンティアモデルを使用し、ワークフローのさまざまな部分をそれぞれのタスクに適したシステムにルーティングします。これにより、独立した作業を並行して実行することもできます。
  3. 制御された環境内でツール呼び出しを実行する。エージェントは、ウェブ検索、API、接続されたアプリケーション、ファイル操作、コード実行などのツールを通じて環境とやり取りします。実行レイヤーはこれらのアクションを実行し、結果をエージェントに返します。
  4. エージェント間で結果とコンテキストを受け渡す。エージェントがタスクを完了すると、次の下流のエージェントは作業を続けるために関連する出力を必要とします。引き継ぎ記録には、タスク ID、出力の参照、スキーマのバージョン、ソースのメタデータなどを含めることができます。オーケストレーターは、後続のステップに必要なコンテキストを維持しながら、こうした引き継ぎを調整します。重要なのは、エージェントが他のすべてのエージェントの作業履歴全体を自身のコンテキストウィンドウに保持する必要がないことです。
  5. 実行状態をエージェントのコンテキストとは別に記録する。エージェントがタスクを開始、完了、または失敗するたびに、実行エンジンは永続的なワークフロー記録を更新し、タスクのステータス、実行試行、出力の参照、残りの作業を記録します。この記録により、オーケストレーターは進捗を追跡し、LLM に会話履歴からワークフローを再構築させることなく、中断後に再開できます。
  6. 結果を検証し、次に何をするかを判断する。タスクが戻ってくると、オーケストレーションレイヤーは、その出力が期待されるコントラクトを満たしているか、次のタスクの依存関係が満たされているかを確認します。問題が見つかった場合、ワークフローは修正のために前のステップに戻るか、一時停止されます。問題がなければ、完了に向けて進みます。

一見シンプルな AI エージェントオーケストレーションの裏では、多くの要素が動いています。エージェント間の連携をどう構成するかによって、実行をどれだけ制御できるかが決まります。もちろん、そうした連携にはオーバーヘッドが伴います。そのため、常に割に合うとは限りません。

AI エージェントオーケストレーションはどのような場合に使うべきか?

タスクの各部分に異なる専門知識が必要な場合、独立した作業を並行して実行できる場合、または次のステップを事前に決められない場合は、マルチエージェントオーケストレーションを検討しましょう。

つまり、オーケストレーションが役立つのは次の3つのシナリオです:

  • タスクに異なる専門性が必要な場合。たとえばコーディングプロジェクトでは、計画、設計、開発、レビューのエージェントを分けると効果的な場合があります。
  • 独立したタスクを並行して実行できる場合。1つのエージェントにすべてを順番に処理させるのではなく、複数のエージェントが同時に作業し、その結果をオーケストレーターに返すことができます。
  • 問題がオープンエンドな場合。エージェントは、あらかじめ決められた手順に従うのではなく、さまざまなアプローチを探り、意思決定を行い、協力する必要があるかもしれません。

それ以外の場合、オーケストレーションはコストのかかる流行にすぎません。エージェントが増えれば調整も増え、トークンコストが高くなる可能性もあります。

「私はたいてい最もシンプルな選択肢から始めて、そこから構築していきます。ステップがわかっていて繰り返し可能なら、それはおそらくワークフローです。複数のエージェントを導入する理由があるのは、それぞれの責任、権限、ユーザーが異なる場合だけです」と、Josh Spilker 氏(AirOps 検索マーケティング責任者)は述べています。

その場合でも、追加のモデル呼び出し、引き継ぎ、レイテンシー、障害点とメリットを比較検討しましょう。

AI エージェントオーケストレーションのアーキテクチャとそのトレードオフ

エージェントの連携を構成する一般的な方法は、集中型、分散型、階層型オーケストレーションの3つです。適切なアーキテクチャの選択は、次の1つの問いに集約されます:誰が作業を制御し、エージェント同士はどのように連携するのか?

集中型オーケストレーション

集中型オーケストレーションでは、1つのオーケストレーターがプロセスを管理します。タスクを分解し、専門エージェントに作業を委任し、進捗を追跡し、それらの結果をまとめ上げます。

トレードオフ:集中型の連携では、単一の制御ポイントで実行を追跡し、共通ルールを適用しやすくなります。ただし、オーケストレーターがボトルネックになる可能性があり、システムが復旧をサポートしていない限り、その障害によってワークフロー全体が中断される恐れがあります。

分散型オーケストレーション

分散型オーケストレーションでは、1つのマネージャーにすべての意思決定を任せるのではなく、エージェント同士がより直接的に連携します。メッセージを交換し、共有状態を読み取り、次のステップを独立して判断できます。

トレードオフ:エージェントは中央のプランナーを待たずに動作できるため、このアプローチは探索的な作業や独立した貢献に役立ちます。しかし、エージェント間で意見が食い違ったり、共有情報を更新したり、一貫した結果を出す必要があったりする場合は、連携が難しくなります。

階層型オーケストレーション

階層型オーケストレーションは、マネージャー型のアプローチを複数のレベルに拡張したものです。最上位のオーケストレーターが下位のオーケストレーターに責任を委任し、下位のオーケストレーターがそれぞれの専門エージェントのグループを調整します。

営業、財務、法務の各チームが関わるエンタープライズワークフローを考えてみましょう。最上位のオーケストレーターは、各ワークストリームをドメイン固有のコーディネーターに委任できます。各コーディネーターは自身の専門エージェントを管理し、統合された結果を報告します。

この構造は、ワークフローが広範すぎて1つのオーケストレーターでは効果的に管理できない場合に役立ちます。

トレードオフ:階層構造により、チームは連携の責任を分担し、個々のブランチ内で障害に対処できる可能性があります。ただし、引き継ぎの増加、状態管理の複雑化、運用上のオーバーヘッドの増大を伴います。また、ローカルでの復旧は、チェックポイントと実行状態の実装方法に左右されます。

これらのアーキテクチャの比較:

基準

集中型

分散型

階層型

実行の主導権

1つのオーケストレーターが委任を制御

エージェントがピアまたは共有状態を通じて連携

責任がオーケストレーションの各レベルに分散

状態の一貫性

1つの制御ポイントを通じて調整しやすい

明示的な同期と競合処理が必要

ブランチ内およびブランチ間での調整が必要

障害の分離

中央コントローラーが重大な依存先になる可能性がある

個々のエージェントは独立して障害を起こし得るが、共有インフラは依然として重要

復旧を考慮して設計されていれば、障害をブランチ内に封じ込められる場合がある

ポリシーの適用

共通の制御を一元的に適用できる

参加者全体でポリシーを一貫して適用する必要がある

グローバルレベルとドメインレベルで制御を適用できる

運用の複雑さ

一般的に低い

調整の複雑さが高い

複数のオーケストレーション層により複雑さが高い

逐次実行、並列実行、ハンドオフ型実行

もう1つ理解しておくべき違いがあります。アーキテクチャは、誰がエージェントを調整するかを決定します。実行パターンは、エージェントのタスクがどのように進行するかを決定します。

実行パターンには次の3つがあります。

  • 逐次ワークフロー:エージェントがあらかじめ定められた順序で作業し、あるエージェントの結果が別のエージェントの入力になります。
  • 並列実行:独立したエージェントが同時に作業します。
  • ハンドオフ型実行:タスクの進行に応じて、専門エージェント間で制御が移ります。次のステップを処理するのに別のエージェントのほうが適している場合に有効ですが、各ハンドオフでは処理の継続に必要な情報を保持しなければなりません。

これらのパターンは相互に排他的なものではなく、オーケストレーションのアーキテクチャと1対1で対応するわけでもありません。目標は、ワークフローの依存関係、調整要件、許容できる運用オーバーヘッドに対応できる、最もシンプルな構造を選ぶことです。

AIエージェントのオーケストレーションでよくある失敗

オーケストレーションでは、単純な見落としから複雑な障害まで、あらゆる問題が起こり得ます。エージェントが正しく仕事をしているように見えても、ワークフロー全体は失敗していることさえあります。実務者の経験をもとに、オーケストレーションされたワークフローの信頼性を損なう、よくある間違いをまとめました。ぜひ注意してください。

  • 情報が欠落するエージェント間のハンドオフ。オーケストレーターが要約した計画を専門エージェントに渡しますが、その要約から制約、依存関係、実装の詳細が抜け落ちてしまいます。
  • 時期尚早なファンイン実行。上流のすべてのタスクが完了する前に、下流のエージェントが結果の集約を開始してしまいます。
  • 非決定的な共有状態の更新。並列エージェントが、明確に定義されたマージセマンティクスがないまま同じ状態キーに書き込みます。フレームワークによる更新の処理方法によっては、書き込みの消失、データの重複、順序に依存する出力、競合する変更が発生する可能性があります。
  • チェックポイントと副作用の不一致。タスクが外部操作を実行したものの、ワーカーが障害を起こす前に、その実行の成功が永続的に記録されません。復旧時、オーケストレーターは未完了のタスクがあると判断して再実行してしまいます。
  • 人間の承認後の再開時に起こる競合状態。実行の一時停止と再開は、それ自体に固有の同期の問題をもたらします。
  • 委任ループとリトライの増幅。責任範囲が重複している、依存関係が循環している、または完了条件があいまいであるために、エージェント同士が何度も作業を渡し合います。
  • 指示レベルの制御を実行時のセキュリティと取り違える。オーケストレーターはエージェントに対し、特定のリソースにアクセスしないよう、または機密性の高い操作を行わないよう指示できますが、モデルへの指示によってオペレーティングシステムの権限、ネットワーク制限、認可の境界が強制されるわけではありません。Perplexityのセキュリティエンジニアリング研究は、悪意のある指示がなくても、エージェントが正当な目標を追求する過程でセキュリティ境界を越えてしまう理由を明らかにしています

これらの失敗がいかに異なるかに注目してください。スケジューラーの時期尚早な遷移も、あいまいな外部書き込みも、誤った結果を生む可能性がありますが、それぞれ実行ライフサイクルの異なる部分に起因しています。だからこそ、信頼性の高いオーケストレーションには、プロンプトの改善やリトライの追加だけでは不十分なのです。

本番環境での信頼性を高めるAIエージェントオーケストレーションの7つのベストプラクティス

1. 明示的なタスク契約、受け入れ基準、停止条件を定義する

目標があいまいで完了の定義が不明確だと、エージェントが生成する結果は期待外れになりがちです。解決策はプロンプト契約(エージェント向けの作業範囲)です。実行を開始する前に、目標、制約、出力形式、失敗条件について合意しておきましょう。

たとえば、断続的に失敗する統合テストの修正を担当するエージェントの契約は、次のように定義できます。

  • 目標:不安定なチェックアウトAPI統合テストの原因を特定し、修正する。
  • 入力:テストのソースコード、CIの失敗ログ、最近のコミット、関連するアプリケーションコード。
  • 制約:テストを無効化したり、アサーションを緩めたり、無関係なアプリケーションの動作を変更したりしない。
  • 期待される出力:コードパッチ、根本原因の説明、テストの実行結果。
  • 受け入れ基準:以前は失敗していたテストが10回連続の実行で成功し、関連する回帰テストスイートも成功する。
  • 失敗条件:根本原因を特定できない、修正によって回帰が発生する、または必要なテスト環境が利用できない。

ただし、もう1つ重要な点があります。エージェントはいつ停止すべきでしょうか?

満足のいく結果が得られていないからといって、エージェントが無期限に反復を続けるべきではありません。何をもって正常完了とするか、どのような場合に部分的に完了したタスクを返すか、要件を満たせないためにいつ停止するかを定義しましょう。未解決のタスクが無限ループにならないよう、委任の最大深度と反復回数の上限、または実行予算を設定してください。

CIの例に戻りましょう。次のような停止条件を定義できます。

  • 成功:修正が10回連続のテスト実行と関連する回帰テストスイートに合格する。
  • 反復回数の上限:エージェントが試せる修正案は2つまで。
  • 実行予算:問題が未解決のままでも、エージェントは60分後に停止しなければならない。
  • 委任の上限:エージェントは1つの専門エージェントに作業を委任でき、それ以上のサブエージェントへの委任は行わない。
  • 部分的な完了:両方の試行が失敗するか制限時間が切れた場合、エージェントは調査結果、試みた変更、テスト結果を返す。
  • 実行のブロック:テスト環境が利用できない場合、エージェントは成功を主張するのではなく、停止して障害要因を報告する。

2. オーケストレーターを軽量に保ち、構造化されたハンドオフを徹底する

開発者がオーケストレーターに多くの責任を与えすぎると、オーケストレーターが専門エージェントを調整する代わりに、自らコードの作成、デバッグ、詳細なレビューを始めてしまうことがあります。これはボトルネックを生みます。オーケストレーターがコンテキスト予算を実装の詳細に費やし、委任が遅れ、結果に対する責任の所在があいまいになるのです。

そこで、オーケストレーターには本来の仕事を任せ、具体的なアーティファクトを参照させることでハンドオフを徹底しましょう。参照すべきなのは、元のタスク、関連する入力、出力アーティファクト、実行ステータス、未解決の問題です。

次の例を考えてみましょう。status: completed はエージェントに割り当てられた作業を指しており、ワークフロー全体を指すものではありません。テストはまだ pending であるため、オーケストレーターは最終結果を承認すべきではありません。

json
{ "task_id": "fix-42", "status": "completed", "artifact_ref": "patch-17", "test_status": "pending", "blockers": [] }

3. ワークフローの状態を永続化し、コンテキストの増大を制御する

エージェントの会話履歴は、ワークフローの進捗を示す信頼できる記録ではありません。コンテキストウィンドウがいっぱいになると、自動圧縮によって重要な詳細が失われることがあります。また、ワーカーがクラッシュした場合、次のエージェントはどのステップが実際に完了したかを把握する必要があります。

たとえば、コーディングエージェントがパッチを生成した後にクラッシュした場合、次のワーカーは保存されたアーティファクトを取得し、記録されたワークフローの状態から処理を再開する必要があります。ただし、そのエージェントが外部のCI実行もトリガーしていた場合、オーケストレーターはアクションを繰り返す前に、その実行を別途照合しなければなりません

そのため、実行状態はエージェントの作業コンテキストとは分けて管理しましょう。タスクのステータス、実行の試行、完了したステップ、アーティファクトへの参照は永続ストレージに保存します。一方で、実行履歴全体をコンテキストウィンドウに詰め込むのではなく、エージェントの現在のタスクに関連する指示、入力、結果だけを読み込むようにします。

4. 障害を考慮したリトライと復旧可能なツール実行を設計する

CIエージェントがテスト実行をトリガーしたものの、APIリクエストがタイムアウトしたとします。テスト実行の開始に失敗したのでしょうか? それとも、CIサービスがキューに入れたものの、レスポンスが失われたのでしょうか?

タイムアウトは、必ずしも操作が失敗したことを意味しません。だからこそ、次の対応を決める前にエラーを区別する必要があります。

  • 一時的なエラー(429、503):上限付きの指数バックオフとジッターを用いてリトライし、Retry-After が指定されている場合はそれに従います。
  • 検証エラーまたは権限エラー(400、403):同じリクエストを繰り返すのではなく、停止するか、根本的な問題を修正します。
  • あいまいな結果(書き込みが行われた可能性がある状態でのタイムアウト):再試行する前に、操作が成功したかどうかを確認します。

注:リトライ可能なエラーであっても上限が必要です。ツール呼び出しごとにタイムアウトを設定し、リトライ回数と合計リトライ時間に上限を設け、ワークフロー全体の期限を適用して、ネストされたエージェントが同じ操作を再開し続けられないようにします。依存先が繰り返し失敗する場合は、サーキットブレーカーを使用してリクエストを一時的に停止します。

外部に副作用を及ぼす操作では、論理的なアクションごとに安定した冪等性キーを割り当て、リトライ間で再利用します。APIがサーバー側の重複排除をサポートしていれば、アクションを2回実行することなく、繰り返されたリクエストを認識できます。サポートしていない場合は、相関IDやその他の信頼できる参照を使用して外部システムに問い合わせます。

何が起きたかを確認できない場合は、停止してエスカレーションします。

CIエージェントのリトライロジックの例を疑似コードで示します。

python
op_id = get_or_create_operation_id( task_id=task_id, patch_id=patch_id, action="start_ci_run" ) try: return ci.start_run(commit, request_id=op_id) except TimeoutError: run = ci.find_by_request_id(op_id) if run: return run if ci.supports_idempotency: return bounded_retry( lambda: ci.start_run(commit, request_id=op_id) ) raise NeedsReconciliation(op_id)

コードに関する注記:この例では、CI APIがリクエストIDによる実行の検索をサポートしていることを前提としています。request_id による重複防止は、プロバイダーが冪等性を明示的に保証している場合にのみ有効です。bounded_retry() は説明用の疑似コードです。本番環境では、操作ごとのリトライ予算(最大試行回数または経過時間)とワークフロー全体の期限の両方によってリトライを制限する必要があります。

複数のサービスにまたがる長いワークフローでは、後続のステップが失敗したときに補償アクションを調整するため、Sagaパターンの採用を検討してください。ただし、補償が常に完全なロールバックになるとは限らない点に注意が必要です。データベースの更新は元に戻せても、送信したメールを取り消すことはできません。

5. 明示的なリソース予算に基づいて作業をルーティングし、並列化する

ここでは2つのバランスを取る必要があります。各タスクにどの程度のモデル能力が必要か、そして同時にいくつのタスクを実行できるかです。どちらかを誤ると、エージェント同士が共有APIのクォータを奪い合ったり、高価な推論モデルだけに頼ったりするリスクがあります。

まず、モデル選択については、タスクの複雑さに合わせてモデルの能力と推論の強度を選びましょう。シンプルですが、見落とされがちなポイントです。ルーティングルールを設定してモデルを自分で評価することも、モデル選択を代行してくれるオーケストレーションプラットフォームを使用することもできます。

たとえば、Perplexity ComputerのEffort Modeを使えば、モデルを手動で選択しなくても、タスクにかける労力の度合いを選べます。Light、Standard、High、Ultraのいずれかを選ぶと、Perplexityがオーケストレーションを担うモデルとその推論レベルを自動的に選択します。そのオーケストレーターがサブタスクを補助エージェントに委任し、補助エージェントはさまざまなプロバイダーのモデルを使用できます。

Perplexityはモデル構成を品質とコストの観点から評価し、同等の結果が得られる低コストの選択肢を優先します。モデルと推論レベルを自分で選びたい場合は、Customコントロールを使うこともできます。

並列処理については、インフラと外部依存関係に基づいて上限を決めるべきです。共有APIのリクエストおよびトークンのレート制限を確認したうえで、同時実行数を増やしながらワークフローの負荷テストを行います。スループットが向上するのか、それともリクエストがキューに溜まり始めたり、遅くなったり、429エラーを返したりするのかを観察しましょう。

リソース消費を予測可能な範囲に保つため、リソース制限とスケジューリング制御を適用します。

  • 同時実行数とリクエストレートを制御する:サービスごとに処理中の呼び出し数に上限を設け、超過した作業はキューに入れます。同時実行数の上限だけでは、1分あたりのリクエスト数や1分あたりのトークン数の制限は強制されない点に注意してください。
  • トークンとコストの予算を追跡する:サブエージェントを含むワークフロー全体の使用量を把握し、残りの予算が足りない場合は新しい作業の開始を停止します。
  • 実行期限を適用する:タスクとワークフローに時間制限を設定し、サポートされている場合は実行中のエージェントにキャンセルを伝播させます。
  • 依存関係を尊重する:すべてのエージェントを同時に起動するのではなく、必要な入力が揃った時点で下流のタスクを開始します。

6. 承認を徹底し、エージェントの実行を分離する

自らの操作が安全かどうかの判断を、決してモデルに委ねてはいけません。代わりに、エージェントには最小権限のアクセス許可を与え、リスクに基づく承認ルールをアプリケーションコードで適用します。エージェントがコードを実行する場合は、その実行をホスト環境から分離し、ファイル、ネットワーク、認証情報へのアクセスを制限します。これにより、エージェントがミスを犯したり、安全でないコードを実行したりした場合の被害を抑えられます。

「私は、過度に複雑なマルチエージェントシステム、特にエージェント同士が互いの作業をレビューして承認し合うようなシステムには懐疑的です。複数のエージェントが同じ間違いを自信満々に受け渡し、誰も実際にはそれに気づかないという事態になりかねません」とSpilker氏は警告します。

人間による承認が必要なアクションでは、実行を一時停止し、提案された操作を次の内容とともに正確に保存します。

  • 操作のパラメーター
  • 対象リソース
  • コミットまたは状態のバージョン
  • レビュー担当者の判断

また、承認が却下された場合、期限切れになった場合、エスカレーションが必要な場合にどうなるかも定義しておきましょう。これは再開可能なフレームワークでは不可欠です。中断されたノードを再開すると、そのノードの先頭からコードが再実行されるためです。中断前の副作用が再び実行される可能性があります。

つまり、承認が却下されるか期限切れになった場合、リクエストはクローズされます。実行前に対象のコミット、パラメーター、権限が変更された場合は、承認を無効にして新たな承認を要求します。

また、Spilker氏は、目標と見なされがちな完全自律型のエンドツーエンドのエージェントという考え方も支持していません。「私としては、責任が明確で、権限が定義され、適切なポイントで人間によるレビューが入る、少数の特化型エージェントを構築するほうが良いアプローチだと考えています。完全な制御を手放すことなく、効率性も得られます」と同氏は締めくくっています。

7. 出力を独立して検証し、復旧時の動作をテストする

実際には失敗しているのに、エージェントがSuccessと報告したことはありませんか? 腹立たしいとまでは言わなくても煩わしいものです。しかも、エージェントの最終メッセージがどこで問題が起きたかを教えてくれるとは限らないため、修正も簡単ではありません。

調査するには、実行中に何が起きたかをトレースし、結果を独立して検証します。では、時間をかけて問題を切り分け、解決していきましょう。

ワークフローをトレースして問題の原因を特定する

エージェントのプロンプトをデバッグする前に、実行パス全体を記録しましょう。同じワークフロー実行のもとで、エージェントの呼び出し、ツール呼び出し、エラー、リトライを関連付けるトレースが必要です。

OpenTelemetryのGenAIセマンティック規約は、こうした操作を記述するための標準化された方法を提供します。たとえば、invoke_workflow はワークフローの実行、invoke_agent はエージェントの呼び出し、execute_tool はツール呼び出しを表します。各操作は、タイミング、ステータス、関連するメタデータとともにスパンとして記録できます。

このステップで実行パスのトレースが得られるため、エージェントがどこでつまずいたかを特定できます。

plaintext
invoke_agent generate_patch OK execute_tool start_ci_run OK run_id=9812 execute_tool get_ci_result TIMEOUT agent_response: "Success"

実行トレースの例。

出力を独立してレビューする

可能な限りプログラムによるチェックを使用しましょう。出力をJSONスキーマに照らして検証し、ユニットテストと統合テストを実行し、必要なアーティファクトが存在するかを確認し、外部システムに問い合わせてアクションが実際に成功したかを確かめます。

主観的な判断が必要で、プログラムによるチェックでは評価できない出力については、独立したレビュー担当エージェントを導入します。1つの方法は実装者–レビュー担当者–解決者ループです。あるエージェントがアーティファクトを作成し、新しいコンテキストを持つレビュー担当者が問題を特定し、解決者がそれらに対処してから、再び検証を実行します。

それでも、可能な場合はレビュー担当者の指摘を検証する必要があります。また、繰り返しの評価にLLMベースの採点者を使用する場合は、人間がレビューした例を基準にその判定を調整しましょう。

障害を注入して復旧をテストする

ここまで、エージェントが実行した内容をトレースし、その出力が正しいかどうかを確認してきました。しかし、タスクの途中でワーカーがクラッシュしたり、リクエストを受け付けた後にAPIがタイムアウトしたりした場合はどうなるでしょうか。意外なことに、ワークフローは通常の条件下では問題なく動作していても、復旧時に失敗する可能性があります。

これをテストするには、テスト環境で意図的に障害を注入します。

  • APIのタイムアウトをシミュレートする
  • 外部への書き込みとチェックポイントの間でワーカーをクラッシュさせる
  • 不正な形式のツール出力を返す
  • 承認を期限切れにする

各テストの後、実行トレースを調べて、どのステップが実行されたか、ワークフローがどこから再開したか、アクションが重複したりスキップされたりしていないかを確認します。そのうえで、実際の結果を確認します。

たとえば、CIエージェントがテスト実行を開始するリクエストを送信したものの、APIレスポンスがタイムアウトしたとします。エージェントはリトライして成功レスポンスを受け取り、Successと報告します。すべて問題ないように見えますが、CIサービスを確認すると、テスト実行が1つではなく2つ作成されていたことが判明します。

そのため、ワークフローに記録された状態と、外部システムにおける実際の変更の両方を検証する必要があります。復旧テストは、意図しない副作用を伴わずにワークフローが期待される状態に到達した場合にのみ合格とすべきです。

見つかった障害はリグレッションテストに追加し、今後の変更によって再発しないようにします。

最終的に、成功とは、ワークフローが必須のチェックに合格し、かつ外部での結果も検証されたことを意味します。

AIエージェントオーケストレーションに関するよくある質問

なぜサイロ化したAIエージェントはエンタープライズ規模で破綻するのか?

サイロ化したエージェントは、個々のタスクを正しく完了できても、全体としては一貫性のない結果を生み出すことがあります。たとえば、営業エージェントが10:00に顧客の契約条件を取得し、価格設定エージェントが10:05に更新された価格で見積もりを算出し、法務エージェントが10:07に変更された契約書を確認するとします。各エージェントはビジネスの異なるスナップショットに基づいて作業するため、それぞれの出力が互いに矛盾する可能性があります。

エンタープライズ規模では、この問題はさらに顕著になります。エージェントはそれぞれ独立して更新される複数のシステムとやり取りし、異なる権限で動作し、コンテキストや実行状態を必ずしも共有していないためです。

AIエージェントの無限リトライループを防ぐにはどうすればよいですか?

複数のレベルで上限を設定します。具体的には、ツール呼び出しの最大リトライ回数、エージェントの最大反復回数、委任の深さ、ワークフロー全体の期限です。リトライする前に障害を分類します。一時的な429レスポンスの場合は、Retry-Afterが指定されていればそれに従います。それ以外の場合は、ジッター付きで上限を設けた指数バックオフを使用します。

検証エラーや権限エラーが発生した後は、内容を変えないままリクエストをリトライするのをやめます。ダウンストリームのサービスが繰り返し失敗する場合は、サーキットブレーカーによってエージェントが追加の負荷を発生させるのを防げます。

クラッシュ後にAIエージェントのワークフローを再開するにはどうすればよいですか?

復旧の仕組みはランタイムによって異なります。LangGraphでは、PostgresSaverなどの永続的なチェックポインターがグラフの状態をthread_idに紐付けて保存するため、永続化された状態から実行を継続できます。Temporalでは、別のワーカーがイベント履歴をリプレイすることでワークフローを再構築できます。リプレイ中は、以前に記録されたアクティビティの結果が再利用されます。

ワークフローの実行中にアプリケーションが再デプロイされると、保存された状態や実行履歴との互換性が失われる場合があります。Temporalでは、Worker Versioningとワークフローのパッチ適用によってこれに対処します。チェックポイントベースのシステムでは、スキーマの移行を計画し、互換性のない変更をロールアウトする前に、既存の保存済み状態に対して復旧をテストします。

AIエージェントオーケストレーションの信頼性をテストするにはどうすればよいですか?

同じ代表的なタスクを複数回実行し、pass@k(k回の試行のうち少なくとも1回が成功するかどうか)とpass^k(k回の試行がすべて成功するかどうか)を区別します

単一の総合的な成功率に頼るのではなく、タスクのカテゴリーとワークフローのバージョンごとに結果を測定します。初回試行での成功率、繰り返し実行した際の一貫性、p95レイテンシ、完了したタスクあたりのコスト、人による介入が必要な割合を追跡します。成功率については、サンプルサイズと不確実性区間を報告します。