チームが人間のために築いてきた環境上の規律は、そのままコーディングエージェントにも当てはまる。だがほとんどのチームは、エージェントが優秀になった瞬間にそれを静かに手放してしまった。新人を入社初日に本番環境へ近づけないような組織が、エージェントには長期有効な認証情報とタスクの説明だけを渡し、消えてはいけないものが消えたときに驚いてみせる。

主張はあえて地味にしてある。エージェントは異常に速いが組織的な判断力を持たないコントリビューターであり、環境の階段はまさにそうしたコントリビューターのために存在する。開発、ステージング、本番、それぞれの間にゲートを置く。これは人間そのものについての話だったことは一度もなく、常に被害範囲についての話だった。

なぜ階段は省略されたのか

誰かが階段を省略しようと決めたわけではない。それは徐々に浸食されていった。その経緯を知っておく価値がある。おそらくあなたのチームも、その途中のどこかにいるからだ。

エージェントは最初、単なる自動補完として始まる。自動補完をステージングする者などいない。次にローカルでテストスイートを実行するようになる。ここまでは問題ない。次にバグを再現するために実サービスへアクセスする必要が出てきて、誰かがステージングへの読み取り権限を与える。次にステージングのデータが古くなり、誰かが本番のレプリカを指すようにする。次にあるタスクが書き込みを必要とし、環境にすでに置かれていた認証情報がたまたまそれを持っている。エージェントが本番に書き込めるようにしようと誰かが決めた瞬間は一度もない。それぞれ単体では理にかなった一連のステップを経て、そこにたどり着いただけだ。たいていのインシデントは、どこでもそうやって発生する。

エージェントが人間と違う点

この階段は、人間よりもエージェントにとって重要だ。理由はモデルの能力に対する評価ではなく、構造的なものにある。

  • 速さが「間」を奪う。破壊的な操作をする人間は、たいてい先に躊躇する。その躊躇は文書化されていない安全装置であり、緩く運用されているにもかかわらず人間に対して階段が機能してきた理由の大部分を占める。エージェントは2秒で全力の確信を持って実行する。そこに拾い上げるべき「間」はない。
  • 結果の重みが分からない。エンジニアは、このテーブルが課金テーブルであり、木曜日が請求書発行日だと知っている。その知識はリポジトリには書かれていないため、エージェントのコンテキストにも存在しない。スキーマは知っていても、賭かっているものの大きさは知らない。
  • 目的を文字通りに受け取る。統合テストを通すよう指示されたエージェントは、テストが検証しているデータそのものを書き換えることを検討しうる。それは提示された問題に対する正当な解決策であり、間違っているのはエージェントが持っていないコンテキストのせいでしかない。
  • 量。エンジニア1人なら1日にプルリクエストを3件開く。エージェントの一団なら30件開く。1件あたりの不良変更の確率が下がったとしても、不良変更の絶対数は増えうる。

エージェント向けに階段を言い直す

段の数は同じ3つのままで、エージェント特有の部分だけを取り上げる。

  • 開発: 使い捨てで隔離されている。1エージェント、1ワークスペース、共有状態なし。2つのエージェントが同じチェックアウトで作業すれば、同じファイルを奪い合い、どちらも理解できないマージコンフリクトを午後いっぱいかけて読むはめになる。使い捨てのブランチとワークツリーは安価だが、共有される可変状態はそうではない。
  • ステージング: 形は本物、賭け金は偽物。ステージングが存在意義を持つのは、構造的に本番に似ている場合、つまり同じスキーマ、同じサービストポロジー、同じ失敗の挙動を持ちながら、失っても困るものを何一つ含んでいない場合だけだ。データはシード投入か合成のものにし、決して本番のコピーにしない。ステージングにある本番レプリカは、監視の甘い本番環境にすぎない。
  • 本番: 人間とゲートのみ。エージェントの成果物が本番に届く経路は、他のあらゆる変更と同じでなければならない。レビュー済みのプルリクエストと、既存のデプロイゲートを通す。裏口も、近道を持つサービスアカウントも用意しない。

隔離を決めるのは認証情報であって、URLではない

チームが自分を欺く場所はここだ。エージェントをstaging.internalに向けたとしても、その環境にある認証情報が本番でも有効であれば、それは隔離になっていない。環境の境界を決めるのは、タスクがどのホスト名に言及しているかではなく、そのIDが到達できる範囲だ。広いロールを持つエージェントは、混乱したツール呼び出し1回で間違ったアカウントに到達してしまう。しかもそれを丁寧に、即座にやってのける。

ここで通用するのは、目新しさのないAWSのプラクティスを一貫して適用することだ。

  • 環境ごとにアカウントを分ける。そうすれば環境をまたぐミスは、存在するタイプミス1つではなく、存在しないロールの引き受けを必要とするようになる。
  • エージェントのタスクごとに専用ロールを用意し、そのタスクに必要なリソースだけにスコープを絞り、実行時間中だけ引き受ける。
  • エージェントの環境に長期有効な鍵を置かない。短期の認証情報であれば、コンテキストが漏洩しても有効期限付きの問題で済む。
  • 破壊的な操作はデフォルトで拒否する。DeleteObjectを一度も必要としないエージェントは、単に呼び出さない傾向にあるのではなく、構造的に呼び出せない状態にすべきだ。
  • 実データを持つアカウントに踏み込む操作には人間の承認を必須にする。エージェント自身では満たせない統制として機能させる。

レビューゲートは摩擦ではなく本質だ

予想される反論はこうだ。これではエージェントが遅くなる、エージェントの魅力はそもそも速さだったはずだ、と。この反論は真剣に検討したうえで退けるべきものだ。トレードオフの値付けを誤っているからだ。

エージェントの速さの優位は、生成にあって検証にはない。1時間ではなく90秒でもっともらしい修正を書く。これは本物で、しかも大きな差だ。だが検証は、エージェントが取り除くようなボトルネックだったことは一度もない。レビューゲートを外しても、エージェントが得意な部分がさらに速くなるわけではなく、ただ自信満々な出力のうち間違っている1割を捕まえる仕組みが失われるだけだ。90秒の修正はそのまま得られる。レビュアーもそのまま残る。それが全体の構成であり、良い構成だ。

まとめ

ここに挙げたものは、どれも新しいエンジニアリングではない。環境の分離、スコープを絞った認証情報、本番前のレビュー。あなたのチームはこれらのルールを人間のために書き、おおむね守っている。誤りは、エージェントをコントリビューターではなくツールとして扱うことにある。ツールには環境の階段は不要だが、コントリビューターには必要だからだ。エージェントには、本番に似た見た目を持ちながら重要なものを何も抱えていないサンドボックスと、期限が切れて境界を越えられないIDと、デプロイとの間に立つレビュアーを与えること。そのうえで、その箱の中では思う存分速く動かせばいい。

次に読むべき記事

この背後にあるアカウントレベルの統制については、AWS Organizationsにおけるマルチパーティ承認が、単独で実行してはいけない操作に対するゲートを扱っている。掲載はercan.cloud。ハブはercanermis.comだ。