在第二篇里,我们理清了文档为什么要抛弃横向分层,改为按"项目、模块、功能"三层纵向组织。很多人看到这里的第一反应是:结构设计得很清晰,那我们马上叫团队按照这个新模板来写文档吧。
可以让人来写吗?可以。但完全没有必要。
如果还是让人来手动维护这套结构,这套体系就失去了最大的意义。传统文档之所以长期滞后于代码、互相矛盾,根本原因就是依赖人在高频的开发节奏中手动对账。而在 AI 编码时代,AI 一下午能生成二十个功能的代码,如果仍然让人去手动更新文档,人就会成为整个研发链条上最慢的那个物理瓶颈。
既然我们已经把新文档的结构定死了、段落定义明确了、约束边界清晰了,那维护文档这件事,就完全可以、也应该交给 AI 来做。
所以,为了让这套文档体系真正运转起来,我们应该为它规划一套专用的工具。这套工具的作用,就是让 AI 能够按照严格的格式去读写文档、自动追踪约束,而不是让人打开 Markdown 编辑器去敲字。第二篇结尾那句"每一条必须遵守的硬约束...决不能靠人工评审兜底",说的就是这套工具链。
但这套工具链并不是一开始就在图纸上设计完美的。今天的形态,是经历了我们在自己的项目中使用演化出来的。这套东西从 v0 迭代到现在经历了十几个版本,下面我挑三个踩得最疼的坑。
回头再看,这三个坑恰好对应了工具防线失效的三种形态:没装上、装错了、装晚了。
一、能力层失配:防线根本没装上
有个项目上,我将执行工具链升到了新版本,但隔了几天才去更新配套的模型能力文件。两边都没报错,一切看似正常。
问题出在创建一个"议题"时。议题是我们利用工具维护文档的核心动作:把待讨论的技术方案列出来,逐条评审,选定后才由工具落盘。那天创建出来的待评审议题,选项莫名其妙少了两条。
误判:我的第一反应是模型漂移。以前发生过这种事:模型在重组内容时,把旧条目当成过时信息给清理了。为此,我曾专门在提示词里加过一条硬约束------待评审议题的内容只能增,不能减。可这条规则这次失效了。
原因:一路查下去发现,问题根本不在模型。执行工具升了级,但模型侧的能力文件没跟上:旧能力文件里根本没有新工具的调用说明。而那条"只能增不能减"的审核约束,恰恰挂载在一个需要新工具标识的基础层上。由于缺乏新标识,整条审核规则根本没被加载进入上下文。
更棘手的是,底层工具确实报错了,但链路里第一个截获报错的是模型,而不是人。模型遇到调用失败,直接换种写法继续尝试,报错就这样被 AI 默默消化了。
防线:此后,我不再把工具升级当成"替换一个二进制文件"。能力层、指令层、版本声明被强绑定为一个完整的发布单元:要升一起升,少一层直接拒绝启动。
判断:防线的存在,不等于防线的运行。 写在文件里的约束不叫防线,被成功加载到上下文里的才叫防线。前者是静态的文档问题,后者是动态的运行时问题,往往失效的偏偏是后者。
二、接口能力错配:防线的入口装错了
有一回我用工具更新系统日志库的文档。本意是新增一节"审计通道",同时保留原有的"运行日志"章节。
现象:AI 生成时,我扫了一眼工具调用日志,看到它往"运行日志"那一节传了一个空内容。当时没在意。但打开文档一看,原本好好的"运行日志"整节消失了。
误判:回退,重做。第二次我死盯着看,同样的地方,同样是空内容,同样整节消失。我最初以为又是模型漂移,指望重做一次能撞大运。但连着两次精准踩坑,不能再归结为偶然。
原因:原因在工具的 API 设计上:写入工具不判空。传空内容进去,底层逻辑就等同于删除该段落。写入和删除共用了一个入口------空值同时承载了"这次什么都不做"和"把这段全删掉"两种截然相反的语义。
站在 AI 的视角,它只想原样保留那一段,最符合直觉的写法就是传空(因为它觉得,我既然不修改就没有必要重新生成一遍)。底层工具收到了空值,忠实地执行了删除。而且,我们的文档对段落结构要求极其严格,规整的结构让"按结构替换整段"成了一个看似极其安全的操作。但这恰恰掩盖了风险:操作容易,并不代表操作正确。
防线:随后,"写"和"删"被彻底拆分为两个独立的方法。写入操作严禁传空值,删除则变成了一个必须显式调用的高危动作。
判断:破坏性语义绝不能藏在默认值里。 一个参数留空,人默认理解成"不改",工具却理解成"清空"。不可逆操作必须在入口处显式拦截,绝不能指望调用方(无论是人还是 AI)靠默契记住"不要传空"。
三、提交粒度:防线装晚了
这个严格来说不算代码坑,而是思维惯性的代价。
现象 :有一次某个技术方案需要调整,我打算把几天前的一笔 feat 提交整体回滚。结果发现根本回滚不了------那次提交里,揉进了一次文档更新、两个新功能,外加一个顺手重构的接口。回滚意味着要把这一锅全倒掉,而其中一半的代码我是要保留的。
误判:如果是传统手工开发,我大概率也会图省事,把一下午的工作合成一个 Commit。我一直以为一次提交代表一个开发意图,回滚就是回到这个意图发生之前。
原因:AI 工具彻底击碎了这个前提。AI 一下午能同时完成文档修订加三个功能,这些事在物理时间上是同时发生的,但在逻辑意图上是完全独立的四件事。当我按照"这次干了多少活"去切分提交时,切出来的根本不是逻辑意图,而是物理时间段。
防线 :后来的提交流程改成了按 pathspec 加语义拆分:新增功能feat、重构逻辑refact、消缺fix、更新方案docs、测试用例test、杂项chore,各自独立成一次提交。而判断语义、划分范围的工作交给了 AI------它能精准读懂这次 diff 里哪些是新增、哪些是重构,比人眼扫得准得多;人只负责审核拆分是否合理,不再手动执行。
判断:提交粒度必须按"可能被单独回滚的最小意图"切分,绝不能按"这次干了多少活"切分。 你以为 Commit 是在记录"我做了什么",它实际决定的是"将来能单独撤销什么"。一次提交混入了多个意图,就永久丧失了单独回退其中之一的权利。这个权利不是在回滚那天丢的,而是在敲下 Commit 的那一刻就丢了。
结语
这三个坑有一个共性:全程没有任何人看得见报错。 第一个的报错被模型吞噬,第二个的删除是"成功"调用,第三个的"一锅炖"提交在当时看完全合规。它们全都是事后追查时才显露原形的隐患。
所以工具的职责,绝不仅是替 AI 做得更快,而是让隐性错误不容易发生,或者一旦发生必须尽快显形------这也是harness的本质。
诚实地说,这套体系依然管不住"人没想到要建的防线"。这三个坑,全是用真实的事故换来的认知;那些还没出过事的地方,大概率依然是一片盲区。工具能兜底已经被写下来的规则,但兜底不了还没被想到的。
下一篇,我将逐个拆解这 8 个 SKILL:开发能力包具体解决了什么问题、背后藏着哪条判断,以及你如何才能在真实项目中跑通它们。