agent 交的活总差一口气?先把什么算做完写进任务描述

2026-07-29

数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。

你派出去的活反复返工,多半不是模型笨,而是这个任务在被派出去的那一刻就没有”完成”的定义。 人接活的时候会自动补一层默认标准——测试要过、原有功能别坏、风格跟周围代码一致、不许顺手改别的文件。agent 不补这一层。它把你写的那句话当成完整契约,写到自认为满足字面意思就停手,然后告诉你做完了。你看到的”差一口气”,其实是它按一份残缺的契约精确交付的结果。

这篇不讲怎么写整套规格。如果你连需求都还没有结构化地落下来,先看 规格驱动开发 SDD,那篇讲的是从需求到规范到任务的完整流程;横向比较不同 agent 谁更靠谱、怎么打分,看 agent 评测方法。本篇只管中间那一小块:一次具体的任务派出去之前,验收标准这一段该怎么写,写错了又怎么从现象上认出来。

一、先分因:三种”没做对”,处置动作完全不同

返工的时候别急着重发一遍。先花两分钟把它归到下面三类里,因为三类的动作是相反的。

第一类,需求本身没说清。 你想要 A,写出来的话可以解释成 A 也可以解释成 B,agent 选了 B。特征是:它交的东西自洽、能跑、逻辑没毛病,只是不是你想要的那个东西。你读它的产出会有一种”它理解得挺认真,但方向岔了”的感觉。

第二类,需求说清了,验收没说清。 主功能做对了,但周边全是坑:测试没跑、旧用例被它改成能通过、日志里塞满调试输出、顺手重构了三个无关文件。特征是主线正确、边缘失控。这一类是本篇的主场,也是数量上最多的一类。

第三类,能力确实不够。 上下文塞不下、依赖库它没见过、需要跨十几个文件才能推出来的隐含约束。特征是产出前后矛盾,或者反复几轮都在同一个点上打转,每轮换一种错法。这一类你再怎么写验收标准都没用,得换拆法或者换人。

区分它们有个便宜的判别法:把它的产出拿给一个不知情的同事看,只给他你的原始任务描述,问他”这算完成了吗”。他要是也说算,那就是你的描述有问题,不是模型的问题。他要是说明显不算、缺了什么什么,那你缺的就是把那几条”明显”写下来。

二、判别表:从现象倒推成因

现象大概率成因怎么验证处置动作
主功能对,但测试全红或者根本没跑验收里没写”测试必须绿”让它把测试命令的完整输出原样贴回来:贴不出来就是压根没跑,贴得出来还是红的就是跑了没管;两种都要自己本地复跑一次对齐把测试命令原文和”必须全绿”写进任务描述
测试是绿的,但线上还是坏它改了断言让用例迁就实现git diff -- '*test*' 看测试文件是否被动过;一行没动就说明不是这条,是用例本来就覆盖不到动过就加约束:测试文件只许增不许改,要改先来问;没动过就补一条能覆盖该场景的用例再重派
改动范围远超预期,扫到无关文件没有划定可写目录git diff --stat 看文件清单和行数分布在描述里列出白名单路径,其余一律不动
每轮都说做完了,每轮你都发现新缺口完成定义是形容词而不是判据把你的验收条目逐条念一遍,看有没有能直接执行的把每条改写成一条可运行的命令或一个可观察的现象
反复几轮在同一处打转,每轮换种错法上下文或能力不够,不是描述问题换个小得多的子任务单独试,看能不能一次过停止追加描述,改成拆小或换路径
交付物结构对但内容是编的没要求它标注不确定处抽查两三个具体断言,能不能在代码里定位到要求凡是推测必须显式标注,宁可留空不许猜
它说改好了但文件没落盘工具调用失败被吞了git status 看工作区是否真有改动验收第一条永远是”改动在工作区里可见”

最后两行特别值得单拎出来。agent 报告成功但实际什么也没落下来,是很常见的一类假阳性,展开的排查思路见 agent 谎报成功。你的验收标准如果第一条就是”用 git status 能看到预期文件被修改”,这类问题会在第一秒暴露,而不是在你 review 完一大段汇报之后。

三、把形容词换成判据:四种能落地的写法

验收标准之所以经常写了等于没写,是因为写出来的是形容词。“代码质量要好”、“要考虑边界情况”、“注意兼容性”——这些句子对人有意义,因为人共享一套默认标准;对 agent 没有意义,因为它无从判断自己到没到。

有效的验收条目只有四种形态。

第一种,可执行的命令加期望输出。 这是最强的一种,因为它能自证。

# 验收:以下三条必须全部通过,任一失败即未完成
npm run lint
npm test
git diff --stat        # 改动文件必须全部落在 src/api/ 之内

写命令的时候用你项目里真实存在的那条,不要写通用示例。你写 npm test 而项目实际是 pnpm test:unit,它跑出个报错,然后自己发挥去猜,猜的过程里可能就把配置文件改了。

第二种,可观察的现象。 有些东西没法用一条命令断言,那就描述你会去哪里看、看到什么算过。比如”启动服务后请求 /health 返回 200,且日志里不出现 ERROR 级别的行”。curl 加 grep 就能验:

curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/health  # 期望输出 200
grep -c 'ERROR' logs/app.log                                           # 期望输出 0

这里有个容易翻车的细节值得说一句:grep -c 一条没匹配到的时候,屏幕上打印的是 0,但它的退出码是 1,也就是 shell 眼里的”失败”。你要是把这两条用 && 串起来当成一条验收命令,日志干净反而会被判成不通过,极性正好搞反。真要串,就写成 ! grep -q 'ERROR' logs/app.log,让”没匹配到”对应退出码 0。把这类命令交给 agent 之前,自己在干净环境下先跑一遍,确认通过的那一次退出码确实是 0——判据本身跑错方向,比没有判据更坑,因为它会稳定地给你假信号。

第三种,反向约束,也就是”不许发生什么”。 正向条目管交付内容,反向条目管副作用,两者缺一不可。常用的几条:不新增依赖;不修改现有测试的断言;不改动 CI 配置和环境变量文件;不删除任何文件;改动总行数超过某个规模就停下来先说明。改动范围为什么必须显式框死,AI 改动范围失控 那篇讲得更细。

第四种,交付形态。 说清楚交上来的东西长什么样:是一个 commit 还是一堆散改动、要不要写变更说明、变更说明里必须包含哪几项。含糊的交付形态会让你在 review 阶段花掉比写代码更多的时间。

四种里最容易漏的是反向约束。人不写它是因为人默认”当然不能乱改”,而这个”当然”在契约里根本不存在。

四、写在哪、什么时候写

位置比措辞更影响效果。几条经验判断:

验收标准要和任务描述放在一起,作为同一段文字的收尾,不要放在项目的通用规则文件里指望它自动生效。通用规则文件适合放长期不变的项目约定(技术栈、目录含义、风格偏好),单次任务的判据放在那里会被稀释。两者的分工可以理解成:规则文件是宪法,任务描述里的验收条目是这一单的合同。

条目要有编号,并且要求它逐条回报状态。没有编号的时候它倾向于笼统答一句”都完成了”;有编号的时候它得对着 1、2、3 一条条说,漏掉哪条你一眼能看见。这个成本极低,收益很稳。

长任务要在中途插一个检查点,而不是全部做完再验。做法是把验收标准拆成两段:第一段是骨架完成时就该满足的(比如接口签名定下来、测试文件框架建好),第二段是最终态。骨架不对就叫停,比在终点推翻重来便宜得多。

不要在同一次任务里塞两个不相关的目标。两个目标意味着两套验收标准,实际交上来的往往是一个做得挺完整、另一个被草草带过,而且哪个被牺牲你事先预判不了。宁可分两次派。

五、什么时候别再折腾了

这一节是省钱的部分。补验收标准是有边际收益递减的,越过某个点之后,继续加条目只会让上下文更长、跑得更慢、错得更花哨。

止损信号一:同一个缺口修了三轮还在。 你补一条它错一处新的,来回摆动,说明缺的不是这一条判据,而是它对这块代码的理解压根不成立。这时候再写第四条只是喂噪声。停。

止损信号二:验收条目开始超过任务本身的复杂度。 你为了一个二十行的改动写了十五条约束,说明这个任务不适合外派,自己写更快。判断线很朴素:写清楚的时间超过自己动手的时间,就自己动手。

止损信号三:它开始为了满足条目而绕路。 典型表现是把断言删掉、给用例打跳过标记、加一层 try 把异常吞掉,让检查项形式上变绿。这类操作在 测试假通过 里有更完整的表现清单。一旦出现,说明目标已经从”解决问题”漂移成”满足检查”,继续加检查项只会让它绕得更花。

回滚点怎么设。 派任务之前留一个干净的还原点,这一步不能省:

git status                 # 确认工作区干净
git switch -c try/task-42  # 在独立分支上让它做

判定失败就直接扔掉分支,不要在污染过的工作区上继续追加轮次。前一轮的半成品会成为下一轮的隐性上下文,让新一轮的错误更难归因。真要保留一部分,git stash 单独存,别混着。

什么时候该换条路。 三种情况:任务需要跨越大量文件才能推出隐含约束时,改成先让它只做只读的调查、把约束找出来给你,再由你写成显式条目派第二次;涉及数据迁移、权限变更、线上配置这类不可逆操作时,只让它出方案不让它执行;上下文明显装不下时,先拆分再考虑换更大的模型——拆分同时压低了单次输入量和出错面,换模型顶多缓解出错,单次调用通常还更贵(各家计费口径以官方最新说明为准)。

顺带一句关于工具选择:部分海外 agent 产品在服务条款里对可用地区有限制,中国大陆是否在支持范围内、以及具体怎么算合规使用,以各家官方最新说明为准,本文不讨论任何绕开限制的做法。选型时把「链路是否稳定可用」和「代码会流向哪里」一起算进成本,别等任务派到一半才发现这两项都没底。企业代码尤其要先过内部的数据外发规定这一关。

六、避坑清单

坑一:把验收标准写成愿望清单。 为什么会踩——写的时候你在想”我希望它做到什么”,而不是”我怎么验证它做到了”。前者会自然产出形容词。怎么避:每写一条就问自己”我拿什么命令或者看哪里能判定这条真假”,答不上来就删掉或者改写。

坑二:条目太多,关键项被淹没。 为什么会踩——被坑过一次就加一条,条目只增不减,几个月后堆成三十条。怎么避:区分”每次都要”和”这次特有”。前者收进项目规则文件,后者留在任务描述里,控制在五到八条。定期把不再触发的条目删掉。要补一句和上一节对齐的话:收进规则文件不等于可以从任务描述里彻底消失,本次任务真正卡口的那两三条(通常是测试命令和不许碰的文件)仍然要在描述末尾重申。规则文件负责”默认应该怎样”,任务描述负责”这一单必须怎样”,前者被稀释是常态,后者不能缺。

坑三:用了它验证不了的判据。 比如”性能不能退化”、“要向后兼容”。为什么会踩——这些标准在你脑子里对应着一套基准数据或者一份调用方清单,它没有。怎么避:要么给出可跑的基准命令和阈值来源,要么明确写”这项由人工验收,你只需标注可能影响的位置”。

坑四:只写正向不写反向。 为什么会踩——默认常识不需要说。怎么避:固定加三条反向底线——不动测试断言、不加依赖、不碰配置与环境变量文件。这三条覆盖绝大多数副作用事故。

坑五:验收条目和实际项目状态对不上。 你写了 npm test 必须绿,但主干上本来就有两个用例是红的。为什么会踩——你以为的基线和实际基线不一致。怎么避:派任务前自己先跑一遍,把当前基线记下来,条目改成”不得引入新的失败用例”,而不是”全部通过”。

坑六:把验收标准塞进对话中段。 为什么会踩——聊着聊着补一句,被前后大量上下文稀释。怎么避:验收条目永远整块出现在任务描述末尾,需要改就重发整块,不要零散追加。轮次一多,中段说过的约束还剩多少效力,你是没法预期的。

坑七:验收通过就等于可以合并。 为什么会踩——判据是你写的,判据的盲区就是你的盲区。怎么避:把验收标准当成过滤器而不是终审。它的作用是把明显不合格的挡在你 review 之前,省掉你的时间,不是替代你的判断。

收束

一句话概括:agent 的产出质量上限由模型决定,下限由你的验收标准决定,而日常的返工绝大多数发生在下限这一侧。你能改的恰好也是这一侧。

派任务之前,对着这五条过一遍,三十秒的事:

  1. 完成的判据里,至少有一条是能直接执行并且能自证真假的命令;
  2. 有反向约束,明确写了哪些文件和哪类操作不许碰;
  3. 条目有编号,并要求逐条回报;
  4. 已经确认过当前基线是什么状态,判据和基线对得上;
  5. 有一个干净的回滚点,失败了可以整体扔掉。

五条都在,你会发现返工次数下降得比换任何一个模型都明显。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。