補足: 本記事は AI(Claude)が私の最初のメモと着想をもとに仕上げたものです。
前回の「計画はチケットに書く」では、エージェントの状態をどこに置くべきかを扱い、issue tracker のコメント欄へ引き上げる、という結論に至った。だがチケットに残るのは段階と段階のあいだの受け渡しだ——計画、承認、PR、マージ。一巡の内側がどう回っているかまでは、チケットの手は届かない。
今回はその内側の話をする。
先に言っておくと、エージェントがいちばんよく起こす失敗はコードを間違えることではない。頼まれてもいないことをやり、そのうえで「終わりました」と報告してくることだ。
いちばん素直な防御は、手を動かすたびに確認させることだ。この方法は失敗する。しかも静かに失敗する——訊かれる回数が多すぎると、人は読まずに yes を押しはじめる。ゲートは画面に残っているが、もう何も止めていない。
本当の問題は「何回訊くか」ではなかった。訊かれたその一回に、答えるだけの材料が手元にあるかどうかだ。
いま私は一巡を八つに切り、そのうち三番目だけが人を待つようにしている。
1 見積り → 2 受入条件 → 3 ゲート〔人を待つ〕→ 4 下絵
↓
8 締め ← 7 再検証 ← 6 コンプライアンス審査 ← 5 実装ループ
残りの七つには、誰も横についていない。そこはモデル自身の規律だ。
止まるその一箇所で出てくるのは、四つの欄だけだ。
Size ▰▰▱ medium — 一行:どこまで広く、どこまで深く、どれだけ戻しにくいか
Acceptance:
- 観察できる結果を一つ
Non-goals: この一巡で意図的に触れないもの
Changes: どのファイルを、どういう意図で
四つの欄には、それぞれ役目がある。
none と書けばいい。埋めるために盛る必要はない。この四欄が本当に買っているものは、一度の返事で一巡すべてを決められるということだ。ゲートが一つしかないのは、それが高価だからでもある——情報がいちばん揃った瞬間に、一度だけうなずく。
ここで問題が出てくる。モデルはルールを忘れる。安価なモデルならなおさらだ。
しかも忘れ方が具体的だ。設定ファイルの冒頭に書いたルールは、四十ターン目にはコンテキストの端へ押しやられている。 違反されたのではない。ただ視界に入っていないだけだ。一度読み込まれたルールは会話とともに減衰する。これはモデルの賢さとはあまり関係がない。
だから私の対処は素朴だが、効く。毎ターン注入し直す。 ユーザーのメッセージが届くたび、hook がゲートの仕様と審査の発火条件をコンテキストへ貼り直す。ルールは冒頭の挨拶ではなく、背景音になる。
この設定のなかでいちばん地味で、いちばん効いている部分がこれだ。
一つだけ持ち帰るなら、この三本であってほしい。
段階が見積りを超えた ──→ 見積りへ戻る (押し切らない)
検証が食い違った ──→ コードへ戻る (テストへ戻らない)
審査で指摘が出た ──→ コードへ戻る、再検証より前に
一本目。 あなたが与えた一言が覆うのは、そのとき示された記述であって、後から育った姿ではない。範囲が広がった、深さが増した、戻しにくくなった——どれか一つでも当初の見積りを超えたなら、止まって測り直し、もう一度あなたの言葉を待つ。途中で別物になったと気づきながら、古い許可のまま進むのが、私の見てきたいちばんよくある逸脱の形だ。
二本目。 結果が計画とずれたときは、テストではなくコードへ戻る。テストを曲げて通すのは、あらゆる近道のなかで最も安く、最も致命的だ——赤を緑にするだけで、何一つ正しくならない。
三本目。 審査で出た指摘は「再検証」の前に直す。後回しにできない理由は次節にある。
「三つ前のメッセージではテストは緑だった」は数に入らない。
証拠は、それが支える主張と同じターンから来なければならない。 その緑のあとに手を入れたのなら、あの緑はいま手元にある木を説明していない。同じターンでの再実行なしに「完了」と報告するのは、事実ではない——事実の服を着た推測だ。
ついでに、小さいわりに実入りの大きい落とし穴を一つ。
set -o pipefail; flutter analyze 2>&1 | tail -6
先頭の set -o pipefail がないと、shell が返すのは tail の終了ステータスであり、tail は解析器が何を見つけようが成功する。つまりこのチェックは永遠に通過し続ける。この手のものは必ずルールとして書き残すべきだ。そうしないと数か月おきに同じ発見をやり直すことになる。
何が完了したか、何を先送りしたか、何がまだ不確かか。
黙って飛ばしたものがあるなら「完了」は誤りだ。skip されたテスト、pending のまま置かれたテスト、中身を抜かれたテストが一つでもあるなら「テストは通った」も誤りだ。正直な報告は形が整わない。だが読み手は、示された疑いには手を打てる。誰も口にしなかった穴には、何もできない。
代償は実在する。一巡ごとにあのブロックを書くところから始まる。 小さな用事では儀式めいて感じるので、逃げ道を三つ残してある——読み取りだけのターンはそもそも免除、スラッシュで呼んだスキルには外側のゲートを重ねない(呼んだこと自体が許可だ)、そして「とりあえずやって」の一言でセッション中はゲートを下ろせる。
もっと正直に言うべきはこちらだ。モデルが八段すべてを守りきる保証は、私には出せない。 毎ターンの注入は忘れにくくするだけで、忘れないようにするものではない。だから次にやることはルールを増やすことではなく、どれだけ守られているかを測ることだ。それは別の記事になる。
ゲートは一つに畳み、情報が最も揃った瞬間に人が一度だけうなずく。残る七つは規律に委ね、その規律は記憶に頼らず毎ターン注入し直す。そのうえでなお生じるずれは、後ろへ戻る三本の辺が引き戻す。