终端退出码为零之前:把 AI 验收写成省钱脚本
把“看起来完成了”换成终端证据
每天在编辑器里让 AI 改代码,最贵的环节通常不是第一次生成,而是后面的来回解释。“这里不对”“再完善一下”没有明确终点,模型只能继续读文件、猜需求、重写实现。省钱的起点不是缩短提示词,而是让每一轮都有可判定的结果。
我现在接到任务,先写验收,再让代理动手。标准很简单:它能否在没有我补充判断的情况下,运行命令、识别失败,并证明修复有效?如果还需要我看一眼才知道对不对,这条标准就没有真正闭环。
给导出接口写四条可执行契约
假设任务是给订单服务增加 CSV 导出。“支持筛选,格式正确,不能泄露数据”听着完整,实际每一句都有歧义。我会把它改成下面这样的契约,并在仓库中预先准备对应的测试夹具。
- 使用固定订单夹具请求导出接口时,响应状态必须为 200,且内容类型必须包含 text/csv。
- 使用指定起止日期筛选订单时,导出结果必须包含边界日期记录,并排除范围之外的记录。
- 订单备注包含逗号、双引号和换行时,导出内容必须能被现有 CSV 解析器还原为原始字段。
- 使用另一个租户的身份请求导出时,响应中不得包含当前租户的任何订单编号。
这里最重要的不是条数,而是输入、动作和断言都有落点。日期是否包含边界、时区如何处理、空结果是否保留表头,都应该提前定下来。否则模型跑通测试,也可能只是在验证自己的猜测。
让一条验收命令覆盖准备、执行与退出码
在这个项目里,我会先配置 npm run test:acceptance,让它负责启动隔离数据库、装载固定数据、执行接口测试并清理资源。测试使用固定时钟和明确时区,不依赖线上账号、真实付款或临时网络状态。
再把 npm run typecheck 和 npm run lint 加进完成条件。约定这些脚本已经存在,全部成功才算通过;命令缺失、数据库连不上、测试被跳过,都不等于验收成功。环境错误应该单独报告,不能包装成产品缺陷,更不能被忽略。
我的任务说明通常还有一句:先运行验收并记录基线,再修改实现,最后重新运行全部检查。给已有功能补回归测试时,还要确认测试能在缺陷版本上失败。一个从未见过红灯的测试,可能根本没有测中问题。
锁住断言,避免 AI 自己降低过关门槛
让 AI 自验,不等于让它自己出题、自己评分。我会明确保护验收文件:未经确认,不得删除断言、扩大允许误差、增加跳过标记,或者修改预期结果来迁就实现。确实发现契约有错,就先停下来说明矛盾。
结束报告也固定格式:修改了哪些文件、运行了哪些命令、各自退出码是什么、还有哪些未验证项。终端日志才是证据,“应该可以工作”不是。对于权限和金额计算这类高风险逻辑,我仍然保留人工审查;自动验收只能证明已经编码的约束。
用失败摘要控制下一轮令牌支出
失败后,我不把整个仓库和几千行日志重新塞回上下文。先定位到具体断言,再提供失败输入、预期值、实际值和相关文件路径。完整日志留在本地,需要时再读。这样下一轮修复围绕一个确定问题展开,而不是重新理解整个项目。
还要给循环设预算:连续两轮没有减少失败项,就停止修改,提交阻塞原因。依赖缺失、需求冲突、外部服务不可用,都不适合用更多生成来硬撞。少一次无效重试,往往比删掉几行提示词更省。
沿用同一份验收契约比较模型成本
在 Fluxo 上,我可以用一个密钥和一个基础地址 https://api.fluxorelay.com,接入 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen、Grok 等系列。Claude Code、Codex、Gemini CLI 和任何 OpenAI SDK 都能沿用这套接入方式,验收脚本则留在仓库,不跟着工具切换。
例如,边界明确的小修复先交给 DeepSeek V4 Flash;遇到跨模块约束,再尝试 Claude Sonnet 5.5。这不是预设谁一定更便宜,而是用相同契约记录通过率、重试次数和实际用量,再决定任务分配。
Fluxo 没有月费,按实际令牌用量计费,缓存读取和写入也计入账单。因此不能只比较最后一轮输出:需求、重复上下文、失败重试和缓存用量都要算。邀请他人后,对方付费会带来推荐分成,但我会把它单独记账,不拿它掩盖任务本身的成本。
如果你想用一个真实任务试试,可以创建一个 Fluxo 账号,把现有验收脚本接进自己的终端流程。需要帮助时,登录后在联系页面留言即可。
提交前留下能重复运行的完成证明
我希望最终提交里留下的不只是实现,还有下一次能复用的验收入口。需求变更时改契约,回归时跑同一条命令,换模型时保留同一把尺子。真正省钱的工作流,是把“你再看看”变成一次可复现的失败,把“已经做好”变成一组可核对的证据。