コード作成に使うAIコーディングエージェントは保守コストを下げる必要がある
(jamesshore.com)- 新しいコードを書く速さよりも、保守コストが長期的な生産性を左右する
- 例のモデルでは、2年半後に保守が全体時間の半分を超える
- AIエージェントが産出量と保守コストの両方を増やすと、効果はすぐに消える
- エージェントの利用をやめても、すでに作ったコードの追加保守コストは残り続ける
- 産出量が2倍なら、コード当たりの保守コストも半分まで下げる必要がある
保守コストが生産性を決める
- コード作成に使うすべての時間は、その後もバグ修正、整理、依存関係のアップグレードといった保守時間を継続的に発生させる
- 新機能や改善作業ではなく、コードが存在する限り毎年繰り返される保守だけを対象にしている
- 例の推定値は、コード作成1か月ごとに初年度は10日、以後は毎年5日の保守時間がかかるという仮定に基づいている
- Wisdom of the Crowd 方式で50人ほどの開発者に保守コストを尋ねれば、かなり正確な答えが得られるとみている
- この仮定で作ったスプレッドシートモデルによると、新規プロジェクトの初期には大半の時間を機能開発に使うが、時間がたつほど過去のコード保守の比重が大きくなる
- この推定では、2年半後に保守に使う時間が全体の半分を超え、10年後にはほとんど他の仕事ができなくなる水準に達する
- 保守の推定値を半分に下げると、50%地点まで3年余裕が生まれ、2倍にすると1年もたたないうちに生産性が50%を下回る
- 生産的なチームを望むなら、新しいコードを書く速さよりも保守コストに注目すべきだ
モデルは間違っているかもしれないが、方向性は正しい
- 後期段階のスタートアップでは、5〜9年ほどたつとチームが仕事をきちんと終えられなくなる問題が現れ、これはグラフが示すパターンに似ていた
- 実際のチームがグラフほど悪く見えない理由は、保守コストが低かったからかもしれないし、別の方法で問題を覆い隠していたからかもしれない
- 可能な対応策としては、すべてのバグを直さない、すべての依存関係をアップグレードしない、チームが遅くなったら人員を追加し続ける、全体を捨てて書き直す、といったものがある
- 正確な数字は議論できても、時間とともに生産性が下がる大きな流れは経験的に正しそうだ
AIコーディングエージェントが生む乗算効果
- 例として、最新のエージェント型コーディングフレームワーク Rock Lobster がコードの産出量を2倍にすると仮定する
- 同時に、コードが少し理解しにくくなり、チームがプルリクエストに圧倒され、承認前にコードをきちんと読まなくなると仮定する
- 1か月で2か月分のコードを作り、その産出物の保守コストも2倍になるなら、翌月の保守コストは4倍になる
- この極端な例では、Rock Lobsterの使用後およそ5か月で生産性は元の水準に戻り、数か月後にはまったく使わなかった場合より悪くなる
- これはAIが実際に生産性や保守コストを2倍にするという意味ではなく、保守性が人間の書いたコードと同程度であっても、生産性の利得は長続きしないことを強調している
エージェントの利用をやめても保守コストは残る
- コーディングエージェントにはコストがかかり、その効用がコストを下回れば以前のやり方に戻したくなるかもしれない
- エージェントの利用をやめると生産性の利得は消えるが、エージェントで作ったコードの追加保守コストはコードが残っている限り続く
- この場合、エージェントをまったく使わなかった場合より低い生産性に縛られる可能性がある
成り立つ数学は保守コスト削減だけ
- LLMがコードの産出量を増やす比率の正確な逆数だけ、保守コストを下げなければ全体の生産性計算はつじつまが合わない
- 産出量が2倍で、その産出物の保守コストも2倍なら、全体の保守コストは4倍になる
- 産出量が2倍で、産出物ごとの保守コストがそのままでも、全体の保守コストはなお2倍になる
- 産出量が2倍なら保守コストは半分、産出量が3倍なら保守コストは3分の1でなければならない
- この条件を満たしてはじめて、速度の利得を得ながら長期的な負債化を避けられる
現在のコーディングエージェントへの懸念と、別のてこになりうるもの
- Hacker News のようなソースでは、コーディングエージェントが保守コストを増やしていることを示す兆候が多いように見える
- 大規模システムの理解に役立つという意見もあるが、必要な水準の大幅な保守コスト削減は見られず、むしろ逆に近いとみている
- モデルが現実を完全には表していなくても、AIは新しいコードを書く速度に比例して保守コストを下げる必要がある、というメッセージは有効だ
- コーディング速度の改善を追求するなら、保守コスト改善にも同じだけ時間を使うべきだ
- これは反AIの主張ではなく、コード自体の保守性を高めなくても、保守作業そのものをより生産的にするAIのような別のてこもありうる
- 実際の状況に合わせて仮定を変えたいなら、スプレッドシートをコピーしてモデルの各種変数を調整してみることができる
1件のコメント
Hacker Newsの意見
Dconf'24の発表 Software as investment では、ソフトウェアの各断片ごとに合成可能な価値関数に基づく基本フレームワークが提案されていた。
このフレームワーク自体はAIのせいで特に変える必要はなく、別途、保守においてAIがどれだけうまくやるかに応じてコストモデルだけ更新すればよい。
AIはバグを1.7倍多く生むという話もあるが、もしかするとより速く直せるのかもしれず、何とも言えない。
ソフトウェアを投資として見ると、「技術的負債」ではなく「価値」を語ることになり、負債とは価値が0未満の資産にすぎない。
ソフトウェアが過去の高マージンな世界を離れるなら、経済的に 存在する価値のあるソフトウェア とは何かを精密に定義しなければならない。
ソフトウェアには常に、もっとうまく書けたはずの部分があり、それが負債だ。
洞察に富んだ見方で、同意する。
残念ながら保守性は普通、非機能要件 という箱に入れられる。
だが保守性のような非機能要件は、将来の機能要件の提供を維持し可能にするものとして捉えるべきだ。
単にソフトウェアが何をすべきかに対する「どうやるか」という程度の枠組みで考えるべきではない。
継続的な機能追加と改善が重要なプロジェクトなら、ごく短い期間を除けば保守性は実質的に 機能要件 に近い。
別の名前を与えた瞬間、それをよく分かっていない人に切り離して優先度を下げる口実を与えてしまう。
品質は重要であり、維持しなければ損益計算書に非常に速く、そして強く響く。
だから他のどんな要素と同じくらい重要だ。
Kevlin Henneyの表現である 運用特性 と 開発特性 を使えばよい。
保守性は根本的な開発特性だ。
1〜2年の製品ロードマップがあることはあるが、正直に言えばそうしたロードマップはエンジニアリング計画というより営業目的に近い場合が多い。
売上が落ちると製品とエンジニアリングは方向転換し、会社の初期ほどそうしたことがよく起きる。
スタートアップ段階を抜けたら安定化すべきだが、多くの会社はそうならず、短期計画のパターンを繰り返し続ける。
その結果、製品の安定性 は低い優先順位のままになる。
結局、多くの会社は良いソフトウェアを作るための資源がないか、実際には気にしていないように見える。
自分たちのプロジェクトを作りながら実感したのは、AIは速いが、AIが入れたバグは妙に見つけにくいということだ。
露骨なバグではなく、3週間後に本番環境で何かが壊れ、追跡してみるとAIが微妙な部分を誤解していた、という類いのロジックだ。
正直、AIは保守コストを下げるというより コストの位置を変える。
作成時間は減り、レビュー時間は増える。
AIのコードは間違っていても流暢で自信満々なので、人間のコードよりレビューが難しい。
純利益になるかどうかは、チームがコードを書く能力よりも 読む能力 にどれだけ優れているかに完全にかかっている。
私の経験では、AIは 保守コスト を下げてくれる。
ただし文脈は重要かもしれない。私は数十年物の複数のプロジェクトを扱っており、新機能開発も多いが、古いコードや古いプロジェクトが突然はるかに扱いやすく、モダナイズしやすくなり、多くの場合は削除すら可能になった。
古いライブラリやビルドツールの依存関係は、更新されたものもあれば、単に削除されたものもあり、ビルドは速くなって開発者にも扱いやすくなった。
エンドツーエンドテストの設定と自動化もはるかに簡単になり、DevOpsも大きく改善され、運用問題の診断もかなり良くなった。
ログや情報は非常に多く、重要なものを捉えるための統合ダッシュボードや監視もあるが、いまではデプロイ済みシステム約50プロジェクトについて、はるかに多くの分析ができる。
記事の基本主張は、「価値追加」機能開発1時間あたり、保守を何時間しなければならないか、ということだ。
だから第一に、保守コストだけを測るべきではなく比率を見るべきであり、第二に、その 古いコード はそもそもAIで書かれたものではない。
ただ著者のポイントは、AIツールへのアクセスを失うとすべてがより心細くなる、ということのようだ。
重機で楽に山を動かしていたのに、再び手工具に戻るようなものだ。
デプロイされるコード行数とともに障害が増え、しかも障害はますます深刻になっている。
もちろん古いコードをかなり改善し、より多く削除し、コードのモダナイゼーションを自動化できるし、問題診断も改善し、緩和策の選択肢も増えた。
だがそのすべてでも、誰もきちんと理解していないままデプロイされるコードの 圧倒的な規模 を相殺できなかった。
私たちのチームはAIでコードを追加することもあるが、古くなって放棄されたコードを積極的に削除するのにも使っている。
「まだこれを使っている人はいるのか?」「これはどう呼び出されるのか?」といった疑問は、フロントエンド、バックエンド、コードベース全体をエージェントに投げてソフトウェアプロジェクトの地図を作らせると答えやすくなる。
IDEも単一言語かつ通常は単一プロジェクトの中ならある程度はやってくれるが、RPC や REST のような境界が多いとIDEツールは壊れがちだ。
この問いは本当に好きだ。望めるなら、どんなコードベースが欲しいか?
少し考えれば、たぶん機能が極端に多いコードベースを望むわけではない。
いま持っているものとかなり似ているが、理解しやすく、今後の事業課題に合わせて保守や拡張がしやすい コードベース を望むことになる。
「動いている」コードベース、つまり保守されているコードベースは現実の問題を解いており、その問題を解くことは常にきれいさより優先されるべきだ。
きれいなコードベースというのは、たいてい棚に置いて眺めるための 展示用サンプル であることが多い。
2つ付け加えたい。
第一に、ソフトウェアには技術的保守だけでなく ユーザーサポート もあり、ソフトウェアが大きくなるほどこれも増える。
第二に、保守コストが線形に増えるとは確信していない。
たとえ線形に増えるとしても、結局は保守にすべての時間を使う地点に達する。
各部分だけでなく、部分同士がどう相互作用するかまで保守しなければならないなら、そうかもしれない。
AIが実際に保守コストを下げるかどうかについて、私が見た中で最も強いシグナルは、開発者がAI出力を 下書き として扱うか、それとも最終成果物として扱うかだ。
既存のコードベースでAIツールを使う場合、たとえば不慣れなモジュールの理解、狙いを定めたリファクタリングの生成、マイグレーションスクリプトの作成では、保守負担は実際に下がる。
自分がアーキテクチャ的にすでに理解しているコードの上でAIが作業するので、出力を素早く評価できるからだ。
問題は、AIが誰も深く理解していない新規コードを生成するときに現れる。
そのコードは、書いても設計してもいない人が保守しなければならない。
他人が書いたコードなら、少なくとも名前、構造、コミット履歴から意図を推測できる。
AI生成コードには、「作者」がファイル全体にわたる持続的な意図を持っていないため、そうした 読み取れる意図 が欠けていることが多い。
この記事が正しいのは、速度だけでなく保守コストも測るべきだという点だ。
実際には、AI支援コードと人間が書いたコードについて、理解に要する時間や変更失敗率を、数日ではなく数か月にわたって追跡すべきだ。
コードレビューも同じだ。
AIがコードレビューをもっと見やすくできるのか気になる。
人間のコードレビューでは、開発者はコードやコメントをリフローしたり、ツールが隠せないインデントを変えたり、関数を移動したり、行を消したりといった不要な視覚的変更を避けることをすぐ学ぶ。
不要なリファクタリングもしないほうがいい。
レビューを 機能変更 と 見た目の変更 の2つに分けることもできそうだ。
REFACTOR_ONLY:のような表現を付ければよい。そうすればレビューはずっと楽になる。
レビューは「何も変わってはいけない」から始まり、レビュー担当者はパターンマッチングができる。
そうでないと、レビュー担当者はすべてのコード行を再評価して本当に何も変わっていないか確認しなければならず、まともにやるのは本当に難しい。
私が使ってきたバージョン管理システムはどれも、それぞれ独立してレビューされる変更キューを許していた。
開発中にリファクタリングが必要なら、1つコミットを積んでリファクタリングし、レビューを送り、その後進行中の作業をリベースして続ければいい。
CLEANUP:やREFACTOR_ONLY:のような変更を流し続ければ、最終的な変更は巨大な怪物のような変更よりずっと小さくなる。レビュー担当者はその配慮に感謝するだろう。
そういう組織なら、指標ゲームも邪悪にならずに済む。
著者は、人間がすべてのAIコードを詳しくレビューし、AIの助けなしに理解して保守できなければならない、という前提から出発しているように見える。
私の経験では、人々はAIをそこまで厳密には使っていない。
最初はそう始める。まだ信頼しておらず、望む結果を得るようにプロンプトする方法も学んでいないうちは、退屈な部分の自動化に使うが、初期実装やパターンは人間が作り、AIが隙間を埋める。
コードの書き方における大転換というより、強化された自動補完 に近い。
AIと長く働くほど、人々はAIが実際に生成するコードをあまり気にしなくなる。
それが良いという意味ではない。バグ、性能問題、セキュリティホールを作る可能性がある。
だが現実はそうだ。AIコードがバグを作った? AIに直させればいい。
AIコードが肥大化して読みにくい? 気になるならAIに直させればいい。多くの人は気にしない。
人間がコード保守から完全に外れるなら、保守可能なコード の必要性も消える。
まだ100%そこまで行ってはいないが、その方向には進んでいる。
多くの会社では、すでに十分に良いので、リスクを取ってYOLOで進む価値がある。
個人的には、AIが生成したコードを読まないほどには信頼していないが、すべての行を読むわけでもない。
テスト対象のコードよりテストのほうを注意深く見て、性能が重要な部分にはより気を配り、全体構造を導く。
それでも基準を満たさなければ、自分で保守するのではなくAIに直させる。
保守がこれほど安いなら、保守コストは自分の関心事には上ってこない。
この記事は、AIエージェントや補助ツールが最初の「新しいウィジェットを作ってくれ」という部分だけでなく、ソフトウェア開発のさまざまな部分を助ける必要があることをよく浮き彫りにしている。
著者は、誰かがAIエージェントや補助ツールを新しいウィジェットを作る段階にしか使わないなら、AIによってより多くのコードを吐き出せるため、保守すべきコードもはるかに増えると見ている。
コード品質が高くても、時間が経てば 保守コスト は発生する。
ただし著者が語る問題は、誰もが直面する問題というより、かなりの部分が自ら招いた問題に近い。
著者が指摘するスタートアップの状況、つまり「市場適合性を確認し、顧客を獲得するために、とにかくこれを動かそう」という状況は、もともと後でより高い保守コストを伴ってきた。
事業があるかを確認し、あるなら素早く拡大するために、スピードの名目で品質を下げるのはある程度もっともだからだ。
また、著者はAIが保守の部分を実際にどう助けられるかについて語るのを避けているようにも感じた。
AIは、人間のガイドがあるとき、古い依存関係の修正や厄介なバグの解決にとても有用になりうる。
こうした作業はソフトウェアエンジニアにとって雑務のように感じられることがあり、AIの助けを借りたくなる種類のものだ。