第一性原理 · 第 10 篇

模型负责思考,
程序负责正确

凡是写着「模型应该自觉」的地方,都是未来的事故。

一本标书生成到一半,账单不对劲。查了账才发现问题所在:八百多次工具调用里,六成多是模型在「找路」——找目录在哪、自己该写哪节、承诺值是什么。这些信息全是确定的,模型却在靠读文件猜。

这不是模型笨,是我们把确定性的信息留给它自己去找。这篇讲我们从几起事故里总结出的分工铁律,以及它怎么把一本中型标书的成本从十来块压到三四块。

分工的判据

先说结论:一件事该给模型还是给程序,不看它发生在生成阶段还是组装阶段,看它的性质——

语义判断归模型:理解这条要求在说什么、判断素材跟这一节合不合适、组织语言、决定结构怎么调。

确定性操作归程序:路径、编号、清单值、对账、校验、格式迁移、查重。答案可以明确列出来、逐项核对的,都不该烧模型的钱,也不该赌模型的发挥。

语义判断归模型,确定性操作归程序,判据不是阶段而是性质
语义判断归模型,确定性操作归程序,判据不是阶段而是性质

下面三起事故,每一起都是这条判据的反面教材。

事故一:派发说明塌成七个字

我们的架构是主代理拆解任务、派发子任务写正文。规范里白纸黑字写着:派发说明必须带全上下文——任务路径、写作指引、要求原文、承诺值,缺一不派。

实际跑起来,模型塌成了七个字:「重写表单设计节」。

于是每个子任务开局都要自救:翻文件找指引、找承诺清单、找自己的任务清单,平均每个子任务多烧一倍调用,其中六成是重复探索。纪律明明写了,为什么没用?因为纪律是概率的,模型今天守明天可能不守。提示词改了三轮,没用。

最后的修法是把这件事整个从模型手里拿走:派发说明由程序拼装。模型只写一句话意图,剩下的——输出路径、这一节的写作指引、要求原文和出处、可用素材、承诺清单的全部值、兄弟章节的开头摘要、今天的日期——程序从确定的数据里组装,一个字节都不靠模型复述。修完,每个子任务的调用次数从二十六次降到十四次,同类工作成本降了约六成。

节名对不上目录怎么办?程序宁可整单放行也不猜——拼错了比不拼更糟。

事故二:任务清单几小时不动

界面上有一块任务清单,显示干到哪了。有一次它停在「确认写作指引」,一停几个小时——底下四十多次子任务派发、四波共二十几节都写完了,清单一个字没更新。

工具说明里明明写着「实时更新、完成立刻标」。没用,同一个原因。

第一次修法是在对话里加提醒:清单旧了,模型该更新了。结果提醒天然滞后一大截,有一次清单停了四分钟,正文其实已经在写了。

第二次修法才到位:清单过期,就整批拒绝新的派发,直到它更新;同批自带更新则放行;连续三次拒绝仍不更新,强制放行——防止系统把自己锁死。这次生效了。后来我们还找到一个公开的同行佐证:开源工具 OpenCode 的官方讨论区记录过一模一样的问题——模型执行中不更新任务清单——官方的处理是关闭不修。纯纪律路线的失效,不是我们独有。

事故三:参数写歪

AI 向用户提问时,候选项应该写在一个专门参数里。有一次模型把候选项当成正文写进了问题,参数本身空着——按钮消失,问题里出现一行伪代码。

修法不是「下次注意」,是读写两侧都加机械归一化:不管模型把参数写成什么样,进系统先洗成标准形态。洗不出来的保留原文诚实呈现。改提示词治不了的事,让程序兜住。

两件配套的账

缓存。同样的内容发给模型,命中缓存的按缓存价计,约为新内容十分之一。但缓存按请求开头的字节匹配——不是「意思一样就行」。我们曾把一个秒级时间戳写进系统提示,它每秒都变,整场缓存全废。规矩从此定死:进请求开头的所有内容,整个任务期内一个字节都不许变;日期只到天。

限流。用户可能接各种模型网关,有的只给两三路并发。八个写任务齐发过去,被限流打回来,重试又齐发,死循环。现在系统遇到限流自动降速,恢复后自动回升——限流不是错误,是对方在说「慢一点」。它会自己学出一个网关的真实容量。

还有一条工具层的纪律:工具出错必须返回一句人话错误,让模型自己决定缩小范围重试;不能抛一个异常把整个任务打死。给写手的工具也砍到只剩十三个——用不着的工具说明每轮都跟着请求发,白花钱还分散注意力。

这条铁律的边界

程序不越权。有一类问题程序永远不做主:「这段素材该不该用在这一节」是语义判断,程序只核对用没用,不替你换素材——判断的出口是批注,回到你面前(上一篇讲过)。

模型和程序都会错。当两者都可能出错时,最后一道防线是什么?下一篇《出错时,裁决权在你》——这是本系列的最后一篇。

读原文、搭结构、写正文、交付带修订痕迹的 Word——繁琐的交给 AI,关键的你来把关。可以拿一份你手边的真实招标文件试一遍。