かつてマージはゴールラインだった。プルリクエストを開き、誰かがレビューし、それが取り込まれれば変更は完了していた。コーディングエージェントは、そのラインを静かに動かしてしまった。エージェントがLinearのissueを引き受け、コードを書き、あなたが会議に出ている間にマージリクエストを開くとき、マージはもはや作業の終わりではない——マージが触れるすべての物事の始まりなのだ。
マージはもうゴールラインではない
マージは決して単なるマージではない。あらゆる変更は、それを取り巻く仕組みに依存している。今こそクローズされるべきissue、今朝からわずかに事実と異なることを説明しているドキュメント、昨日より少し赤くなったCI、誰も書いていないリリースノート、実際には数時間前に出荷済みの修正をいまだに待っているサポートの会話。
ひとりのエンジニアが週にわずかな変更を出荷していた頃は、こうした後始末は隙間に収まっていた。プルリクエストを開いたついでにissueをクローズし、コードに触れたばかりだからドキュメントのことも覚えていた。ところがエージェント——あるいはその集団——が1日に多くの変更を出荷するようになると、その隙間があふれ出す。もはやボトルネックはコードではない。コードの下流にあるすべてがボトルネックなのだ。
メンテナンスのモデルは変わらなかった
開発は速くなった。メンテナンスは速くなっていない。プロジェクトの一貫性を保つために使うツールは今も大半が手作業であり、今も誰かが適切なタイミングでそれに手を伸ばすのを覚えていることに依存している。
- マージリクエストは取り込まれたが、それが解決するLinearのissueは開いたままだ。
- ドキュメントは相変わらず古い挙動を説明しており、どのページなのか誰もはっきり分からない。
- CIは1週間断続的に落ち続けており、誰もがそれを読み飛ばす術を身につけた。
- 3か月前のフィーチャーフラグには担当者もいなければ削除予定日もない。
- サポートは火曜日に修正済みのバグに対して、回避策でチケットに回答してしまう。
- 「今回のリリースで何が出たの?」と聞かれ、正直な答えは「gitログを読ませて」になる。
これらはどれも新しい問題ではなく、実のところエージェント特有の問題でもない。ソフトウェアプロジェクトにありふれたエントロピーだ。エージェントはただそのペースを上げ、かつてそれを吸収していた非公式な仕組みが追いつけなくなるところまで押し上げているにすぎない。
プロンプトによる後片付けはスケールしない
分かりやすい解決策は、エージェントにも片付けを頼むことだ。実際それはできる。マージリクエストで@taskgoblinにメンションし、ドキュメントの更新、issueのクローズ、リリースノートの下書きを指示すればいい。うまくいく。しかしそれは、ループ全体の中で最も希少なリソース、すなわち「毎回、適切なタイミングで頼むことを覚えている人間」に依存している。
メンテナンスは一度きりのタスクではなく、ループだ。「ドキュメントが最新かを確認する」は一度やれば終わりのことではない。「マージされたissueが確実にクローズされるようにする」も一度やれば終わりのことではない。誰かがループを回すべきタイミングに気づくのを待つものは、一貫性なく実行される——なぜなら人が気づくかどうかは一貫していないからだ。特に、エージェントの存在意義そのものが、こうしたことすべてを頭の中に抱え続けなくて済むようにすることだったはずなのに。プロンプトによる後片付けは作業をエージェントに移すが、その作業のスケジューリングはそのままあなたのもとに残る。
なぜ私たちはLoopsを作ったのか
通常のエージェントランはイベントによって起動する——issueの割り当て、メンション、新しいプルリクエスト。Loopは時間によって起動する。エージェントに常設の指示と頻度——平日の毎朝、毎週月曜日、毎月1日など——を与えれば、他のどのランとも同じツールとアクセス権を持つサンドボックスの中で、それ自身が実行される。
指示こそがタスクのすべてであり、優れた指示は願望ではなく職務記述書のように読める。何を見るか、どのリポジトリか、何をするか、何をしないか、そして——無人で実行しても安全にするための肝心な部分——やることが何もないときに何をするか、それは何もしない、ということだ。
平日の毎朝9時、
group/repoで過去1日にマージされたマージリクエストを確認し、それらが解決したLinearのissueでまだ開いているものがあればクローズせよ。該当がなければ何もしない。
これは担当者のいるメンテナンスループだ。あなたが思い出すのを待つ必要はない。スケジュール実行は完全なエージェントランであるため、最後まで通しでやり遂げられる。古くなったドキュメントに印を付けるだけでなく、それを修正するマージリクエストを開く。マージ済みのissueが開いたままになっていることに気づくだけでなく、それをクローズする——そしてあなたが実際に目にする場所、Linearのissueへのコメント、指定したSlackチャンネルへのメッセージ、他に適した場所がなければメールとして、報告する。
そして通常のランがすでに行っているすべてを再利用しているため、細かな難所も処理済みだ。取りこぼした時間は後追いで実行されるのではなくスキップされるため、1時間ダウンしていたスケジューラが目覚めたとたんに100件の追いつき実行をあなたに浴びせることはない。各ランには独自の予算とガードレールがある。私たちはまさにこうしたループのための出発点となるテンプレート一式を提供している——issueとマージの同期を保つ、長く赤いままのCIを監視する、担当者が去ってしまったフィーチャーフラグを追いかける、物事が出荷されるたびにリリースノートを下書きする。役に立つものはほとんどのチームで同じだからだ。あなたは自分のリポジトリとチャンネルを埋めるだけでいい。ガードレールはすでに書かれている。
エンジニアの仕事は一段上に上がる
この話の根底には不安がある。メンテナンスを自動化することは、判断力まで自動化してしまうことではないか、と。そうではない。それは判断力を一段上に押し上げる。ループが自ら回るようになると、あなたはissueをクローズすることを覚えている人ではなく、どのループが存在すべきか、そのガードレールは何か、それぞれにとっての「完了」とは何かを決める人になる。あなたは雑用をこなすのではなく、常設の指示をレビューするのだ。
いずれにせよ、それがこの仕事のより上級なバージョンだ。エージェントはコードを書くコストを下げた。残された仕事は、システムについて何が真であるべきかを決め、それが真であり続けるようにすることだ。Loopsは、そのすべてを頭に抱え込むことなく真であり続けさせる方法だ——エージェントが仕事を生み出し、常設のループがそれを維持する。