世界を動かす技術を、日本語で。

理解の負債:LLM生成コードの時限爆弾

概要

  • LLM生成コード の修正・理解にかかる時間が増加傾向
  • 「comprehension debt」 という新たな技術的負債の発生
  • コードレビューや再作業による 生産性の鈍化
  • 未読・未検証のコード がリポジトリに増加
  • 今後のソフトウェア保守性への 深刻な影響

LLM生成コードと「comprehension debt」の増大

  • Large Language Models(LLM) によるコード生成の普及
  • LLM生成コードの 修正・理解に要する時間の増加
  • レガシーシステム保守時と同様、 コードの意図や動作の把握 が前提条件
  • LLMは 膨大な未読コード を高速で量産
  • 品質重視チームは レビュー・再作業 を徹底、結果的に 時短効果の相殺
  • 一方で、 未読・未検証のままコードを投入 するチームも増加傾向
  • 理解が追いつかない速度で生成されるコード による「comprehension debt(理解負債)」の蓄積

comprehension debtのリスクと現状

  • ソフトウェアが利用され続ける限り、 生成コードの修正ニーズ は必然
  • 一部では「 ツールで再生成すればよい」との楽観論
  • 実際には、 LLMで100%修正できるケースは少数
  • 「doom loop」 :LLMで修正を試みても解決できず、何度もやり直す悪循環
  • 最終的には人間による直接編集が不可避
  • comprehension debt は、 コード理解にかかる追加コスト として確実に増加
  • 理解負債の山 が急速に拡大中

今後の対応と課題

  • コード生成の効率化保守性のバランス が重要課題
  • レビュー体制の強化LLM活用ルールの策定 の必要性
  • 理解負債の可視化・管理 による長期的な品質維持
  • 人間によるコード理解・編集能力 の再評価
  • LLM依存リスク に対する組織的な意識の醸成

Hackerたちの意見

これはもともとあった問題だけど、LLMに頼ることでさらに悪化してるね。Naur(https://gwern.net/doc/cs/algorithm/1985-naur.pdf)が「理論構築」と呼んでたけど、>「プログラムの死は、その理論を持つプログラマーチームが解散するときに起こる。死んだプログラムは、コンピュータで実行され続け、有用な結果を生むこともある。実際の死の状態は、プログラムの修正要求に対して知的に答えられなくなったときに見えるようになる。プログラムの復活は、新しいプログラマーチームによってその理論を再構築することだ。」ラモートは「プログラミング ≠ コーディング」と呼んでいて、プログラミングは「達成したいこととその方法」で、コーディングは「コンピュータにどうやってやらせるか」って言ってる。これにはすごく同意するよ。たとえ開発チームが理論構築やモデリングのフェーズをスキップしても、コードを打ち込むときにモデルの一部を受動的に吸収してると思う。LLMが置き換えるのは、その偶発的なモデル構築の最後の手段だと思う。モデルや理論が必要だと思わないプログラマーと、LLMが自分たちを速くしていると報告している人たちの間には強い相関関係があるんじゃないかな。

「モデルや理論が必要だと思わないプログラマーと、LLMが自分たちを速くしていると報告している人たちの間には強い相関関係があると思う。」私は、コンピュータや関連技術から完全に離れているときに、ソフトウェアプロジェクトでより多くの価値を生み出せるという経験がある。自分が何を求めているのかが明確だと、コードがどれだけ早く進むかは驚くべきことだよ。この時点でLLMは非常に役立つことができる。なぜなら、その幻覚がすぐに自分の視点でフラグを立ててくれるから。もし自分が何を求めているのかわからなければ、これがどう機能するのかは見えない。私は、毎日何時間も真っ白なキャンバスを見つめる理由が本当に理解できない。LLMはあなたを解放して正しい方向に進ませるかもしれないけど、むしろ無駄な追跡に引き込まれる可能性が高いと思う。私が解決した最後の10/10の難しい問題は、たぶんキッチンで玉ねぎを切っているときに起こった。

「理論構築」 LLMが生成したコードの「理解の負債」をプログラミングを理論構築と結びつけたのは洞察に満ちているね。これはプログラミングの活動を超えて、思考や理解のプロセス全般に当てはまると思う。LLMが生成したコンテンツ、文章や視覚芸術も含めて、これはコードに相当するもので、表面的には最終結果として人々が見るものだ。でも、もし人がその生産に関与していないと、何を意味し、どう機能するのかの理論を構築することはできない。詳細を通じて全体をまとめることができないと、表面的な理解しか得られない。たとえLLMが進化してこの「理論構築」を自分で行えるようになったとしても、人間が関与しない人工的な理解に何の意味があるのか?それは非常に役立つかもしれないし、価値もあるかもしれないけど、最終的には機械に考えさせる方が便利になって、人々は理解するスキルを失っていくかもしれない。

これが、AIコーディングで他の同僚よりも少し成功している理由の一部だと思う。LLMが出る前のワークフローは、何かのクソみたいなバージョンを素早く作って、理解を深めるために再構築する(場合によってはプロトタイプを捨てることも)って感じだった。多くの思想的リーダーがこの一般的なアプローチ(迅速なプロトタイピング、継続的なリファクタリングなど)について語っているけど、多くのエンジニアは抵抗を示して、アプローチを考えた上で「正しく」作りたいと思ってる。あるいは、何かをさっと作り出して捨てずに、最初のクソみたいなものを修正することに苦労している。AIを使うと、このループがずっと楽になる。何かの3つの並行実装を作るのも安上がりだし、システムが面白いと思う機能を追加するのを許可する別のものを作ることもできる。これを比較して、要件や関心の分離、大きなシステムとの統合方法を考えた「プログラムの理論」を構築するのに使える。AIにそれを作らせて、出力をしっかりレビューすれば(何を作るべきか大体わかっていれば、時間もかからない)、すごくうまくいくよ。

完全に同意だね。かつて、元の開発者たちが突然消えて、新しいチームが引き継いだプロジェクトに関わったことがあるんだけど、すべての制度的知識が失われてしまったんだ。元の設計を理解するのに、無駄に時間をかけてしまった。理解が深まるまでにかなりのバグを導入してしまったけど、頭をぶつけながらも多くの設計問題を修正したよ。結局、ほとんど書き直されて、元々計画されていなかったことをするように拡張されたんだけど、そのプロセスは本当に苦痛だった。

プログラミングは「達成したいこととその方法」だね。線形プログラミングや動的プログラミングのように。 > モデルや理論が必要だと思わないプログラマーと、LLMが彼らを速くしていると報告している人たちの間には強い相関関係があると思う。これは面白い予測だね。根本的な原因に関係なく相関が得られると思うよ。ほとんどのプログラマーはモデルや理論が必要だと思っていないし、ほとんどのプログラマーがLLMが速くしていると報告しているから。でも、それを考慮に入れると、逆のことが真実である理由もいくつかあるかもしれない。LLMによって最も速くならないと感じるプログラマーは、主にコードを書くことが貢献だと感じている人たちかもしれないし、正しいモデルを見つけることを仕事と考える人たちは、コードを正しい順序に整えるという雑務がなくなるから、より速くなる可能性がある。

そうだね。業界はドメイン特有の知識やコード特有の知識の必要性、開発者が残ることの価値を軽視してたと思う。開発者が「理論構築」や共有に時間を使うこともね。全てのコーディングチームを入れ替えて、同じ開発ペースで進めると思ったら大間違いだよ。コードが比較的良くて、新しい開発者がそれなりにスキルがあってもね。特に「アーキテクチャモデル」レベルのドキュメントが不足してるときは。まあ、LLMがそれをめちゃくちゃなレベルに押し上げてるけど。もし全てのコーダーが自閉症の天才幼児で、毎月新しい幼児チームに入れ替わったらどうなるんだろう。

LLMのおかげで、僕たちには良くなったよ。ジュニア開発者がコミットするコードの質が向上した。

キャリアの中でいくつかのレガシーアプリケーションに関わってきたけど、プログラミングの他の多くの問題と同じように、この問題の最も重要な解決策は良いモジュール化だと思う。そうすれば、新しいチームがモジュール同士の相互作用を高いレベルで理解できるし、変更が必要なときは関わるモジュールだけを理解すればいい。理想的には一つずつね。だから、全体のアプリケーションの詳細な理論を一度に作る必要はないんだ。LLMを使ってみて分かったのは、良いモジュール化の原則と実践を守れば、LLMがあればあまり知らないコードベースでも作業を始めやすくなるってこと。ナビゲートしたり、「必要な分だけ」理解したり、特定の変更をするのにすごく助けてくれる。でも、これはLLMが自動でやることじゃない、少なくとも僕の経験ではね。やっぱり人間が良い、一貫したモジュール化を強制する必要がある。

プログラマーがモデルや理論が必要だと思わないことと、LLMが彼らを速くしていると報告していることの間には強い相関関係があると思う。僕もランポートに強く同意するけど、なぜAIが元のチームやプロジェクトを引き継ぐチームの「理論構築」プロセスに役立つと思わないのか、ちょっと気になるな。つまり、コードベースやアルゴリズムを理解することについてね?全ての知識を置き換えるわけではないけど、ギャップを埋めることはできると思う。

実際、LLMによって開発者がスピードアップしている(つまり、単にコードの行数ではなく、保守可能な成果物の出力を増やすこと)というのは、彼らが取り組んでいるシステムの理論をしっかり持っている人たちだと思う。少なくとも今のところ、LLMは「どうやって」の部分では素晴らしいけど、「何を」「なぜ」を理解するためのコンテキストが欠けていることが多い(それが書かれていなかったり、彼らのトレーニングデータにあまり含まれていなかったりするから)。

私の経験では、LLMは時々動く解決策を見つけるけど、必要以上に複雑なことが多い。元々コードを作成するときが一番、その複雑さを認識して取り除くのが簡単なんだ。なぜなら、その時点で著者は解決しようとしている問題を最もよく理解しているはずだから。でも、これには余分な時間と労力が必要なんだよね。複雑すぎるコードがコミットされると、その複雑さが必要ないと認識するのがずっと難しくなる。コードの読者やメンテナンスをする人は、既存のコードが現実の問題を解決していると仮定することが多いから、もっとシンプルな解決策が機能することに気づくための十分なコンテキストがないんだ。

Hacker Newsで議論の続きを見る