你的 AI 写手需要一个严父,而不是更好的 Prompt
AI 写完代码说「搞定了」—— 但搞定 ≠ 能用。解法不是调 prompt,而是一个自动化的 QA Agent:打开浏览器验渲染、打 API 验接口、查数据库验落库,全过了才算完。
上周我让 Claude Code 给用户资料表单加一个手机号字段——前端输入框、API 处理器、数据库迁移,标准的全栈任务。
Claude 写了组件,更新了 handler,创建了 migration,加了单元测试,跑了 typecheck。然后它说:「Done! 手机号字段已经完整实现并正常工作。」
我打开页面。字段在。输入号码,点保存。成功提示出现了。刷新页面。字段空了。查数据库。没有这个列。Migration 文件存在但没有执行,API handler 引用了一个还不存在的字段。
代码语法正确。类型通过。单元测试 mock 了数据库调用,所以也通过了。但这个功能根本不能用。Claude 完全不知道。
90% 的情况都是这样
不是这个具体的 bug——是这个模式。AI 写手停在「代码编译通过 + 测试通过」就宣布胜利。而任何人类开发者都会做的验证闭环——打开页面看看、试一下、查查数据——被直接跳过了。
不是因为 AI 做不到。Claude Code 有 Playwright MCP 可以控制浏览器,有终端可以跑 curl 和数据库查询。工具全都有。
它跳过验证,是因为没人告诉它「搞定」意味着不只是「代码写完了」。
这就是 verification debt(验证债务)问题。Sonar 2026 年的数据:96% 的开发者不完全信任 AI 生成的代码,但 AI 已经贡献了 42% 的提交代码。数学很残酷——如果 AI 每步准确率 85%,5 步的工作流成功率只有 44%。[1]
问题出在 Harness
斯坦福的 Meta-Harness 论文给出了精准的定义:Agent = Model + Harness。Harness——系统提示词、工具定义、验证逻辑、生命周期钩子——对性能的决定作用不亚于模型本身。同一个模型,不同的 harness,性能差 6 倍。[2]
你的 AI 写手的 harness 有个洞:没有 E2E 验证层。它知道怎么写代码、跑测试、检查类型。它不知道对于你的项目来说,「完成」意味着页面能渲染、表单能提交、数据能落库。
社区已经开始修补了。claude-review-loop 用 Stop hook 触发跨模型代码审查。super-smoke-test 加了 Playwright 冒烟检查。Spotify 的编码 agent 用了一个 LLM-as-judge,否决了 25% 的完成请求。
但这些全都聚焦在代码审查——读 diff,判断代码看起来对不对。审查不等于验证。审查者读你的 migration 文件说「看起来没问题」。QA 工程师会真的跑 migration、插入数据、然后查一下数据在不在。
你的 AI 写手不需要又一个审查者。它需要一个严父。
严父模式
严父,就是那个永远不接受「相信我,没问题的」的家长。他自己检查每一样东西。
模式很简单:当你的写手 agent 试图说「搞定了」时,一个独立的 QA agent 自动拦截,根据实际的代码改动判断需要验证什么,然后亲自执行验证。
写手 Agent 完成工作 → 试图停止
│
Stop Hook 拦截
│
QA Agent(严父)激活:
├─ 读取任务描述 + git diff
├─ 推断需要验证什么(不是硬编码规则——AI 自行判断)
├─ 第 1 层:打开浏览器 → 检查渲染
├─ 第 2 层:填表单 → 提交 → 验证行为
├─ 第 3 层:curl API → 检查响应
├─ 第 4 层:查询数据库 → 验证数据持久化
└─ 判决:PASS 或 FAIL
│
PASS → 写手可以停止
FAIL → 具体反馈 → 写手必须修复
关键洞察:QA agent 根据改动内容动态决定验证什么。 只改了 CSS?检查渲染就够了。新增 API 端点?curl 验一下。全栈功能?所有层都验。不是 bash 脚本匹配文件后缀——QA agent 读 diff 后自行判断,和人类 QA 工程师一样。
而且它必须是一个独立的 agent——不是写手自查。原因和不让学生给自己改卷一样。写手对自己的代码有沉没成本偏见。QA agent 以全新的上下文看到改动,唯一的任务就是:找出什么坏了。
一次验证 session 长这样:
yanfu QA Agent | 任务:给用户资料添加手机号字段
=== 第 0 层:构建 & 类型 ===
[PASS] typecheck — 0 错误
[PASS] 单元测试 — 14/14 通过
=== 第 1 层:视觉渲染 ===
[PASS] 导航到 /profile — 页面加载正常
[PASS] 手机号输入框可见
[PASS] 无 console 错误
=== 第 2 层:用户交互 ===
[PASS] 输入 "13800138000" → 点击保存 → 成功提示
[FAIL] 输入 "abc" → 表单提交成功,没有验证错误
期望:无效手机号格式的验证错误
实际:静默接受
=== 第 3 层:API ===
[PASS] GET /api/users/me → 200,phone_number 字段存在
=== 第 4 层:数据库 ===
[PASS] SELECT phone_number FROM users WHERE id=1 → "13800138000"
判决:FAIL
→ 缺少手机号格式验证
单元测试通过了。类型通过了。但严父发现了缺失的验证——通过真正使用这个功能。
我把它做出来了
yanfu(严父) 是一个 Claude Code 模板,实现了严父模式。复制到你的项目里,每次写手 agent 试图完成任务时,QA 验证 agent 都会自动验证。
它是模板,不是框架——你可以查看和修改所有东西:
- 拦截完成的 Stop hook 配置
- 收集上下文的 gate 脚本(git diff、项目类型、任务描述)
- 驱动验证决策的 QA agent prompt
- 框架示例(Next.js、Express、Django、Astro)
一键安装:
curl -sSL https://raw.githubusercontent.com/spytensor/yanfu/main/install.sh | bash
自动检测项目类型,配置 dev server URL,如果可用还会设置数据库访问。
更大的启示
AI 编码感觉不靠谱,不是因为模型不行。是因为我们给了它开发者的工具,却给了它自动补全的工作流。写代码、检查语法、收工。
真正的开发有一个验证闭环。模型有能力跑这个闭环——它们只需要一个让闭环成为强制而非可选的 harness。严父不增加能力,它增加责任。
严父没说完,你的 AI 就没完。
参考文献
- Sonar, “State of Code 2026: AI Verification Gap”
- Lee et al., “Meta-Harness: End-to-End Optimization of Model Harnesses” — Stanford/MIT, 2026
- Verification Debt: When Generative AI Speeds Change Faster Than Proof — ACM
- Feedback Loops for Background Coding Agents — Spotify Engineering
- claude-review-loop — Hamel Husain
- super-smoke-test
- Playwright MCP — Microsoft
- yanfu:AI 写手的自动化 E2E 验证