#AI Agent#软件工程

AI 写完代码之后,谁来证明它真的完成了

把编译、测试、页面运行与设计检查变成 Agent 可以读取的反馈,在交付前自己发现、修正并重新验证。

种下2026/07/25 4 分钟 常青

你现在的流程大概是这样的:让 AI 改一个功能,它说改好了。然后你打开页面点一遍,翻一眼日志,再把浏览器拖窄到手机宽度试试。这几下每次都得你自己做。

要交出去的,就是你每次亲手点的那几下。

小机器经过检查门,失败后先回资料桌 发现问题之后,先回到资料桌重新看一遍。

两类检查:一半机器看得见,一半只有你才能看见

Agent 干活的完整流程长什么样?Anthropic 官方画了一张图:拿到指令 → 收集上下文 → 动手 → 验证结果 → 回话。验证没过的时候,箭头指回去的不是”动手改”,而是**“收集上下文”**。这个细节正文没展开,但比什么都重要。

它不会拿着同一份信息硬改第二遍。它先回去把新情况摸一遍,再决定怎么改。

验证这一环,Agent 本来就在做一部分。有些信号是机器能直接读的:编译器报错、类型检查不通过、测试跑挂了、linter 的警告。这些东西一出现它就看得见,也知道该回头。

麻烦的是另一半。页面里的按钮点了有反应没?移动端那些溢出屏幕的内容藏住了没?改动碰了设计规范没?这些没有任何机器信号会替你报警。所以它们每次都落回你手上。

接下来要做的,就是把右边这些也写成它能读的信号。

不是多写几个测试,是把视觉判断变成机器信号

你可能第一反应是”多写测试”。测试能解决一部分问题——按钮的逻辑对不对、数据渲染对不对——但它解决不了”这个按钮溢出屏幕了”和”这个间距跟设计稿对不上”。

这两个问题需要的不是测试断言,是把浏览器里看到的画面重新送给 Agent 让它自己判断。

最简单的办法:跑起来→截图→把图送回 Agent→让它对照检查项逐条核对。这一步听起来重,其实可以放进一个 skill 里。Claude Code 的做法是给验证写独立的技能文件——一份 Markdown,描述检查什么、怎么检查、检查失败怎么办。

举个例子。一个项目级验证技能大概长这样:

读当前 diff 里涉及前端页面的改动。对每个改动的页面,跑 npm run build,然后在 /design-review/ 目录下生成桌面和移动端截图。逐条核对:按钮是否完整可见、文字是否溢出容器、移动端导航是否折叠正确。每个违规点报文件:行号,然后修。

这条技能把三个原本只有你能做的判断——“这个按钮完整吗""文字溢出了吗""移动端对吗”——都变成了 Agent 自己读得懂的东西。

验证器的否决权

一个容易被忽略的细节是:验证器必须有否决权。

如果 Agent 验证发现三个问题,然后说”三个问题,已记录”就提交了——那验证器只是装饰。正确流程是:验证失败→回去收集新上下文→重新修改→再次验证→通过才能结束。

Anthropic 官方的 agentic loop 图里,验证没过的时候箭头指回”收集上下文”。为什么不是”动手改”?因为你不能假设自己第一次看到的信息足够改对。验证失败说明你对当前状态的理解不完整——你需要的不是同一份代码改第二遍,是先搞清现在到底什么状态。

验证循环在不同项目里有不同的接入位置。最简单的:做完任务后单独跑一次,手动触发。成熟一点的:把验证步骤嵌入到每次代码修改的流程里。再往上:多个验证串起来——先跑类型检查,过了再跑前端截图检查,都过了再跑性能回归。最高一档:挂到每个 PR 上,合并之前自动挡一枪。

你的项目现在在哪个位置?如果一次都没挂过,从”做完任务后跑一次”开始。这一步只要做一次,就会被固化进系统,以后每次都是自动的。

验证器不是 AI 写完代码后的警察。它是 Agent 工作流里唯一可以说”不”的环节。 没有否决权,整个循环就是一台只生产、不检验的流水线——产出越多,烂东西越多。