🪚 通俗比喻:你请了个装修师傅来修水龙头。师傅修好了水龙头,但顺手把厨房刷成了粉色,卫生间换了个马桶,客厅的沙发也给你挪了个位置。你只想要水龙头不漏水啊师傅!——这就是Over-Editing。AI代码模型干的就是这种事:你让它改个变量名,它把整个函数重写了。
📖 什么是 Over-Editing?
Over-Editing(过度编辑)是指AI代码模型在修改代码时,修改了超出必要范围的代码。用户只要求改一行,模型改了十行;用户只要修bug,模型顺便重构了整个模块。
2026年4月,一篇研究博客"Over-editing refers to a model modifying code beyond what is necessary"登上Hacker News首页(158分),引起了广泛讨论。研究量化了这个问题的严重程度。
⚠️ 为什么严重?Over-Editing不只是"改多了"的问题——每一次多余的修改都是一次引入新bug的风险。在CI/CD流水线中,一个不必要的改动可能触发完整的测试套件、代码审查、部署流程,成本远超想象。
🔬 Over-Editing 的表现形式
1. 代码风格"顺手"修改
📝 用户要求
修复 getUserById 的 null 检查
🤖 AI实际输出
- 改了 null 检查 ✓
- 顺便改了变量命名风格
- 顺便加了 TypeScript 类型
- 顺便重构了错误处理
- 顺便更新了注释
2. 无关代码"顺手"优化
// 用户:修复这个 bug
if (user != null) {
return user.name; // 用户只要加这一行检查
}
// AI的输出:
if (user !== null && user !== undefined) { // 改了比较方式
const userName = user.name; // 提取了变量
console.log(`User: ${userName}`); // 加了日志???
return userName.trim(); // 加了 trim???
}
3. 整体重写而非最小修改
AI模型的倾向是重写而不是最小修改。因为从训练数据来看,完整的代码片段比"只改一行"的示例更多,模型学到的就是"写出完整代码"。
📐 量化分析
# Over-Editing 的量化指标
# 最小编辑率 (Minimal Edit Rate)
MER = 必要修改行数 / 实际修改行数
# MER = 1.0: 完美,只改了该改的
# MER = 0.2: 80%的修改是不必要的
# 不同模型的MER对比(示意)
模型A (指令跟随好): MER ≈ 0.75
模型B (默认行为): MER ≈ 0.35
模型C (不加约束): MER ≈ 0.15 # 灾难级
🛡️ 防范策略
💡 核心原则:Minimal Edit(最小编辑)
只修改达成目标所必需的代码。不多改一行,不少改一行。
只修改达成目标所必需的代码。不多改一行,不少改一行。
策略1:Prompt约束
# 在Prompt中明确约束编辑范围
prompt: |
修复以下bug,只修改与bug直接相关的代码。
不要修改代码风格、命名、注释或其他无关代码。
如果不确定某处修改是否必要,不要修改。
规则:
- 只输出需要修改的行
- 不要重写整个函数
- 不要添加新功能
策略2:Diff-Based输出
# 要求AI输出diff而非完整代码
output_format: diff # 只输出差异
# 而不是
output_format: full_code # 输出完整代码
策略3:编辑后验证
# 自动化验证AI的修改范围
def validate_edit(original, modified, required_changes):
actual_diff = compute_diff(original, modified)
required_lines = set(required_changes)
actual_lines = set(actual_diff.keys())
unnecessary = actual_lines - required_lines
if unnecessary:
return f"Over-editing detected: {len(unnecessary)} unnecessary changes"
return "OK"
⚙️ OpenClaw 实战:防范Over-Editing
OpenClaw的Agent系统通过多层机制防范过度编辑:
# OpenClaw AGENTS.md 中的编辑策略配置
editing_policy:
# 最小编辑原则
minimal_edit: true
# 允许的编辑范围
scope: "target-only" # 只修改目标文件/函数
# 禁止的编辑行为
forbidden_actions:
- style_changes # 禁止风格修改
- refactoring # 禁止重构
- adding_comments # 禁止添加注释
- renaming_variables # 禁止变量重命名
# 差异模式
output_mode: "diff" # 输出差异而非完整代码
# 修改后自动验证
post_edit_validation:
run_tests: true
check_diff_size: true
max_diff_lines: 20 # 超过20行修改需要确认
SOUL.md 中的行为约束
# SOUL.md - Agent行为准则
behavior_rules:
code_editing:
- "只修改用户明确要求的部分"
- "如果发现其他问题,先报告,不要擅自修改"
- "每次修改后说明改了什么,为什么改"
- "diff > 10行时,列出每个修改的原因"
实际运行示例
# 用户:修复 login 函数的空指针异常
# ❌ 无约束的Agent(Over-Editing)
"我修复了空指针异常,同时:
- 重构了错误处理逻辑
- 添加了TypeScript类型
- 优化了代码结构
- 更新了相关注释"
# → 87行修改,3个新bug
# ✅ OpenClaw约束的Agent(Minimal Edit)
"修复了 login() 第42行的空指针检查:
- 第42行:添加 user != null 前置检查
共1行修改,测试通过"
# → 1行修改,0个新bug
🎯 Over-Editing vs 相关概念
| 概念 | 核心区别 |
|---|---|
| Hallucination | 编造不存在的信息,Over-Editing是改了不需要改的代码 |
| Code Refactoring | 有意重构,Over-Editing是无意修改 |
| Guardrails | 通用护栏,可包含Over-Editing防范 |
| Scope Creep | 项目管理的需求蔓延,Over-Editing是代码层面的"需求蔓延" |
💡 最佳实践总结
- Prompt先行约束 — 明确告诉AI"只改需要的"
- Diff模式输出 — 让AI输出差异而非完整代码
- 修改后验证 — 自动检测修改范围是否合理
- 人工审批阈值 — 修改超过N行需要确认
- 行为准则内化 — 在SOUL.md中固化最小编辑原则
Over-Editing 过度编辑 最小编辑 AI代码 OpenClaw 代码安全 Diff