一句"看看这个页面"给审查者留下太多要自己拿主意的地方:是找行为上的错误,还是评估界面,或者干脆建议换种写法。回来的可能是一份整整齐齐的意见清单,却帮不上您手头的任务多少忙。我们来看看,怎样给 Claude Code 的 subagent 布置一份清楚明白的任务,再核对它是不是真的做到了。

如果 reviewer 这个角色还没配置好,先建好这个角色并跑一遍。这里只讲任务书本身,以及怎么判断回答够不够完整。

1. 该给审查者哪些信息

审查者检查别人的成果,回来时带着意见和支持这些意见的证据。在我们的例子里,这是一个配置好的自定义 subagent,名字叫 reviewer,只能读文件、搜文件:Read, Grep, Glob。它研究代码,但不会去改,也不会在浏览器里打开页面。叫它 reviewer 并不会自动生成这个角色,我们假定您的项目里已经配置好了。

按常规方式重新启动时,这样的 subagent 不会自动拿到您全部的对话历史。跟您对话的主智能体会单独给它写一份任务。所以像"两件同名商品算作两条不同的记录"这样的重要条件,必须写进任务书,或者写进一份专门让审查者读的文档里。这一点在关于 subagent 上下文的文档里有说明;这里说的是启动一个自定义角色,不是那种带着对话副本的 fork。

比较一下"看看这个项目"和"检查删除条目和计数器更新的逻辑;代码不要改"。第二种说法已经点明了该看哪里、不希望它做什么。剩下的就是说清楚,怎样的结果才算对。

别给智能体一个太宽泛的任务

这句话我们说过,还会再说一遍:别给智能体一个太宽泛的任务。让它"做得更好一点",指望它自己猜出您的意思,这是个常见的坑。任务写得越宽,留给它自己拿主意的地方就越多。它可能自作主张替您把需求补全,把时间花在您根本不需要的地方,比如把整个页面重做一遍,而不是去检查计数器。启动之前,先讲清楚要拿回什么结果、什么可以改、什么绝对不能动。要是缺了什么重要条件,就让它开口问。

短平快的一次性检查,一条消息就够。要是条件比较多,或者修完之后还要反复检查,不如保存一份任务书:跟项目放在一起的一段简短说明。不是十页纸的规格文档,而是几条没有它审查者就只能瞎猜的条件。

不可能提前想到每一个问题,也不必这样。输入信息不够的时候,审查者应该在报告里点明这个缺口,主智能体再回头向您确认。写得好的任务书能减少理解上的分歧,但不能保证答案一定对:任务再清楚,模型也可能出错。

2. 任务书的四个部分

目标回答的是要检查哪种行为。对购物清单页面来说,就是添加、删除和条目计数器。"把项目做得更好"太宽泛了:完全不清楚现在哪项改进才是重要的。

输入指明文件和预期行为。如果光看代码看不出是否允许重名,那单单给一个 app.js 的路径是不够的。这是产品层面的决定,得明说。同时也说清楚用什么方式检查:我们这里就是只读代码,不动浏览器。

边界把这次检查和相邻的任务分开。比如,样式、移动端表现、跨会话保存清单,现在都不在这次检查范围内;文件不要改。要是缺了需要的文件,就停下依赖它的那部分检查并说明情况,而不是自己编一份内容出来。

结果描述您想要拿回什么:检查过的范围、有证据支持的发现,以及限制。不要要求它一定得挑出五个问题。Claude Code 关于审查的建议专门提到过这种提法的风险:让它去挑毛病,会把它往找意见的方向推,哪怕工作其实做对了。

目标、输入、边界和预期结果汇成一份给审查者的任务书目标检查什么输入文件和要求边界排除项和禁止项结果报告要返回什么一次检查的任务书消息或文件REVIEW_BRIEF.md
四个部分汇成一份任务书

每条分支都补上了别的分支给不了的东西:文件路径说不出预期行为,目标也定不出改动的禁区。把这些条件收在一起,审查者检查时才能拿它们互相对照。

所以,与其说"检查购物清单页面",不如交出下面这份任务书。可以直接发消息,也可以存到项目根目录的 REVIEW_BRIEF.md 里:

# 购物清单检查
目标:通过代码检查添加、删除和计数器。
输入:项目根目录下的 index.html 和 app.js。
预期:添加的条目会出现在清单里;
计数器等于条目数量;删除一条记录
不会删掉另一条同名记录。
边界:不改动文件;样式、移动端表现和跨会话保存清单
不在这次检查范围内。
如果缺了需要的文件或需求,说明这个缺口,
不要自己编,按能检查的部分交结果。
结果:按 reviewer 的格式来;说明检查过什么、
还有什么没检查。没有发现问题也是可以接受的结果。

reviewer 的格式马上在下面讲。要是您这个角色还没有固定格式,也可以直接放进这条一次性消息里。字段名不是必须的,重要的是它们提醒您别漏掉的那些信息。

"报告里先列三个最重要的发现"这种要求限制的是回答的篇幅,不是检查的深度。要是需要这样的上限,另外让它说明是否还有别的发现。查到第三条意见就停下、宣布任务已检查完毕,这样不行。

3. 什么该写进文件

具体任务的条件一直在变:今天查计数器,明天查清单的保存。这些放在任务书里。而要求它标出错误位置和根据,几乎每次审查都要用到,写一次放进角色说明里更方便。

Output contract,也就是结果契约,这里指的是双方谈好的回答格式。名头听着挺唬人,其实就是给审查者的普通说明,不是 Claude Code 的特殊设置,也不是自动的质量检查。这种格式能帮您在报告里找到需要的信息,但不能让这些信息变得可信。

审查者结合任务书里当前任务的条件和角色说明里固定的回答格式,再给出一份供检查的报告当前任务的任务书REVIEW_BRIEF.md现在要检查什么、范围有多大角色说明.claude/agents/reviewer.md包括固定的回答格式reviewer按任务书检查代码供您检查的报告范围、发现、根据、限制
条件随任务而变,回答格式留在角色说明里不变

上面两条分支各管各的事:任务书定检查的内容,角色说明里定的东西也包括报告的形式。要让审查者用上保存好的任务书,得让它去读那个文件;它自己不会主动看。到了下面,出来的是一份报告,它的根据和完整程度还得您自己判断。

下面是可以加进已有角色文件 .claude/agents/reviewer.md 正文部分的一段,放在它的配置之后:

## 结果格式
列出检查过的文件和标准。
对每个发现:说明位置、预期行为、根据、
检查条件和影响;优先级要解释清楚。
把代码已确认的和未经检查的推测分开。
限制和缺失的数据要单独说明。
按标准没找到问题,就照实写出来。

这只是说明的一个片段,不是完整的 subagent 文件。我们这个角色只能读和搜,所以不需要固定的"改动了哪些文件"这一栏。在范围更大的报告里,关于改动的说明必须如实反映情况:不能不管实际发生了什么,都预先写死"改动的文件:无"这一行。

任务书保存好之后,给主智能体发这样一条请求:

让 reviewer 读一下项目根目录的 REVIEW_BRIEF.md,
按它里面的标准检查提到的那些文件。
把最终报告完整地返回给我。

我们明确要求它去读那份文档,而不只是提了一下文件名。不过文件本身不能保证什么:审查者还是有可能漏掉某个条件。保存好的任务书好处在于,可以拿它对照结果、重复检查。要求变了,先更新文档,不然下一轮检查的还是旧任务。

4. 怎样检查报告

先看看实际检查了什么。任务书里有添加、删除、计数器,还有同名记录互不影响。要是报告只说了计数器,那还算不上整个任务的结果,哪怕那唯一一条发现完全正确。

把任务书里的每条标准和回答对一遍很方便。比如,在我们这个学习用的部分报告里,情况是这样的:

任务书里的标准报告说了什么缺了什么
添加条目按代码检查过,没有意见关键路径可以自己核对一下;没说有没有实际跑过
删除和计数器有一条发现,带位置和根据决定要不要修之前,先核实一下根据
两条同名记录没提到问清楚这条标准到底查没查

没有关于同名记录的那一行,不代表那里就没有问题。同时,一条有根据的计数器发现,也不能算是补上了漏掉的那部分任务。带着具体的追问把报告退回去:

任务书里有删除两条同名记录中一条的要求。
报告里没有反映这条标准。用现有手段检查一下,
说明结果的根据,或者说明为什么没能检查。
其他结论不用重复说一遍。代码不要改。

再单独评估一下重要发现是否可信:把指出的位置、需求和结论的根据放在一起对照。关于解读审查报告的文章里有详细的例子。这里需要两种检查:任务覆盖得够不够,结果站不站得住脚。给出的测试方案,不等于已经跑过的测试。

先检查任务覆盖情况和数据够不够,再检查结论的根据;之后要么接受结果,要么退回去要求补充说明报告任务覆盖全了、数据也够吗?结论有根据、又跟任务相关吗?接受结果要求补充,或者评估后只接受已检查的部分要求补充根据,或者驳回错误的结论是是否否
检查的覆盖范围和结论的正确性分开评估

第一个岔路口决定的是,对我们这个任务来说,检查够不够。要是不够,就要求补上缺的部分,或者只接受已经检查过的那部分,同样先评估它的根据。第二个岔路口区分的是有根据的结论和存疑或者错误的结论。根据不清楚的值得追问;已经证明是错的意见,或者跟任务无关的建议,可以驳回。

没有发现问题的报告,也可能通过这道检查。比如:"检查了 index.html 和 app.js 里添加、删除的路径,同名记录互不影响,还有计数器的更新。按这些标准没找到问题;没有在浏览器里跑过。"这样的结论并不是保证项目里完全没有 bug。它说的是在写明的范围内的结果,需要的话,关键路径您可以自己核实。

而"按给定路径没找到 app.js,删除行为没法检查"这句话,意味着数据不够,不是没有 bug。这时候要给出正确的路径,让检查继续下去。一句诚实的短回答,比一份把缺口藏起来的长报告更有用。

要是拿到的不是报告,而是一堆改动

先暂停后续的改动,看看文件里到底改了什么。一句"我什么都没改"代替不了对实际改动的检查。也别下意识地把所有东西都回滚:旁边可能正放着您还没做完的工作。违反不许改代码的约定,这事得单独处理,但这本身不能说明查出来的 bug 就是假的。

接受一份报告,不等于要求把里面列的东西全都修一遍。您只是认可了检查结果是有根据的;现在到底改什么,是另外一个决定。

5. 什么时候需要再来一轮

要是报告里缺根据,不必从头再审一遍,退回去说清楚具体缺什么就行。比如,关于计数器那条发现的简化版本,只写了 bug 的名字,没有捋一遍调用链。这时候给主智能体的请求可以是这样:

把报告退回给 reviewer 要求补充说明:关于计数器的发现
没有说明删除之后计数器在哪里更新。
让它检查这条路径,给结论补上根据。
代码不要改。

要是发现更新其实已经在另一个函数里做了,这条意见就该撤掉,也不要为了凑够原来的条数另找一条顶上。要是 bug 确认了,可以另外发一个请求,让主智能体去修,明确指出具体是哪条发现、允许改动的范围有多大。

修完之后,按同一份任务书再走一轮很有用:

让 reviewer 重新读一遍 REVIEW_BRIEF.md,检查
现在删除和计数器的代码。之前的发现是:
删除之后计数器没有更新。
让它说明问题是不是已经解决、结论依据是什么,
再检查一下同名记录是否还保持互不影响。
代码不要改。

现在要找的是一个具体问题的答案:问题是不是已经解决了,改动有没有影响到旁边的行为。要确认页面上的实际表现,自己在浏览器里再跑一遍同样的场景。要是这一轮审查只看了代码,这个限制在新报告里依然存在。

报告可能变短、变长,也可能没有新的发现,成功与否不在于此。重要的是,原来的缺陷确实解决了,结论建立在当前代码上,没检查过的部分依然清清楚楚。决定先把修复往后放?那就保留已确认的发现和推迟的理由;对着没改过的代码再审一遍,只为了拿到一个不一样的答案,没什么意义。

6. 从一份任务书到一个检查过的结果

用 Claude Code 干活的时候,主智能体把任务转给审查者的这段时间里,任务书帮您把最初的预期保留下来。固定格式让回答更容易读懂。但您还是有自己的活要干,具体是这些:

  • 主智能体写好任务书,转给合适的角色;您定的是预期行为和边界;
  • 审查者研究文件,交回结论的根据;而覆盖范围和重要发现,靠您自己去检查;
  • 主智能体可以另外发请求去追问报告,或者修一个已确认的 bug;改什么、怎么确认结果,由您来定。

对购物清单来说,最后的结果不该只是一句"加个函数调用"这样的建议,而是一份检查过的解释:什么操作下数字变旧了,更新在哪个环节被破坏了,修复之后又改变了什么。有这样的结果,才好接着干活。