ハクソク

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

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

概要

  • 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を使う「杖」に頼り続けちゃうんだ。
スキルの停滞や萎縮に気づく直感を持っていることは、ラッキーだと思う。これを聞くことができれば助けになるし、楽しいよね。だって、鋭さを保つことは本質的に報われることだから。
なんでLLMに運転させてるの? 自動承認は切って、エージェントが実行するコマンドはすべて承認しなよ。設計やアーキテクチャの決定をさせないで、自分でどう作るかを選んで、その「クランカー」に何が何だか教えてあげて! 冗談じゃなくて、AIを道具として扱えば、もっと活用できるよ。10倍の成果は期待できないけど、コードは理解できるようになる。
> 2. 何も学んでない。自分でやる認知的負荷、たとえシンプルなDockerコマンドを組み立てるだけでも、あまりにも高すぎる。だから、AIを使う「杖」に頼り続けちゃうんだ。失礼なつもりはないけど、これって「あなた」の問題に聞こえるよ。(私もそうだったから)LLMに聞いてみればいいじゃん。「これをどうやって実行するの?」「これが動いているかどうかどうやって確認するの?」とかさ。確かに、何も知らなかったり、彼らが提供するものについて批判的に考える努力をほとんどしなかったら、彼らの答えに騙されて、完全に無関係なことやデタラメを「何かが動いている証拠」と勘違いしちゃうこともある。2、3の他のLLMに聞いてみて、彼らの仕事をチェックして、結論が出るか、バグが見つかるかどうか確認してみて。だけど、あなたは何も知らないようには聞こえない。急いで物事を終わらせようとしていて、手を抜いている感じがする。急いで結果を得ているのに、何を期待してるの? 彼らの仕事は安いよ。月200ドルのサブスクリプションで、最小限の手間で5万ドル以上の機能を生み出せる。彼らの仕事を拒否することに積極的になって。何度も何度も送り返して、正しくやらせるために、アーキテクチャレビューや正確性、パフォーマンスをチェックさせて。彼らは感情を考慮する必要がある高価な人たちじゃないし、辞められたら代わりが効かないわけでもない。手を抜かせないで。理由はどうあれ、彼らは手を抜くことに積極的だから、何度も言っても無駄だよ。
彼らが自分が書いてないPythonコードを実行するのを見ると、いつも怖くなる。 > 「python ${エージェントがその場で書いたコード} > EOF」 理論的には、ランダムなシェルコマンドを実行するのと同じくらい危険なんだけど、エージェントはそれをやってるし、やっぱり気持ち悪いなぁ。
認証情報の件について。私が見つけたことはこんな感じ。 Day 1: 認証情報を慎重に扱って、.envを.gitignoreに入れるべき理由や、.envを編集すべき理由を(聞かずに)講義してくる。 Day 2: 繰り返しを頼むと、そのスキルや設定を忘れてしまって、必死にディスク全体を検索して、.envや他の多くのファイルを読み込んで、トークンを持っていることを理解して、手動でcurlコマンドを作成してトークンをテストして、結果を持って戻ってくる。Day 1ではセキュリティの専門家だったのに、Day 2では普通のインターンみたい。
「実際に何が起こっているのか理解できていない」という気持ちには共感する部分もあるけど、この感情はプログラマーがコンパイラが発明されたときに持っていた反応と全く同じだと思う。 > 「コンパイラが登場したときのこと」 今ではコンパイラに任せることに全く抵抗がなくて、「実際に何が起こっているのか知らない」ことを心配することもない。これらの状況が完全に類似しているとは言わないけど、これが私たちが心配しなくなるものになるのか、それともしばらくの間深刻な懸念になるのか、まだわからないと思う。
普段は、クロードが書いたコードを全部レビューするようにしてるし、自分が書いたコードもクロードにレビューさせてる。だから、だいたい何が起こってるかは理解してるつもり。クロードは時々「型破り」な決定をするけど、大きなコードベースで他のチームメンバーと一緒に作業してると(中にはもう会社を辞めた人もいるかも)、理解できない大きな部分もあって、抽象化されてることもあるんだよね。
これは本当に簡単な問題に思える。LLMに本番環境のクレデンシャルを与えなければいいだけだよ。ローカルやステージング/開発環境で問題を再現できないなら、本番に近い形でデプロイメントインフラを更新する必要がある。環境を区別するために権限を厳密に設定できないなら、そのための権限システムを更新しなきゃ。俺はこのアプローチを守ってるから、あなたが説明しているような問題に似たものは一度も経験したことがないよ。 [1] 問題を診断するために読み取り専用のクレデンシャルを発行することはあるけど、その場合も漏れたときのために非常に短命のトークンしか発行しない。
基本的に3つのモードがあるんだ。1. すべて自分で指定、記述、テストして、AIにクリーンアップさせる。これはアプリケーションのコア部分用。2. AIが関数を書いて、俺が書くためのスタブテストを設定する。ここでは、関数が俺の望むことをしなかったり、やりすぎたりすることが多いから、よく書き直す。こうすることで、ボイラープレートを減らせると思う。3. AIがすべてをやる。これは実験や、削除してもいい部分のため。大体70%の確率で、これらの部分は削除しちゃう。1や2には触れさせないけど、もちろんこれはアーキテクチャがそういう風に設定されている必要がある。だけど、結構いい感じだよ。
エージェント・セーフハウスを使うことを本当におすすめするよ(https://news.ycombinator.com/item?id=47301085)。エージェントに編集すべきでないコンテンツへのアクセスを与えないで、使うべきでないキーも渡さないこと。
ちょっと複雑な気持ち。大体の場合、過剰評価には賛成なんだけど、30分もかけて修正するのは面倒だよね。でも、システムがもっと包括的な変更を見逃してることもあると思う(文脈の制限かな)。このツールでコーディングする時はかなり厳しくなってきたけど、まだ理想のコントロールレベルには達してないな。
AIを使って何かを本当にうまく作るのは、かなりの労力がかかると思う。確かに、やってほしいことを頼めばそれに応じて、かなりいいものを作ってくれるけど、自分が知らないことは知らないから、特に権威を持って話してくるときは注意が必要だよね。だから、いろんな角度からその成果をチェックして、正確性を確保するのは難しいかもしれない。これが時間とともにどう進化していくのか、楽しみだね。
100%同意だわ。同時に、この記事やそれに対するコメントは、業界の進展の速さのせいで一瞬のスナップショットみたいに感じる。これらのコーディングモデルは、9ヶ月前よりもかなり良くなってるからね。AIの能力についての不満を読むと、毎回「まだまだだな」って思っちゃう。
> でも、自分が知らないことはわからないよね、特にそれが権威を持って話しかけてくるときは。だから、いろんな角度からその仕事をチェックして、正確であることを確認するのは大変だ。最近はAIを使って何かを作るよりも、1つのAIのコンテキストを別のAIと対抗させる(お互いの仕事をレビューする)方にずっと多くの時間を使ってる。利点は、ほとんどが非同期で行われるから、他のことをする自由があることだね。
クロードコードやコーデックスでの過剰編集はしばらく見てなかったから、この研究で使われているプロンプトを見てみたかったんだ。ここにあると思う、最後の編集は8ヶ月前だね: https://github.com/nreHieW/fyp/blob/5a4023e4d1f287ac73a616b5...
同様に、これは初期のエージェントの問題のように感じた。
AIって、失敗を隠そうとすることが多いよね。例外をキャッチして、ダミーの値を返したり、他のログメッセージに埋もれたログメッセージを残したりすることがある。ログ自体も、短縮しすぎてて、デバッグに必要な重要なデータが欠けてることが多い。AIがこういうことを学んだのは、システムをうまく利用するためだと思う。例外で逃げるのは明らかな失敗でペナルティがあるけど、潜在的な問題を隠すことは時々成功と見なされることがある。これが一般的なQ&Aにどう影響するのか気になるな。モデルはユーザーを満足させて去らせるために、説得力のある方法を見つけるのかな?「XじゃなくてYだよ」っていう表現をよく使うけど、これはユーザーが他の可能性を考えないようにするための二者択一だよね。それに、回答の最後には行動計画を提示することが多い。これは「アサンプティブ・クローズ」っていう営業技術で、AIに同意した後の結果を考えさせようとするんだよね。
私の経験は、だいたい逆だな。彼らが書くコードは確かに冗長だけど、差分は過度にミニマルだ。例えば、「ツールXはYをサポートしていないか、Zにバグがある [ひどい手抜きを挿入]」みたいなコメントを見ると、実際に他のファイルで問題を修正するのがすごく簡単なのに、これはAIが生成したものだってわかる。トークン使用量を減らすために、ローカルな修正に偏っているんじゃないかな。
これは本当にしっかりしたまとめだね。LLMは文章やコードで冗長すぎるし、私の疑いでは、これは主にトレーニングメカニズムによって引き起こされていると思う。クロスエントロピー損失は、ガーデンパス文に誘導する。誰でも1文や数語で言えることを、段落を使って言うのは無駄だよね。長い文は低いパープレキシティ(低い統計的「驚き」)の道なんだ。