# 如何给 Loop 造个验证器

> 没有验证器的 Loop，就是印钞机在印废钞。这篇讲清楚验证器到底是什么——它就是你每次替 AI 手动补的那个动作，以及怎么用 Claude Code 的内置能力和 Skill，把它从手动喊一步步自动化到每个 PR 强制跑。

- 原文链接: https://laojin.blog/blog/20260724_build_the_verifier
- 作者: 老金
- 发布日期: 2026-07-24
- 标签: Claude Code, AI 编程, 验证器, Skill, Loop

---

![如何给 Loop 造个验证器](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260724/00_cover.png)

上一篇《Loop 还是 Graph》，我在结尾塞了四条能直接抄的做法。排第一条的是这句：

> 别一上来搭图，先跑通一个带真验证器的 Loop。

有读者私信我：道理我都懂，可这个"验证器"到底是个啥？我要去哪儿找它？是不是又得学个新框架、装个新工具？

问得好。因为整个 Loop 的成败全押在这个词上——没有验证器的循环，就是一台印钞机在印废钞，而且印得飞快。但"验证器"这三个字，被我们这些写公众号的用得太玄了，好像它是什么需要顿悟的高深东西。

这周 Claude Code 团队发了篇博客，把这层窗户纸捅破了。看完我最大的感受是：

**你要找的验证器，大概率就是那件你每次都在手动做、做完还骂骂咧咧的破事。**

它不在别处。它就在你的肌肉记忆里。

---

## 验证器不是发明出来的，是"记下来"的

先说清楚验证是什么。你让 AI 改个东西，它干完，你不会闭眼就信——你会去看：类型对不对、lint 过没过、测试红不红、跑起来崩不崩。这些确定性的信号，Claude 其实已经会自己看了。

真正的问题在于它看不见的那部分。

比如你的项目里有条不成文的规矩："每个新组件必须带一个同目录的测试文件"。比如"错误日志里必须带 request ID，但绝对不许打印请求体"。比如"任何删列的数据库迁移，必须配一个回填步骤"。

这些东西，通用的 linter 抓不到，类型检查器也不管。于是每次 AI 写完，你都得亲自上手补一遍。补第一次、第二次、第十次……

![验证器就是你每次手动补的那个动作，把它记下来](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260724/01_capture_manual_step.png)

**那个"你每次都得手动补的动作"，就是你要找的验证器。** 你不用发明它,你早就在执行它了,只是执行的人一直是你,不是 AI。

博客里那句提示我觉得值得裱起来：

> 检查项不必是"定性的"才够格。"拒绝任何删列却没有回填的迁移"是一条铁规则,通用工具抓不到,但项目专属的规则可以。任何你一直不得不手动强制执行的检查,都够资格被做成一个循环。

所以造验证器的第一步，不是打开编辑器，是打开记事本，把你这周替 AI 擦过的屁股，一条条列出来。

---

## 别急着造，先看看内置的够不够

在你动手写之前，先泼盆冷水：Claude Code 里已经内置了一堆验证能力，很多时候你根本不用自己造。

我把官方列的几个整理成人话：

| 内置能力 | 干什么用 |
|---------|---------|
| **`/verify`** | 构建、跑起来、亲眼看变化对不对，一条命令搞定 |
| **工具链** | 自动捕获 linter / 编译器报的错误码。前提：把你确切的构建和测试命令写进 CLAUDE.md，别让它猜 |
| **Code Review（预览版）** | 托管的多智能体服务，自动审 PR，你在问题下 @claude 就能让它闭环去修 |
| **GitHub Actions** | 把你本地那套检查，搬到每次 push / PR 自动跑 |
| **规格验证** | 对照仓库里的 markdown 规格文档验证改动，还试着自己修违规 |
| **Rubrics（beta）** | 独立评分 Agent 按评分标准打分，不及格自动打回返工 |

这里面最容易被忽略、性价比却最高的，是第二行：把构建和测试命令写进 CLAUDE.md。就这一下，AI 从"猜命令、跑错、等你来救"，变成了自己跑、自己看错误码、自己改。很多人的 Loop 死活转不起来，追到底往往就卡在这：连最基本的那个验证入口，都没人告诉过它。

先用够内置的。发现内置的确实盖不住你那条私房规矩了，再往下走。

---

## 把那条私房规矩，写成一个 Skill

好，假设你确认了：有一条检查是你项目独有的，内置工具管不了。那就把它变成一个 [Skill](https://claude.com/blog/complete-guide-to-building-skills-for-claude)。

写 Skill 有个心法，我觉得比任何模板都重要：

> 像给入职第一天的新同事做交接那样，用大白话写。

不用术语，不用伪代码，就写"你先看哪儿、确认什么、发现不对怎么办"。如果你连大白话都说不清这条规矩，那说明你自己都没想明白——这时候可以反过来先问 Claude "这类检查的最佳实践是什么"，然后在它的版本上改。你改动的那几个点，恰恰就是你项目最该被捕捉下来的私货。

最简单的验证 Skill，就是 frontmatter 加一段正文。直接抄这个改：

```markdown
# .claude/skills/verify-log-hygiene/SKILL.md
---
name: verify-log-hygiene
description: 检查错误日志是否包含 request ID、且绝不包含请求体。
  当 diff 涉及错误处理或日志时使用。
allowed-tools: [Read, Edit, Grep]
---
读取当前 diff 里所有错误处理路径。

对每一处错误路径上的日志调用，确认它包含了 request ID，
并且没有传入请求体、请求头，或任何用户提交的数据。

发现违规就报出 file:line，然后直接修复：
缺 request ID 的补上，日志里的敏感数据剥掉。
```

就这么点东西。它不智能、不花哨——它就是把"你每次手动检查日志"这个动作，钉成了一份 AI 每次都会照做的契约。

嫌手写麻烦，装个 skill-creator 插件，一句话让它采访你：

```
/skill-creator 帮我造一个端到端验证前端改动的 skill，就我的工作流采访我
```

---

## 四种装法，其实是你成长的四个阶段

Skill 写好了，最后一个决定是：它什么时候启动？官方给了四种形态。但我想换个讲法——对独立开发者来说，这四种不是并列的选项，是你一个人往前走的四个台阶。

![从手动喊到每个 PR 强制跑的四个台阶](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260724/02_four_stages_ladder.png)

**第一阶 · 独立（Standalone）**：你手动喊它。
产物做好了，你主动 `/verify-xxx` 一下。适合那种不是每次都要跑的横切检查：提交前扫一遍安全、发 PR 前查一遍无障碍。代价很明确：你得记得喊。而当你发现自己每次改完都在喊同一个——恭喜，你不该再停在这一阶了。

**第二阶 · 内嵌（Embedded）**：让它跟着产出自动跑。
把检查直接塞进"生产这个产物的那个 Skill"的结尾。比如你那个 `scaffold-component` 脚手架 Skill，正文最后加一行就行：

```markdown
创建完组件文件后，对它跑一遍 eslint，
把所有错误改完再报告完成。
```

从此这个检查有了永久的家，不用你再开口。注意：内嵌只对你能改的 Skill 有效——内置的、插件管的（更新会被覆盖那种）不适用，那些得用下一阶。

**第三阶 · 链式（Chained）**：一个 Skill 结束时喊下一个。
Anthropic 团队自己就这么干：`/code-review` 找 bug → `/simplify` 清理 diff → `/verify` 确认端到端行为 → 涉及 UI 再 `/design` 对照 DESIGN.md。一条链自己跑完整个开发周期，你只在需要拍板时才介入。

它的妙处还在于：给你改不了的 Skill 套验证的唯一办法，就是包一层链。

```markdown
# .claude/skills/safe-refactor/SKILL.md
先对当前 diff 跑 /simplify。
/simplify 结束后，调用 /verify-no-public-api-changes。
```

一开始只是个习惯（"我总在 simplify 后跑一下 verify"），跑久了就固化成契约（"simplify 结束**总会**自动跑 verify"）。代价是：用灵活性换自动化，而且链会多烧 token，先小范围测，别一上来铺满。

**第四阶 · 每个 PR**：从个人基础设施，变成团队基础设施。
这条链在你自己身上跑稳了，就能搬到每个 PR 上强制执行。谁的改动都走同一道关卡，管他记不记得喊。你当初为了每周给自己省两分钟写下的检查，现在替每个人、每次改动省两分钟。

作为一人公司，你现在大概活在第一到第三阶。但第四阶不是"以后带团队才用得上"的空话——那个"每个 PR 都过关卡"的关卡，未来的你、你雇的第一个人、甚至半年后忘了规矩的你自己，都是它要拦的对象。你今天写下的每条私房规矩，都是在给未来的混乱提前上锁。

---

## 一个必须钉死的原则：验证器不能自己既当运动员又当裁判

讲到这，得把上一篇那个词请回来：现实锚点。

验证循环最容易造出来的赝品，是让同一个 Agent 又写代码又判对错。它写完，你问它"行不行"，它说"行"——这不叫验证，这叫一台"昂贵的自我认同机器"。它会以工业级的自信，把自己的错误盖章为正确。

![验证信号必须来自 Agent 管不着的外部](https://pic-1258874139.cos.ap-hongkong.myqcloud.com/laojinblog/posts/20260724/03_external_anchor.png)

真正的验证器,那个信号必须来自 Agent 管不着的地方:

- 测试真的跑过了(不是 AI 说"应该能过")
- 构建真的编译了
- 那条私房规则是写死的,AI 不许在验证时顺手改掉它
- 最根上那个问题——"什么算对"——必须由你定死,因为循环里每一步都预设了它

一句话:**验证器的价值,全在于它不听 Agent 的话。** 你造 Skill 时最该守住的,就是这条边界:让检查的依据,永远是外部的、AI 改不动的东西。

---

## 今天就能抄的四步

不给模糊建议，直接上能执行的：

1. **列清单。** 打开记事本，写下这一周你替 AI 手动补过的收尾动作——补测试、改日志、加回填、统一命名……哪个出现最多，圈出来。那就是你的第一个验证器。

2. **先喂 CLAUDE.md。** 别急着写 Skill。先把你确切的构建、测试、lint 命令写进 CLAUDE.md，让内置工具链先转起来。很多"Loop 转不动"到这一步就解决了。

3. **把圈出来那条写成 Skill。** 照上面 `verify-log-hygiene` 的样子，大白话写，扔进 `.claude/skills/`。然后在一个全新任务里调用它，亲眼确认那步检查真的跑了——没跑，就是 description 没写对。

4. **等它成了习惯，就给它找个家。** 发现自己每次都在手动喊它 → 内嵌进产出它的 Skill，或链到工作流末尾。让"我记得跑"升级成"它自动跑"。

---

给 AI 圈的概念取名，是门半年一换的生意：Prompt → Context → Harness → Loop → Graph……但底下有根轴从没变过——你那台改进机器，到底接不接触它声称要改进的现实。验证器，就是这根轴伸进现实的地方。

所以别再纠结"验证器到底是个啥"了。你替 AI 擦过多少次屁股,你就有多少个现成的验证器躺在那儿,等着被你写下来。
