タスクステートメント**5.3「マルチエージェントシステムにわたるエラー伝播戦略を実装する」**は、Claude Certified Architect — Foundations(CCA-F)試験のドメイン 5(コンテキスト管理と信頼性、試験配点 15 %)の中に存在する。ドメイン 5 は配点では最も軽いドメインだが、シナリオ密度は非常に高い。すべてのマルチエージェント問題(そしてマルチエージェント問題はドメイン 1(27 %)を支配する)は最終的に「subagent が壊れたらどうなるか?」という問いに向かう。エラー伝播は、マルチエージェントシステムが優雅に劣化するか・安全に停止するか・完全な失敗にカスケードするかを決めるステッチだ。
本学習ノートは、CCA-F 受験者がアーキテクチャレベルで設計できるようになるべきエラー伝播の全体像を説明する:ネストされたエージェントシステムが新しい失敗境界を生む理由・エラーを一時的 vs 永続的・局所的 vs カスケード的に分類する方法・fail-fast が fail-safe に勝るとき・subagent のクラッシュを封じ込めてコーディネーターが生き残る方法・エージェント境界を越えてもセマンティクスを失わない構造化エラーペイロードの正確な形状・コーディネーターが失敗した subagent をリトライするかどうかを決める方法・一部の subagent だけが成功したときに部分的な結果で進む方法・ハードアボートの閾値が発動するまでソフト失敗を蓄積する方法・繰り返し失敗する subagent を無効にするサーキットブレーカーパターン・根本原因エラー報告をトップレベルコーディネーターまで連鎖させる方法・そしてそのすべてをデバッグするために必要な分散トレーシングのサーフェス。最終的な罠セクションと 5 問の FAQ が、このタスクを最も集中的に行使する 2 つの試験シナリオ(マルチエージェント研究システムとカスタマーサポート解決エージェント)にすべての抽象化を固定する。
エラー伝播の課題 — ネストされたエージェントシステムにおける境界を越える失敗
単一エージェントの Claude システムには失敗境界がちょうど 1 つある。エージェントのループ自体だ。ツールが失敗すれば、ループがそれを見る;ループがアボートを決定すれば、呼び出し元がそれを見る。マルチエージェントシステムにはエージェント層の数だけ失敗境界がある。3 つの subagent をスポーンし、それぞれがさらに 2 つの subagent をスポーンするコーディネーターは、少なくとも 3 種類の境界タイプを持つ失敗サーフェスを持つ:ツールから subagent へ、subagent からコーディネーターへ、コーディネーターから呼び出し元へ。各境界はエラーが飲み込まれ・歪曲され・静かなカスケードに変えられる機会だ。
なぜ境界が重要か
境界は実行コンテキストが手渡される点だ。単一のエージェントループ内では、Claude はすべての tool_result(エラーを含む)を連続した会話の一部として見る。エージェント境界を越えると、あなたが明示的に通過させるものだけが見える。壊滅的に失敗した subagent はコーディネーターに何が起きたかを自動的に伝えない;あなたの統合コードが返すことを決めたものを単に返す。その決定がエラー伝播戦略だ。
マルチエージェントシステムの三つの失敗モード
- 静かな劣化 — subagent が失敗し、もっともらしい見た目のプレースホルダー結果を返す。コーディネーターはプレースホルダーを信頼し・最終回答に統合し・ユーザーはエラー指示子なしで捏造されたコンテンツを受け取る。これは見えないため最悪の失敗モードだ。
- カスケード失敗 — subagent が失敗し、コーディネーター全体をクラッシュさせる例外をスローして伝播させる。他の subagent が健全であっても実行全体が停止する。すべての subagent の結果なしには進めないコーディネーターは脆弱すぎる。
- 無限リトライ — コーディネーターが失敗した subagent を無限にリトライし、トークンと実時間予算を使い果たしても出力を生成しない。これはサーキットブレーカーが存在するために防ぐ失敗モードだ。
エラー伝播とは、マルチエージェントシステムの 1 つの層での失敗が、その層がリトライ・スキップ・劣化・アボートのいずれかを決定するのに十分な構造化された詳細を持って次の層に伝えられる一連のメカニズムだ。エラー伝播はエラー処理のアーキテクチャ上の補完だ:エラー処理は失敗サイトで何をするかを決定し、エラー伝播は失敗サイトが上流に何を伝えるかを決定する。明示的な伝播戦略を持たないマルチエージェントシステムは、回答を静かに捏造するシステムだ。 Source ↗
CCA-F がこれをテストする理由
コミュニティの合格報告は、受験者が subagent が構造化エラーを返したときの正しいコーディネーターの動作を選ばなければならないドメイン 5 のシナリオを繰り返し引用する。誤答選択肢はほぼ常に「無限にリトライする」「静かに subagent を削除する」「実行全体をアボートする」のいずれかで、それぞれ特定の状況では正しく他では誤りだ。エラー伝播を正しく理解することは、720 点のパスと 900 点超えを分ける核心的な差別化要因だ。
エラー分類 — 一時的 vs 永続的、局所的 vs カスケード的
伝播戦略を設計する前に、エラーを分類しなければならない。CCA-F は 2 つの直交する軸の認識を要求する。
軸 1:一時的 vs 永続的
- 一時的 — 根本的な原因は人間の介入なしに自然に解決されることが期待される。例:ネットワークタイムアウト・レート制限スロットル・一時的なデータベースの競合・再起動中の下流サービス。一時的エラーはリトライの候補だ。
- 永続的 — 根本的な原因は入力・設定・外部状態の変更なしには解決しない。例:不正な入力・権限拒否・リソースが見つからない・スキーマ違反。永続的エラーはリトライしてはいけない;リトライすると予算を無駄にし、実際の問題を隠す可能性がある。
コーディネーターが永続的エラーをリトライすると、諦める前に反復上限を使い果たす。コーディネーターが一時的エラーをリトライしないと、最初のネットワーク障害でアボートする。
軸 2:局所的 vs カスケード的
- 局所的 — エラーは 1 つの subagent の作業にのみ影響し、ピアの subagent がすでに完了した作業を無効にしない。1 つの特定のソースに到達できない研究エージェントは、他の 3 つのソースから有効な結果を持っている。
- カスケード的 — エラーがこの subagent の出力に依存する上流の仮定または下流の作業を無効にする。「ユーザーを認証する」subagent が失敗すれば、すべての下流の「ユーザーデータを取得する」subagent は今や無効な前提で動作している。
局所的エラーは部分的失敗処理の候補だ(持っているもので進む)。カスケード的エラーは下流の作業を短絡させなければならない。
四つの象限
| 局所的 | カスケード的 | |
|---|---|---|
| 一時的 | subagent 内でリトライ;リトライが尽きたら部分的な結果でコーディネーターは続行 | バックオフでリトライ;リトライが尽きたらパイプライン全体をアボート |
| 永続的 | この subagent をスキップ;部分的な結果でコーディネーターは続行しギャップをアノテーションする | 即座にアボート;パイプラインの前提が壊れている |
CCA-F の誤答選択肢はこれらの象限を頻繁に混乱させる。罠のパターンは、永続的な局所エラーに対して「3 回リトライする」を答えとして提示したり、カスケード的な永続エラーに対して「部分的な結果で進む」を提示したりすることだ。試験当日に伝播戦略を選ぶ前に、シナリオを四象限マトリクスに当てはめる:それは一時的か永続的か、そして局所的かカスケード的か?答えはほぼ機械的に出る。 Source ↗
Fail-Fast vs Fail-Safe 戦略 — いつアボートするか vs いつ優雅に劣化するか
エラー伝播戦略は 2 つの極の間のスペクトルに存在する:fail-fast(問題の最初の兆候で停止)と fail-safe(システムの一部が誤動作しても有用な出力を生成し続ける)。どちらの極も普遍的に正しくない;CCA-F は受験者が戦略をシナリオに対応付けられるかをテストする。
Fail-Fast
Fail-fast 戦略は問題の最初の検出でアボートする。コーディネーターは新しい subagent のスポーンを停止し、完全なコンテキストを持つエラーを上方に報告し、呼び出し元が何をするかを決定できるようにする。適切な場面:
- 下流の作業が失敗したステップの正確さに依存する(カスケード的な永続エラー)。
- システムが重大な状態変化を処理する(金融取引・医療記録・破壊的な操作)。
- 部分的な出力が出力なしよりも悪い(欠落した条項のある法的文書は使用できない;スキップして進むと危険なものが生まれる)。
- 呼び出し元が明示的なエラーシグナルからのみ回復できる人間または別の自動化システムだ。
Fail-Safe
Fail-safe 戦略は subagent の失敗にもかかわらずコーディネーターを実行し続け、どのパーツが成功してどのパーツが成功しなかったかを明確にアノテーションしたベストエフォートの結果を生成する。適切な場面:
- subagent の作業が独立している(局所的エラー)。
- 部分的な結果が本物のユーザー価値を持つ(4 つのリサーチソースのうち 3 つはまだ有用なリサーチだ)。
- ユーザーが部分的な回答から情報に基づいた判断を下せる(請求の質問を解決したサポートエージェントは製品情報のルックアップが失敗してもそれができる)。
- アボートのコストが高い(ユーザーの不満・失われた作業・SLA の未達)。
コーディネーターの役割
コーディネーターは fail-fast vs fail-safe の決定が実際に実装される場所だ。subagent は通常、自分の失敗がカスケード的か局所的かを知らない。依存マップを持っているのはコーディネーターだけだ。コーディネーターは構造化エラーを読み・どの subagent が重要でどれがオプションかについての自分の知識を参照し・戦略を選ぶ。
試験問題が 4 つの subagent が独立したトピックを調査するマルチエージェント研究システムを説明する場合、正しい戦略はほぼ常に部分的結果処理を持つ fail-safe だ。試験問題が「顧客の身元を確認する」subagent が失敗するサポートエージェントを説明する場合、正しい戦略はほぼ常に fail-fast だ。未確認の身元で安全に続行することはできない。下流の作業が失敗したステップに依存するかどうかに基づいてパターンマッチングすること。 Source ↗
エラー封じ込め — subagent の失敗がコーディネーターをクラッシュさせないようにする
未処理の例外をスローする subagent は、封じ込めを設計しないとコーディネーターの実行全体を引き倒す可能性がある。CCA-F の期待は、subagent の呼び出しが封じ込めプリミティブにラップされ、生の失敗をコーディネーターが推論できる構造化された戻り値に変えることだ。
三つのレベルの封じ込め
- 例外境界 — すべての subagent 呼び出しは try-catch(またはその言語の同等物)ブロックの中になければならない。subagent 内の捕捉されない例外は呼び出しサイトで捕捉され、構造化エラーの戻り値に変換されなければならない。subagent の例外を生のまま伝播させてはいけない。
- リソース分離 — subagent はコーディネーターと可変状態を共有すべきでない。subagent が自身の会話履歴を破損しても、その破損はコーディネーターの履歴に到達してはならない。Agent SDK の subagent プリミティブはデフォルトでこの分離を提供する。各 subagent は独自の context window で実行する。subagent のメッセージをコーディネーターのメッセージ履歴に単純に結合するとその分離が失われる。
- タイムアウトウォール — すべての subagent 呼び出しには最大のウォールクロック予算がなければならない。遅いツールでハングした subagent はコーディネーターを無期限に人質にしてはならない。タイムアウトは「ハングした subagent」が「ハングしたコーディネーター」になることを防ぐため封じ込めの一部だ。
subagent のコンテキスト分離はエラー分離ではない
これは CCA-F のエラー伝播サーフェスで最もテストされる微妙な点だ。subagent のコンテキストは分離されている。subagent はコーディネーターの会話履歴を見ず、その逆も同様だ。その分離はトークン管理と情報の隠蔽に有用だ。エラーは自動的に分離されない。subagent が例外をスローし、あなたのコードが呼び出しサイトでそれを捕捉しなければ、コンテキストが別々であってもコーディネーターのプロセスはクラッシュする。
コミュニティの合格報告はこの罠を具体的に指摘する。誤答選択肢は「subagent は分離されたコンテキストを持っているため、そのエラーはコーディネーターを破損できない」と読まれる。この文は半分だけ真実だ。コンテキスト分離は会話履歴の破損を防ぐが、プロセスレベルまたは制御フローの破損は防がない。すべての subagent 呼び出しの周りに明示的な try-catch がまだ必要だ。コンテキスト分離とエラー分離を同一視する回答は誤りだ。 Source ↗
Agent SDK での封じ込め
Agent SDK の subagent プリミティブを使う場合、SDK はデフォルトの封じ込めを提供する:subagent は独自のループで実行し、その結果(またはエラー)が構造化された値としてコーディネーターに返され、コーディネーターはそれを推論できる観察として受け取る。その結果のエラー指示子を確認し何をするかを決定する必要はまだある。SDK は伝播戦略を考案しない。
エージェント境界を越えた構造化エラーペイロード — エラーセマンティクスの保持
エラーがエージェント境界(subagent からコーディネーターへ、またはコーディネーターから呼び出し元へ)を越えるとき、受け手が何をするかを決定するのに十分な構造化情報を運ばなければならない。「何かがうまくいかなかった」のような一般的な文字列はすべての受け手に推測を強いる。
境界を越えるすべてのエラーペイロードに必要な五つのフィールド
errorCategory— 制御された語彙の分類:transient・permission・business・internal・validation。これは受け手にどの四象限が適用されるかを伝える。isRetryable— ブール値。リトライの決定を直接エンコードし、受け手がカテゴリから再導出する必要がないようにする。message— 何が間違えたかの簡潔で人間が読める説明。実行可能であり、スタックトレースのダンプではない。context— 失敗サイトに関する構造化メタデータ:どの subagent・どのツール・どの入力・どの反復。デバッグとコーディネーターが失敗を正確に帰属させるために不可欠だ。correlationId— このエラーをトップレベルのリクエストに結び付ける分散トレーシング識別子。オブザーバビリティに不可欠(後で説明)。
なぜ構造化ペイロードが重要か
文字列だけを受け取るコーディネーターは、その文字列に対してパターンマッチングして何をするかを決定しなければならない。subagent ライブラリがエラーの言い回しを変えると、コーディネーターのロジックは静かに壊れる。構造化ペイロードを受け取るコーディネーターは errorCategory と isRetryable を決定論的なコードでディスパッチできる。これはドメイン 2 が MCP ツールエラーでテストするのと同じパターンで、コンシューマーが Claude ではなくコーディネーターである場合の消費パターンは同一だ。
連鎖上のセマンティクスの保持
コーディネーターが自身の呼び出し元にエラーを再スローするとき、構造化ペイロードを文字列に集約してはならない。フラット化せず、ラップする。トップレベルの呼び出し元はまだ元の errorCategory・元の subagent のアイデンティティ・元のコンテキストを見えるべきで、「ステップ X のエラー:ステップ Y のエラー:ステップ Z のエラー」という 7 層のスタックではない。
構造化エラーペイロードは、エージェント境界を越えて最低限 errorCategory(制御された語彙)・isRetryable(ブール値)・message(人間が読める)・context(構造化メタデータ)・correlationId(分散トレーシング ID)を運ぶ機械可読オブジェクトだ。構造化ペイロードはコーディネーターが推測なしに正しいリトライ・スキップ・アボートの決定を下せるようにするものだ。一般的な文字列エラーは、すべての受け手がテキストからセマンティクスを再導出することを強いるため、標準的なアンチパターンだ。
Source ↗
コーディネーターレベルのリトライ判断 — コーディネーターが subagent をリトライすべき場面
コーディネーターが subagent から構造化エラーを受け取ったら、次の判断はリトライするか・スキップするか・アボートするかだ。コーディネーターレベルのリトライロジックは、単一のエージェントループ内のリトライロジックとは微妙に異なる。
リトライ判断ツリー
- 構造化エラーの
isRetryableを読む。false なら、リトライしない;局所的ならスキップ、カスケード的ならアボートする。 isRetryableが true なら、このコーディネーターの実行でこの subagent のリトライ予算を確認する。subagent がすでに N 回リトライされている場合(典型的に N = 2 または 3)、リトライを停止する。- リトライ予算が利用可能なら、リトライ前に指数バックオフを適用する(1 秒待機、次に 2 秒、次に 4 秒)。即座のリトライは通常同じ一時的な状態にまた当たる。
- リトライが成功すれば、結果で続行する。再び失敗すれば、失敗カウンターをインクリメントしてステップ 2 に戻る。
- リトライ予算が尽きたら、その subagent の失敗をその subagent に対して終端と見なし、適切なフォールバックを適用する(局所的なら部分的結果処理;カスケード的ならアボート)。
リトライ予算 vs 反復上限
3 つの subagent と subagent あたり 2 回のリトライ予算を持つコーディネーターは、最大 9 回の subagent 実行の実効的な外部ループ反復回数を持つ(3 subagent × 3 試行)。これを各 subagent の内部エージェントループ反復上限と組み合わせると、総トークンエンベロープは大きくなる。予算計画は設計の一部だ。
べき等性の考慮
リトライは subagent の作業がべき等である場合のみ安全だ。毎回実行するたびにデータベースレコードを作成する subagent は安全にリトライできない。リトライすると重複が生まれる。ドキュメントを取得して要約する subagent はべき等だ。リトライは安全だ。設計時にこれらを区別する。subagent がべき等でない場合、isRetryable に関係なくコーディネーターがリトライを拒否するよう、その定義にエンコードする。
subagent が破壊的なアクション(本番データベースへの書き込み・メールの送信・有料 API の呼び出し)を実行することを説明する CCA-F シナリオは、コーディネーターレベルのリトライと組み合わせるべきではない。破壊的なアクションの自動リトライを推奨する回答は誤りだ。リトライはべき等な作業のためだけにある;破壊的な作業は fail-fast して人間にエスカレーションすべきだ。 Source ↗
部分的失敗処理 — 利用可能な subagent の結果でコーディネーターが続行する
実際の fail-safe 戦略は次のように見える:コーディネーターはすべての subagent から結果を収集し・欠落とエラーをギャップとして扱い・利用可能なデータで最善の回答を生成する。
アノテーションつきギャップパターン
すべての部分的な結果は、欠落しているものを明示的にアノテーションしなければならない。「3 つの情報源によれば」という研究の要約は正直で監査可能だ;「4 つの情報源によれば」という要約が 3 つしか応答していない場合、それは捏造による嘘だ。
アノテーションは最終の統合ステップに存在する。コーディネーターが subagent の出力を収集するとき、成功した結果と失敗プレースホルダーの両方を記録するデータ構造を構築し、ギャップを明示的に記述する指示とともにその構造を統合プロンプトに渡す。
閾値ロジック
部分的失敗処理は最小完全性閾値を超えた場合のみ安全だ。研究エージェントが 4 つのソースを参照することになっていて 1 つしか応答しなかった場合、「部分的な結果」は部分的ではない。それは 1 ソースだ。事前に閾値を定義する:
- 絶対的 — 少なくとも N の成功した subagent。
- 割合 — 少なくとも subagent の X %。
- 重要度重み付き — 特定の subagent が「必須」とマークされ、その失敗は他のどれだけが成功したかに関わらず強制的にアボートする。
試験シナリオにおける優雅な劣化
マルチエージェント研究システムシナリオは標準的な fail-safe の候補だ:4 つのトピック研究者が 1 つの統合者に報告する;1 つを失うことは許容できるが 3 つを失うことは許容できない。カスタマーサポート解決エージェントシナリオは戦略を混在させる:身元確認 subagent は重要(失敗時に fail-fast)、提案記事 subagent はオプション(fail-safe)。
エラー蓄積 — ハードアボートの閾値が発動するまでの複数のソフト失敗の追跡
すべてのエラーが個別に致命的なわけではない。コーディネーターは 1 回の気まぐれなツール呼び出しまたは 1 回の subagent のひっかかりを許容できるが、パターンが繰り返されれば必ずアボートしなければならない。エラー蓄積は、ノイズと実際の停止を区別するメカニズムだ。
蓄積パターン
コーディネーターの実行全体にわたって失敗カウンター(subagent ごと・ツールごと、またはグローバル)を維持する。各ソフト失敗(is_error: true の tool_result・errorCategory: transient の構造化エラー・最終試行でのみ成功したリトライ)で、カウンターをインクリメントする。任意のカウンターが閾値を越えたとき、コーディネーターの応答をエスカレーションする:
- 閾値以下:ログに記録・続行・組み込みのリトライロジックに依存する。
- 閾値で:オブザーバビリティにアラート・より安全な戦略に切り替える(低並列度・長いタイムアウト・シンプルなツールパス)。
- 閾値超過:実行をハードアボートして人間のレビューにエスカレーションする。
なぜ蓄積がエラーごとの反応に勝るか
すべての単一のソフト失敗に反応してアボートするコーディネーターは本番環境には脆弱すぎる。蓄積した失敗に全く反応しないコーディネーターは甘すぎ、劣化した状態で予算を喜んで消費する。蓄積閾値はノイズフロアを許容しながら、持続的な失敗を捕捉できるようにする。
マルチエージェントシナリオにおける蓄積
10 のトピック subagent をスポーンする研究コーディネーターは、1〜2 の個別の失敗を許容できる(部分的結果処理)が、同じ実行内で 4 つ以上が失敗した場合はハードアボートするかもしれない。1 回の実行での 4 つの失敗は、個別のソース問題ではなく上流の停止を示す可能性が高いからだ。
エラー蓄積チェックリスト(試験当日のために暗記する):
- subagent ごとおよびエラーカテゴリごとのカウンターを維持する。
- リトライで成功したものを含む、すべてのソフト失敗でインクリメントする。
- 実行が始まる前に閾値を設定する。動的にではない。
- 閾値を越えたときに応答をエスカレーションする。ハードアボートを待たない。
- 各新しいコーディネーター実行の開始時にカウンターをリセットする。
蓄積の履歴なしに現在のエラーだけに反応するコーディネーターを記述する回答は、CCA-F が期待する信頼性パターンを欠いている。 Source ↗
サーキットブレーカーパターン — 繰り返し失敗する subagent を無効にする
サーキットブレーカーは、下流の失敗が上流のシステムを圧倒することを防ぐための業界標準パターンだ。CCA-F は受験者にパターンを認識し・その 3 つの状態を知り・そして最も重要なこととして、それが組み込みの Agent SDK の機能ではなく自分で実装する設計パターンであることを知ることを期待する。
三つの状態
- クローズド — 通常の動作。リクエストは subagent に流れる。失敗がカウントされる。
- オープン — 失敗カウントが閾値を越えた。すべてのリクエストは subagent を試みることすらなくコーディネーターで拒否される。遅い失敗が速い失敗に置き換わる。
- ハーフオープン — クールダウン期間の後、単一のプローブリクエストが通過を許可される。成功すれば、ブレーカーはクローズドに戻る。失敗すれば、ブレーカーは別のクールダウンのために再オープンする。
なぜブレーカーが助けになるか
ブレーカーがなければ、持続的に失敗する subagent を持つコーディネーターはすべての実行でその subagent をリトライし、今やほぼ確実な失敗にトークンとレイテンシを無駄にする。ブレーカーはコーディネーターが不健全と証明された後に失敗した subagent を完全にスキップし、まだ機能している subagent のためにリソースを確保できるようにする。部分的失敗シナリオでは純粋なメリットだ:健全な subagent の出力をより速く得られる。
ブレーカー vs 蓄積器
蓄積器は単一の実行内のエラーを追跡してアボートのタイミングを決定する。ブレーカーは複数の実行にわたる(またはより長い時間ウィンドウの)エラーを追跡して無効にするタイミングを決定する。これらは補完的であり代替ではない。本番のマルチエージェントシステムには通常両方がある。
ブレーカーはパターンであり SDK の機能ではない
これは CCA-F のエラー伝播サーフェスで 2 番目に多くテストされる微妙な点だ。Claude Agent SDK は subagent 呼び出し用の組み込みサーキットブレーカーを出荷していない。設計がサーキットブレーカーに依存するなら、subagent 呼び出しのラッパーを通じて・ランタイムの Polly / resilience4j のようなライブラリを通じて・またはコーディネーターのカスタム状態を通じて、自分で実装する責任がある。
一般的な誤答選択肢は「Agent SDK のサーキットブレーカーを有効にする」または「設定で組み込みの subagent サーキットブレーカーを設定する」と主張する。どちらの言い回しも誤りだ。サーキットブレーカーはコーディネーターの呼び出しラッパーに実装するパターンの選択だ。フラグをオンにする組み込みの SDK の機能ではない。サーキットブレーカーを SDK 設定として記述する回答は誤りだ。 Source ↗
エラー報告連鎖 — 根本原因エラーをトップレベルコーディネーターに伝える
深いマルチエージェントシステムでは、3 層下で発生したエラーは根本原因を保持した状態でトップレベルコーディネーターに見える必要がある。エラー報告連鎖はこれを可能にする規律だ。
フラット化せず、ラップする
N 層のコーディネーターが N+1 層の subagent からエラーを捕捉するとき、それを一般的な文字列に圧縮するのではなく、自分のコンテキストを追加しながら独自の構造化ペイロードでそのエラーをラップしなければならない。N-1 層の受け手は外側のラッパーから内側の根本原因まで掘り下げられるべきだ。
概念的にペイロード連鎖は入れ子人形のようだ:
- 外側のラッパー:
{ source: "synthesis_coordinator", errorCategory: "subagent_failure", cause: ... } - 中間のラッパー:
{ source: "topic_coordinator", errorCategory: "tool_failure", cause: ... } - 最内部:
{ source: "web_search_tool", errorCategory: "transient", message: "connection timeout" }
根本原因の帰属
トップレベルのログとユーザー向けのエラーメッセージは、デバッグのために完全な連鎖を保持しながら、最内部のエラーのカテゴリとメッセージを優先するべきだ。「検索ツールがタイムアウトしたためリクエストを完了できませんでした」というユーザー向けのメッセージは、より完全ではあるが「統合コーディネーターが失敗した:トピックコーディネーターが失敗した:ウェブ検索ツールが失敗した:タイムアウト」よりも明確だ。
Correlation-ID による結び付け
連鎖のすべてのエラーは同じ correlationId を運ぶ。これにより、オブザーバビリティ層が分散トレースから完全なエラーツリーを事後的に再構築できる。エンドユーザーのエラー報告が薄い要約であっても、エンジニアは完全な連鎖が必要なときに見られる。
マルチエージェントエラーのオブザーバビリティ — 分散トレーシングと Correlation ID
見えないものはデバッグできない。マルチエージェントのエラー伝播は、明示的なオブザーバビリティなしには見えない。CCA-F は受験者が本番のマルチエージェントシステムの最小限のオブザーバビリティサーフェスを知ることを期待する。
すべての subagent 呼び出しが発行すべきもの
- 開始イベント — タイムスタンプ・subagent 名・コーディネーターの correlationId・親スパン ID・入力トークン数。
- ツール呼び出しイベント — subagent 内のすべての
tool_useとtool_result(単一エージェントループのオブザーバビリティサーフェスと一致する)。 - 終了イベント — タイムスタンプ・継続時間・最終ステータス(成功 / ソフトエラー / ハードエラー)・出力トークン数・失敗した場合の構造化エラーペイロード。
Correlation ID
correlationId(または traceId)はトップレベルコーディネーターで生成され、すべての subagent 呼び出し・ツール呼び出し・エラーペイロードを通じて伝播される一意の識別子だ。ログからエージェントをまたぐフロー全体を再構築できるようにする主キーだ。
Correlation ID がなければ、コーディネーターとその subagent からのログは 3 つの別々の河川であり、どの subagent のログ行がどのコーディネーター実行に属するかを判断できない。Correlation ID があれば、すべてのエージェントのすべてのログ行を単一のトレースに縫い合わせられる。
分散トレーシングのスパン
各 subagent 呼び出しはコーディネーターの親スパンの下のスパンだ。subagent 内の各ツール呼び出しは subagent のスパンの下の子スパンだ。結果として得られるツリーは実行の正確な形状を視覚化する。どの subagent がどれだけかかったか・どのツール呼び出しが失敗したか・どこでレイテンシが蓄積したかを含む。トレーシングツール(OpenTelemetry・Datadog APM など)はスパンと correlationId が正しく発行されると、このツリーをネイティブにレンダリングする。
なぜオブザーバビリティが伝播戦略の構成要素なのか
エラー伝播は発生後にエラーをどう処理するかだ。オブザーバビリティはエラーが発生したときに何が見えるかだ。オブザーバビリティなしでは、正しく伝播されたエラーでさえ推測でデバッグされる。CCA-F シナリオは時々「このマルチエージェントシステムが失敗していることをどうやって知るか?」として問いをフレーミングする。答えは常に構造化ログ + correlation ID + 分散トレーシングであり、「サーバーに SSH してgrepする」ではない。
マルチエージェントのオブザーバビリティは CCA-F では省略できない。最初にトレーシングと correlation ID を追加せずに壊れたマルチエージェントシステムを修正することを推奨するシナリオの回答は誤りだ。それらを見るためのオブザーバビリティなしには、エージェントをまたぐエラーについて推論できない。ましてや、それらを意味のある形で伝播させることなど到底できない。 Source ↗
白話文解釋(平易な言葉での解説)
エラー伝播は、多くの人がすでに知っているシステムに根ざしているときに抽象から具体になる。三つの非常に異なる比喩が概念の全体像をカバーする。
比喩 1:病院のトリアージネットワーク — エラー分類と fail-fast vs fail-safe
メインのトリアージデスク(コーディネーター)が入ってくる患者を専門の病棟(subagent)に振り分ける病院を想像してほしい:循環器内科・放射線科・整形外科・一般検査室。胸の痛みを訴える患者が来た。トリアージデスクは 4 つすべての病棟に同時にリクエストを送る。循環器内科は心電図の結果を素早く報告し;放射線科は胸部 X 線を報告し;整形外科は関連するものなしと報告し;しかし一般検査室は遠心分離機が壊れて血液パネルを 2 時間実行できないと報告する。今やトリアージデスクは決定しなければならない。欠けている血液パネルが重要(疑われる心臓発作の心臓酵素)なら、トリアージデスクは fail-fast する。オンコール医師にエスカレーションし、完全な情報を持っているふりをしない。欠けた検査結果があっても良いもの(通常のビタミン D の確認)なら、トリアージデスクは fail-safe する。「ビタミン D は未定、明日リトライ」というアノテーションを付けたレポートを生成する。今週 3 回目に壊れた遠心分離機はカスケード的な永続的問題だ(新しい遠心分離機を注文し、リトライし続けない)。ときどき誤動作する遠心分離機は一時的だ(再起動後にリトライする)。病院にはまたルールがある:1 シフトで 3 つの機器が壊れたら部門長にエスカレーションする。それがエラー蓄積だ。ある機器が 1 ヶ月で 12 回壊れたら、メンテナンスが認定するまでそこにジョブを送るのをやめる。それがサーキットブレーカーだ。すべての患者・すべての検査・すべての技術者は同じ入院 ID を持っており、問題を追跡できる。それが correlationId だ。良いエラー伝播を持つマルチエージェント Claude システムは、トリアージデスクが欠けた結果を存在するかのように見せかけず、1 台のマシンが停止しただけで止まらない病院だ。
比喩 2:コンテナ埠頭 — 封じ込めと境界
複数のクレーンが異なる船に積み込む埠頭を想像してほしい。1 台のクレーンの油圧が荷物を持ち上げる最中に故障しても、その失敗が隣のクレーンにカスケードしたり・埠頭の管制塔を倒したり・積み込み中の船を沈めたりしないようにしたい。各クレーンは失敗を隔離する自動シャットオフを持つ鋼鉄補強ゾーンで動作する:クレーンが止まり・警報が鳴り・管制塔が構造化されたインシデントレポート(クレーン #3、油圧圧力損失、荷物はすでに停止中、失敗時刻)を受け取り・他のクレーンは作業を続ける。それがエラー封じ込めだ。管制塔のインシデントレポートは構造化ペイロードで、「どこかのクレーンで何かが間違っている!」という慌てた叫びではない。どのクレーン・どのカテゴリの失敗(機械的か電気的かオペレーターか天候か)・それがリトライ可能か(10 分間冷やす)か永続的か(メンテナンスを呼ぶ)か・そしてこのインシデントを荷物のマニフェストに結び付ける参照番号を指定する。埠頭の監督官は 1 台のクレーンの警報に基づいて船全体の積み込みをアボートするかどうかを決定しない。依存マップを確認する。船 #7 は 6 コンテナのうち 4 コンテナで出港できるか?できるなら、部分的な積み込みで fail-safe する;できないなら、fail-fast してスケジュールを組み直す。このコレオグラフィなしの埠頭は、すべてのクレーンの障害を完全な埠頭のシャットダウンに変える。封じ込めなしのマルチエージェントシステムは、すべての subagent の例外をコーディネーターのクラッシュに変える。
比喩 3:電力網 — サーキットブレーカーとカスケード防止
都市の電力網はサーキットブレーカーパターンの最もきれいな比喩だ。名前自体が電気工学から来ているからだ。変圧器が故障すると、その変圧器に取り付けられたブレーカーがオープンにトリップする。変圧器を網の残りから切り離す。故障が隣接する機器を焼き切る前に。ブレーカーは局所的な失敗と連鎖停電の間の境界だ。すべての家に 1 つあり(メインブレーカー)・すべての近所の変電所に 1 つあり・すべての送電線に 1 つあり、マルチエージェントシステムのコーディネーター階層と同様に正確に層を重ねている。ブレーカーがトリップした後、電力網のオペレーターはすぐに再クローズしない;クールダウン期間を経て(ハーフオープン状態)、テスト再通電を試みる。故障が一時的(木の枝が電線に落ちたが今は除去された)なら、ブレーカーはクローズのままでサービスが再開する。故障が永続的(変圧器自体が壊れた)なら、ブレーカーは即座に再トリップし、人間が介入するまでオープンのままになる。ブレーカーなしの電力網は、単一の故障が地域全体を停電させる電力網だ。これはまさに、dead な subagent を無限にリトライするマルチエージェント Claude システムで起こることだ。重要なことに、ブレーカーは電力網オペレーターが「制御ソフトウェアのスイッチでオンにする」ものではない。設置されてワイアリングされなければならない物理デバイスだ。CCA-F はこの微妙な点をテストする:subagent のサーキットブレーカーは実装するパターンであり、トグルする SDK の設定ではない。
どの比喩がどの試験問題に合うか
- 分類・fail-fast vs fail-safe・部分的失敗処理に関する問題 → 病院トリアージの比喩。
- 封じ込め境界・構造化ペイロード・クラッシュ伝播の防止に関する問題 → 埠頭の比喩。
- サーキットブレーカー・繰り返し失敗の無効化・カスケード防止に関する問題 → 電力網の比喩。
典型的な試験の罠
CCA-F ドメイン 5 はマルチエージェントシステムのエラー伝播に関する 6 つの繰り返しパターンを一貫して活用する。以下のすべての罠はもっともらしい誤答選択肢として偽装されてコミュニティの合格報告に登場している。
罠 1:コンテキスト分離がエラー分離と等しいと仮定する
subagent は分離された context window で実行され、コーディネーターの会話履歴が subagent のメッセージで汚染されることを保護する。誤答選択肢はこの事実を「subagent の失敗はコーディネーターに影響を与えられない」という偽の主張に拡張する。できる。捕捉されない subagent の例外は依然としてコーディネーターのプロセスをクラッシュさせる;不正な形式の出力を返す subagent は依然としてコーディネーターの統合ステップを破損させる。すべての subagent 呼び出しの周りに明示的な try-catch に加えて出力バリデーションが必要だ。コンテキスト分離を自動的なエラー分離として扱う回答は誤りだ。
罠 2:サーキットブレーカーを SDK 組み込みとして扱う
サーキットブレーカーパターンは分散システムで広く理解されているため、受験者は Agent SDK がそれを提供しているはずだと思う。提供していない。「SDK の subagent サーキットブレーカーを有効にする」や「settings.json でサーキットブレーカーの閾値を設定する」などの誤答選択肢は作り話だ。サーキットブレーカーはコーディネーターの subagent 呼び出しラッパーに実装する設計パターンだ。SDK のトグルとして言い表す回答は誤りだ。
罠 3:永続的エラーのリトライ
リトライは一時的エラーのためだ。権限拒否・スキーマ違反・リソースが見つからないは、待ってから再試行することでリトライ可能にならない。誤答選択肢は権限エラーに対する答えとして「指数バックオフで 3 回リトライする」を提案する;これは(既知の無駄な試みにトークンと時間の予算を消費するため)無駄であり、(破壊的な操作では 2 回目と 3 回目の試みが損害を倍増させる可能性があるため)積極的に危険だ。isRetryable: true に対してのみリトライを制限すること。
罠 4:エラー連鎖のフラット化
subagent のエラーを捕捉して単純な文字列として再スローするコーディネーターは、回復ロジックとデバッグの両方に必要な根本原因情報を破壊する。誤答選択肢は「再スローする前にエラーを説明的なメッセージに変換する」を推奨する。これは責任感があるように聞こえるが、実際には構造を消去する。正しい動作は内側の構造化エラーを外側の構造化エラーにラップし、完全なネストを保持することだ。ユーザー向けのメッセージは単純化できる;ログに記録されるペイロードはそうであってはならない。
罠 5:べき等でない subagent のリトライ
データベースに書き込む・メールを送る・クレジットカードに請求する subagent は安全にリトライできない。リトライは副作用を重複させる可能性がある。誤答選択肢は「一時的なエラーでトランザクション subagent をリトライする」を正解として提示する;これは誤りだ。べき等でない subagent は任意のエラーで fail-fast し、人間のレビューまたは補償アクション subagent に委任しなければならない。べき等性はエラータイプではなく subagent の作業の特性だ。
罠 6:すべての局所的エラーでアボートする
Fail-fast が常に正しいわけではない。subagent が独立していて部分的な出力が価値を持つ場合、最初の局所的エラーでアボートすることは健全な subagent の作業を無駄にする。誤答選択肢は「安全な」選択として「任意のトピック subagent が失敗したときに研究パイプラインをアボートする」をフレーミングする;マルチエージェント研究システムシナリオでは、1 つの失敗したソースとの一貫性を保つために 3 つの成功したソースを失うことは、fail-safe の部分的結果パスが正しい。アボートを決定する前に、常にエラーが局所的かカスケード的かを検査すること。
実践アンカー
エラー伝播の概念は 6 つの CCA-F シナリオのうち 2 つで最も多く登場する。以下をタスク 5.3 をテストするシナリオクラスター問題のアーキテクチャ骨格として扱うこと。
マルチエージェント研究システムシナリオ
このシナリオでは、トップレベルの研究コーディネーターがトピック subagent のセット(多くの場合 4〜8)をスポーンし、それぞれがウェブ検索・ドキュメント読み込み・要約ツールを呼び出して独立したトピックを研究する。subagent が報告し、統合 subagent が出力を最終レポートに縫い合わせる。ここでのエラー伝播問題はほぼ常に fail-safe / 部分的結果の象限に属する:1〜2 つのトピック subagent が一時的なネットワークエラーで失敗する;コーディネーターは進めるかどうかを決定しなければならない。正解はほぼ常に(1)errorCategory と isRetryable を持つ構造化エラーペイロード・(2)予算までの指数バックオフを持つコーディネーターレベルのリトライ・(3)最終統合での欠落ソースの明示的なアノテーションを持つ部分的結果処理・(4)コーディネーターが完全にアボートする閾値(例えば subagent の半分未満が成功する)を含む。「最初の失敗でアボートする」または「無限にリトライする」を誤ったパスとして提供する罠を期待してほしい。
カスタマーサポート解決エージェントシナリオ
このシナリオでは、サポートコーディネーターが受信チケットを一連の subagent(身元確認・アカウントルックアップ・知識ベース検索・返答起草)にルーティングする。研究シナリオとは異なり、これらの subagent は独立していない。下流の作業は上流の結果に依存する。ここでのエラー伝播問題は fail-fast の象限をテストする:身元確認が失敗すれば、すべての下流の subagent は無効な前提で動作しており進んではいけない。正解は通常(1)コーディネーターでのカスケード的エラー検出(身元の失敗は重要)・(2)リトライではなく人間のエージェントへの即座の fail-fast とエスカレーション・(3)人間が根本原因を見るための呼び出し元への構造化エラー報告・(4)そのサービスの持続的な停止がキュー全体をブロックしないようにする身元確認 subagent 周辺のサーキットブレーカーを含む。このシナリオを研究シナリオと混同する罠を期待してほしい。未確認の身元での部分的なサポート解決は危険なため、ここでは部分的結果処理は誤りだ。
よくある質問 — エラー伝播トップ 5 の質問
エラーはどのように subagent からコーディネーターに伝播するか?
あなたのコードが subagent 呼び出しサイトで生成するいかなる戻り値を通じてのみ伝播する。コーディネーターは自動的に subagent エラーを「見る」ことはない;ラッパーが返すものを見る。正しいパターンはすべての subagent 呼び出しを try-catch でラップし・捕捉した任意の例外を errorCategory・isRetryable・message・context・correlationId を持つ構造化エラーペイロードに変換し・そのペイロードを subagent の結果として返すことだ。コーディネーターはその結果を検査し、errorCategory に基づいてリトライするか・スキップするか・アボートするかを決定する。呼び出しサイトで捕捉されない subagent の例外は、コンテキスト分離に関わらずコーディネーターのプロセスをクラッシュさせる。コンテキスト分離は会話履歴を保護するが制御フローは保護しない。
subagent のコンテキスト分離はコーディネーターへのエラーカスケードを自動的に防ぐか?
いいえ。これはエラー伝播サーフェスで最もテストされる微妙な点だ。subagent のコンテキスト分離とは、subagent が独自の会話履歴を持ち、それがコーディネーターの履歴に流入しないことを意味する。これにより履歴の破損を防ぎトークン管理に役立つ。プロセスレベルまたは制御フローのカスケードは防がない:未処理の subagent の例外は依然としてコーディネーターをクラッシュさせ、不正な形式の subagent の結果は依然としてコーディネーターの統合を破損させる。真のエラー分離を達成するには、すべての subagent 呼び出しの周りに明示的な try-catch と出力バリデーションが必要だ。コミュニティの合格報告はコンテキスト分離をエラー分離と混同する回答を最上位の誤答選択肢として一貫して指摘する。
コーディネーターが失敗した subagent をリトライするのか部分的な結果で進むのかをどう判断するか?
エラーペイロードの isRetryable が true であり・この subagent のリトライ予算が尽きていず・subagent の作業がべき等(リトライが副作用を重複させられない)である場合にリトライする。リトライ間には指数バックオフを使う(典型的に 1 / 2 / 4 秒)。エラーが永続的またはリトライ予算が尽きており・subagent が局所的(他の subagent の作業がまだ有効)であり・下流の統合ステップがギャップを正直にアノテーションできる場合に部分的な結果で進む。エラーがカスケード的(下流の作業がこの subagent に依存する)または実行全体のソフト失敗の蓄積が事前設定の閾値を越えた場合に実行全体をアボートする。
サーキットブレーカーパターンは Agent SDK の組み込み機能か?
いいえ。サーキットブレーカーは subagent 呼び出しのラッパーとして、またはランタイムのレジリエンスライブラリを通じて自分で実装する設計パターンだ。Agent SDK はコンテキスト分離と構造化結果を持つ subagent プリミティブを提供するが、設定可能なサーキットブレーカーは出荷していない。トグルできる circuitBreaker: { threshold: 5 } の設定はない。サーキットブレーカーは実行にわたって(またはある時間ウィンドウにわたって)失敗カウントを追跡し・閾値を越えたときにオープンし・クールダウンを待ち・完全にクローズする前に単一のリクエストでプローブする。サーキットブレーカーを SDK の設定フラグとして説明する回答は作り話であり試験では誤りだ。
複数のコーディネーター層にわたって根本原因エラー情報を保持するにはどうすればよいか?
フラット化せず、ラップする。外側のコーディネーターが内側のコーディネーターまたは subagent から構造化エラーを捕捉するとき、元の構造化ペイロードを cause フィールドとして保持しながら自分のコンテキスト(どの内側のコンポーネントが失敗したか・どの反復で・どの入力で)を追加するべきだ。結果として得られるエラーはネストされた構造で、最外側のラッパーはコーディネーターが失敗を見た場所を反映し・最内部の層が本当の根本原因を反映する。すべての層が同じ correlationId を共有するため、分散トレーシングが推測なしに連鎖を縫い合わせられる。ユーザー向けのメッセージは根本原因を要約できる(例えば「ウェブ検索ツールがタイムアウトした」)が、ログに記録されるペイロードはエンジニアがデバッグできるように完全なネストを保持するべきだ。「再スローする前に内側のエラーを説明的な文字列に変換する」を推奨する回答は必要な情報を破壊し、誤りだ。
さらなる学習リソース
- Subagents in the Agent SDK — error propagation: https://docs.anthropic.com/en/docs/claude-code/sdk/subagents
- Handle tool calls — tool_result format and structured errors: https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/handle-tool-calls
- Orchestrate teams of Claude Code sessions (Agent Teams): https://code.claude.com/docs/en/agent-teams
- Building effective agents — escalation and failure handling: https://docs.anthropic.com/en/docs/build-with-claude/agentic-loop
- Tool use with Claude — overview and agentic loop: https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview
関連 ExamLab トピック: コーディネーター・サブエージェントパターンによるマルチエージェントオーケストレーション、MCP ツールの構造化エラー応答、エスカレーションと曖昧さ解決、抽出のためのバリデーション・リトライ・フィードバックループ。