とある面白いボードゲームにしばらくハマっていて、プレイを助けるコンパニオンアプリが欲しいなということで作りました。開発フローのうちAIエージェントで自動化できる箇所をループ化して、開発と改善のサイクルを回しながら作っていました。スマートフォンからタスクを投げ込み、機能要件をAIエージェントに磨いてもらい、上がってきたPull Requestをレビューしてはマージする、という繰り返しです。振り返ってみると、3日足らずでPull Requestを50個ほどマージできていて、この間MacBookは一度も開きませんでした。
この開発のやり方は最近になって名前が付きました。ループエンジニアリング(Loop Engineering)です。今年の6月、Claude Codeの開発者であるBoris Chernyが「もうClaudeにプロンプトを書いていない。ループが走っていて、そのループがClaudeにプロンプトを書いている。僕の仕事はループを書くことだ」という趣旨の発言をし、そのすぐ後にOpenClawの作者であるPeter Steinbergerがこうポストして知られることになりました。
その翌日にAddy Osmaniが「Loop Engineering」という記事で体系的に説明しています。
概念の解説は既に日本語でも読めるものがあります(@ITの記事が分かりやすいです)。
これがここ1-2ヶ月ほどの話なので、AI関連の流れは本当に早いです。定義や解説の記事が既にたくさんネット上に存在するので、ここではそうした土台の話は最小限にして、「どう始めたか(始めるか)」の話をしようと思います。
僕は、ループエンジニアリングはコーディングをエンジニアリングに昇華させるものだと解釈しています。「コードを書く」という時間が人間の手から消えることで、人間の仕事が設計・評価・判断、つまり根本的に「エンジニアリング」と呼ばれてきた部分に寄ってきています。
これは特別新しい現象ではなくて、エンジニアリング手法の進化の中で繰り返されてきた「本質でないものを自動化する」ことの一種だと思っています。アセンブラからコンパイラへ、手動のメモリ管理から(半)自動GCへ、手動リリースからCI/CDへ。その延長線上にエージェントのループがあるという感じです。
一方で、ループエンジニアリングは「エンジニアを含めた各ロールの人間がいなくてもエンジニアリングやビジネスが完璧に自走するもの」でもありません。指針や評価軸を設定して調整する人間がどのレイヤーにも必要です。
ちょうど先日、Osmaniがフォローアップの「Own the Outer Loop」で関連することを述べています。
Now they run the inner execution loop. Engineers own the outer loop. (いまやエージェントが実行の内側のループを回している。エンジニアが所有するのは外側のループだ。)
Inside the system, there's really just one kind of thing our agents are doing: capability. The capability to investigate tasks, implement plans, test their results, and report back. (システムの内側でエージェントがしていることは、突き詰めれば一つだけ、「能力」だ。タスクを調査し、計画を実装し、その結果をテストし、報告する能力である。)
Outside the system, there's a single kind of thing: agency. The agency to decide, verify, approve, and own. (システムの外側にあるものも一つだけ、「主体性」だ。判断し、検証し、承認し、結果に責任を持つという主体性である。)
Only people can choose. Only people inherit consequence. (選ぶことができるのは人間だけだ。結果を引き受けるのも人間だけだ。)
僕の見解もだいたい近い場所に着地します。
ループエンジニアリングで回すループは、入れ子になった二つに分けて考えると整理しやすいです。この記事ではそれぞれ「コーディングのループ」「エンジニアリングのループ」と呼びます。これは英語圏でよく話される「inner loop」「outer loop」という語彙と似ていますが違う切り分け方で、混同を避けるために別の呼び方をします。
プログラミングの作業は突き詰めると「コードを書く」「テストを走らせる」「レビューする」「フィードバックを受けてまたコードを書く」の繰り返しです。AIエージェントは「コードを書く」ことができます。テストを走らせることも、レビューすることもできます。「であれば、このループそのものを自走させられないか?」というのが出発点であり、誰もが行き着く発想です。
これを現実的にしたのは、生成AIモデルそのものというより、エコシステムの成熟だと思っています。MCPやAgent Skillsがオープンスタンダードになり、それらの仕様は今では主要なコーディングエージェントで採用されています。エージェントに道具と状態を渡すインターフェースがようやく標準化されてきたわけです。
もちろんエンジニアリングにはプログラミング以外の作業も無数にあります。要件の策定、その精査や設計、タスク管理、デプロイ管理、リリースノートの作成、ローカライズに伴う翻訳。しかし書き出してみると、どれも生成AIが得意そうなものばかりです。
そしてエンジニアリングという営みそのものが、計画・実行・評価のループ(いわゆるPDCA)で改善していくのが主流です。ならばこのエンジニアリングのループも、機械的な部分を自走させられないか?という考えに行き着くのは必然です。しかし依然として判断・承認・責任は人間が所有し続けます。自動化するのはサイクルの機械的な部分です。
個人でも生成AIで大規模な作業をこなせるようになったせいで、誰もが大風呂敷を広げがちです。
英語圏では早くも「loopmaxxing」という批判語が生まれています。「ループを回し続ければいつか正解に着く」という誤解のことで、AIエージェントが自分の仕事を自分で採点するループは、自身の確信だけを高めていってしまい、結果の品質が蔑ろにされてしまうことが多々あります。外部の判定者によるテスト、型検査、独立したレビューのないループは空転するということを意識しておかなければなりません。
大きなものも小さく始める。僕たちはリーンなやり方を開発手法としてもう知っているはずです。ムーンショットを狙わず、小さな成功を積み重ねるのが大きな成功への道で、幸い小さなループエンジニアリングはなにも難しくありません。
しかし面白いもので、現実的なループエンジニアリングを構築すると、そのレビューやフィードバックのサイズの観点から「小さなPull Requestを次々に作る」という形に自然に着地します。小さな変更を刻むこと自体が、生成AIで増える変更量に対する安全装置として働くのです。
「AIエージェントで簡単にコーディングができるようになった!」と言われていても、やっぱりある程度の経験や知見は依然として必要だと実感します。最低ラインとしてGitやGitHub、Markdownが扱えないといけませんし、レビューやフィードバックのためのCIビルドや、モバイルアプリなら内部チャンネル配布といったフローを構築できないとループの成果物を細かく確認できません。トークン効率や成果物の正確度を突き詰めるにはいわゆるハーネスエンジニアリングの知識も必要です。
とはいえ、プログラミング言語の書くための深い知識は必要なくなったと言っていいと思います。正確に言うと、必要なくなったのは「書くための知識」で、正しい評価軸を設定するためのアーキテクチャやソフトウェアリライアビリティのような専門性はむしろ重要になったんじゃないかと感じます。ボトルネックは書くことから検証することへ移っていて、その検証は体感に頼れません。過去には「経験豊富なOSS開発者達がAIを使うとむしろ19%遅くなり、しかも本人たちは終わった後も20%くらい速くなったと信じていた」というデータもあります。
僕自身がどう始めたか振り返る形で、小さく始める方法を考えてみます。まずは内側、コーディングのループからです。
ループはAgent Skillとして実装します。僕は「取り組む」みたいな意味で/addressという名前にしました。骨格はこんな形です。
--- name: address description: Drive one unit of work — a GitHub issue, a pull request, or a free-form prompt — from intake to a review-ready pull request in one continuing session; plan and pause for human approval, implement and verify, request the independent review, and address its findings. `continue` resumes a paused run. argument-hint: <issue-or-pr number/URL | free-form prompt | continue> user-invocable: true --- You are the `/address` driver. Take one unit of work — a GitHub issue, a pull request, or a free-form prompt — from intake to a review-ready pull request inside this single continuing session. Target: `$ARGUMENTS` For a free-form prompt, open a tracking issue capturing the request before planning, so the run is issue-anchored and `/address continue` can reconstruct it. ## Phase 1 — Plan Turn the target into a buildable specification recorded in the issue. Rewrite the issue body into a comprehensive plan: requirements, design, acceptance criteria, and verification strategy. For any visual change, the plan must not present a single implied design — it presents a choice of visual presentation options that the human decides at the plan-approval gate, with the choice recorded in the issue. Once the plan is written, the plan-approval gate always applies — the human verifies the plan before any implementation. End the turn and wait for the human to send `/address continue`; for visual work, do not enter Code until the chosen design has been approved. ## Phase 2 — Code + Verify Implement strictly from the approved plan, keeping edits within the smallest surface that satisfies the acceptance criteria. Run the verification the changed surface requires and record the evidence in the pull request body. ## Phase 3 — Request Independent Review
作るループは「コードを書く」→「テストする」→「他のエージェントにレビューさせ、そのレビューをウォッチする」→「フィードバックを受けてコードを書く」形です。
書き手とレビュワーを別のエージェントセッションにするのは、コンテキストを引き継ぐことで発生するバイアスを防ぐためです。これについては、Anthropicが公式のベストプラクティスで以下のように明言しています。
A fresh context improves code review since Claude won’t be biased toward code it just wrote. (フレッシュなコンテキストはコードレビューを改善する。書いたばかりのコードへの肩入れが発生しないからだ。)
ただ、正確にはフレッシュなコンテキストが消してくれるのは自分の直前の推論へのバイアスまでです。多くのモデルはフレッシュコンテキストでも自分の出力を好む傾向(自己選好バイアス)があるそうです。これを消すにはレビュワーを別のベンダーの別のモデルにするか、あるいはAIエージェントにとって外部の判定をループに組み込むしかありません。E2Eテストやユニットテスト、リントや型チェッカーは依然として必要どころかその重要性を増しているといえます。
また、レビュワーは粗探しを求められると健全なコードにも必ず何か指摘します。なので、レビューの往復には上限を設けるべきです。僕はコーディングとレビューのセットを4ラウンドで打ち切って人間(僕)に投げる設計にしています。必要ならば『さらに4ラウンド行って』と指示を出せばこのラウンド数を追加できます。副次的ですが、コーディングとレビューとで必要以上にループを回してしまわないようにする安全装置としても機能します。
書き手とレビュワーを分けると新しい問題が出てきます。実装対象の前提知識を持たないレビュワーが、的外れなレビューをしてしまうことがあるのです。ここで、コードの書き手もレビュワーも参照する「今何をしているのか、ゴールは何か」という情報をAIエージェントセッションの外側に格納する必要があることがわかります。
置き場所はエージェントのメモリーファイルでも、独立したドキュメントでも、JiraのチケットやGitHubのIssueでも構いません。僕は主にGitHub上で作業をするので、わかりやすくGitHubのIssueに置いています。外部に置くようにするとクラウド環境でエージェントを走らせても問題なくなります。フローの一環として、最初にGitHub Issueを書かせて(あるいは精査させて)その方針のすり合わせをしておくと、そのまま計画承認のゲートにもなって便利です。
状態の外部化とレビューループの部分は、こんな指示になります。
## External state The running session is the primary state store; write durable status to GitHub as a safety net, not as the mechanism of record. - Record the plan in the issue body; its approval arrives as `/address continue`. - Keep the run's state in a single status block: an HTML comment embedded in the pull request description — invisible in the rendered GitHub UI, present in the raw markdown. Before the pull request exists, keep the same block in the issue body. Record the current phase, the review-round count, what the run is waiting on, and any open question. - On resume, reconstruct state from GitHub before acting — the plan in the issue, the open pull request, its CI status, the independent review's comments, unresolved threads, and the status block — and resume the one pending step the block names, not restart from Plan. ## Review loop 1. Open the pull request in draft with `Closes #<n>`. 2. Request the review by posting a top-level comment whose body is exactly the review trigger phrase, and nothing else — it fires the review workflow, a separate agent session on separate infrastructure. The workflow fires on that phrase appearing anywhere in a comment body, so never write it in any other comment. 3. CI and the review are machine events that complete on their own — poll for them. When findings land, address each blocking one, push, and re-request the review. 4. Gate the draft→ready flip on a clean independent review plus green CI — never on your own assessment of your code.
トークンの枯渇やサーバーダウンなどの外的要因でセッションがハングすることが割とよくあります。あるいは、エージェントが動いている最中に割り込んで指示を与えて作業の方向性を変えたいこともたまにあります。
こうした状況への対応策として、ループは冪等に作った方が良いです。リトライで複数回実行されても結果が重複しないようにという分散システムの定石と同じ考え方です。僕は/address continueという引数付きの挙動を実装しました。直前のセッションの状況を、あるいは紐づけられたGitHub Issueを再度読み込んで途中から引き継ぎます。
## `continue` `continue` matches the bare token only. For a bare `continue`, resolve the invocation to exactly one of two outcomes, in this precedence order: 1. This session holds an `/address` run — resume it: re-read the target's current state (the plan recorded in the issue, the open pull request, its CI status, the review's comments, unresolved threads, and the status block) before acting, and resume the single pending step rather than restarting. When the pending step is plan approval, treat the bare `continue` as that approval. 2. No in-session run — state that there is nothing to resume and ask what was meant. Never start new work from a bare `continue`. To resume existing work in a fresh session, invoke `/address` with the issue or pull request number instead. Keep each externally observable step idempotent, so a re-run of `/address continue` re-reads state and continues rather than duplicating work.
まずは1つのリポジトリでフローを組んで回してみるのがいいと思います。冒頭に書いたとおり、僕の場合はボードゲームのコンパニオンアプリで、ループの構築後はすべてモバイルアプリ経由で、Claude Codeのクラウド環境上で行いました。モバイルアプリからタスクの投入も要件定義もPull Requestの作成も自動でできるので、出先でもどこでもプロンプトを投げて、次に見たときにはレビューまで終わっていて、確認してマージするだけ、という感覚でした。
回してみると、いろいろな発見がありました。
エージェントはステートレスだという前提に立つこと。フローのうち今どのフェーズにいるか、どんなことをしていたか、などは「覚えさせる」のではなく「記録させる」。これは上で書いた外部状態の話ですが、実際に回すとこの前提の大事さが身に沁みます。セッションは切れるものだし、切れても困らない作りにしておけば、切れたこと自体が問題でなくなります。
どれだけ人間の確認を挟むか。確認させすぎると手放しで作業が進みにくいし、確認せずに働かせすぎると手戻りが大きくなります。ここは自分の好きなマネジメント粒度に合わせて調整するところです。どの段階で確認させるかも悩みどころで、コードを書く前にあらゆる確認をしてもらうのが理想ですが、書き始めないとわからないこともあります(そして確認のためのコード走査で余計なトークンも消費します)。試行錯誤の結果、僕は計画の承認を含めて2-3回の確認フェーズを置き、それ以外は手放しで動く調整に落ち着きました。
ドキュメント資産も一緒に更新させること。ループエンジニアリングに限った話ではないですが、コードと一緒に、関係するAgent Skillなどのドキュメント資産も更新させます。Living Document(コードと同様に更新され続けるドキュメント)を作るのは、生成AI時代では本当に容易になりました。
E2Eテストの作成・実行コストが下がったこと。特にE2Eテストは以前とは考えられないほど維持しやすくなったと感じます。これは僕の体感だけの話ではなくて、PlaywrightもTest Agents(テスト計画を作るplanner、テストに起こすgenerator、失敗したテストを修繕するhealerのセット)を公式に出しています。E2Eテストがループの検査機関になる形に、ツールの側が追いついてきたといえます。
うまくいかなかったこともたくさんあります。セッションが不具合で止まって /address continue のお世話になったことは一度や二度ではないですし、承認・確認のゲートをどこに置くかは何度か作り直しました。この記事で書いたことの多くは、失敗から学んだことでもあります。
ループエンジニアリングのループは一度作って終わりではなく、回すたびに直すものになりました。そうした意味では、AIエージェントの進化に合わせてループを回して自己改善していく必要のあるものなのかもしれません。
冒頭のコンパニオンアプリで組んだ最初の形は axross/bombdog に残っています(今アクティブに回しているループよりも少し古いやり方です)。そこから使い回せる共通部分を axross/claude-loop-template というテンプレートリポジトリにまとめて切り出し、いまはこのブログ(axross/btnopen.com)の機能開発を、改良版のループで回しています。どれも公開してあるので、興味があれば覗いてみてください(Starも貰えると嬉しいです)。
大層な仕組みは何もありません。小さく始めて、失敗するたびに少しずつ直す。ここで書いたのはその繰り返しの現在地です。コーディングのループの外側、エンジニアリングのループをどこまで自走させ、どこからどこまでの責務をソフトウェアエンジニアが負うのか、それがどうなっていくのかはまだわかりません。
Here’s your monthly reminder that you shouldn’t be prompting coding agents anymore. You should be designing loops that prompt your agents.

コメント
(0)comments.length === 0
最初のコメントを書いてみませんか。