#AI Agent#TypeScript#DevOps

编程 Agent 需求验收追踪:把 Acceptance Claim 连到 Diff 与测试证据

Agent 可以交出绿色测试,却未必实现了需求。本文用版本化 acceptance claim、双向证据图、反证样本和量化门禁,让每项验收都能追到具体改动与同一快照上的结果。

本文要点

  • 主题聚焦:AI Agent、TypeScript、DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年5月17日·更新于 2026年7月20日

编程 Agent 最容易交付一种“看起来完成”的补丁:测试全绿、描述流畅,但原需求中的某个异常分支没有实现,或者顺手加入了未经批准的行为。原因不是缺少测试,而是需求、代码和结果没有共同身份。Reviewer 只能凭自然语言猜测某个测试为何足以证明某条需求。

Spec 驱动开发 解决如何把意图写清楚,编程 Agent 的改动验证门 决定应该运行哪些检查;本文只处理更窄的问题:一条验收声明如何双向追到实现 diff、可失败的测试和绑定同一仓库状态的结果。

冻结 acceptance-claim.v1

任务进入实现前,把需求拆成带稳定 claimId 的原子声明。合同至少包含 specId、specVersion、claimId、claimRevision、规范化条件、预期结果、风险级别、适用接口版本、允许证据类型和 supersedes。Gherkin 的 Given/When/Then 可表达场景,但场景标题或行号会变化,不能充当长期身份。

yaml
schema: acceptance-claim.v1
specId: avatar-upload
specVersion: 4
claimId: AC-017
claimRevision: 2
given: authenticated user and a payload larger than 5 MiB
when: POST /avatars is invoked
then: response is 413 and no object is persisted
evidence: [integration-test, storage-probe]

修改预期行为必须提升 claimRevision,保留旧版与批准记录;只改措辞但规范化语义不变,可以保留 revision。实现开始后新增、删除或弱化 claim 都是合同差异,不能由 Agent 静默改写测试来“修复”失败。接口 schema 的演进仍由 Agent API 契约兼容门 判断,本合同证明的是当前任务承诺,而不是所有消费者兼容性。

建立双向证据图

证据图使用 W3C PROV 的 entity、activity 与 derivation 思路,但节点必须落到可核验工件。一次评估记录 baseCommit、headTree、未提交补丁摘要、claim 合同摘要、测试源码 blob、执行配置摘要与结果摘要。边至少有四类:CLAIM_COVERED_BY_TEST、TEST_EXERCISES_DIFF、RUN_EVALUATES_TEST、RESULT_SUPPORTS_CLAIM。

正向查询从 AC-017@2 出发,应找到至少一个先在错误实现上失败、在当前 headTree 上通过的测试,再找到负责行为的 diff hunk 或生成制品。反向查询从每个语义 diff hunk 出发,应找到它服务的 claim、必要的基础设施理由或明确的 NON_BEHAVIORAL 分类。这样既能发现“需求无人覆盖”,也能发现 Agent 添加了需求之外的权限、默认值或遥测。

不要把文件路径当成实现证据。重命名会让路径失效,一次测试也可能经过许多无关行。节点应保存 Git blob ID、hunk 上下文摘要和符号身份;生成代码连接到生成器与输入,不逐行虚构 claim。依赖影响面可由 仓库依赖图变更规划 提供候选边,但最终边仍要由测试命中、调用观测或人工理由确认。

证据强度不能只看覆盖率

行覆盖只能说明执行经过某行,不能证明断言验证了 claim。每条高风险 claim 至少需要一个行为断言和一个反证:删除对应分支、翻转比较符或替换返回码后,测试必须失败。适合广泛输入空间的规则,再加入 AI 生成代码的属性测试,但属性测试仍要声明支持哪些 claim,不能用随机样例数替代关系。

测试结果绑定 headTree 与测试 blob;Agent 在绿色结果后修改源码或测试,相关 RESULT_SUPPORTS_CLAIM 边立即变为 stale。跳过、重试后通过、外部依赖不可用与只运行测试子集都作为一等结果,禁止折叠成绿色勾号。人工验收可以成为证据,但要记录 reviewer、输入、观察和有效期,不能写成“已看过”。

用故障注入校准图和门禁

在影子任务中依次注入:删除一个 claim 对应的测试映射;让测试绑定旧 tree;保留覆盖率但移除关键断言;添加没有 claim 的业务分支;把 AC-017@1 的结果挂到 @2;让测试在错误实现上也通过。系统应分别报 UNCOVERED_CLAIM、STALE_RESULT、WEAK_ORACLE、UNJUSTIFIED_DIFF、REVISION_MISMATCH 和 NON_DISCRIMINATING_TEST,而不是只显示 CI 失败。

合并量化门为:活跃 claim 正向可达率 100%,语义 diff 反向归属率 100%,高风险 claim 反证通过率 100%,stale 结果为 0,未批准合同差异为 0;普通 claim 的变异或错误实现杀伤率至少 90%。同时限制伪精确:工具无法建立 hunk 关系时进入人工队列,不得自动补一条边凑满比例。

可逆地启用强制执行

先只生成图并抽样 30 个已合并任务,比较 reviewer 实际判断;再对一个仓库启用缺边告警,连续两周误报率低于 5%、关键漏报为 0 后,才阻断高风险 claim。每次判定记录 policyVersion,豁免必须有 owner、理由和最长 7 天期限。

回滚时把强制模式切回告警,恢复上一版 claim 解析器与 policy,但保留已签发图、失败结果和豁免,不能删除证据让旧补丁显得合格。若新 schema 写入期间需要双读,先证明旧 reader 能忽略未知边;不兼容时停止晋级并重算,绝不把无法解析当作通过。最终 Reviewer 看到的不是“Agent 说完成了”,而是每条承诺如何被这版代码、这组测试和这次真实执行共同支持。

Related

相关推荐