tacit-spec-as-spec-compression

隐性 spec,以及作为 spec 压缩的递归

上级:recursive-harness

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 重构)。这笔税并没有消失——它只是有了一把尺子。
tacit-spec-as-spec-compression