Skip to content

编程 Agent:编辑之后如何证明修复 ​

对应 CS329Z · 2026-11-18 · Coding & Software Agents。日期为校方课表日期,可能调整。核对官方课表。

资料状态

核对日期:2026-09-19。对应课程尚未开课;本文是基于公开课纲与文中原始资料的原创预习技术解读,不是课堂实录、讲义翻译或官方作业答案。本文于 2026-09-20 深度修订。示例为原创教学设计;离线实验与真实模型实验的边界分别说明,不以推演冒充模型实测。

研究助手的实现出现一个真实类型的缺陷:版本过滤漏掉了 B 1.0,导致旧证据进入 B 2.0 的比较。让编程 Agent 修复时,不能只说“改好了”;我们需要证明它修复了这一行为,而且没有破坏其他合法检索。

本讲把软件修改组织成一条证据链:失败输入、预期语义、最小修改、测试结果和交付说明。

修复之前先确定什么行为是错的 ​

假设当前过滤代码只比较产品名,忽略版本。测试语料包含 D3(B 1.0)和 D4(B 2.0),请求明确指定 2.0,预期只有 D4 能作为当前证据。

这里需要区分“完全不返回旧资料”与“允许历史参考但禁止作为当前依据”。两种设计都可能合理,但测试必须与接口约定一致。如果下游依赖历史比较,粗暴删除所有旧资料可能修好一个场景、破坏另一个。

因此先读调用方和证据类型,确认当前缺陷是分类错误还是召回错误,再编辑代码。

让失败测试先于修复存在 ​

原创教学断言表达业务语义:

javascript
// selected 为执行后的当前证据,不包含历史参考。
assert.deepEqual(selected.map(x => x.id), ['D4']);

修复前应观察到 D3、D4 同时出现,测试失败。若测试原本就通过,说明它没有复现报告中的问题;不能把运行一次绿灯当作修复证据。

再加入版本未知的文档。它应进入待核查或历史线索,而不是自动符合 2.0。这个反例可以识别“只排除 1.0”这类为当前样例硬编码的补丁。

用反例识别只对当前样本有效的补丁 ​

错误修复可能写成“文档 ID 不等于 D3”,正好让当前测试通过。把旧版文档改成 D8,缺陷立即重新出现。正确责任是版本适用性,不能编码某条样本的身份。

因此测试应包含相同版本不同 ID、不同版本相似标题、缺版本字段以及版本字符串如 2.0 与 2.0.1。补丁需要依据产品对版本兼容性的明确规则;不能默认字符串相等就是所有项目的兼容判断。

当前教学任务只要求精确版本匹配,因此可以采用严格相等。若未来支持版本范围,应新增解析和兼容性规则,并同步修改任务契约与测试。这样需求扩展不会悄悄藏在一个看似简单的过滤条件里。

一个可信修复既解释为什么当前案例通过,也解释哪些变形案例仍应失败。

工具反馈影响修复路径 ​

SWE-agent研究适合 Agent 的计算机交互接口。对本项目,搜索结果应带文件与位置,测试返回退出码和关键失败,长日志提供回读引用。

如果工具只返回“失败”,模型可能盲目修改多个模块。明确的断言差异能让它定位到版本筛选。工具设计因此是修复能力的一部分,而不只是外接终端。

最小修改不是最少字符 ​

把 version === requested 加到一个调用点,改动很少,却可能让其他入口继续有漏洞。应找到承担版本适用性责任的共同边界,在那里修复,并检查所有调用路径。

另一方面,不应借一个小缺陷重构整个检索系统。改动范围越大,需要解释的回归风险越多。最小合理修改,是足以修复责任边界、又不顺带改变无关行为。

测试通过还需要审查测试本身 ​

Agent 可能删除失败断言、扩大期望集合或把异常吞掉。最终审查应同时查看实现与测试差异。若修改了预期行为,需要明确业务依据,不能仅因为新的结果更容易通过。

测试环境也要先跑基线。已有失败、依赖不可用和新增失败应分别报告。没有运行的检查写成未运行;静态阅读发现的可能性不能写成实测结论。

从局部测试扩展到任务回放 ​

单元测试检查版本过滤;集成测试检查检索结果是否正确分类;任务回放检查最终报告是否仍把历史资料当作当前事实。三层对应不同故障,不能靠一层替代全部。

若单元测试通过但报告仍错误,检查缓存、摘要和旧记忆是否保存了 D3。第七讲的失效机制在这里重新出现:代码修好了,已派生的数据仍可能继续污染答案。

交付说明应写清触发条件、行为变化、已运行检查和剩余限制。这样下一位工程师可以从失败样例复现,而不是相信一句“问题解决”。

下一讲讨论系统主动发现问题时,何时可以提出帮助、何时不能自行行动。继续阅读主动式 Agent。


本课程逐讲目录 · 两门课程映射与资料边界 · 离线实验与验证边界