如果你希望编码智能体每次都做同样的事,比如对二十个文件执行相同的重构,或者按固定顺序跑部署流程,那么只靠Markdown文档是不够的。智能体天生倾向于探索和自由发挥,它们会读你写的贡献指南、规则文件、运行手册,然后说“我读了文档,会尽力遵守”。但“尽力”意味着判断,而判断就可能偏离。

Markdown文档本质上是建议,不是约束。你写“使用仓库现有的日志约定”,智能体得猜是哪个约定、在哪儿;“函数要小”,多小算小?“推送前跑测试”,哪些测试、什么命令、哪个环境?文档越多,智能体需要解析和权衡的指令就越多,冲突时它只能靠猜。猜对了是运气,猜错了就是事故。

更可靠的做法是把偏好翻译成确定性动作。比如把“读文档并遵循代码风格”变成“运行lint、format、typecheck这三个脚本”。智能体执行后得到通过或失败的结果,失败时看到具体错误,没有解释空间。把“做重构”变成“运行某个转换工具”,工具按设计更新文件,智能体不需要决定改哪些文件。这样你就把智能体框进了一系列确定性的动作里。

这不是要降低智能体的智商,而是让环境没有歧义。智能体仍然可以聪明地读失败信息、修正、重跑测试,但它不能跳出这个框。框就是一系列要么通过要么失败的命令。

有一个实际例子:某位开发者觉得AI模型的回复不容易读,于是把航空维护手册用的简明英语标准ASD-STE100加进了智能体的Markdown规则,其中一条是“句子不超过20词”。后来他把这条规则写成了脚本。让智能体用这个脚本检查自己一次会话中的10条回复,结果发现了9处违规。脚本是在回复写完之后才运行的,因为之前没有任何机制强制提前跑。所以这个脚本应该放进钩子里,在生成回复时自动触发。

另一个例子来自CI。一位不写Ruby的开发者给Forem项目提交修复,他的编码助手写了代码和测试。第一次CI运行失败了,问题出在测试而不是代码。这个结果不依赖助手对自己工作的评价,是客观的。但CI也放过了一行未使用的代码,只有人工评审才发现。这说明检查只能框住它测试到的东西。

所以,如果你想让智能体可靠,不要停在Markdown文件上。把每个“请记得”变成命令,每个“我们偏好”变成检查,每个“推送前”变成pre-push钩子。智能体可以跳过本地钩子,所以还要用必需的CI任务和合并门禁来兜底,并且让智能体没有权限修改这些门禁。如果检查失败,智能体可以修正后重跑。这就是把智能体框进确定性序列的方法。它不是建议,是契约。智能体无法交付未通过检查的工作。

具体操作上,你可以先盘点现有文档里那些模糊的指令,把它们分类:哪些能写成一条命令,哪些能写成一段检查脚本,哪些能挂到钩子上。对于代码风格,用现成的lint工具加配置文件,而不是用文字描述。对于提交信息格式,写一个校验脚本。对于测试,明确命令和范围。把这些脚本放进Makefile或package.json的scripts里,让智能体只需要运行它们。然后配置pre-commit和pre-push钩子,再在CI里设置必需检查,并保护分支规则防止智能体绕过。

当然,脚本不是万能的。它只能检查你写进去的规则,无法覆盖设计决策、可读性等主观判断。而且编写和维护脚本本身需要成本,规则变化时脚本也要更新。但对于重复性高、容错率低的任务,这种投入是值得的。智能体仍然可以发挥探索能力,比如在脚本报错后尝试不同的修复方式,但最终必须通过同一套检查。这样你既利用了智能体的灵活性,又守住了底线。

Logo

更多推荐