隐性 spec,以及作为 spec 压缩的递归
LLM 补上 spec 中写不出来的那部分
让一个分解得以完备的"常识",其形式是隐性的、写不出来的:
- 隐性知识(Polanyi):"我们知道的,比我们能说出来的多。"
- 从计算的角度看:这是一个最短描述就是模型本身的函数(无法压缩成显式规则);它是由梯度下降写出来的,而不是由人写出来的——"可以被写出来,但不是被人写出来的。"
- (Kripke 的遵循规则悖论:任何有限的显式规则都无法完全决定自己该如何被应用;总还需要一种隐性的"照着同样的方式继续下去"。LLM 是第一个把这种隐性闭合真正实现出来的人工物。)
这正是 LLM-agent 能做到 GOFAI/Cyc 做不到的事的原因:Cyc 试图手写常识,结果失败了——因为常识本来就不是能手写的,只能被学出来。 LLM 的真正角色不是"补上一些显而易见的缺口",而是扛起 spec 中人写不出来的那部分。
递归把无限的 spec 压缩成一条有限的规则
你没法把"在每一种情况下该怎么做"(无限、隐性)写下来。但一条递归指令却是有限却能无限适用的:把递归步骤加基例只写一次,递归性就覆盖了所有可达的状态。于是人的负担就变成了那条有限的递归规则,而不是那张无限的情形表——这就是为什么"这条指令在任何情况下都适用:因为它是递归的"。递归是一种spec 压缩装置。
但隐性不会消失——它会集中到两个点上
| 隐性发生点 | 位置 | 失败代价 |
|---|---|---|
| dispatch(规则的哪一分支适用) | 内部节点 | 危险——会误导整个子树,而且它在 P×C 的上游(不被其约束) |
| 叶子(原子化的基例动作) | 最底层 | 可承受——P×C 到这里就截止了,所以失败本身已经足够便宜 |
→ 最强的设计:把所有隐性负荷都推向叶子,让 dispatch 变得可写、可确定。 这样一来结构可靠,dispatch 可靠,叶子的隐性风险也被 P×C 圈定了上限。harness 到底能有多强,真正的关键就在于——dispatch 有多"可写"(结构化的领域:可以;带有品味/依赖语境的领域:不行——这时 dispatch 就需要一个一致性 gate)。
不可验证性税
一个写不出来的 spec 没法被机械地验证——所以隐性步骤只能拿到一个语义 gate(由另一个 LLM 来判断),而这个 gate 是会出错的。可写的 spec 层级 → 机械 gate → 可靠;写不出来的 spec 层级 → 语义 gate → 脆弱。这正是"eval 就是类型系统"这条原则在接缝处的体现:类型检查器检查可写的部分,eval 是唯一能检查那不可写部分的东西,而 eval 本身也可能出错。
重访——放到理论层之下再看
- "把隐性推向叶子"现在有了一个精确的判据:一个叶子的隐性负荷是否有上限,当且仅当它的 spec 能从其注入内容中被学到——这就是 coupling-to-the-learner 里的 PAC 叶子规则(context window = 样本预算
m;spec 复杂到超出m的承受范围 ⟹ 模型就会用先验去填补空缺 = 正是本文所说的隐性漂移)。 - "dispatch 是危险的"现在有了它的补救办法:在 root-protocol 里,这个拆分本身就是一件人工制品——dispatch 在任何子节点生成之前,先要通过它自己的 gate(且拿到最大的一份预算),而且没有哪个 agent 是自己撰写用来评判自己的 spec 的。
- 不可验证性税现在是可度量的了:语义 gate 的可错性是一个经过标定的
α(mutation testing,operationalizing-tolerances),而"是否可理解"本身也有了一种近乎机械化的检验(round-trip 重构)。这笔税并没有消失——它只是有了一把尺子。