はじめに
こんちには!GitHub Copilot Agent を毎日何かしら試しているShahinです!
この記事が少しでも参考になったら、ぜひいいね・共有をお願いします。
間違っている箇所や「ここが分かりにくかった」という指摘は、やさしくコメントいただけると助かります!
先日、X を眺めていたら @aktsmm さんのこんな投稿が流れてきました。
「ちょっと読んでみるか」のつもりだったんですが、読んだ瞬間に「あ、これ自分がずっと困ってたやつだ」と気づいてそのまま手を動かし始めてしまいました。
「Copilot に複雑なタスクを頼んだら、途中で止まってしまった」「何度も同じ失敗を繰り返してどんどん迷走した」こういう経験、けっこうあると思います。
AIエージェントって、シンプルなタスクはめちゃくちゃ得意なんですよね。でも複数ステップの複雑なゴールになると、途中で止まったり、同じ修正を繰り返して進まなかったり、「完了した」と言いながら実は全然できてなかったりする。
GOAL-Loop は、そこに正面から向き合った Skill です。@aktsmm さんが「AIエージェントを最後までやり切らせる」ための運用寄りのループ設計を SKILL.md にまとめたもので、GitHub Copilot・Claude Code といった Agentic な LLM 環境に適用できます。
リポジトリ: https://github.com/aktsmm/Agent-Skills/tree/master/goal-loop
実際に動かしてみたら設計思想がかなりしっかりしていて、個人的にかなりテンション上がりました!今日はこの Skill の仕組みを解説しつつ、デモも交えて紹介していきます。
GOAL-Loop って何?
一言でいうと「success criteria を最初に合意して freeze し、達成するまで orchestrator + evaluator のループを回す」という設計です。
よくある AI エージェントのアンチパターンを真正面から潰しにいく作りで、以下の問題に対処しています:
| 問題 | GOAL-Loop の対処 |
|---|---|
| 途中で迷走・止まる | 多層 stop 条件でループを制御 |
| 自己申告で "完了" にする | 外部 signal(test/lint/build の exit code)で検証 |
| 同じ失敗を繰り返す | attempt 教訓 table に記録し、同手を 2 回使わせない |
| いきなり全体変更して事故 | Small-Bet-First で最小単位から試す |
| 暴走して取り返しのつかない操作をする | Autonomy Mode で破壊的操作を制御 |
この SKILL.md を GitHub Copilot などに渡すと、エージェントが orchestrator の役割を担って、上記のルールに従ってゴールへ向かって動き続けます。
7 フェーズのフロー
GOAL-Loop は 7 つのフェーズで構成されています。
各フェーズをざっくり説明します。
Phase 1 — Criteria 合意 + Freeze(gate)
ここが一番大事です。
「何が達成されていれば完了か」を、エージェントと合意して 固定(freeze) します。フワッとした目標のまま実行させると、自分都合で「完了」にされてしまう。だから最初に検証コマンドつきで具体化します。
## Acceptance Criteria(各に verify: を必須)
- [ ] AC1: すべてのテストが pass する
- verify: `pytest -q` が exit 0
- [ ] AC2: 型エラーが 0 件
- verify: `mypy src/` が exit 0
- [ ] AC3: README に使い方が書かれている
- verify: `grep -c "## Usage" README.md` が 1 以上
「検証できない基準は、検証可能な形に書き直す」 という原則があって、これが地味に効いてます。曖昧な品質基準をコマンドで切れる形に変換するんですね。
Phase 2 — 計画
粗い全体計画を立てて、検証可能な最小サブゴールの列に分解します。細かく決めすぎず、前提が崩れたら Phase 6 で replan する前提です。
独立した read-only 調査は並列、mutation(書き込み)は直列、というルールも明示されています。
Phase 3 — Small-Bet-First + Worker 委譲
大きな変更をいきなり全体適用しない。1 ファイルで pilot → 外部検証 PASS → 残りへ展開、という手順です。
Worker には runSubagent で委譲し、自分(orchestrator)は進捗管理と判定に集中します。Worker に goal state を持たせないのがポイントで、worker は evidence を返すだけ。checkpoint の判断は orchestrator だけが行います。
Phase 4 — 外部検証
pytest、mypy、eslint、grep などのコマンドを実行して、exit code と実出力を取得します。
自己評価だけで PASS としない、推測で判断しない、というのが基本姿勢です。実際、自己評価だけの reflection はむしろ精度を下げることがあると、論文の引用とともに明示されています("Large Language Models Cannot Self-Correct Reasoning Yet")。
Phase 5 — 評価(Evaluator)
外部検証の出力を使って、rubric で criteria と突合します。生成ロールと評価ロールを分離し、position bias や verbosity bias を抑える工夫も含まれています。
Phase 6 — ループ判定(多層 stop)
ここが GOAL-Loop の心臓部です。
多層 stop と呼んでいて、max_iteration だけに頼らない設計になっています:
| 停止条件 | 動作 |
|---|---|
| 全 must PASS | 完了 |
| stall_counter ≥ 4 | replan |
| oscillation(同一操作の繰り返し) | replan か HITL |
| diminishing returns | HITL |
| budget 超過 | HITL |
同じ失敗を繰り返しているだけのとき(oscillation)は自動検知して replan に切り替える、というのが特に好きな部分です!
Phase 7 — 完了報告
各受入基準について verify: の証跡を示し、残リスクと次アクション(Deferred)をハンドオフします。
Two Ledgers — 状態管理の仕組み
GOAL-Loop では Task Ledger と Progress Ledger の 2 つで状態を管理します。
Task Ledger(ゴールと計画の現在像)
# Task Ledger — FastAPI リファクタリング
## Goal
src/ の全エンドポイントを async 対応にし、既存テストが全 pass する
## Acceptance Criteria(freeze済み)
- AC1: pytest -q が exit 0 / status: FAIL
- AC2: mypy src/ が exit 0 / status: FAIL
- AC3: 全エンドポイントが async def / status: 未検証
## 確定した事実
- routes/users.py: 3 関数が同期
- routes/items.py: すべて非同期済み
## 未確定の推測
- DB クライアントが非同期対応かどうか未確認
## 現計画(サブゴール列)
1. routes/users.py を async 化 — status: in_progress
2. DB クライアントを確認・必要なら差し替え — status: pending
3. pytest / mypy を全体実行 — status: pending
Progress Ledger(ループ進捗)
| iter | goal_satisfied? | making_progress? | stall_counter | 次アクション |
|---|---|---|---|---|
| 1 | No | Yes | 0 | AC1 再検証 |
| 2 | No | Yes | 0 | DB クライアント確認 |
| 3 | No | No | 1 | replan 検討 |
Attempt 教訓 Table
同じ失敗を繰り返さないための記録。worker には関連分だけ delta で渡します。
| # | subtask | approach | 外部 signal | 教訓 |
|---|---|---|---|---|
| 1 | AC1 | users.py を一括 async 化 | mypy FAIL: 型不一致 | 一括前に 1 関数で pilot する |
| 2 | AC1 | 1 関数で pilot | mypy PASS | 同パターンを残りへ展開可 |
Autonomy Mode — 自律度の設定
Phase 1 で「どこまで自律でやらせるか」を決めます。
| 操作 | Normal(既定) | 超自律(AUTO / FULL / ALL) |
|---|---|---|
| backup を取れる破壊的操作 | backup → 自律実行 | backup → 自律実行 |
| backup 不能の不可逆操作 | HITL | 実行可(rollback 不能を明記) |
| criteria の緩和・再定義 | HITL(再合意) | 自分で緩和し記録+通知して継続 |
| verify 検証手段の修正 | 常に自由 | 常に自由 |
「超自律モードでも criteria の偽装は禁止」「秘密情報の露出は対象外」という抜け道封鎖もしっかり書かれています。この辺の設計が丁寧だなと思いました。
Effort Scaling — 小さいゴールに full ループを被せない
全タスクに 7 フェーズを適用するのは過剰なので、規模に応じて重さを変えます。
| ゴールの規模 | 対応 |
|---|---|
| 些末(1 ファイル・自明) | このスキルを使わず直接実行 |
| 小(数ステップ・低リスク) | 軽量 orchestrator で OK |
| 中(複数成果物・依存あり) | 通常ループ |
| 大(不可逆・広範囲・多段) | 厳格ループ + Durable Ledger |
ここが「実用的だな」と感じた部分で、ちゃんと使い分けが設計されているんですよね。
デモ:実際に GitHub Copilot Agent で使ってみる
VS Code の GitHub Copilot Agent モードで、実際に動かした様子を紹介します。
検証環境
- VS Code + GitHub Copilot(Agent モード)
-
.github/skills/goal-loop/SKILL.mdをリポジトリに配置済み - タスク:3層構造の Python プロジェクト(routes / services / db)を全 async 対応にする
Step 1: ゴールを投げる → Phase 1 Criteria 合意
まず /goal-loop でスキルを呼び出して、ゴールを自然言語で渡します。
GOAL-Loop に「routes/services/db の全関数を async 対応に」と投げた直後。ファイルを読み込んで Phase 1 に入ります。
すぐに Phase 1 が始まり、コードを調査してから Criteria 合意の提示が来ます。

GOAL-Loop Skill に従い「criteria を固定してから実行」フェーズに入ります。まず現状コードを確認。
そして、検証コマンドつきの Acceptance Criteria が提示されます。ここで「OK」と返すと freeze されます。

AC1〜AC5 がそれぞれ grep・pytest・mypy コマンドつきで提示。非ゴールと must NOT も明示されているのがポイントです。
Step 2: 計画とサブゴール分解(Phase 2)
Criteria が freeze されたら、Task Ledger を初期化して依存順にサブゴールを並べます。

db → service → route の依存関係を考慮した 8 つのサブゴール列。各 status が pending で管理されます。
Step 3: Small-Bet-First で pilot 実行(Phase 3)
3 ファイル・12 関数の変更 → Small-Bet-First が発動します。いきなり全部変えず、db_get_user 1 関数だけ先に pilot 適用します。
db_get_user・UserService.get_by_id・routes.get_user の 1 関数ずつを async 化し、3 ファイルが更新されます。
pilot 適用直後に mypy でチェックします。PASS なら同パターンを残りへ展開します。

mypy src/ を実行して「no issues found in 9 source files」。pilot PASS → 残り 9 関数へ展開できます!
pilot が通ったので、残り全関数を一括展開します。

db 残り 3・service 残り 3・routes 残り 3 を直列で適用。pilot と同じパターンなので安全に展開できます。
Step 4: 外部検証(Phase 4)+ 評価(Phase 5)
全変更が完了したら、pytest と mypy を実際に実行して exit code を取得します。

pytest 8 tests PASS、mypy no issues。自己申告ではなく「コマンドの exit code」で判断するのが GOAL-Loop のルールです。
外部検証の出力を受けて、evaluator が rubric で AC ごとに PASS/FAIL を判定します。

AC1〜AC5 すべて PASS、confidence = 1.0。「全 must 基準 PASS」で収束判定が出ました。
Step 5: 完了報告(Phase 7)
全基準が揃ったら、verify コマンドの証跡つきで完了報告が出力されます。

12 関数の async 化完了。変更ファイル・検証証跡・Deferred(なし)が整理されて報告されます。
実際に動かしてみて一番印象的だったのは、途中でよく見る「なんとなく完了にされる」問題が全く起きなかったこと。Phase 1 で検証コマンドつきの criteria を固定していたから、「exit 0 を取れるまで止まらない」という動きが自然と実現されていました。Small-Bet-First も自動で発動して、依存チェーンを壊さずに変更を積んでいく様子が見えたのが個人的には一番テンション上がりました!
設計思想の背景
GOAL-Loop の SKILL.md には設計根拠の論文・記事が列挙されていて、ちゃんと学術的な裏付けがあります:
- Anthropic "Building effective agents" — orchestrator-workers / evaluator-optimizer パターン
- Reflexion (arXiv:2303.11366) — 外部 signal 起点の self-reflection
- Self-Refine (arXiv:2303.17651) — 反復改善ループ
- "LLMs Cannot Self-Correct Reasoning Yet" (arXiv:2310.01798) — 自己評価だけの反省は劣化しうる根拠
- Magentic-One (Microsoft Research) — task + progress ledger、stall → replan
「なんとなく良さそう」じゃなくて、各メカニズムの根拠が明示されているのが信頼できるポイントだと思います。
まとめ
GOAL-Loop Skill をまとめると:
- 「最初に criteria を freeze して、外部検証で PASS を取るまでループする」 が核心
- 自己評価・推測で完了にしない / 同じ失敗を繰り返さない / 暴走しない、の三拍子
- Small-Bet-First で事故を防ぎながら、Effort Scaling で過剰な重さを避ける
- Autonomy Mode で「どこまで自律でやらせるか」を明示的に制御できる
エージェントに「やり切らせたいけど暴走されても困る」というニーズに、かなりストレートに応えている設計でした。
/goal や ゴールまで回す などのキーワードで発火する設定になっているので、Agent Skills Ninja で入れておくとサラッと使えます!


