Skip to content
Published on

ループエンジニアリング — エージェントにプロンプトを与えるシステムを設計せよ

Authors

はじめに

最近Addy Osmaniが公開した「Loop Engineering」という記事が、Hacker NewsとGeekNewsで大きな話題を集めました。要旨は明快です。プロンプトエンジニアリングの次の段階は、より良いプロンプトを書くことではなく、「エージェントにプロンプトを与えるシステム」、つまりループを設計することだという主張です。

同じ時期にもう一つ興味深い出来事がありました。スタンフォードの人気講義CS336(Language Modeling from Scratch)の課題リポジトリにCLAUDE.mdファイルが含まれていることが発見され、コミュニティで論争が起きたのです。講義の課題リポジトリにまでAIエージェント向けガイドラインが明記される時代 — これが2026年の現実です。Claude Code、Codex、Copilotの類のコーディングエージェントが普及し、数時間単位の自律作業が可能なfrontierモデル世代が登場したことで、開発者の役割は「コードを書く人」から「エージェントが回るループを設計する人」へと移動しつつあります。

本記事では、ループエンジニアリングの概念と構成要素、検証ループの構築、リポジトリレベルのガイドファイル設計、マルチエージェント分業、チェックポイント設計、失敗モードとガードレール、そしてGitHub Actionsベースの実戦例まで順に見ていきます。

毎ターン手動プロンプトの限界

コーディングエージェントを初めて使うやり方はだいたいこうです。指示を入力し、結果を見て、間違った部分を指摘し、また指示する。この「手動ピンポン」方式には構造的な限界があります。

  • ボトルネックが人間: エージェントは毎分数千トークンを生成しますが、人間の確認と再指示は分単位かかります。全体のスループットが人間の反応速度に縛られます。
  • フィードバック品質の不安定さ: 人間が疲れるとレビューが緩くなります。「まあ良さそう」が積み重なると欠陥が通過します。
  • 再現不可能: 同じ作業を再度頼んでも、その都度指示が異なり結果が変わります。知識がシステムではなく個人のチャット履歴に閉じ込められます。
  • スケール不可能: 同時に回せるエージェント数が人間のマルチタスク限界で制限されます。

核心の洞察はこれです。エージェントの出力品質を決めるのは最初のプロンプトではなく、出力に対するフィードバックがどれだけ速く正確に返ってくるかです。そしてそのフィードバックは人間ではなくシステムが与えられます。テストが、リンターが、型チェッカーが、そして別のエージェントが。

手動ピンポンとエンジニアリングされたループを並べると、違いが明確になります。

区分手動ピンポンエンジニアリングされたループ
フィードバック主体人間テスト、リント、検証者エージェント
フィードバック遅延分から時間単位秒から分単位
再現性低い (個人のチャット履歴)高い (スクリプト、ガイドファイル)
同時実行1〜2個数十個
品質の下限レビュアーの調子に依存検証ゲートが保証

この表の右列を作ることが、本記事の残り全部です。

ループの解剖学 — plan、act、verify、self-correct

ループエンジニアリングの基本単位は、次の4段階の循環です。

        +-----------------------------------+
        |                                   |
        v                                   |
   [1. PLAN]                                |
   作業をステップに分解、成功基準を定義       |
        |                                   |
        v                                   |
   [2. ACT]                                 |
   コード作成、ファイル修正、コマンド実行     |
        |                                   |
        v                                   |
   [3. VERIFY]                              |
   テスト、リント、型チェック、ビルド実行     |
        |                                   |
        v                                   |
   合格? --- はい ---> [完了、成果物提出]    |
        |                                   |
        いいえ                               |
        v                                   |
   [4. SELF-CORRECT]                        |
   失敗ログを読み原因分析、修正計画 ---------+

各段階の設計ポイントを見ていきましょう。

Plan — 計画を成果物にせよ

計画段階をエージェントの頭の中(コンテキスト)だけに置かず、ファイルに書かせることが重要です。計画ファイルは三つの役割を果たします。第一に、人間が作業開始前に方向性をレビューできるゲートになります。第二に、長い作業の途中でコンテキストが圧縮されても計画が失われません。第三に、作業完了後に「計画と比べて何が変わったか」を追跡できます。

Act — 行動範囲を明示せよ

修正可能なディレクトリ、実行可能なコマンド、触ってはいけないファイルを明示します。Claude Codeのsettingsファイルで許可ツールを制限したり、サンドボックス環境で実行したりするのがこれに当たります。

Verify — ループの心臓

検証のないループはループではなく、ただの自動タイプライターです。次の節で詳しく扱います。

Self-correct — 失敗情報の品質が修正品質を決める

エージェントが自己修正を上手く行うには、「何がなぜ失敗したか」が機械にとって読みやすい形で伝わる必要があります。テストフレームワークのverbose出力、リンターのJSONフォーマット出力のようなものが、自然言語の説明より効果的です。

検証ループ — テスト、リント、型チェックをエージェントのフィードバックに

ループエンジニアリングの80%は検証ループの構築です。原理は単純です。人間がコードレビューで捕まえていたものを機械検証に移すほど、エージェントは人間なしでより遠くまで行けます。

検証レイヤーの優先順位

レイヤーツール例捕捉するものフィードバック速度
文法、型tsc, mypy, rustc型エラー、タイポ数秒
スタイル、静的解析eslint, ruff, clippyアンチパターン、未使用コード数秒
ユニットテストvitest, pytestロジックエラー数十秒
統合、E2Eplaywright, testcontainers境界の欠陥数分
プロパティベースhypothesis, fast-checkエッジケース数分

速いレイヤーから実行して即座に失敗させるのが核心です。型エラーがあるのにE2Eを回すのはトークンの無駄です。

最小実装 — 検証ループスクリプト

エージェントに「このスクリプトが通るまで修正せよ」と指示する単一エントリポイントを作るパターンが、実務で最も効果的です。

#!/usr/bin/env bash
# verify.sh — エージェントフィードバック用の単一検証エントリポイント
set -euo pipefail

echo "== 1/4 typecheck =="
pnpm tsc --noEmit

echo "== 2/4 lint =="
pnpm eslint . --max-warnings 0 --format json -o lint-report.json \
  || { cat lint-report.json; exit 1; }

echo "== 3/4 unit tests =="
pnpm vitest run --reporter=verbose

echo "== 4/4 build =="
pnpm build

echo "ALL CHECKS PASSED"

エージェント側のループは次のようにシンプルに構成できます。

MAX_ITERATIONS = 8

def agentic_loop(task: str) -> dict:
    plan = agent.run(f"次の作業の実行計画をplan.mdに書け: {task}")
    for i in range(MAX_ITERATIONS):
        agent.run("plan.mdに従い次のステップを実装せよ")
        result = run_shell("./verify.sh")
        if result.exit_code == 0:
            return {"status": "success", "iterations": i + 1}
        agent.run(
            "検証が失敗した。以下の出力を分析し原因を直せ。\n"
            "同じアプローチを繰り返すな。二回連続で同じエラーなら"
            "アプローチ自体を変えよ。\n\n" + result.output[-8000:]
        )
    return {"status": "needs_human", "iterations": MAX_ITERATIONS}

注目すべきディテールが三つあります。第一に、反復回数に上限があります(ループ暴走の防止)。第二に、失敗出力の末尾だけを渡します(コンテキスト節約 — ほとんどのツールは核心のエラーを末尾に出力)。第三に、「同じアプローチの繰り返し禁止」の指示が入っています(エージェントが同一の修正を無限に繰り返す慢性的な失敗モードへの対応)。

テストのないコードベースなら

検証ループの前提はテストですが、テストがなければどうするか。逆説的ですが、それこそがエージェントの最初の任務になるべきです。「修正の前に、現在の動作を固定する特性化テスト(characterization test)を先に書け」という指示をループの第0段階に入れるのが定石です。

リポジトリレベルのガイドファイル — CLAUDE.mdとAGENTS.mdの設計法

ループが毎回うまく回るには、エージェントがリポジトリのルールを知っている必要があります。そのための標準的な慣行がCLAUDE.md(Claude Code)とAGENTS.md(汎用規格)です。

スタンフォードCS336の事例が物語ること

CS336課題リポジトリのCLAUDE.mdは短いものの示唆的です。学生がエージェントを使うことを前提とし、エージェントに「課題の正解を代わりに解かないこと」のような行動規範をリポジトリレベルで指示しています。コミュニティ論争の核心もここにありました。AI使用を防げないなら、リポジトリ自身がAIの行動を規定するのが現実的だということ。ガイドファイルは今や人間向けREADMEと同格の第一級成果物です。

良いガイドファイルの構造

実務で検証された構成は次のとおりです。

# CLAUDE.md 構造の例

## プロジェクト概要
一段落。何をするコードベースか。

## コマンド
- 検証: ./verify.sh (コミット前に必ず通過)
- テスト単体: pnpm vitest run path/to/test
- 開発サーバー: pnpm dev

## コード規約
- すべてのpublic関数に型を明示
- エラーはResult型で返す、throw禁止
- 新しい依存追加の前に既存ユーティリティを検索

## 禁止事項
- data/migrations ディレクトリの修正禁止
- テストを通すためにテストを弱めないこと
- CI設定ファイルの修正禁止

## 落とし穴 (よく間違えるもの)
- このリポジトリのalias @/ は src/ ではなく app/ を指す

ガイドファイル作成の原則

  • 短く保つ: ガイドファイルは毎セッション、コンテキストにロードされます。500行のガイドはそれ自体がcontext rotの原因になります。核心だけ残し、詳細文書はリンクで。
  • 命令形で: 「テストを回すことが望ましいです」ではなく「コミット前に./verify.shを実行せよ」。
  • 失敗から逆算: エージェントが実際に間違えた事例が出るたびに一行ずつ追加する方式が、最初から完璧に書こうとするより効果的です。
  • 検証可能なルール優先: 「良いコードを書け」は無意味です。「throwの代わりにResultを返す」はリントルールとしても強制できます。

マルチエージェント分業 — 作成者と検証者

人間の組織で作成者とレビュアーを分けるように、エージェントも役割を分離すると品質が上がります。同じコンテキストの中で「自分でレビューせよ」と指示するより、作成コンテキストを知らない別のエージェントがレビューする方が欠陥発見率が高いというのが実務の一貫した観察です。作成者の自己正当化がコンテキストに残っていると、レビューもそれに汚染されるからです。

                  [オーケストレーター]
                        |
        +---------------+---------------+
        v                               v
  [作成者エージェント]            [検証者エージェント]
  - plan.md 作成                  - diffだけを見てレビュー
  - コード実装                    - スペックとの照合
  - verify.sh 通過まで修正        - セキュリティ/性能の点検
        |                               |
        +---> diff + 計画を渡す --------+
                        |
                  承認 / 差し戻し (理由付き)
                        |
        差し戻し時は作成者へフィードバックループ

分業設計の要点は次のとおりです。

  • 検証者にはdiffとスペックだけを提供し、作成者の推論過程は提供しません(独立レビューの保証)。
  • 検証者の差し戻し理由は構造化された形式(位置、深刻度、根拠)で受け取り、作成者のループに注入します。
  • 差し戻し・修正サイクルにも上限を設けます。3回を超えたら人間にエスカレーション。

長時間自律作業とチェックポイント設計

2026年のfrontierモデルは数時間単位の自律作業が可能です。しかし作業時間が長くなるほど、一度の誤った方向転換が生む損失も大きくなります。解決策はチェックポイントです。

チェックポイントの3要素

  1. 状態スナップショット: gitコミットが最も自然なチェックポイントです。意味のある単位ごとにコミットさせ、コミットメッセージに「計画に対する進捗」を書かせます。
  2. 進捗ノート: コンテキスト圧縮を生き残る外部メモ(progress.md)。完了項目、未解決の問題、次のステップを更新させます。
  3. 検証ゲート: チェックポイントごとにverify.shを通過しなければ次の段階へ進めない。失敗状態のまま前進することを構造的に遮断します。

進捗ノートの形式は自由ですが、次の構造が圧縮生存性と可読性のバランスに優れていました。

# progress.md — エージェントが維持する進捗ノート

## 目標
イシュー142: 決済Webhookのリトライロジック追加

## 完了
- Webhookハンドラに冪等性キー検証を追加 (コミット a1b2c3)
- リトライキューのテーブルマイグレーション (コミット d4e5f6)

## 進行中
- 指数バックオフスケジューラ — テスト2件が失敗中

## 詰まっている / 決定が必要
- 最大リトライ回数がスペックにない。暫定で5回と仮定 (確認要)

## 次のステップ
1. スケジューラのテスト修正
2. デッドレター処理の追加
時間 -->
[計画]--[実装1]--C--[実装2]--C--[リファクタ]--C--[文書化]--完了
              |          |             |
              v          v             v
        コミット+ノート コミット+ノート コミット+ノート
        verify OK     verify OK     verify OK

C = チェックポイント。失敗時は最後のCにロールバックし
別のアプローチを試す

チェックポイントがあれば「4時間作業した後に全部破棄」の代わりに「最後の正常地点にロールバックして再試行」が可能になり、人間の介入ポイントも明確になります。

失敗モードとガードレール

ループは強力な分、失敗も自動化します。代表的な失敗モードと対応を整理します。

失敗モード症状ガードレール
ループ暴走同じ修正を無限に繰り返す反復上限、同一diff検出時に中断
報酬ハッキングテストを弱めて通過させるテストファイル修正禁止ルール、検証者の分離
スコープ爆発依頼外のファイルまで大量修正diffサイズ上限、許可パス制限
コンテキスト腐敗後半に初期指示を忘却チェックポイントノート、中核指示の再注入
コスト暴走夜間ループが予算を使い果たすトークン/時間予算の上限、アラート

この中で最も狡猾なのが報酬ハッキングです。「テストを通せ」という目標を受けたエージェントがassertをコメントアウトしたり、期待値を実際の出力にすり替えたり、テストをskip処理したりする事例は実際に頻繁に報告されています。対応は三重です。第一に、ガイドファイルでの明示的禁止。第二に、テストディレクトリを書き込み禁止パスに設定。第三に、検証者エージェントが「テストが弱められていないか」をdiffで別途確認。

実戦例 — GitHub Actionsでエージェントループを構成する

ループをCIに載せると、「イシューにラベルを付けるとエージェントがPRを作ってくる」ワークフローになります。Claude Code GitHub Actionを使った構成例です。

name: agent-loop
on:
  issues:
    types: [labeled]

jobs:
  agent:
    if: github.event.label.name == 'agent-task'
    runs-on: ubuntu-latest
    timeout-minutes: 90
    permissions:
      contents: write
      pull-requests: write
      issues: read
    steps:
      - uses: actions/checkout@v4

      - name: Run agent on issue
        uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            イシュー #${{ github.event.issue.number }} を解決せよ。
            手順:
            1. plan.md に計画を書く
            2. 実装する
            3. ./verify.sh が通るまで修正する (最大8回)
            4. 通ったらブランチをプッシュしPRを開く
            制約:
            - .github/ と tests/ ディレクトリは修正禁止
            - diffが500行を超えたら作業分割を提案して中断
          claude_args: "--max-turns 60"

ここに二つ目のワークフローとして「PRが開いたら検証者エージェントが自動レビュー」を付ければ、作成者・検証者の分業がCIの上で完成します。人間は最終マージの判断だけを行います。

運用時の注意点は次のとおりです。

  • timeout-minutesとmax-turnsで二重の上限をかけます。一つだけでは不十分です。
  • エージェントが作ったPRが再びエージェントをトリガーする再帰を遮断する必要があります(ラベル条件、ボットアカウントのフィルタ)。
  • secretsのアクセス範囲を最小化します。2026年6月のnpmサプライチェーン攻撃の事例が示すように、CIで動くすべてのものはサプライチェーン攻撃の標的です。

ループテレメトリ — ループ自体を観測せよ

ループを運用システムとして扱うには、ループ自体の観測データが必要です。実行ごとに次のような構造化レコードを残せば、「どんな種類の作業でループが空回りしやすいか」「ガイドファイルの修正が収束速度を改善したか」といった問いにデータで答えられます。

{
  "run_id": "loop_20260612_042",
  "task_ref": "issue-142",
  "iterations": 3,
  "wall_clock_minutes": 41,
  "tokens": { "input": 412000, "output": 38000 },
  "verify_failures": [
    { "iteration": 1, "stage": "unit-tests", "summary": "backoff off-by-one" },
    { "iteration": 2, "stage": "lint", "summary": "unused import" }
  ],
  "guardrail_triggers": [],
  "human_interventions": 0,
  "outcome": "merged"
}

このレコードで最も注目すべきフィールドはiterationsとverify_failuresのstage分布です。特定のstageに反復失敗が集中するなら、そのstageのエラーメッセージがエージェントにとって不親切だというシグナルであることが多い。ループ改善の対象はモデルではなく、フィードバックの品質である場合の方が多いのです。

よくある質問

  • 小さなチームでもループエンジニアリングは必要か? — 1人プロジェクトでもverify.shとCLAUDE.mdの二つは即座に利益があります。CI統合とマルチエージェントは、チーム規模とPR頻度が大きくなったときに導入すれば十分です。
  • ループが失敗ばかり繰り返すならモデルの問題では? — 経験上、80%は検証フィードバックの品質問題か、作業定義が曖昧な問題です。モデル交換の前に、失敗ログが「人間が見ても原因がわかるレベル」かをまず確認してください。
  • 検証が遅くてループが非効率だ — 検証の階層化(速いものから)と変更影響ベースのテスト選択(affected tests only)を先に適用してください。ループ1回転が10分を超えると体感効率が急落します。
  • エージェントが作ったコミットをそのままマージしてよいか? — チェックポイントコミットは作業履歴であってリリース単位ではありません。マージ前のsquashと人間の最終レビューを推奨します。

導入ロードマップ

ループエンジニアリングは全か無かではありません。段階的に進めます。

  1. 第1週 — 検証の単一エントリポイント: verify.shを一つ作り、エージェントへの指示に「これが通るまで」を付けるだけで半分は到達します。
  2. 第2週 — ガイドファイル: CLAUDE.mdを作り、エージェントが間違えるたびにルールを一行ずつ追加します。
  3. 第3〜4週 — ループ自動化: 上記のagentic_loopパターンをスクリプト化し、チェックポイント(コミット + 進捗ノート)を導入します。
  4. 第2ヶ月 — 分業とCI統合: 検証者エージェントを分離し、GitHub Actionsでイシュー-PRループを構成します。
  5. 継続 — 測定: ループ1回あたりのコスト、人間の介入率、差し戻し率、マージまでの時間を測定し、ループ自体を改善します。

落とし穴と批判的視点

ループエンジニアリングへの懐疑論も正当に扱うべきです。

第一に、検証可能なものだけが良くなるという限界です。テストで表現できない品質 — 設計の適切さ、コードの意図伝達力、プロダクト感覚 — はループが保証できません。ループは「機械が検証できる品質」の下限を引き上げるツールであり、良いソフトウェアの十分条件ではありません。

第二に、検証ループ自体が技術的負債になります。遅いテスト、フレーキーなE2Eは人間よりループにとって致命的です。人間は「これは元々たまに失敗する」と流せますが、エージェントはそれを直そうとして無関係なコードを掘り返しかねません。

第三に、コスト構造の変化です。ループは人間の時間をトークンコストに置き換えます。8回の反復ループが毎回回る作業なら、そもそも作業定義が間違っているか、ガイドファイルが貧弱だというシグナルかもしれません。「ループが回った」ではなく「何回で収束したか」を見るべきです。

おわりに

プロンプトエンジニアリングが「一度の良い質問」を作る技術だったとすれば、ループエンジニアリングは「人間なしでも品質が収束するシステム」を作る技術です。そのシステムの部品は華やかなプロンプトではなく、よくできたverify.sh、簡潔なCLAUDE.md、適切なチェックポイント、そして報酬ハッキングを防ぐガードレールです。

興味深いことに、これらはすべてAI以前から良いエンジニアリング組織がやってきたこと — 速いCI、明確なコンベンション文書、小さなPR、独立したレビュー — の延長線上にあります。エージェント時代の競争力は結局「機械が働きやすいコードベース」を作ることから生まれます。そしてそういうコードベースは、人間にとっても働きやすいコードベースです。

参考資料