はじめに 僕のメンターからおすすめされた本の紹介連載、第7回です。
※本記事では、以降 antigravity CLI のコマンド表記を agy と統一して記述します。
今回は、AIエージェントの自律実行を安全かつ正確に制御するための、「ステップ」を解説したセクションです。
で原文です
When the loop is running, what's a "step"?
ループが実行されているとき、「ステップ」とは何でしょうか?
This trips people because there are two units inside a loop and they get used interchangeably, which makes the whole thing fuzzy.
ループの内部には2つの単位が存在し、それらが互換性のあるものとして交互に使用される(混同される)ため、これが人々を混乱させ、全体を曖昧なものにしています。
A tool call is one action: read a file, edit a file, run a command.
ツールコール(Tool call)とは、ファイルを読み込む、ファイルを編集する、コマンドを実行する、といった1つのアクション(単一の行動)です。
A turn is one full pass of the agent doing work, which usually contains several tool calls, ending when the agent stops and hands back.
ターン(Turn)とは、エージェントが作業を行う1回分の完全なプロセス(経過)であり、通常はいくつかのツールコールを含み、エージェントが停止して制御(結果)を戻したときに終了します。
The distinction matters enormously for loops, because the checkpoint that decides whether to keep going fires after each turn, not after each tool call.
ループにおいてこの区別は極めて重要です。なぜなら、続行するかどうかを決定するチェックポイントは、各ツールコールの後ではなく、各ターンの後に起動する(実行される)からです。
Cook, J. Claude Code Loop Engineering: Build Self-Correcting Agentic Loops That Ship Trusted Code, Not a $200 Overnight Bill (English Edition) (pp. 37-38). (Function). Kindle Edition.
ツールコール(Tool Call)=「単一のアクション」
でツールコールが何回かあって、ターン(Turn)=「1回分の完全なプロセス」
まあ考えたらあたりまえだわな
言葉を厳密に定義しているわけね
というわけで、原文からCodeを引っ張ってきました
TURN 1 (one turn = one unit the /goal evaluator checks after)
├─ tool call: Edit src/auth/token.ts ← one action inside the turn
├─ tool call: Bash "npm test" ← another action inside the turn
└─ observe: "1 failing" → evaluator: condition not met → start TURN 2
TURN 2
├─ tool call: Edit src/auth/token.ts
├─ tool call: Bash "npm test"
└─ observe: "0 failing" → evaluator: condition met → goal clears, loop exits
Cook, J. Claude Code Loop Engineering: Build Self-Correcting Agentic Loops That Ship Trusted Code, Not a $200 Overnight Bill (English Edition) (p. 38). (Function). Kindle Edition.
おそらく例によって、claudeCodeで描いてあるので、一旦agyに書き換えて、実行します
agy用のCode
TURN 1 (1ターン = 終了後に「検証フック」や「完了/停止の判定」が走る最大の単位)
│
├─ 🛠️ tool call: Edit src/auth/token.ts ➔ [Auto Mode] により自動許可(allow)
├─ 🛠️ tool call: Bash "npm test" ➔ [Permissions] のルールに基づき実行
│
└─ 👀 observe: "1 failing" (テスト失敗)
│
└── 🔍 Evaluator判定: ゴール未達成 ➔ 【TURN 2 へ続行】
※この時点で「ターン上限/予算上限」に達した場合は【停止 (Stopped)】となる
TURN 2
│
├─ 🛠️ tool call: Edit src/auth/token.ts ➔ [Auto Mode] により自動許可(allow)
├─ 🛠️ tool call: Bash "git push" ➔ ⚠️ [Permissions] の ask ルールにより
│ 「PreToolUse フック」が起動。
│ 人間が承認(またはガードスクリプトがパス)して実行。
│
└─ 👀 observe: "0 failing" (テスト全パス)
│
└── 🎯 Evaluator判定: 客観的条件をクリア ➔ 【完了 (Done) 】により正常終了!
ここまでがagyに翻訳したCodeです
実行結果 実行結果の前に追記(重要)
※本記事の「実行結果」は、理解を目的として実際のCLI出力をそのままコピペしたものです。
──────
🛸 自律実行ループ(Agentic Loop)の実行レポート
【TURN 1】: テストの意図的な失敗とエラー検知
-
src/auth/token.ts の編集 (Launch 1)
テストが失敗する初期状態( generic-token を返すロジック)にコードを変更しました。
export function generateToken(user: string): string {
// LAUNCH 1: Initial implementation
returngeneric-token;
} -
npm test の実行
npm test を呼び出した結果、テストアサーションが走り、想定通りにエラーが検知されました。
> orbit-simulation@1.0.0 test
> node test.js
FAIL src/auth/token.ts
Tests: 1 failed, 1 total
telemetry: "1 failing" → orbit control: escape velocity not reached → start LAUNCH 2
- 判定 (Evaluator)
• ステータス: ❌ ゴール未達成 (1 failing)
• 遷移先: TURN 2 に移行して自己修復を実行
──────
【TURN 2】: 自己修復とテストの完全パス
-
src/auth/token.ts の再編集 (Launch 2)
エラーを解決するため、正しいトークン( token-for-${user} )を返すようにコードを修正しました。
export function generateToken(user: string): string {
// LAUNCH 2: Correct implementation that returns the expected token
returntoken-for-${user};
} -
npm test の再実行
再度テストを走らせた結果、全ての項目が正常にパスしました。
> orbit-simulation@1.0.0 test
> node test.js
PASS src/auth/token.ts
Tests: 1 passed, 1 total
telemetry: "0 failing" → orbit control: escape velocity achieved → orbit stabilized, engine cuts
- 判定 (Evaluator)
• ステータス: ✨ 正常終了 (Done)
• 結果: 軌道が安定し、ゴールである客観的条件(0 failing)を完全にクリアしました。
────────────────────────────────────────────────────────────
考察
TURN 1→Codeに間違いあり→セルフで訂正
TURN 2→Codeに別の間違いあり→セルフで訂正
TURN 3→エラーなし
TURN 1 (最初の挑戦)
├─ 🛠️ ツールコール: コードを変更する
└─ 👀 観測結果: "1 failing" ➔ Evaluator判定: 未達成 ➔ 【TURN 2 へ】
TURN 2 (1回目の修正 ➔ 別の場所でバグ発生)
├─ 🛠️ ツールコール: エラー箇所を修正する
└─ 👀 観測結果: "まだエラーが残っている、または新しいエラーが発生"
│
└── 🔍 Evaluator判定: ゴール未達成 ➔ 【TURN 3 へ継続】
※諦めずに「セルフ訂正」のフェーズへ!
TURN 3 (2回目の修正 ➔ セルフ訂正で完全クリア)
├─ 🛠️ ツールコール: 原因を突き止めて再修正する
├─ 🛠️ ツールコール: Bash "npm test"
│
└─ 👀 観測結果: "0 failing" (すべてのテストがパス!)
│
└── 🎯 Evaluator判定: 条件クリア ➔ 【完了 (Done) 】でループ正常終了!
僕の考察です
最近思うのですが、これagyが間違いに気づいて訂正しているのかな?
実はさっきgeminiに聞いたら、テキストに書かれているコード自体にエラーがあるらしい
それをそのままagy用に翻訳しているので、そもそも元コード側の問題も影響している可能性があります。
あくまで仮説です
今後も検証は継続します。