Agent Engineering
ループエンジニアリング:あなたを裁くループをつくる
プロンプトエンジニアリングは「何を言うか」を問う。ループエンジニアリングは「システムがどう仕事をやり遂げるか」を問う——そして、うまくいった日には、それがどうあなたを有罪と裁くか.
短縮版
この二年間、我々はより良いプロンプトの書き方を学んできた。プロンプトはハンドルだ。車そのものではない。
本当の仕事には、それ以外のすべてが必要だ——確認できるゴール、書き留める場所、ブレーキ、温度計、整備士、承認するおとな、そして明日が今日より賢く始まるためのノート。それがループであり、それをつくることこそがエンジニアリングだ。
誰も書かない部分が、良い部分だ——きちんとつくられたループは、いずれあなたに間違っていたと告げる。私のループは一週間で四度それをやった。この四つの話こそが本稿の証拠であり、図解などより、はるかに高い代償を払って手に入れたものだ。
ツリーハウス
父はこう言う——「安全なツリーハウスをつくれ」
目を閉じて魔法の一言を唱えれば、目覚めたらツリーハウスができている、というわけにはいかない。ループを走らせるのだ。「安全」とは何を意味するのか?手持ちの木材は何か?板は合っているか?梯子はぐらつかないか?何が壊れたのか?弟はそれに登れるのか?
では名詞を入れ替えてみよう。ツリーハウスはソフトウェアになる。板はコードになる。ネジはAPI呼び出しになる。安全確認はテストになる。父親はヒューマンレビューになる。ノートはメモリになる。失敗はフィードバックになる。
エージェントが強力なのは、一度答えを出せるからではない。試し、確かめ、判断し、直し、また試すことができるからこそ強力なのだ。
一対一対応表
| メンタルモデル | 技術的な名称 | なぜ重要か |
|---|---|---|
| 「安全なツリーハウスを作る」 | Goal Contract(ゴール契約) | エージェントには目的と「完了」の定義が必要だ。 |
| 先にスケッチしておく | Plan(計画) | 行動する前に提案された道筋。 |
| 作業台の上の道具 | Tool Access(ツールアクセス) | 能力は、意図的に境界づけられている。 |
| 木材を測る | Observation(観測) | 思い込みではなく、実際のフィードバック。 |
| 梯子がぐらつかないか確認する | Evaluation(評価) | これは本当に十分なのか? |
| 緩んだネジを締め直す | Recovery(復旧) | 実際に起きた失敗を直す。 |
| 子供が登る前に父親がチェックする | ヒューマンゲート | 影響の大きい行動には承認が要る。 |
| 失敗したことを書き留める | 記憶 | 次の実行は今日より賢くなる。 |
| 安全なときに止まる | 停止基準 | いつ終えるかを知ること。 |
| チェーンソーを一人で使わせない | ポリシーゲート | 危険な行動には決定論的な制御が要る。 |
この表がアーキテクチャの全体像だ。以下はすべて詳細にすぎない。
なぜプロンプトだけでは足りないのか
プロンプトはこう言える。fix this bug。しかしコーディングエージェントは、issueを読み、リポジトリを調べ、該当ファイルを見つけ、仮説を立て、編集し、テストを実行し、失敗内容を読み、再度パッチを当て、再実行し、根拠をまとめ、プルリクエストを開き、レビューを待たなければならない。
それは一つのプロンプトではない。ハンドルのついたオペレーティングシステムだ。
背骨
User intent → Goal Contract → State Ledger → Planner → Tool Router
→ Policy Gate → Executor → Observer → Evaluator → Recovery
→ Human Gate → Memory → next loop or delivery
ゴール契約(Goal Contract)——注文票
レストランの注文票にはこう書いてある。テーブル7、チキン、ピーナッツ抜き、中辛、20分。それがなければ厨房は勘で動くしかない。
悪い例:fix the checkout problem. 良い例:
{
"objective": "Fix timeout during checkout payment confirmation",
"success_criteria": [
"Payment confirmation completes under 3 seconds",
"Existing payment tests pass",
"No duplicate charges are created",
"Pull request includes test evidence"
],
"constraints": {
"max_iterations": 8,
"max_cost_usd": 10,
"forbidden_actions": ["deploy_to_production"],
"requires_human_approval": ["database_migration", "payment_logic_change"]
}
}
エージェント型システムがうまくいかないのは、モデルが愚かだからではない。ゴールが曖昧だったからうまくいかないのだ。曖昧なゴールは曖昧な計画を生み、計画が曖昧ならツールの使い方も適当になり、結果として高くつく混乱が生まれる。
State Ledger(状態台帳) — ホワイトボード
自転車を修理するとき、人は試したことを書き留める。モデルは脳であり、台帳はホワイトボードだ。脳にホワイトボードの役目まで兼ねさせてはいけない。コンテキストは劣化するし、ツールの出力にはノイズが混じるし、古い推論はすぐに腐る。
すべてのツール呼び出しについて、ステータス、イテレーション、現在の仮説、完了したステップ、未解決の疑問、直近のエラーを記録すること。
Policy Gate(ポリシーゲート) — ブレーキ
ティーンエイジャーは包丁を使ってよい。だが、チェーンソーを一人で使わせてはいけない。ポリシーゲートとは、チェーンソーの脇に立つ大人のようなものであり、それは確率ではなくコード:
def policy_gate(tool, args, state):
if tool == "process_refund":
if not state.get("verified_customer_id"):
return {"allowed": False, "next_action": "lookup_verified_customer"}
if args["amount"] > 500:
return {"allowed": False, "next_action": "escalate_to_human"}
if tool == "deploy_to_production":
return {"allowed": False, "next_action": "request_approval"}
return {"allowed": True}
でなければならない。プロンプトによる指示は確率的だ。ゲートは決定的でなければならない。その行為がお金、本番環境、プライバシー、安全、法的リスクに関わるなら、確率程度では足りない。
Evaluator(評価器) — 温度計
鶏肉が焼けたかどうかを勘で判断してはいけない。テストが通る、スキーマが検証される、型チェックが通る、数字が合う――そうした決定的なチェックを優先し、モデルには本当に判断が必要なことだけを判断させる。
決して問わない――これでいいか?そうではなく、こう問う――どの基準を満たし、どの基準を満たさなかったのか。その判定を裏づける証拠は何か。 次の行動を生み出さない評価は、単なる意見にすぎない。
Recovery(リカバリー) — 整備士
チェーンが外れても、新しい自転車は買わない。まず分類し、それから行動する。一時的な失敗はバックオフしながらリトライし、検証エラーは入力を修正し、権限エラーはアクセスを要求し、ビジネスルール違反は停止するかエスカレーションする。そして同じ失敗が三度続いたら、戦略そのものを変える。
リトライは戦略ではない。それはツールにすぎない。優れたエージェントは、より頑張ろうとするのではなく、違うやり方を試す.
停止 — 失敗ではなく制御
組み立てをやめるのは、疲れたときではない。フレームが安定し、梯子が安全で、父親が承認したときだ。何かを実行する前に、五つの停止条件をあらかじめ定義しておく――成功、失敗、エスカレーション、予算、安全。止まれないループは自律的とは言えない。それはただ迷子になっているだけだ。
Human Gate(ヒューマンゲート) — 責任ある大人
エスカレーションはエージェントの失敗ではない。それこそが、真剣に作られたシステムが安全であり続けるための仕組みだ。しかし「need human help」だけでは、エスカレーションとして役に立たない。まっとうなエスカレーションには、必要な意思決定・推奨案・根拠・リスク・代替案が添えられ、人間が二分以内に判断できるものでなければならない。
記憶――キュレーションされる、決して自動ではない
悪い記憶は誤りを複利で増やし、良い記憶は知恵を複利で増やす。だから記憶は提案され、人間かゲートによって承認される。保存していい教訓は、具体的で、根拠に裏打ちされ、再利用可能で、未来の行動に結びついているものだけだ。
ループに四度、私は捕まった
ここからは、一年前の自分には書けなかった部分だ。これらは、自分の一群のリポジトリを作り込んでいたある一週間の出来事であり、それぞれが、自分の作った仕組みが自分自身に「お前は間違っている」と告げたケースである。それがループエンジニアリングの見返りだ――スピードではなく、訂正のほうだ.
1. ゲートが最初に有罪と認めたのは、他でもない作者自身だった
私はバリデーターに新しいブロッキングルールを追加し、それを本番に反映したところ、ビルドが赤くなった。ルール自体が間違っていたからではない――そのルールをコードには追加したのに、コードが照合するべき仕様のほうには追加していなかったからで、パリティテストがそのズレを捉えたのだ。私の新しいゲートが最初にブロックしたのは、この私自身だった。
法則:一度も作者自身に対して発動したことのないバリデーターは、おそらく何もチェックしていない。
2. 語幹をすべて、静かに取りこぼしていたルーター
私は、新しい記事やリポジトリがどのリポジトリの役に立つかを判定する、決定論的なルーターを構築した。それは正しく見え、テストにも通った。ところが実際の四つのソースで走らせてみると、ルートされたのはたった一つだった。
原因は私自身にあった。ルーターが読み込むレジストリは、トリガーワードを部分文字列マッチとして文書化しており、そのうちのいくつかは意図的な語幹だった――たとえば「self-improving」のような形だself-improv, portfolio rebalanc。私は完全単語一致を実装してしまっていたので、「self-improving pipelines」について書かれたページは何にもマッチしなかった。テストが通っていたのは、私がデータではなく自分の実装に合わせてテストを書いていたからだ。
法則:自分のテストが通った(グリーンになった)ことを信じる前に、実データで走らせよ。
3. 採点者が私の成績表を突き返した
私のシステムでは、すべての納品物が独立した採点者によって採点される成績表を受け取る。あるとき私が一つ提出すると、採点者はそれを差し戻してきた0.00――上限つきで、こう理由が添えられていた――"significance unstated"(訳:重要性が未記載)。私は自分がやったことは説明したが、それがなぜ重要なのか、どの数値を動かしたのかは一度も述べていなかった。
その後、同じ採点者は小さな変更に対して1.00何らかの指摘とともに、こう記した。(sandbagged?)自分自身に課していた基準が低すぎたのだと、そのひと言が教えてくれたのだ。どちらの判定も正しく、どちらも心地よいものではなかった。
法則:評価者が悪い点をつけられないなら、それは飾りにすぎない。
4. 自分自身のゴールを説明できなかった計画
私は360日間の収益計画のためにクリティカルパス・ルーターを構築した。実際の収益はゼロだったにもかかわらず、それは90日のマイルストーンに対して40日で完了するという、余裕をもって実現可能な計画として算出されていた。
計算自体は正しかった。問題はグラフのほうだった——そこに含まれるノードのうち、収益を生むと宣言しているものは一つもなかったのだ。それは、計画の顔をした、ただのリポジトリ依存関係グラフだった。これは今、ブロッキングルールになっている。対象が測定可能であるにもかかわらず、その対象に何も貢献していない場合、ルートは一切提供されない。
法則:自分自身のゴールを説明できない計画は、ガントチャートを着た願望にすぎない。
十二の法則
- 明確なゴールなくして、信頼できるエージェントなし。曖昧なゴールは、さまよう仕組みを生む。
- 状態はモデルの外に存在する——モデルは考え、システムは記憶する。
- ツールには契約が必要だ。目的、入力、出力、境界、失敗モード。
- 重要なルールにはゲートが必要だ。プロンプトによる指示は制御ではない。
- 評価は証拠を生み出さなければならない。 エビデンスがなければ、信頼もない。
- リトライは、リトライ可能な失敗にのみ許される。 がむしゃらにやることは、賢く立て直すことではない。
- 停止条件はアーキテクチャである。 止まれないループはバグだ。
- メモリはキュレーションされねばならない。 悪いメモリはエラーを増幅する。
- 人間はレバレッジの高いゲートに置くべきである。 それは責任であり、弱さではない。
- 可観測性が信頼を生む。 検査できないものは、運用できない。
- エージェントを増やすことは、知能を増やすことではない。 難しいのは調整(コーディネーション)だ。
- ループは複利で伸びていくべきだ。 すべての実行が、次の実行をより良くするべきだ。
そして十三番目の法則――上記の四つの物語が、その代償として買い取ったものだ。ループを、自分自身を有罪にできるように組め。 自分の作者だけを検証し続けるシステムは、鏡にすぎない。
三十日間、正直に
この節に書かれているものはすべて、目指すべき目標であって、報告している結果ではない。対照実験は行っていない。ここに挙げるのは、自分自身のビルドに課している基準だ。
第1週――最小限のループ。 ゴール契約、状態スキーマ、ツール結果スキーマ、コントローラー、プランナー1つ、ツール2つ、評価器1つ、反復回数の上限。目標:手を触れずに単純なタスクを完了させること。
第2週 — 信頼性。 エラーの分類、is_retryable リトライ上限超過フラグ、リカバリーポリシー、繰り返しエラーの検知。目標は、一過性のエラーか、検証エラーか、権限エラーか、業務ルール違反かを区別できることだ。
第3週 — ブレーキ。 リスク階層、コードによるポリシーゲート、承認パケット、監査ログ。目標は、テストスイート内のすべての制限付き呼び出しがブロックされることだ。
第4週 — 複利化。 メモリ候補、恒久化する前の人間によるレビュー、失敗パターンの追跡。目標は、同じ失敗が再発しなくなることだ。
本稿が主張しないこと
- ベンチマークはない。 このアーキテクチャを別の手法と比較測定したわけではない。四つのエピソードは事例であって、研究ではない。
- 上記の数字は目標値である。 この原稿の初稿には、これらがまるで実測結果であるかのように読める箇所があった。それは誤りであり、こっそり削除するのではなく、ここで訂正しておく。
- 一人の運用者、一つの現場。 ここで学んだことはすべて、自分自身のリポジトリと自分自身のエージェントから得たものだ。あなたの現場で起こる失敗パターンは、これとはきっと違う。
出典
自分に課しているルールはこうだ——出典なきところに主張なし。この記事の以前の草稿は、まさにこのルールを破っていた。Tree-of-Thoughts論文について出典を示さずに主張してしまっており、それはこのルールが防ごうとしている失敗そのものだった。だからここに出典を示す。
- Tree of Thoughts: Deliberate Problem Solving with Large Language Models、Yao et al., 2023 — arXiv:2305.10601。この論文は、探索・計画タスクにおいてchain-of-thoughtを大きく上回る成果を報告している。ここでは正確な数値をあえて再掲していない。公開時点で再検証していないためだ。
- 四つのインシデントはすべて自分自身のリポジトリのコミット履歴から取ったもので、期間は2026年8月5日から2026年8月11日である。
まとめ
プロンプトエンジニアリングはAIを役立つものにした。ループエンジニアリングはそれを信頼できるものにする。
プロンプトは答えを生み出せるが、ループは仕事を生み出せる。プロンプトは賢そうに聞こえるが、ループはテストできる。プロンプトは人を感心させられるが、ループは複利で積み上がっていく。
ゴールを、状態を、ツールを、ゲートを、評価者を、リカバリーを、人間を、記憶を組み立てよ。そして最後に、ほとんどの人が飛ばす一点を組み立てよ。自分が間違っていたと告げることを許された部分を、だ。