Anthropic 官方教你把手动代码检查写成技能,让它自己查自己修

他们内部四个技能接力跑:抓 bug、清理 diff、把 app 跑起来看,改动碰了界面再核一遍设计规范。
作者:Claude 官方博客07-25 · 9 分钟⚑ 方法教程
工具教程 · 小互解读
一分钟速览
  • AI 改完代码,编译报错、类型检查、测试、linter 这些信号它自己看得见;剩下那几步只有你知道的检查,每次都得你亲手点一遍。
  • Claude Code 团队给的做法:把你每次都在点的那几步用大白话写下来,存成一个技能,它就能自己跑、自己修。最小的一个只有十几行。
  • 检查写得好只是一半,另一半是它装在哪一层:你想起来才叫、嵌进生成代码的那个技能里、一个技能干完自动叫下一个、挂到每个 PR 上(PR 就是把改动提交给团队合并的那个请求)。四层越往后越省心,也越难改。
  • Anthropic 自己的 Claude Code 团队日常跑的是四个技能接力:/code-review 找 bug,/simplify 清理 diff,/verify 把 app 真跑起来看效果,改动碰了界面就再叫一个自定义的 /design 对着 DESIGN.md 核一遍。
  • 代价也写在明处:技能一旦加载就常驻上下文到会话结束,串得越长 token 烧得越多;而且 /verify 和 /code-review 从 v2.1.215 起只在你开口叫的时候才跑,不会自己开火。
⚑这是 Claude Code 团队自己写的做法说明,讲的是他们内部怎么用自家工具。全文没有给出任何效果数字,省了多少时间、误报率多高、token 多花多少都没测;检查本身写错了会怎样,文章也没碰。下面标注「本站补」的段落来自 code.claude.com 官方文档,原文没有展开。
1循环长什么样

AI 改完代码,哪些检查它自己会做,哪些还得你来

Anthropic 官方团队分享了他们怎么在 Claude Code 里建立验证循环(verification loop):把平时手动做的检查步骤,变成自动化的技能(Skill),让 AI 自己纠错。作者是 Claude Code 团队的 Delba de Oliveira,7 月 22 日发布。

简单来说,验证循环就是让 Claude 写完代码后自己检查一遍、发现问题自己修好,不需要你一直盯在电脑前当监工。

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

先看 AI 干活的完整流程长什么样。

Anthropic 官方图:AI 干活的循环,从 Prompt 到收集上下文、动手、验证结果、回话,虚线框标出 Agentic loop
你给一句提示,Claude 去收集上下文(Gather context)、动手改(Take action)、验证结果(Verify results),最后回话给你。虚线框圈住的中间三步就是它自己在转的那个圈。图片来源:Claude 官方博客。

这张图上有一个正文没提的细节:验证没过的时候,箭头指回去的是「收集上下文」,不是「动手改」。也就是说它不会拿着同一份信息硬改第二遍,而是先回去把情况重新摸一遍,再决定怎么动。

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

麻烦的是另一半,那一半没有任何报错文本可看。

它自己看得见
代码库里的确定性信号,出错就有明确的报文
  • 编译器报错
  • 类型检查不通过
  • 测试没跑过
  • linter 的警告
只有你知道
没有任何工具会为此报错,它推不出来
  • 这个按钮在手机宽度下会不会被挡住
  • 这条错误日志有没有把用户的请求体一起写进去
  • 这次迁移删了一列,数据有没有补进新结构
  • 这个改动合不合团队那份设计规范

右边这一列,没有任何机器信号会替你报警。所以它们每次都落回你手上,变成你亲手点的那几下。接下来要做的,就是把右边这些也写成它能读的信号。

站内相关
Claude Code 官方讲透循环设计:4 级递进到无人值守
同一个官方博客系列的前一篇,讲整个循环怎么从手动确认一路放手到无人值守。验证是那四级里的一环,这里展开的就是它。
2现成的

Claude Code 里已经装好的六种检查,各管什么

从零开始写之前,先看看现成的。Claude Code 里已经装好六种,各站在不同的位置,有的要你开口叫,有的自己就跑。

/verify
你叫才跑
把你项目的 app 构建出来、真跑起来、观察结果,用看到的东西判断改动对不对,而不是靠测试或类型检查。需要 Claude Code v2.1.145 以上。
写进 CLAUDE.md
一直生效
Claude 会接住你提供的工具报出来的错误码和警告并跟着动作。把项目确切的构建和测试命令写进 CLAUDE.md,它就不用自己猜该敲哪一条。
Code Review(研究预览)
自动跑
一个托管的多 Agent 服务,在你开启的仓库里对 PR 跑一遍自动审查。发现的问题你可以自己改了推上去,也可以在那条发现下面回一句 @claude 让它闭环,前提是 GitHub Actions 已经配好。
GitHub Actions
每次推送都跑
定义一个 job,让它调用带着验证技能的 Claude,你本地跑的那套检查就会在每次推送或者每个 PR 上同样开火。
Spec validation
你叫才跑
一个技能,拿仓库里的 markdown 规格文档当标准,逐条核对每次改动,并尝试把违反的地方修掉。
Managed Agents 的评分表(beta)
不合格自动打回
一个托管的 Agent 服务,让另一个独立的阅卷 Agent 按一份评分表核对产出。没达标的自动退回去重做。
本站补 · 来自官方文档

/verify 和 /code-review 从 Claude Code v2.1.215 起,只在你主动调用时才跑;在那个版本之前,Claude 可以自己决定要不要跑它们。文章把 /verify 列在内置验证循环的第一条,容易让人以为它会自己开火,实际上得你开口叫。

还有两个常跟它们一起用的:/simplify 会派四个审查 Agent 并行跑,分别看能不能复用已有的辅助函数、能不能写得更简单、效率如何、以及这个改动是不是做在了正确的抽象层级上;从 v2.1.154 起它不再负责找正确性 bug,找 bug 归 /code-review。/run-skill-generator 则是专门教 /run 和 /verify 怎么在你这个项目上从干净环境把 app 构建、启动、驱动起来。

3起手

怎么把你每次都在做的检查写下来

起手第一步是写字。把你每次都在做的那几个小纠正,一条条记下来。

用大白话把「最佳做法」的那个版本写出来,就像你要把它交给一个第一天来的新同事。不用写成文档的语气,写成交代事情的语气就行。

如果你发现自己说不清这个检查到底在查什么,还有个反过来的办法:先问 Claude 这类事情的通行做法是什么,拿它给的版本当底稿,再往上改成你的。你的做法跟通行做法不一样的那几点,恰恰是最该被写下来的,因为那些正是没人会替你记着的部分。

检查不必是那种需要品味判断的

举个例子,这么一条规矩:任何一个删了列、却没有回填步骤的数据库迁移,一律打回。回填指的是把数据补进新的结构里,跟备份是两回事,备份是留后路,回填是保证数据不丢在半路上。

这条规矩死得不能再死,判断标准清清楚楚,但通用 linter 抓不到它,只有你项目自己的检查抓得到。凡是你老得用手盯着执行的规矩,都够格变成一个循环。

4成品

一个能直接抄的验证技能,一共十几行

最省事的做法是让 Claude 反过来采访你。装上 skill-creator 插件,然后敲这么一句:

让 Claude 采访你,直接生成技能
/skill-creator Create a skill for verifying frontend changes end-to-end. Interview me about my workflow.
中文意思:给我做一个技能,用来端到端地验证前端改动,就我的工作流采访我。它会一条条问你平时都怎么做,再把答案写成技能文件。

手写也不难。在项目里的 .claude/skills/ 放一个 markdown 文件,那就是一个技能。最小的例子只有十几行,查的是错误日志有没有带上请求 ID、有没有把请求体写进日志:

.claude/skills/verify-log-hygiene/SKILL.md
---
name: verify-log-hygiene
description: Check that error logs include the request ID and never
  include the request body. Use when the diff touches error handling
  or logging.
allowed-tools: [Read, Edit, Grep]
---
Read the error-handling paths in the current diff.

For each log call on an error path, confirm it includes the request ID
and does not pass the request body, headers, or any user-supplied payload.

Report each violation with file:line, then fix it: add the request ID
where it's missing and strip the payload from the log call.
description
Claude 靠它判断什么时候该用这个技能。这里写清了触发条件:当改动碰到错误处理或者日志的时候用。
allowed-tools
调用这个技能的那一轮里,Read、Edit、Grep 这三个工具它可以不问你直接用。你发出下一条消息之后,这个授权就失效了。(本站补)
正文三段
先读这次改动里的错误处理路径,再逐个核对每一处日志调用,最后带着文件名和行号报出每一处违规。

最后那句是整个技能的关键:报完不算完,报完接着修。它先给你一份带行号的清单,然后把缺的请求 ID 补上,把不该写进日志的内容从调用里剥掉。少了这半句,它就只是个报警器,报完停在那儿等你动手。

5核心

检查放在哪跑,四个位置

检查写出来之后,紧接着的问题是它什么时候开火。四个位置,从你想起来才叫,一路到挂在每个 PR 上。位置一变,同一份检查的性质就变了。

1 2 3 4 单独调用 嵌进去 串起来 每个 PR 你开口 工作流 上一个技能 CI 靠你记得 跟人无关
下方小字是「谁来开火」。越往右,开火这件事离你越远。
1
单独调用 standalone
谁开火
你,手动敲
适合
横跨多条工作流、但不需要每次都做的检查
代价
每一次都是你要记得去做的动作
2
嵌进去 embedded
谁开火
生成代码的那个技能,自动带着跑
适合
绑死在一条工作流上的检查
代价
只对你能编辑的技能有效
3
串起来 chained
谁开火
上一个技能干完,自己叫下一个
适合
整条开发流程从头跑到尾
代价
不能再单跑其中一步,token 也花得更多
4
挂到每个 PR on every PR
谁开火
CI,谁提交的改动都跑
适合
要让全团队都遵守的标准
代价
每次调整都变成团队可见的事件
6第一档

单独调用:你想起来才跑

这一档是东西已经做出来之后,你主动敲一下它才跑。

它适合那种横跨很多条工作流、但不需要每次改代码都做的检查。三个典型场景:提交前的一次安全扫描、发 PR 前的一次无障碍审查、整个仓库的许可证头核对。这类检查你希望在任何场景下都能随手叫出来,但不希望它每改一行代码就跳出来一次。

代价很实在:每一次调用都是你要记得去做的一个动作,忘了就是没做。

什么时候该往上升,判据是这一条:当你每改完一次都在跑它,说明它不该再靠你记着了。到这个时候,这个流程已经挣到了一个固定的位置,该往下面两档挪,要么嵌进去,要么串起来。

7第二档

嵌进去:在生成代码的那个技能末尾加一行

这一档是让检查跟着生产它的那条工作流一起跑,你不用开口。

做法比想象中简单,在那个技能的正文末尾追加一句话就行。拿一个生成 React 组件的技能举例,前面都是它原本的内容,加的只有最后那两行:

.claude/skills/scaffold-component/SKILL.md
---
name: scaffold-component
description: Scaffold a new React component under src/components/, including the component file, its co-located test, and an index export. Use when the user asks to create a new component.
allowed-tools: [Read, Write, Edit, Bash, Glob]
---

# Scaffold a new React component

Given a component name (PascalCase), create the following under `src/components/<Name>/`:

1. `<Name>.tsx`: function component with a typed props interface and a default export.
2. `<Name>.test.tsx`: React Testing Library test that renders the component and asserts it mounts without throwing.
3. `index.ts`: re-export the default and any named exports.

Follow the patterns in `src/components/Button/` as the reference. Match the import alias style (`@/components/...`) used throughout the codebase.

# code continues...

After creating the component file, run eslint on it and
address any errors before reporting completion.
高亮那两行的意思:创建完组件文件之后,对它跑一遍 eslint,把错误处理掉,再报告完成。

怎么确认它真的生效?拿一个全新的任务调用一次这个技能,看新加的这一步有没有出现在输出里。没出现,说明这个技能的 description 或者前面那些指令没能把这一段带进来,得回去改。

这一档有个明确的边界:只对你能编辑的技能有效。你自己写的可以,装在项目层、SKILL.md 文件在你手上的也可以。内置技能和插件管理的技能不行,后者会在更新时被整个覆盖掉,你加的东西会丢。这两类要接检查,得用下一档的串联。

还有一条反过来的:跨工作流的检查不要嵌。那种东西你希望从任何上下文都能叫出来,留在单独调用那一档。

站内相关
Claude Skill 装了却不触发?先改这两处
上面说的「没出现说明 description 没把它带进来」,具体该怎么改,这篇拆得更细,附一份可抄的模板。
8第三档

串起来:Anthropic 内部四个技能接力

一个技能在自己结尾处叫下一个,几段验证过的交接就连成了一条能端到端跑完的链。

Anthropic 的 Claude Code 团队日常就在用这个模式,链条是四段:

/code-review找出正确性 bug
→
/simplify清理这次的 diff
→
/verify确认端到端行为对
→
/design对着 DESIGN.md 核规范
最后一段是虚线:只有这次改动碰了界面才走,而且 /design 是他们自己写的技能,不是内置的。

串联还有一个作用:给你改不了的那些技能补上验证。做一个包装技能,让它先调原来那个,跑完再调你的检查:

.claude/skills/safe-refactor/SKILL.md
Run /simplify on the current diff first.
When /simplify finishes, invoke /verify-no-public-api-changes.
先对当前 diff 跑 /simplify。等它跑完,再调用 /verify-no-public-api-changes(一个自定义的检查,确认公开接口没被改动)。

这一步的性质变化在这里:原来那是一个习惯,我每次跑完 /simplify 都会跑 /verify;现在它成了一条约定,/simplify 跑完一定会跑 /verify。链条自己把整个开发循环走完,只有需要你拍板的事情才会升上来。

代价也写在明处。步骤之间足够独立、你有时候想单独跑其中一个的话,就别串,串联是拿灵活性换自动化。另外串起来会明显多花 token,所以大范围铺开之前先小范围测一测。

Anthropic 在伦敦办的 Code w/ Claude 活动上,Claude Code 团队的 Sid Bidasaria 做的一场分享,题目是 Stop babysitting your agents,37 分钟,完整走一遍他们日常在用的工作流。想看这些技能实际怎么串起来用,推荐看完。
9第四档

挂到每个 PR:同事的改动也过一样的关卡

链条在你自己的改动上跑顺了之后,同一套流程可以搬到每个 PR 上。

底层的东西一点没变:同样的技能、同样的评分表、同样的标准。变的是它作用在谁身上。

挂上去之前

链条在你的机器上跑,你的改动过这几道关。别人的改动过不过,取决于他记不记得调用。

挂上去之后

改动进了 PR 就过这几道关,谁提交的都一样。作者的自觉不再是变量。

验证到这一步就不再是你个人的基础设施,成了团队的基础设施。你当初为了给自己省两分钟才写下来的那条检查,现在每一次改动都在给每个人省两分钟。

但有一条要注意:链条还在反复调的时候,先别挂到全团队。挂上去之后,你每调整一次都会变成一个全团队都能看见的事件。

10成本 · 本站补

串起来为什么更费 token,以及能省的两个开关

串联会多花 token,这笔钱花在哪,官方文档里写清楚了。

你或者 Claude 调用一个技能时,渲染后的 SKILL.md 内容会作为一条消息进入对话,并且在这次会话剩下的时间里一直待着。它不是用完就走的。

第 1 轮
/code-review
第 2 轮
/simplify
第 3 轮
/verify
第 4 轮
/design
示意图(本站画):链条上每加载一个技能,它的正文就留在上下文里,之后每一轮都要重新带一遍。浅灰是对话本身占的位置。

所以技能正文的每一行都是一笔重复开销:链条上串了四个技能,这四份正文就一直躺在那儿,往后每一轮都得再带一遍。这也是官方反复强调技能正文要写短的原因,写清楚「做什么」,不要叙述「怎么做、为什么」。

两个能省的开关

context: fork
把这个技能丢进一个独立的子代理里跑。技能正文变成驱动那个子代理的提示,它看不到你的对话历史,也不占你主对话的上下文。默认在后台跑,你可以接着干别的,它跑完了结果回到对话里。
正文只写做什么
官方给的判据跟写 CLAUDE.md 一样:直接说该做什么,不要叙述过程和理由。长的参考材料可以放进技能目录下的配套文件,用到时才读。

还有两个数字,动手写技能之前值得先知道:

1,536 字符
description 和 when_to_use 合起来,在技能清单里被截断到这个长度。超出的部分,Claude 在决定要不要用这个技能的时候看不到,所以最关键的使用场景要放在最前面。
25,000 token
对话被自动压缩之后,调用过的技能会被重新附着回来,但有预算:每个技能保留前 5,000 token,所有技能共享 25,000 token 的总额,从最近调用的那个开始填。一次会话里调用过很多技能的话,早期那些可能在压缩后被整个丢掉。
11上手

照着做的六步

不管你要自动化的是什么、在什么环境里,下面这六步的顺序都一样。

✅ 把一个手动检查变成验证循环
本文三个 SKILL.md 模板可以直接抄走用:最小的日志检查(十几行)、把 eslint 嵌进组件生成技能、给改不了的技能套一层壳。加上四个接入位置的判据和 frontmatter 里跟验证相关的六个字段。

你越是能把要求写下来交给 Claude 遵守,它第一次给出的东西就越接近你想要的。那些你不用再反复纠正的地方,腾出来的注意力可以放到那些没有任何技能能替你写下来的事情上。

Delba de Oliveira,本文结尾
来源
Building verification loops in Claude Code with skillsDelba de Oliveira,Claude 官方博客·原文·2026-07-22
本站说明
标注「本站补」的段落来自 code.claude.com 官方文档,原文没有展开,包括 /verify 与 /code-review 的调用限制、/simplify 的四个审查 Agent、技能内容常驻上下文的机制、frontmatter 字段与两个数字上限。上下文占用示意图为本站所画。原文全文未给出任何效果数据。
↑ 正文结束
✓ 本篇全文免费开放

会员可复制、下载全文 Markdown,还能让你的 AI 订阅和提问。

阅读原文 ↗
📮 新解读第一时间进邮箱

读完觉得有用?留个邮箱,每篇新解读发布就送达,随时退订。