executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
circuit-breaker-patternエージェントのツール呼び出しにサーキットブレーカーロジックを実装する — ツールの健全性を追跡し、 closed/open/half-open 状態間を遷移し、ツールが失敗した際にタスクのスコープを縮小し、 ケイパビリティマップを通じて代替手段にルーティングし、エラーの蓄積を防ぐための障害バジェットを強制する。 オーケストレーション(何を試みるかの決定)と実行(ツールの呼び出し)を分離し、エクスペディターパターンに従う。 信頼性が異なる複数のツールに依存するエージェントを構築する場合、耐障害性のあるエージェントワークフローを設計する場合、 タスク途中のツール停止から適切に回復する場合、または連鎖的なツール障害に対して既存エージェントを強化する場合に使用する。
Independent GitHub snapshot · Automated classification · Original documentation governs
ツールが失敗した際のグレースフルデグラデーション。5つのツールを呼び出すエージェントで1つが壊れている場合、全体が失敗するべきではない — 壊れたツールを認識し、それへの呼び出しを止め、残りで達成可能なスコープに縮小し、スキップした内容を誠実に報告するべきだ。このスキルは、分散システムのサーキットブレーカーパターンをエージェントのツールオーケストレーションに適応させ、そのロジックを体系化する。
核心的な洞察(kirapixelads の「Kitchen Fire Problem」より):エクスペディター(オーケストレーション層)は「料理」をしてはならない。「何を試みるか」と「どのように試みるか」の関心の分離は、オーケストレーターが失敗したツールの再試行ループに囚われることを防ぐ。
各ツールが何を提供し、どんな代替手段が存在するかを宣言する。このマップはスコープ縮小の基盤 — これがなければ、ツールの失敗はエージェントに次に何をすべきか推測させることになる。
capability_map:
- tool: Grep
provides: content search across files
alternatives:
- tool: Bash
method: "rg or grep command"
degradation: "loses Grep's built-in output formatting"
- tool: Read
method: "read suspected files directly"
degradation: "requires knowing which files to check; no broad search"
fallback: "ask the user which files to examine"
- tool: Bash
provides: command execution, build tools, git operations
alternatives: []
fallback: "report commands that need to be run manually"
- tool: Read
provides: file content inspection
alternatives:
- tool: Bash
method: "cat or head command"
degradation: "loses line numbering and truncation safety"
fallback: "ask the user to paste file contents"
- tool: Write
provides: file creation
alternatives:
- tool: Edit
method: "create via full-file edit"
degradation: "requires file to already exist for Edit"
- tool: Bash
method: "echo/cat heredoc"
degradation: "loses Write's atomic file creation"
fallback: "output file contents for the user to save manually"
- tool: WebSearch
provides: external information retrieval
alternatives: []
fallback: "state what information is needed; ask user to provide it"
各ツールについて以下を記録する:
期待結果: エージェントが使用するすべてのツールを網羅する完全なケイパビリティマップ。各エントリには、ツール代替がなくてもフォールバックが少なくとも1つある。このマップは通常暗黙的なことを明示的にする:どのツールが重要(代替なし)で、どのツールが代替可能か。
失敗時: ツールリストが不明確な場合、スキルのフロントマターの allowed-tools から始める。代替が不確かな場合、省略するよりも degradation: "unknown — test before relying on this route" とマークする。
各ツールの状態トラッカーを設定する。すべてのツールは CLOSED 状態(健全、通常動作)で開始する。
Circuit Breaker State Table:
+------------+--------+-------------------+------------------+-----------------+
| Tool | State | Consecutive Fails | Last Failure | Last Success |
+------------+--------+-------------------+------------------+-----------------+
| Grep | CLOSED | 0 | — | — |
| Bash | CLOSED | 0 | — | — |
| Read | CLOSED | 0 | — | — |
| Write | CLOSED | 0 | — | — |
| Edit | CLOSED | 0 | — | — |
| WebSearch | CLOSED | 0 | — | — |
+------------+--------+-------------------+------------------+-----------------+
Failure budget: 0 / 5 consumed
状態の定義:
状態遷移:
期待結果: すべてのツールに対して CLOSED 状態とゼロの失敗カウントで初期化された状態テーブル。障害閾値とバジェットが明示的に宣言されている。
失敗時: ツールリストを事前に列挙できない場合(動的ツール検出)、各ツールの初回使用時に状態を初期化する。パターンはまだ適用される — テーブルを段階的に構築するだけだ。
エージェントがツールを呼び出す必要がある場合、この決定シーケンスに従う。これはエクスペディターロジック — 呼び出しを「どのように実行するか」ではなく「試みるかどうか」を決定する。
BEFORE each tool call:
1. Check tool state in the circuit breaker table
2. If OPEN:
a. Check if it is time for a half-open probe
- Yes → transition to HALF-OPEN, proceed with probe call
- No → skip this tool, route to alternative (Step 4)
3. If HALF-OPEN:
a. Make one probe call
b. Success → transition to CLOSED, reset consecutive fails to 0
c. Failure → transition to OPEN, increment failure budget
4. If CLOSED:
a. Make the call normally
AFTER each tool call:
1. Success:
- Reset consecutive fails to 0
- Record last success timestamp
2. Failure:
- Increment consecutive fails
- Record last failure timestamp and error message
- Increment failure budget consumed
- If consecutive fails >= threshold:
transition to OPEN
log: "Circuit OPENED for [tool]: [failure count] consecutive failures"
- If failure budget exhausted:
PAUSE — do not continue the task
Report to user (Step 6)
エクスペディターは失敗した呼び出しを即座に再試行しない。障害を記録し、閾値を確認して、先へ進む。再試行は後のステップでのハーフオープンプローブメカニズムを通じてのみ発生する。
期待結果: エージェントがすべてのツール呼び出しの前後に従う明確な決定ループ。ツールの健全性は継続的に追跡される。エクスペディター層は失敗したツールをブロックしない。
失敗時: 呼び出し間の状態追跡が実用的でない場合(例: ステートレス実行)、よりシンプルなモデルへのデグレード:合計失敗をカウントしてバジェットで一時停止。3状態のサーキットブレーカーが理想的だが、障害カウンターが最小限の実行可能なパターンだ。
ツールのサーキットが OPEN の場合、ケイパビリティマップ(ステップ1)を参照して最善の利用可能な代替手段にルーティングする。
ルーティング優先度:
Example routing decision:
Tool needed: Grep (circuit OPEN)
Task: find all files containing "API_KEY"
Route 1: Bash with rg command
→ Degradation: loses Grep's built-in formatting
→ Decision: ACCEPTABLE — use this route
If Bash also OPEN:
Route 2: Read suspected config files directly
→ Degradation: requires guessing which files; no broad search
→ Decision: PARTIAL — try known config paths only
If Read also OPEN:
Route 3: Ask user
→ "I need to find files containing 'API_KEY' but my search
tools are unavailable. Can you run: grep -r 'API_KEY' ."
→ Decision: FALLBACK — user provides the information
If user unavailable:
Route 4: Scope reduction
→ Remove "find API key references" from task scope
→ Document: "SKIPPED: API key search — no tools available"
期待結果: ツールサーキットが開いた場合、エージェントは透明に代替手段にルーティングするかスコープをデグレードする。ルーティングの決定と任意のデグラデーションはタスク出力に記録され、ユーザーは何が影響を受けたかを知る。
失敗時: ケイパビリティマップが不完全な場合(代替がリストされていない)、デフォルトでスコープ縮小して報告する。作業をサイレントにスキップしない — 何をスキップしたか、なぜかを常に記録する。
ツールがオープンサーキットで代替手段が尽きた場合、動作中のツールで達成可能な作業にタスクを縮小する。これは失敗ではない — 誠実なスコープ管理だ。
スコープ縮小プロトコル:
Scope Reduction Report:
Original scope: 5 sub-tasks
[x] 1. Read configuration files (Read: CLOSED)
[x] 2. Search for deprecated patterns (Grep: CLOSED)
[ ] 3. Run test suite (Bash: OPEN — no alternative)
[x] 4. Update documentation (Edit: CLOSED)
[ ] 5. Deploy to staging (Bash: OPEN — no alternative)
Reduced scope: 3 sub-tasks achievable
Deferred: 2 sub-tasks require Bash (circuit OPEN)
Recommendation: Complete sub-tasks 1, 2, 4 now.
Sub-tasks 3 and 5 require Bash — will probe on next cycle
or user can run commands manually.
延期されたサブタスクを試みてはならない。うまくいくことを期待してオープンサーキットのツールを再試行してはならない。サーキットブレーカーはまさにこれを防ぐために存在する — その状態を信頼する。
期待結果: タスクが達成可能な作業と延期された作業に明確に分割される。エージェントはすべての達成可能な作業を完了し、延期された項目をその理由と何がブロックを解除するかとともに報告する。
失敗時: スコープ縮小がすべてのサブタスクを削除する場合(すべてのツールが壊れている)、ステップ6に直接スキップ — 一時停止して報告する。作業中のツールがないエージェントは進捗を上げているふりをしてはならない。
ツールが古い可能性のあるデータ(キャッシュされた結果、古いスナップショット、以前に取得したコンテンツ)を返す場合、最新として扱うのではなく明示的にラベル付けする。
古さの指標:
ラベル付けプロトコル:
When presenting potentially stale data:
"[STALE DATA — retrieved at {timestamp}, may not reflect current state]
File contents as of last successful Read:
..."
"[CACHED RESULT — Grep returned identical results to previous call;
filesystem may have changed since]"
"[UNVERIFIED — WebSearch result from {date}; current status unknown]"
古いデータを最新として黙ってユーザーに提示してはならない。ユーザーまたは下流のエージェントは健全な判断を下すためにデータ品質を知る必要がある。
期待結果: 古い可能性のあるすべてのツール出力には明示的なラベルが付いている。最新データにはラベルが付かない(ラベル付けは確認ではなく不確実性のために予約されている)。
失敗時: 古さを判断できない場合(タイムスタンプなし、比較ベースラインなし)、不確実性をメモする:「[FRESHNESS UNKNOWN — no baseline for comparison]」。鮮度についての不確実性それ自体が情報だ。
すべてのツールにわたる合計失敗を追跡する。バジェットが尽きた場合、エージェントはエラーを蓄積し続けるのではなく一時停止して報告する。
Failure Budget Enforcement:
Budget: 5 failures per cycle
Current: 4 / 5 consumed
Failure 1: Bash — "permission denied" (step 3)
Failure 2: Bash — "command not found" (step 3)
Failure 3: Bash — "timeout after 120s" (step 4)
Failure 4: WebSearch — "connection refused" (step 5)
Status: 1 failure remaining before mandatory pause
→ Next tool call proceeds with heightened caution
→ If it fails: PAUSE and generate status report
バジェット枯渇時:
FAILURE BUDGET EXHAUSTED — PAUSING
Completed work:
- Sub-task 1: Read configuration files (SUCCESS)
- Sub-task 2: Search for deprecated patterns (SUCCESS)
Incomplete work:
- Sub-task 3: Run test suite (FAILED — Bash circuit OPEN)
- Sub-task 4: Update documentation (NOT ATTEMPTED — paused)
- Sub-task 5: Deploy to staging (NOT ATTEMPTED — paused)
Tool health:
Grep: CLOSED (healthy)
Read: CLOSED (healthy)
Edit: CLOSED (healthy)
Bash: OPEN (3 consecutive failures — permission/command/timeout)
WebSearch: OPEN (1 failure — connection refused)
Failures: 5 / 5 budget consumed
Recommendation:
1. Investigate Bash failures — likely environment issue
2. Check network connectivity for WebSearch
3. Resume from sub-task 4 after resolution
一時停止・報告は電気システムのサーキットブレーカーと同じ機能を果たす:ダメージの蓄積を防ぐ。壊れたツールを呼び続けるエージェントはコンテキストウィンドウを浪費し、繰り返されるエラーでユーザーを混乱させ、一貫性のない部分的な結果を生成する可能性がある。
期待結果: 障害バジェットが尽きた場合、エージェントはクリーンに停止する。レポートには完了した作業、未完了の作業、ツールの健全性、および実行可能な次のステップが含まれる。
失敗時: エージェントがクリーンなレポートを生成できない場合(例: 状態追跡が失われた)、利用可能な情報を出力する。部分的なレポートはサイレントな継続よりも優れている。
オーケストレーションロジック(ステップ2〜7)がツール実行から明確に分離されていることを確認する。
エクスペディター(オーケストレーション)がすること:
エクスペディターがしないこと:
エクスペディターが「料理」(他のツール障害を回避するためにツール呼び出しを行う)している場合、分離が壊れている。エクスペディターは代替ツールにルーティングするかスコープを縮小すべき — 壊れたツールを修正しようとするべきではない。
期待結果: オーケストレーションの決定とツール実行の間の明確な境界。エクスペディター層は特定のツール API やエラータイプを参照せずに説明できる。
失敗時: オーケストレーションと実行が絡み合っている場合、決定ロジックを各ツール呼び出しの前に実行する別のステップに抽出してリファクタリングする。決定ステップは4つの出力の1つを生成する:CALL、SKIP、PROBE、または PAUSE。実行ステップはその出力に基づいて行動する。
複数のツールがインフラストラクチャ(ネットワーク、ファイルシステム、権限)を共有する場合、単一の根本原因が複数のブレーカーを同時にトリップする可能性がある。各ブレーカーを独立して扱うのではなく、この相関パターンを検出して処理する。
連鎖的な障害の指標:
対応プロトコル:
バックオフ複合: 連鎖的な障害がトリガーされた場合、ハーフオープンのプローブに指数バックオフを使用する:ステップ3でプローブし、次にステップ6、次にステップ12。回復中のシステムを急速なプローブで圧倒することを防ぐために最大間隔を20ステップに制限する。
期待結果: 相関する障害はN個の独立したブレーカートリップではなく、単一の systemic イベントとして検出・処理される。障害バジェットはsystemic イベントをN回ではなく1回カウントする。
失敗時: 相関検出が実用的でない場合(障害が共有原因にもかかわらず異なるエラーシグネチャを持つ)、独立したツールごとのブレーカーにフォールバックする。システムはまだ適切にデグレードする — バジェットの消費が速くなるだけだ。
サーキットブレーカーループ(ステップ3)に参加する前に、オプションでツールが利用可能で成功する可能性が高いことを確認する。これにより予測可能な失敗からの不必要なブレーカートリップが減少する。
事前呼び出しチェック:
| チェック | 方法 | 失敗時のアクション |
|---|---|---|
| Tool exists | Verify tool is in the allowed-tools list | Skip — do not even attempt |
| MCP server health | Check server process/connection status | Route to alternative immediately |
| Resource availability | Verify target file/URL/endpoint exists | Route or degrade scope |
決定テーブル:
Pre-call score:
AVAILABLE → proceed to circuit breaker loop (Step 3)
DEGRADED → proceed with caution, lower the failure threshold by 1
UNAVAILABLE → skip tool, route to alternative (Step 4) without consuming budget
事前呼び出しチェックは参考的なものであり、権威的なものではない。事前呼び出しチェックをパスしたツールでも実行中に失敗する可能性がある。サーキットブレーカーは主要な信頼性メカニズムとして残る。
期待結果: 予測可能な失敗(ツールの欠如、到達不能なサーバー)が障害バジェットを消費する前にキャッチされる。サーキットブレーカーは本物のランタイム障害のみを処理する。
失敗時: 事前呼び出しチェックが利用できないかオーバーヘッドが大きすぎる場合、このステップを完全にスキップする。ステップ3のサーキットブレーカーループがすべての障害を処理する — 事前呼び出し選択は要件ではなく最適化だ。
fail-early-pattern — 補完的なパターン:fail-early は作業開始前に入力を検証する;circuit-breaker は作業中の障害を管理するescalate-issues — 障害バジェットが枯渇したりスコープ縮小が大きい場合、専門家または人間にエスカレーションするwrite-incident-runbook — 繰り返されるツール障害パターンを迅速な診断のためのランブックとして記録するassess-context — 複数のツールがデグレードされている場合に現在のアプローチが適応できるか評価する;スコープ縮小の決定と組み合わせるdu-dum — 観察と意思決定を分離する二重時計アーキテクチャ;エージェントループの観察コスト削減のための補完パターン