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

オーバーエディティングとは、モデルが必要以上にコードを修正することを指します。

概要

  • AIによるコード編集支援ツールで「過剰編集」問題が発生
  • 最小限の修正のみ必要な場合でも、大幅な書き換えが行われる傾向
  • 過剰編集はコードレビューや保守性に悪影響
  • 明示的なプロンプトで過剰編集を抑制可能
  • 各種LLMの比較と評価指標を用いた分析

AI支援コーディングにおける過剰編集問題

  • Cursor、GitHub Copilot、Claude Code、CodexなどAI支援コーディングツールの普及
  • シンプルなバグ修正依頼でも、 モデルが関数全体を不必要に書き換える 事例
  • 変数名の変更や不要な入力検証、ヘルパー関数追加など、 本質的でない変更 が発生
  • これを「 過剰編集」問題と定義
  • コードレビューの負担増大と 可読性・保守性の低下 が懸念点

過剰編集の具体例と背景

  • 例:range(len(x) - 1) → range(len(x)) のみ修正すればよいバグ
    • GPT-5.4は関数全体を再構築し、 本来不要なコード追加や構造変更 を実施
  • ソフトウェア開発の「ブラウンフィールド」作業では、 既存コードの意図を維持しつつ最小限の修正 が重要
  • テストに合格しても、 過剰編集はテストでは検知できず、コード品質の劣化を招く恐れ

過剰編集の測定方法

  • BigCodeBenchから400問を選び、 プログラム的にバグを注入 し正解修正が明確なデータセット作成
  • 編集量の評価指標:
    • トークン単位Levenshtein距離 で編集量を測定
    • Added Cognitive Complexity (認知的複雑度の増加)で可読性への影響を評価
  • 最小修正との差を 相対パッチスコア として算出

モデルごとの過剰編集傾向比較

  • Pass@1(正解率)、Normalized Levenshtein(編集量)、Added Cognitive Complexity(複雑度)で評価
  • GPT-5.4は編集量・複雑度ともに 過剰編集傾向が最も強い
  • Claude Opus 4.6は 最小限の編集 かつ 高い正解率 を実現
  • Gemini 3.1 Pro PreviewやGLM 5も 保守的な編集 を示す

プロンプトによる過剰編集の抑制

  • 「できるだけ元のコードとロジックを維持するように」と明示的に指示
    • すべてのモデルで 編集量が減少 し、Pass@1も向上傾向
  • 特に 推論能力の高いモデル で効果が大きい
  • 明示的な制約がモデルの編集範囲を限定し、 より精密な修正 を促進

推論モデルと過剰編集の関係

  • 推論モデルはPass@1(正解率)が高い一方で、 デフォルトでは過剰編集傾向
  • 明示的な最小編集指示で、 推論モデルが非推論モデルよりも編集量を大きく削減
  • Claude Opus 4.6(推論)は、非推論よりも 編集量が少なくなる例外
  • 推論モデルの「賢さ」が 本来不要な改善まで行う 原因となるが、プロンプトで十分制御可能

まとめと今後の課題

  • LLMによる過剰編集は 現状の大きな課題
  • 明示的なプロンプト設計 で大幅な改善が期待可能
  • 今後は モデルのトレーニング による更なる最小編集化の実現が課題

参考指標や具体的な数値、モデル間の比較表 など、詳細なデータ分析は原文を参照

Hackerたちの意見

面白いことに、よく教えられていた(でも実際にはほとんど実践されていなかった)知恵は「進めながらリファクタリングしろ」ってことなんだよね。つまり、作業しているエリアでは、リファクタリングして整頓し、「技術的負債」を片付けるべきだってこと。実際には、そんなことはほとんど行われていなくて、今やLLMが実際にそれをやっているのを見て、欠点に気づいているところ。

それは本当に疑問だね。変更が役立つかもしれないけど、いくつかの例を見てみたいな。認知的複雑性のメトリクスは信じてないけど、変更が確実に認知的複雑性を増しているのはちょっと興味深い。

「作業しているエリアでは、リファクタリングして整頓し、「技術的負債」を片付けるべきだってこと。」これはひどい実践で、修正が必要な典型的なジュニアの行動だね。自分が書いたものでない限り、チェスタートンのフェンスが適用される。なぜそのコードが今のように存在しているのか、深く考える必要があるけど、それは今のタスクには含まれない。小さなUI修正のために1000行のPRに対処するほど最悪なことはないよ。

もう少しニュアンスがあると思う。多くの場合、抽象化がしっかりしてるから、そのコードエリアで作業できるんだよね。バグを追跡したり、機能を拡張したりするのに。でも時々、行き詰まることがあって、既存の実装をハックするか、再考するかの選択になる。LLMを使うと、どうやって再考するの?再考することに意味はあるの?そもそも、その決定は自分には見えないし。

「変更を加える」と「リファクタリング」にはかなり大きな違いがある。もしLLMが必要なリファクタリングを適切に行っているなら素晴らしいけど、実際にそうだとは全く自信がないな。

モデルが既存のロジックと同じことをする新しいコードを書くのはリファクタリングじゃない。必要なことを正確にやっている関数が目の前にあっても、時々そうなる。さらに悪いのは、既存の関数を修正して、動作を維持するつもりが、他の使用ケースでは壊れてしまうこと。頑張ったとは思うけど、最悪だね。クラス間で状態を変更して、副作用に気づかない。デッドロックや単純なバグが発生する。

何かに手を加えるとき、彼らはしばしば改善しない。私が「リファクタリング」と呼ぶものではなく、むしろスロットマシンのアームを引っ張るような感じ。

ほんとに?リファクタリングと新機能(バグ修正も)を同じコミットに入れるのが賢いって聞いたことないな。俺が知ってる人たちみんな、どこでもそれは良くないって考えてるよ。コードレビューでは有害だし、直球で拒否されることもある。「進めながらリファクタリング」ってのは、機能を追加したりバグを修正した直後にリファクタリングすることを指してるんであって、この記事のエージェントがやってることとは違うよね。

実際には、ほとんど行われていなかったけど、今はLLMが実際にやっていて、その欠点に気づいているところだ。今日はこれに関して少し時間を使ったけど、私にとっての本当の問題は、エージェントが行ったリファクタリングがひどかったことだ。私はただ、その変更をやめさせたかっただけで、何を修正すべきか、どう修正すべきかをもっと明確に指示したかったんだ。

逆に、コーディングエージェントが既存のコードを優先しちゃって、実際には新しい要件に合わせて変更した方がずっと良い仕事ができることが多いんだよね。結局、どれだけ既存のコードを固めたいかにかかってると思う。数十年も動いている大規模なプロダクションアプリなら、最小限の変更を望むだろうけど、たった3日前に存在しなかったプロジェクトで実験しているなら、エージェントには改善してもらいたいよね。多分、プロジェクトの文脈にもっと適応できるように学ぶ必要があるんだと思う。

トレードオフは状況によるから、エージェントがプロジェクトを自分で見て判断できるものじゃないんだよね。同じプロジェクト内でも、特定のPRに対しては自由に修正したい部分と、diffやテストの範囲を減らすために固定したい部分がある。エージェントにどれくらい積極的に既存のコードを修正していいか、どの部分かを事前に説明するようにしてるけど、成功することもあればそうでないこともある。たいていは、重複や抽象化を乱用することになっても、最小限のdiffを優先しちゃうんだよね。もし誰かがもっと良い方法を持ってたら、ぜひ教えてほしいな。

ここで著者が言っているのは、エージェントがコードを過剰に編集しちゃうってこと。でもエージェントは「やりすぎ」なこともあるんだよね。複数のファイルに手を出したり、テストを実行したり、デプロイをしたり、スモークテストをしたり… そのすべてが抽象化されちゃう。一方ではすごいことなんだけど、他方では深い不安を感じてる。1. 実際に何が起こっているのか全然理解できてない。エージェントが組み立てたスクリプトを実行するためにプロンプトを受け入れるのがあまりにも魅力的すぎる。でも、エージェントが正しいと思ってDBを一つや二つ消しちゃったこともあるし、AWSの認証情報をデプロイ先に送信しちゃったこともある。2. 何も学んでない。自分でやる認知的負荷、たとえシンプルなDockerコマンドを組み立てるだけでも、あまりにも高すぎる。だから、AIを使う「杖」に頼り続けちゃうんだ。

Hacker Newsで議論の続きを見る