BoHuYeShan

Back

〇、一行观察,一张公式#

先说个无法引用来源的观察:最近一个月,Command Code 在我这边的 Agent 使用时间大约占 15%。留下我的不是它换模型方便,是它在后台默默做的一件事——taste。

它是闭源的。GitHub 上那个 CommandCodeAI/command-code 仓库只有 .github、mods 和一份 readme,没有实现代码;文档里反复出现的 taste-1 也没有开源权重。所以能拆的只有两样东西:文档把管线描述得多细,以及官网那张公式图。

那张图值得单独看。图里写的是:

Meta-NeuroSymbolic Objective(ϕ)=Ex∼DRLEy∼LLMϕNS(x)[RMNS(x,y)−βNSlog⁡LLMϕNS(y∣x)LLMSFT(y∣x)]+γNSEx∼Dpretrainlog⁡LLMϕNS(x)\text{Meta-NeuroSymbolic Objective}(\phi)=\mathbb{E}_{x\sim D_{RL}}\mathbb{E}_{y\sim LLM^{\text{NS}}_\phi(x)}\left[RM_{NS}(x,y)-\beta_{NS}\log\frac{LLM^{\text{NS}}_\phi(y\mid x)}{LLM^{\text{SFT}}(y\mid x)}\right]+\gamma_{NS}\mathbb{E}_{x\sim D_{pretrain}}\log LLM^{\text{NS}}_\phi(x)

这不是什么神秘的新目标函数。它是带 KL 约束的策略优化——RLHF、PPO、GRPO 那一套的地基,外加一个预训练似然项防遗忘。真正有意思的问题不是”它用了什么公式”,而是:为什么一个判偏好的模型,可以用这套公式做得又便宜又稳,而让大模型自己写笔记就做不到?

一、管线:判决被夹在两个 LLM 中间#

文档给的管线是四步,中间那步是唯一不可替换的:

  1. 输入 LLM(可选):读你的 prompt、编辑、纠错 diff,转成结构化信号——“这次改动把 X 变成了 Y,因为……”
  2. taste-1:判断这条信号是不是真偏好、属于哪个类别(cli、typescript、architecture……)、置信度多少。不生成长文本。
  3. 输出 LLM(可选):把判决写成可读的 markdown。
  4. CLI:存进 .commandcode/taste/**/taste.md,下一轮读回来。

模型可以按行配置:第 1、3 步用你选的任何模型,第 2 步固定。存储是纯文本、可 lint、可像 git 一样 push/pull——有三种包:项目级 .commandcode/taste/、用户级 ~/.commandcode/taste/、远端 commandcode.ai/<user>/taste。

一句话概括它的结构:LLM 负责把世界翻译成符号,判决模型负责在符号上做决定,LLM 再把决定翻译回文本。

四步管线:判决模型夹在两个 LLM 中间

管线本身没有新鲜事;新鲜的是中间那一步的代价结构和置信度语义。

二、公式三项,分别防什么#

把公式拆成三块看:

第一项:ExEy∼πϕ[RMNS(x,y)]\mathbb{E}_{x}\mathbb{E}_{y\sim\pi_\phi}[RM_{NS}(x,y)],在策略自己采样的动作上最大化奖励。注意 yy 是从 LLMϕNSLLM^{NS}_\phi 里采的,不是从数据集里拿的——这是 on-policy,和 PPO 一样。

第二项:−βNSlog⁡πϕ(y∣x)πSFT(y∣x)-\beta_{NS}\log\frac{\pi_\phi(y\mid x)}{\pi_{\text{SFT}}(y\mid x)},对 SFT 参考模型的 KL 惩罚。β\beta 是刹车:β\beta 大,策略贴着参考模型走;β\beta 小,奖励说话。它防的是奖励黑客——奖励模型有洞,策略会往里钻。

第三项:+γNSEx∼Dpretrainlog⁡πϕ(x)+\gamma_{NS}\mathbb{E}_{x\sim D_{pretrain}}\log\pi_\phi(x),在预训练分布上的似然。它防的是能力漂移:模型改着改着,把原来的语言能力改没了。这是 RLHF 里常被忽略、但在小模型上最要命的一项。

三项合起来,就是一个”贴着旧模型改进、别跑偏、别忘本”的标准配方。所谓 neuro-symbolic,落在 RMNSRM_{NS} 上——奖励不是黑箱打分,而是一个带符号结构的判别器。

三、闭式解:为什么判决比生成便宜#

把第二项写成约束形式,这个问题有解析解。最大化

Ey∼π[RM(x,y)]−β KL(π(⋅∣x) ∥ πref(⋅∣x))\mathbb{E}_{y\sim\pi}\big[RM(x,y)\big]-\beta\,\mathrm{KL}\big(\pi(\cdot\mid x)\,\|\,\pi_{\text{ref}}(\cdot\mid x)\big)

对 π\pi 求变分,得到

π∗(y∣x)=1Z(x) πref(y∣x)exp⁡ ⁣(RM(x,y)β),Z(x)=∑yπref(y∣x)exp⁡ ⁣(RM(x,y)β)\pi^*(y\mid x)=\frac{1}{Z(x)}\,\pi_{\text{ref}}(y\mid x)\exp\!\Big(\frac{RM(x,y)}{\beta}\Big),\qquad Z(x)=\sum_{y}\pi_{\text{ref}}(y\mid x)\exp\!\Big(\frac{RM(x,y)}{\beta}\Big)

这个式子的含义很直白:最优策略就是把参考策略按奖励指数重加权。它和 best-of-n、拒绝采样是同一件事的连续版本——采样 nn 个、挑奖励最高的,n→∞n\to\infty 时收敛到这条曲线。

关键在分母 Z(x)Z(x)。如果 yy 是自由文本,ZZ 要遍历整个词表上的所有序列,不可算,只能靠采样估计——这就是 LLM 推理按 token 计费、按 token 变慢的原因。

但如果动作空间是有限类别集,比如”这条信号属于 6 个类别里的哪一个、极性是 prefer 还是 avoid”,那么 KK 很小,Z(x)=∑k=1KZ(x)=\sum_{k=1}^{K} 可以直接精确枚举。没有采样方差,没有逐 token 解码,每来一条信号做一次固定量的计算。 文档说的”便宜约 100 倍、快约 8 倍”(厂商口径,未见独立复现),数学上就来自这里:不是工程优化省出来的,是动作空间小到可以算精确。

这也是它敢说”校准”的原因。有限空间上的分类器,置信度可以用验证集直接校准:说 0.8 的那批,实际正确率就该是 80%。自由文本生成没有这个性质。

顺带一个值得点破的细节:公式里写的是 LLMϕNSLLM^{NS}_\phi。所以”不是 LLM”的准确含义是不生成文本、不可替换,不是”不是 Transformer”。它大概率仍是语言模型形状的网络,只是输出空间被符号层限死了。

四、和”模型自己写笔记”比,数学差在哪#

传统的 Agent 记忆是这样的:模型调用一个 memory_write 工具,把”用户喜欢 X”写进文件;下一轮再读回来。看起来很像,但四个地方在数学上站不住:

维度模型自己写笔记taste 这类判决模型
输出从 p(text∣context)p(\text{text}\mid\text{context}) 采样从有限类别集上取 arg⁡max⁡\arg\max + 校准概率
证据不足时补一个”开发者通常会喜欢”的默认值返回低置信度或”不学习”
置信度模型自报的数字,没有训练信号约束有标签可校准;错得多的那批置信度自动降
更新重写整段文本,新条目静默覆盖旧条目似然累积;冲突被标记,不被覆盖
代价每轮重读全文,O(T⋅M)O(T\cdot M)每条信号固定开销,O(1)O(1)

第三行是最要命的。RLHF 训出来的模型系统性过度自信——人类标注者奖励”听起来确定”的回答,于是模型学会了自信的语调,而不是自信的准确率。把这种数字写进偏好库,等于把噪声当先验。

第四行是结构问题。文本记忆的更新是”覆盖”,而覆盖没有单调性:新写的一条可以抹掉十条旧证据。判决模型可以做成贝叶斯式的累积——这也是我们自己那套实现的做法:

α=1+∑w+,β=1+∑w−,p=α+wj pjudgeα+β+wj\alpha=1+\sum w^{+},\qquad \beta=1+\sum w^{-},\qquad p=\frac{\alpha+w_j\,p_{\text{judge}}}{\alpha+\beta+w_j}

证据按类型给权重(明确说过 1.0、被采纳 0.8、未被回滚 0.8、工具结果 0.5、推断 0.3、矛盾 −1.0、回滚 −1.0),判决模型的概率只作为伪计数进入,wj=2⋅strengthw_j=2\cdot\text{strength}。这样设计的好处是:模型再自信也顶不穿证据不足——空证据下它说”certainly”,后验也只能到 0.75 附近。反过来,聊天模型自己报的置信度在我们的实现里被直接丢弃,理由写在代码注释里:一个未校准的数字进贝叶斯后验,比没有数字更糟。

五、它和外部判决模型是一家#

把 taste-1 和 TypeSafe 的 Jev 摆在一起看,会发现它们是同一类东西的两个实例。Jev 自称 System One Model:给它一个状态和一组类型化问题,返回选项、每个选项的概率、以及置信度,从不生成字符串。文档说它在决策基准上比前沿 LLM 便宜、快两个数量级(同样是厂商口径)。

这一类可以列一长串:

  • 偏好/品味判决:taste-1、Jev
  • 安全守卫:各类 guard 模型
  • 奖励建模:RLHF 里的 RM
  • 检索重排:reranker
  • 路由:把请求分给哪个模型的 router

它们的共同判据只有一条:输出空间是不是类型化、有限。是,它就属于判决模型——便宜、可校准、可组合、可缓存;不是(自由文本),它就还是 LLM,贵、会飘、置信度不可信。

所以”taste 和判决模型差不多”这个直觉是对的。差别在于 taste-1 额外背了一套偏好空间的结构:类别闭合、冲突检测、按使用而非按写入计时的衰减。而 Command Code 和我们的区别,主要不在数学,在开放程度——它整套闭源,taste-1 不可替换;我们那套用可配置的 judge 角色接外部决策模型(typesafe/jev-latest 这类后端),并且和它的 taste.md 格式互通:同一个文件,两个工具都能读。

六、四个风险,别当软文看#

自举回路。 偏好信号里的”采纳/回滚”大多来自 agent 自己提出的改动。它提议、你接受、它学习——学到的是自己的口味,不是你的。这与模型坍缩是同一族问题,只是发生在偏好层。

反馈噪声。 你懒得回滚不等于同意。校准依赖标签质量,标签一脏,置信度会系统性偏高,而系统看起来更”确定”了。

可移植的另一面。 能 push、能分享、能组合,意味着偏好包可以被投毒、被团队规训、被当成入职配置分发。一个能改你代码风格的压缩包,和一段能改你 shell 的脚本,风险等级是同一档。

厂商数字。 100 倍便宜、8 倍快、两个数量级、15 次重复实验——全部来自厂商自己的文档,没有第三方复现。写进文章时只能当”他们声称”,不能当”实测”。

七、结论#

品味不是记忆。记忆是写下来的文本,品味是学出来的分布;文本没有似然,分布有。

这也解释了为什么这类功能最后都长成”判决模型夹在两个 LLM 中间”的形状:语言的部分交给会说话的东西,决定的部分交给会校准的东西。前者贵在 token,后者贵在标注——而标注,恰好是你每天敲键盘时免费产生的。

至于 Command Code 值不值得用:如果你已经有一套自己的规则文件,taste 的增量不大;如果你从来没写过规则,它替你写了,而且写得比你勤。这是它真正卖的东西——不是更聪明的模型,是一个不用你维护的先验。

品味不是记忆:Command Code 的 taste 到底在算什么
https://bohuyeshan.top/2026/11/03/2026-11-03-01-taste-is-not-memory/
作者 BoHuYeShan
发布于 2026年11月3日