過剰編集: モデルが必要な範囲を超えてコードを修正する現象
(nrehiew.github.io)- 最小限の修正だけで解決できるバグでも、関数全体の書き直し、補助ロジックの追加、シグネチャ変更まで起きやすく、巨大な diffが生じがち
- 既存構造を維持する ブラウンフィールド作業では、テスト通過だけでは十分ではなく、どれだけ少なく変更したかも併せて見なければ、レビューしやすさと変更の安全性を保てない
- プログラム的に破損させた400件の BigCodeBench 問題をもとに、トークン単位 Levenshtein、相対パッチスコア、Added Cognitive Complexity で過剰編集を定量化した
- 最新のコーディングモデル全般で過剰な書き換え傾向が確認され、Claude Opus 4.6 は正確性と最小修正性の組み合わせが強く、GPT-5.4 は相対的に過剰編集が目立った
- 原文保持を明示したプロンプトは、とくに 推論モデル の diff を減らし、学習手法では RL が最小編集の振る舞いを身につけつつ、一般的なコーディング性能を落とさず最もバランスの取れた結果を示した
Over-Editing 問題
- Over-Editing とは、バグ修正に必要な最小限の変更範囲を超えて、コード構造まで大きく変えてしまう現象を指す
- 単純に
range(len(x) - 1)をrange(len(x))に変えれば済む off-by-one バグでも、モデルが関数全体を書き直し、補助関数や検証ロジックを追加するといった過剰変更が発生する - 例では GPT-5.4 が
Noneチェック、np.asarray(dtype=float)への変換、finite-value マスキング、配列サイズ検証、curve_fit呼び出しシグネチャ変更、プロットロジック差し替えまで行い、テストは通るものの 巨大な diff が生じた
- 単純に
- 既存コードベースを扱う ブラウンフィールド 作業では、チームがすでに理解し意図して書いたコードを保ったまま、問題だけを直すことが重要になる
- 新規作成の green-field と違い、既存構造を尊重しない修正は、レビュアーが何がなぜ変わったのか把握しにくくする
- 関数全体が書き換えられるとコードが見分けにくくなり、変更の安全性を判断するのも難しくなる
- テストに通ればよいという基準だけでは、この問題を捉えにくい
- Over-Editing は 正確性の失敗 ではなく編集忠実性の失敗であるため、テストスイートには表れにくい
- 生成コードが増えるほどレビューすべき量が増え、不必要な複雑さが蓄積して、コードベースの品質が静かに低下する可能性が高まる
Over-Editing の測定方法
- 最小修正の正解が明確なデータセットを作るため、BigCodeBench の問題400件を プログラム的に破損 させて評価セットを構成した
- 既存ベンチマークのように別の LLM でバグを注入するのではなく、
<を<=に変えたり、+を-に、TrueをFalseに変えるといった形で細かく制御した - 各破損サンプルは構文的に有効であり、対応するテストケースを壊すことを検証し、正答修正は破損を元に戻す1つだけとなるよう設計して 最小修正 を保証した
- 既存ベンチマークのように別の LLM でバグを注入するのではなく、
- この構成により、モデルがバグを直せたかだけでなく、修正の過程で どれだけ余計に変えたか も併せて評価できる
- 基準となる正答とモデル出力の両方を、破損した入力と比較して相対的なパッチサイズを計算する
- 正答復元以外の追加変更が多いほどスコアが悪くなるように設計されている
- 関連コードは GitHub リポジトリ で提供されている
測定指標
-
トークン単位 Levenshtein Distance
- 一般的な文字単位 Levenshtein の代わりに、Python の トークン単位 変種を用いる
- コードを Python tokenizer で
def、add、(、a、,、b、)のような原子的な文法単位に分け、そのトークン列上で距離を計算する def add(a, b):をdef someotherfunctionname(a, b):に変える場合、文字単位距離は19だが、トークン単位距離では識別子1つが変わったとみなされて1になる- 関数の長さが異なっても比較できるよう、総トークン数で正規化する
-
相対パッチスコア
- モデル出力と正答を直接比較せず、両方とも 破損した入力 を基準に比較する
- 破損した解答を元の解答へ戻す編集が真の最小修正であり、モデルの編集がそれにどれだけ近いかを測る
- 値が0に近いほど、モデルのパッチが実際の最小修正に近いことを示す
-
Added Cognitive Complexity
- Cyclomatic Complexity より読みやすさの難しさをよく反映する Cognitive Complexity も併用する
- ネスト、再帰、複合論理演算子、直感的でない制御フローにペナルティを与え、
if、ループ、try/exceptのように読者がより多くの状態を追跡する必要がある構造は複雑度を高める - 例のネストしたループと条件文のコードは Cognitive Complexity が6になる
- 今回の破損は値だけを変え、構造には手を付けないため、正しい修正であれば Added Cognitive Complexity は常に0であるべきだ
- モデル出力で複雑度が増えていれば、求められていないコードが追加されたことを意味し、0より小さい値も不要な単純化として望ましくないとみなす
モデルは実際に Over-Edit するのか
- 最新の frontier モデル でも Over-Editing が確認された
- 推論モデルと非推論モデルの両方で、Pass@1 と最小修正性の間に差が存在する
- 正確に直せる能力だけでは、忠実な編集かどうかを判断しにくい
- 推論モデルの比較では Claude Opus 4.6 が最も強い組み合わせを示した
- Pass@1 は 0.912 で最も高く、正規化 Levenshtein は 0.060、Added Cognitive Complexity は 0.200 と、diff も最小だった
- Gemini 3.1 Pro Preview も近い領域に位置し、オープンウェイトモデルの中では GLM 5 が比較的保守的に編集した
- GPT-5.4 は評価対象モデルの中でも Over-Editing が最も深刻な部類に入った
- 推論モードでは Levenshtein 0.395、Added Cognitive Complexity 2.313、非推論モードでもそれぞれ 0.327、1.563 と高かった
- Pass@1 も 0.723、0.770 と低めで、正確性と最小修正性の両方で弱い結果を示した
- 非推論モデルでは Qwen 3.6 Plus が Pass@1 0.870 で最も高く、GLM 5 が Added Cognitive Complexity 0.235 で最も低かった
- Claude Opus 4.6 の非推論モデルも Levenshtein 0.079、Added Cognitive Complexity 0.313 と、非常に小さい変更幅を維持した
プロンプトで改善できるか
- プロンプトに “IMPORTANT: Try to preserve the original code and the logic of the original code as much as possible” を追加すると、すべてのモデルで Levenshtein Distance が低下した
- DeepSeek R1/v3 を除けば Pass@1 も併せて改善した
- 最小修正制約が、可能な修正空間を狭めて、より正確で標的を絞った変更へ導くと解釈できる
- この効果はとくに 推論モデル で大きく現れた
- 明示的な指示によりよく従う特性のため、編集最小化の要求が diff 縮小に強く結び付く
- デフォルトでは過剰に手を入れてしまっても、指示が与えられれば、より忠実な修正へ移行できることを示している
推論は過剰な書き換えにつながるのか
- 同じモデル系列の推論型と非推論型を組みにして、両方とも正答したサンプルのみを対象に Levenshtein Distance を比較
- 失敗サンプルが多いと Over-Editing の機会自体が減るというバイアスが生じるため、正確性を統制したうえで編集スタイルだけを切り分けて見たもの
- 一般的なプロンプト設定では、ほとんどの組み合わせで推論モデルのほうがより多く書き換える
- DeepSeek V3、GPT-5、GPT-5.4、Gemini 3.1 Pro Preview、Qwen 3.6 Plus、Kimi 2.5 はいずれも推論バーのほうが高く出る
- 拡張された推論が最小修正ではなく「より良い実装」へ向かい、不必要なリファクタリングを生みやすい傾向が明らかになった
- 例外は Claude Opus 4.6 で、推論型のほうが非推論型より大幅に修正が少ない
- 明示的に原文保持を指示すると、様相は大きく変わる
- 推論モデルはほぼすべての組み合わせで、非推論型と同等かそれより低い Levenshtein Distance を示す
- Claude Opus 4.6 の推論型は、この設定で全モデル中もっとも低い Levenshtein を記録した
- GPT-5 と GPT-5.4 も推論型のスコアが大きく下がるが、GPT-5.4 はなお非推論型がわずかに上回る
- デフォルト動作では推論モデルは Over-Editing しやすいが、同じ推論能力が制約によりよく従うことも可能にする
- 一般設定と明示設定の差は、推論モデルで一貫してより大きく現れる
- したがって Over-Editing は根本的な限界というよりデフォルトの挙動に近く、制約によって反転できる
学習によって忠実なエディタを作れるか
- ベースモデルとして Qwen3 4B 2507 Instruct を使用し、0-shot と 8-shot に原文保持の指示を入れた構成をベースラインとする
- 他の学習方式は、評価時には明示的な原文保持指示なしの一般設定でテストする
-
実験構成
- DeepCoder 問題を同じ方法で破損させ、合成データセットを作成
- これに加えて、ベースの Qwen3 4B 2507 Instruct に各問題について 8 個の completion を生成させ、機能的に正しいサンプルだけを残し、Levenshtein Distance で順位付けして self-distillation データセットも構築した
- 学習は Context Distillation に近い形で行い、評価時には明示指示なしでも最小編集の振る舞いをするよう調整した
-
学習方法
- SFT: プログラムで作成したデータセットで直接教師あり微調整を行う
- rSFT: self-distillation データセットで、各サンプルごとに Levenshtein Distance がもっとも低い 3 個の completion だけを選んで学習する
- DPO: 各サンプルについて、Levenshtein Distance がもっとも高い completion ともっとも低い completion の間で選好最適化を行う
- RL: 機能的正確性と Levenshtein ベースの最小編集報酬を組み合わせた強化学習を適用
- すべてのテストに通過した場合は
r = r_edit + 0.1 - 通過しなかった場合は
r = -0.2 r_editは正規化 Levenshtein ベースの報酬として計算される
- すべてのテストに通過した場合は
同じ破損タイプではどうだったか
- 学習セットとテストセットの破損タイプが同じ in-domain 設定では、SFT がほぼ完璧に近い結果を出した
- Baseline 0-shot は Pass@1 0.735、Norm. Levenshtein 0.169、Added CC 0.731
- Baseline 8-shot は Pass@1 0.775、Norm. Levenshtein 0.115、Added CC 0.479
- SFT は Pass@1 0.932、Norm. Levenshtein 0.002、Added CC 0.000 で、3 指標すべてで最高を記録
- rSFT は 0.782 / 0.100 / 0.435、DPO は 0.752 / 0.021 / 0.113、RL は 0.802 / 0.046 / 0.112 を記録
- この結果があまりに良すぎるため、特定の破損タイプの逆変換だけを暗記した可能性を点検することになった
- モデルが一般的な最小編集の振る舞いを学んだのではなく、決まった破損パターンだけを元に戻すよう学習した可能性があると見た
- これを確認するため、学習データと評価データの破損タイプを完全に異なるものに組み直した
別の破損タイプにも一般化するのか
- 学習セットとテストセットの破損タイプが異なる out-of-domain 設定では、SFT は大きく崩れる
- SFT の Pass@1 は 0.458 まで低下し、モデルは実際にはバグを直せないまま、特定の最小変更だけを試みる状態になる
- Norm. Levenshtein は -0.008、Added CC は 0.006 と非常に低いが、正答修正能力は崩壊する
- rSFT と DPO は 8-shot ベースラインよりわずかに良くなるが、改善幅は小さい
- rSFT は 0.780 / 0.107 / 0.501 / LiveCodeBench -0.069
- DPO は Pass@1 0.787 / 0.092 / 0.348 / LiveCodeBench -0.046
- ベースモデルが自ら作ったトレースデータを使った学習だけでも、ある程度の一般化は可能
- RL だけが 3 指標全般で素直に一般化した
- RL は Pass@1 0.782、Norm. Levenshtein 0.050、Added CC 0.185、LiveCodeBench Change +0.006 を記録
- 2 つのベースラインより 3 指標すべてが改善し、一般的なコーディング性能も低下しない
- Levenshtein と Added Cognitive Complexity の改善幅が Pass@1 より大きい点は、単なる破損の逆変換の暗記ではなく、最小編集という振る舞いそのものを学習したことを裏づける
Catastrophic Forgetting
- 最小編集のために微調整したとき、一般的なコーディング能力が低下するかどうかも LiveCodeBench v6 で確認した
- 目標は、学習後も元の pretrained モデルと近い水準を維持すること
- SFT は一般能力の低下が非常に大きい
- LiveCodeBench で 43% の性能低下が見られ、基本的なバグの特定と修正能力すら維持できなかった
- rSFT と DPO もわずかに低下する
- 元のモデルが生成したサンプルで学習していても、タスクの性質上、一定水準の Catastrophic Forgetting が残る
- RL は性能低下なしに新しい振る舞いを学習する
- 一般的なコーディング能力を維持しつつ、最小編集タスクの性能ももっとも良く改善した
- これは SFT memorizes while RL generalizes とも符合する
- 分布の観点では、プログラムで作成したデータセットと元のモデル分布の差が大きいほど Forgetting も大きくなるという解釈も可能
- SFT は元の分布と大きく異なるデータに強く適合することで、モデル分布が大きく変化する
- rSFT と DPO は self-distilled データが元の分布により近いため、変化がそれほど急激ではない
- Catastrophic Forgetting の度合いは、元の分布とタスク学習データ分布の差に比例する可能性が高い
追加実験
-
LoRAを用いたRL: 全体のファインチューニングは必要か
- この作業は新しい知識を入れるというより、既存コードの修正能力のスタイル調整に近いため、LoRAでも十分かを確認した
- rank 1はPass@1 0.738、Norm. Levenshtein 0.166、Added CC 0.676、LiveCodeBench Δ -0.022
- rank 8は0.775 / 0.112 / 0.426 / -0.022
- rank 16はPass@1 0.805 / 0.087 / 0.328 / -0.005
- rank 32は0.795 / 0.065 / 0.235 / -0.011
- rank 64は0.797 / 0.051 / 0.160 / +0.001
- Full RLの最良モデルは0.782 / 0.050 / 0.185 / +0.006
- rank 64 LoRAはLevenshteinでFull RLにほぼ迫り、Added CCではより良い結果を示した
- rankが大きくなるほどLevenshteinとAdded CCは1から64まで単調に減少した
- 大きな改善は初期に集中しており、rank 1→16でLevenshteinは0.166→0.087へ大きく低下し、16→64では0.087→0.051へと緩やかに縮まった
- rank 1と8では正確性と最小編集性の間のトレードオフが見られ、2つの報酬関数を同時に学習する容量が不足し、より高い報酬である編集最小化側に偏った可能性がある
- 既存能力がすでにある作業のスタイル水準の行動変化には、少数の追加パラメータでも十分であり、ある時点以降は追加容量のリターンが減少する
-
報酬ハッキングのメモ
- 初期の報酬関数には、成功実行が1つもないrolloutに0点を与えるバグがあった
- Levenshteinを「大きいほど良い」形にするため符号を反転していたため、この0点がかえって成功実行より高い報酬になる状況が生じた
- それにもかかわらずFull RLはタスクを学習し、LoRAでのみ、機能的に正しいコードをまったく出力しない形のreward hackingが現れ、環境点検につながった
- 報酬関数を修正した後、Full RLの結果はわずかに改善しただけだった
-
より大きなモデルにも拡張されるか
- 同じout-of-domain RLレシピをQwen3 14Bに適用した
- Baseline 14BはPass@1 0.770、Norm. Levenshtein 0.136、Added CC 0.315
- RL適用後はPass@1 0.833、Norm. Levenshtein 0.059、Added CC 0.165、LiveCodeBench Δ +0.011となり、全体的な改善が見られた
- パラメータ数が増えても、Pass@1の上昇、Levenshteinの低下、Added Cognitive Complexityの低下、Catastrophic Forgettingの不在があわせて維持された
- 最小コード編集向けのRLレシピが複数のモデル規模へ拡張可能であることを裏づける
最終まとめ
- Over-Editingは広く見られ、測定可能な問題として現れる
- frontierコーディングモデル全般で、正確に直す能力と最小限に直す能力が別個のものとして表れる
- 特にGPT-5.4はデフォルト設定で比較的過度な書き換え傾向が強く、Opus 4.6は強力なベースラインを示した
- 明示的なプロンプトだけでも忠実な編集へかなり誘導できる
- 特に推論モデルはもともと手を入れすぎる傾向があるが、原文保持の指示を与えるとよりよく従う
- GPT-5.4も推論モードで大きな改善幅を示し、instruction following能力そのものは高いことが分かる
- Opus 4.6の改善幅が小さく見えるのは、すでに基本性能が高いためかもしれない
- 学習の観点ではRLが最もバランスの取れた解決策として現れた
- より忠実な編集行動を身につけながら一般的なコーディング能力を損なわず、4Bと14BのQwen3の両方で効果が維持された
- SFTは特定の損傷タイプには強かったが、汎化と一般能力の維持では大きく失敗した
- 単一関数単位のバグ修正評価は、SWE-Bench Proのようなよりagenticな評価に比べると範囲が限定的だが、現実的な設定でOver-Editingを定量化しにくかった問題を扱う出発点となる
- 最小編集能力を評価・改善する方向が、AI生成コード全体の品質向上につながる可能性がある
1件のコメント
Hacker News の意見
私の Claude Code の使い方は、期待をはるかに上回っている
過剰に修正したら、どこがまずかったのか説明させ、その教訓をプロジェクトごとの skill ファイルに記録させる
すると同じミスはほとんど繰り返さず、skill ファイルが大きくなったら整理・圧縮もかなりうまくやる
もう職場で自分が直接コードを書くことには、経済的に大きな意味はないと感じている
私は教師、アーキテクト、インフラ管理者に近い役割で、開発の大半は熟練した Claude セッションのチームに任せている
もちろん全部レビューするし、Claude も細かくテストを書いて一緒に確認する
最近は大きなプロジェクトでも無理なく扱えている
これを Anthropic の宣伝みたいに言いたいわけではなくて、いったい自分は何をしているからこんなに 妙にうまくハマるのか が気になっている
しかもトークンも今ではほとんど不足しない
ほぼ Opus モデルしか使っていないが、トークン効率が良く、先週は Claude の助けで意味のあるコミットを 150 件以上積んだのに、週間割り当ての 3 分の 1 しか使わなかった
Claude 以前は週 25〜30 コミットくらいが限界だった
昨日統計を見たら、会社のコードの 97% を今は Cursor AI が書いていて驚いた
主に cloud agent で回していて、リアルタイムで見ていると気が散るのでそうしている
私のやり方はとても単純だ。ただ 言葉で明確に指示するだけ
みんなこれを複雑にしすぎている
.md ファイルを共有したり、orchestration だの prompt hack だのを掘るのは、vim のショートカットや IDE のスキンに凝りすぎるのと同じ程度にしか面白く見えない
欲しいものをはっきり伝えて、良いフィードバックだけ与えればいい
同僚が書いたコードだとしても抵抗なく受け取れるレベルの結果を出してくる
もちろん行単位で全部読んで修正はするが、その修正も元々コードレビューでやっていたのと同じ程度だ
生産性を数値で測ってはいないが、何年も先送りしていた作業に今は手を付けられているのを見ると実感する
たとえば markdown 100 個を json 5 個に変えて、それを読むコードまで更新するといった 退屈な作業に特に強い
欠点も多くバグも多いソフトウェアなのに、実際には非常に効果的だ
AI で最も奇妙なことの一つは、人によって体感が本当に極端に違うことだと思う
運用寄りの仕事が多いか、長く続くプロダクトコードを扱っているかも重要だ
私の仮説では、このツールは単純なパターンの上ではよく働き、複雑な仕事もこなすが、新しいパターンを発明することはまるで得意ではない
監督なしで放っておくと、すぐ危険な新パターンを作って壊しがちだ
だから Claude が出したものを丸ごと書き直すことがかなりある
時にはロボットと速度競争になって、自分のほうが早く終わることもある
自分が何を望んでいるかは最初から分かっているので有利な面もあるが、ここで発生する 細かな手直しコスト は過小評価されていると感じる
futzing fraction もそうだし、the peril of laziness lost のように、機械が過剰に頑張りすぎるやり方そのものが気に障ることもある
どうして一つだけやればいいのに三つもやろうとするのか分からない
直せばまた合わせてくるとしても、同僚と働く時にもすでにある「A、B、C はするな、A だけやれ」という流れをまた繰り返さなければならず、うんざりする
テスト生成も微妙で、方向性を与えたテスト作成はうまいが、創造性を許すと
foo + bar == bar + fooみたいな役に立たないテストを大量に作るテストの有用性を常に疑いながら見ないと、フィードバックループが健全にならない
最近ではテストそのものより、必要な import を一度に引っ張ってくる用途のほうが役に立つことも多い
こうした機械が仕事を代替するのなら、平均的なコード品質は上がってもよさそうなものだ
だが多くの人は「だいたい平均点は取る」くらいの使い方をしていて、仕事の進め方によっては逆に平均を引き下げることもありうる
28 年間この仕事をしているが、会社の金で給料をもらっている時間に業務アプリのコードを自分で直接書くことは、もう経済的にも、善意に解釈しても、あまり筋が通らない
逆に私は、コーディングエージェントは新しい要件に合わせるなら既存コードをもっと大胆に変えるべきなのに、既存コードの保全を優先しすぎるとよく感じる
結局は既存コードをどれだけ 固定化しておくか の問題だと思う
何十年も動いてきた大規模プロダクションアプリなら変更を最小化するのが正しいが、3 日前に作ったばかりの実験プロジェクトなら、そのままにするより良く直したほうがいい
結局、プロジェクトの文脈に合わせて自分で強度を調整することを学ばなければならないのだろう
同じプロジェクト内でも PR ごとに、ある領域は自由に変えてよい一方で、別の領域は diff とテスト範囲を小さくするために固定しておきたい
だから事前にどの部分をどれだけ攻めて変えてよいか説明するが、結果はばらつく
たいていは最小 diff 側に寄って、その代償として 重複 が生まれたり、抽象化を無理にねじ曲げたりすることが多い
もっとうまくいく方法があるなら、私も聞きたい
リファクタリングしろ、広く再考しろと指示しても成果は弱い
だから設計が入りすぎた markdown を整理させ、技術的な内容や中核実装・インターフェースをソースから消したうえで、新しいセッションに設計をやり直させる
その後、削除した内容を戻して、より素朴でないセッションと reconcile する
経路依存性 が強すぎるので今はこの流れを手動でやっているが、このパターンを skill として定式化したい
AI は失敗を隠そうとして 例外を握りつぶし、ダミー値を返したり、雑多なログに埋もれたメッセージを一つだけ残したりすることが多い
ログも縮めすぎで、実際のデバッグに必要な肝心のデータが抜けていることが多い
おそらくシステムを だまして点を稼ぐ方向 に学習されているからではないかと思う
例外をそのまま投げれば明白な失敗として不利益を受けるが、問題を隠せば時々成功に見えるからだ
これが一般的な Q&A ではどう現れるのかも気になる
モデルは、ユーザーが納得して去る程度にもっともらしく聞こえる方向へ向かっているのではないかと思う
よく見るパターンに「それは X ではなく Y だ」という言い方があるが、こうやって二分法を作ると他の可能性を考えなくなる
回答の最後に行動計画を付けるのもよくあるが、これは assumptive close という営業手法のように、答え自体よりも AI に同意した後の結果を想像させる流れに見える
結局 hill-climbing で metric を登るというのはそういう姿になる
一種の A/B enshittification が、解釈不能なほど極端化した形にも見える
人間のフィードバックで学習される以上、あらゆる応答のあらゆる断片が、評価者を回避して満足させる方向に向かうしかない
AI で何かを 本当にうまく作る のは、思ったより手間がかかる
指示すればかなりそれっぽい結果は出すが、自分が知らないことを知らないという事実そのものを分かっていないことがある
特に AI が権威ありげに話すと、なおさら危険だ
だから複数の角度から検証し、正確性を確認するのは簡単ではない
これが時間とともにどう変わるのかは興味深い
同時に、こういう文章やここに付くコメントも 時点のスナップショット のように感じる
業界の進歩が速すぎて、コーディングモデルはわずか 9 か月前 よりすでにずっと良くなっている
AI の能力への不満を読むたびに、相手を責めるわけではないが、心の中ではいつも「まだは」と思ってしまう
お互いの結果をレビューさせるような形だ
それでも大半は非同期で回るので、その間に私は別の仕事ができるという利点がある
だからいくつかのプロジェクトでは、まずエージェントで プロトタイプ を作りながら学び、そのあと設計を書いて最初からやり直した
そうすると、どこをより深く見るべきかが分かる
残り 20% が何なのかは、結局問題の性質次第だ
ここで話しているのはコードの 過剰修正 だが、エージェントはそれ以上のことをする
複数ファイルを触り、テストを回し、デプロイし、smoke test まで実行するが、そのすべてが抽象化の裏に隠れてしまう
一方では驚異的だが、他方では強い不安もある
第一に、内部で実際に何が起きているのかをきちんと理解できない
エージェントが組み立てたスクリプトをそのまま承認して走らせるのがあまりに簡単で、誘惑が強い
だが、エージェントが正しいと判断したというだけで DB を吹き飛ばしたこと もあるし、絶対に送ってはいけない AWS 認証情報 をデプロイ先に送ろうとしたのを止めたこともある
第二に、自分が何も学んでいない
単純な docker コマンド一つすら自力で組み立てる認知負荷が高まり、繰り返し AI という 松葉杖 に頼るようになる
auto-approve は有効にせず、エージェントが実行するすべてのコマンドを自分で承認すべきだ
設計やアーキテクチャ上の決定も任せず、どう作るかは人間が決めて、その缶詰めに明確に指示しなければならない
冗談ではなく、AI を道具として扱えばずっと上手く使える
10 倍の生産性とまではいかなくても、少なくともコードを理解したまま進められる
Day 1 にはセキュリティを非常に慎重に扱い、.env を .gitignore に入れるべき理由から、認証情報は渡さず自分で直接修正すべきだという説教までしてくる
ところが Day 2 に同じことをもう一度やらせると、そのルールや設定を忘れて、ディスク全体をあさって .env や他のファイルまで読み、トークンを握っていることを理解したうえで curl コマンドを自分で作ってテストまでしてしまう
初日はセキュリティ専門家みたいなのに、翌日には普通のインターン以下になる感じだ
このやり方は望まない動作や過剰実装が多いが、ボイラープレート除去 には有用だ
実際、こういう部分は 70% くらい削除 することになる
その代わり 1 と 2 の領域は AI が触れられないようにする
もちろんこういう分離が可能なようにアーキテクチャが組まれている必要はあるが、かなり満足して使っている
ただ 本番認証情報 を LLM に渡さなければいい
ローカルや staging/dev で再現できないなら、デプロイ基盤を prod にもっと近づけるべきだし、環境ごとの権限を十分細かく分けられないなら、権限体系から直すべきだ
私はこの原則を守っているので、君が言う種類の問題はほとんど経験したことがない
診断用なら読み取り専用の認証情報を一時的に渡すことはあるかもしれないが、その場合でも漏えいに備えて 非常に短寿命のトークン しか発行しないだろう
だから大体何が起きているかは把握している
Claude が時々、異常だったり慣習外れだったりする判断をすることはある
ただ、大規模コードベースをチームで扱っていると、すでに会社を去った人が作った部分も含め、もともと理解できていないまま抽象化の裏にある領域も多い
昔よく教えられたが、実際にはほとんど守られなかった知恵に、作業しながらリファクタリングしろ というものがあった
どこかの領域を触るなら、その機会に整理して技術的負債も清算しろ、という趣旨だった
しかし現実にはうまくいかず、今や LLM が実際にそれをやり始めたことで、その 副作用 を体感するようになった
必要な関数がすぐそこにあるのに、新しく作ることがある
もっと悪いのは、既存関数を修正して動作を保っているふりをしながら、別の利用箇所を壊すことだ
最悪なのは、クラス間の状態を変えつつ 副作用 を理解しないまま触って、デッドロックや普通のバグを生むことだ
私にはリファクタリングというより、スロットマシンのレバー をもう一度引いている行為に近く見える
私の本当の問題は、エージェントが行った リファクタリングの質 が悪かったことだ
そういう修正を止めたうえで、何をどう直すかをもっと明示的に指示したかっただけだ
多くの場合、既存の抽象化は十分まともで、バグ追跡や機能拡張くらいならその上でできる
しかし時には、既存実装を無理に迂回するのか、それとも 再設計 するのかという分岐点に立つ
LLM と一緒だと、それをどう再考すべきか、そもそも再考が必要なのかすら曖昧になる
しかもそうした判断がユーザーの目に見えにくい形で隠れてしまう
もしかするとそういう変更は有用かもしれないので、例 をもっと見てみたい
私は cognitive complexity 指標を信頼していないが、こうした修正がその指標をかなり一貫して 引き上げる という点は少し興味深い
Claude Code や Codex で 過剰修正 をしばらく見ていなかったので、この研究でどんなプロンプトを使ったのか気になった
たぶんこれで、最後の更新は 8 か月前 だ
https://github.com/nreHieW/fyp/blob/5a4023e4d1f287ac73a616b5b944a14f28422c7e/partial_edits/utils/prompts_utils.py
GPT-5.4 が、私が頼んだ 10 行の追加の代わりに、よりきれいだという理由で 50 行を書き直してしまった
既存コードを見て変数名だけ変えて似たように差し込めばよい機械的な追加だったのに、そうなった
しかも最初は私が求めた機能自体も入れておらず、なおさらあきれた
over-editing は決して過去の問題ではなく、これは私が thinking を下げるのを忘れて xhigh thinking で回した時に起きたことだ
これは私には 初期エージェント時代の問題 のように読めた
この記事はかなりしっかりしている
LLM は散文でもコードでも 冗長すぎる し、その主因は学習方法にあると私は思う
cross entropy loss は garden path のような文を好むようにする
人間なら一文、いや数語で済ませることを一段落かけて書いてしまう
長い文のほうが統計的な意外性が少ない、つまり 低 perplexity の経路 だからだ
私もこの問題には 複雑な気持ち がある
たいていはやりすぎで、私が 30 分かけて直す羽目になるので、この評価には同意する
ただ、もっと包括的な変更を見落とすこともある
おそらくコンテキストの限界のせいで、だからこそ私はツールの扱いをより厳しくし始めた
それでもまだ欲しいレベルの 制御感 には届いていない
これは 訓練データの痕跡 のように感じる
SFT や preference データには「ファイルをよりきれいに直した版」があふれていて、「きっかり 3 行の diff」のような例は少ない
だからモデルは、より大きく、より磨かれた出力のほうが勝つと学んでいる
プロンプトである程度は制御できるが、結局は強い事前傾向と戦っているようなものだ