把 LLM 评审员"代码化":PAJAMA 用 80 个 Python 函数替代一整支裁判团
论文:Codifying the Judge: Scalable Evaluation via Program Distillation(arXiv: 2607.22561) 作者:Tzu-Heng Huang、Shengqi Qiu、Frederic Sala 机构:University of Wisconsin-Madison 链接:https://arxiv.org/abs/2607.22561 | 代码:github.com/SprocketLab/PAJAMA
你有没有过这种经历——线上跑的 reward model 越调越大、API 账单越涨越猛,团队里开始有人嘀咕"我们到底在评什么"?
LLM-as-a-judge 这几年几乎是评测管线的事实标准:成对偏好标注、奖励模型蒸馏、RLHF 反馈,统统靠把候选丢给一个 GPT/Gemini/Claude 让它打分。但代价是 每次评估都要重新跑一遍百亿参数的推理,并且你永远不知道它那句"我喜欢 response A"是基于什么理由、是格式偏好、是位置偏好、还是纯幻觉。
这篇来自 UW-Madison 的工作给出了一个挺反直觉的解法:让 LLM 一次性"吐出"一段 Python 函数,函数签名固定为 judge(query, response) → float,后续所有评分都靠本地执行程序。整个系统叫 PAJAMA,5 个偏好数据集上 78.11% 的平均准确率能追平 OLMo-2-13B-Instruct(79.70%),而吞吐量是后者的 47 倍。最让我意外的是奖励模型蒸馏那一组实验——用 PAJAMA 的程序判分当监督去微调 Qwen2.5-3B,RewardBench 上反而比用 GPT-4 标签训练的版本高出 1.67 个点,API 成本却只有 1/50。
一、LLM 评审员的"四宗罪"
作者把 LLM-as-a-judge 的痛点拆得很细,我把它压缩成一张表:
| 痛点 | 实际工程代价 |
|---|---|
| 推理成本 | GPT-5 评估百万样本 ≈ 一笔不小的话费;开源部署不烧 API 但烧 GPU |
| 逻辑不透明 | 输出理由看着像那么回事,但内部决策链没法审计——到底是真的"在评质量"还是被 markdown 格式分了心? |
| 系统性偏差 | 位置、冗长、引用、性别、富内容——LLM 的偏好像个黑盒抽奖 |
| 重复推理税 | 评分标准微调一次,整个数据集要重跑一遍 |
第一和第三点在工业界是显性成本——账单上看得见、回归测试里能复现。但第二和第四点更隐蔽,也更致命:你没办法把一个"判断"diff 给同事 review。改一个 rubric 就意味着重跑推理,迭代速度被卡死。
PAJAMA 的核心想法是:把"判断逻辑"和"判断执行"彻底解耦。LLM 只在合成时调用一次(一次性 \(\mathcal{O}(1)\) 投资),之后所有评估都是本地 Python 函数调用,\(\mathcal{O}(n)\) 的 API 费用直接消失。
二、思路:把评审员"蒸馏"成程序委员会
2.1 一个合成示例
作者用 Claude Opus 4.6 一次性合成了 ~80 个候选程序,每个程序负责从某个角度评估候选响应。Figure 1 完整展示了"逻辑连贯性"这个评估准则下,LLM 给出的 judging_function 长什么样:

图 1:程序化评审合成示例。LLM 接收合成 prompt(左上)后输出 Python judging_function,实现"逻辑连贯性"评估准则,组合 TF 向量余弦相似度的语义漂移、话语段落的主题一致性、加权打分等可解释特征,对矛盾和截断施加显式惩罚。
最有意思的设计是特征层面的可解释性——coherence_score = 0.53·sim_mid + 0.25·(1/(1+10σ²)) 这种公式,每一项都对应自然语言里说得清楚的语义概念。你想让模型更关注"主题一致性",改一行权重就行;想加个新维度,再让 LLM 合成一个程序。这是 LLM 评审员永远给不了你的可调试性。
2.2 单一程序不够,所以搞了个委员会
作者也承认,单个程序扛不住所有类型的输入。直接让 LLM 自由合成会产生一堆逻辑重复的程序(都基于"长度"打分)。解决方案是预先策划 10 个不同维度的评估准则(如连贯性、清晰度、结构、相关性、可读性、完整性、变化度、长度充分性、话语标记、矛盾检测),每个准则独立合成 8 个候选程序。文本相似性检查会过滤掉逻辑重复的,最终留下大约 80 个差异化程序。
然后按验证集准确率做 top-k 选择:选 8~21 个程序组成最终委员会(不同数据集保留数量不同),丢弃低于随机概率(<50%)的程序。这一步至关重要——它是后续弱监督聚合的输入。
2.3 校准:让"异质打分"在同一坐标系说话
每个程序输出量纲都不同——有的输出 0~1 的概率,有的输出原始 token 数。作者用了两步校准:
- Min-max 归一化到 \([0, 1]\)
- 离散化为投票 + 弃权区间:计算两个候选的质量差异 \(d_{ij} = \hat{s}^{(1)} - \hat{s}^{(2)} \in [-1, 1]\),若 \(|d_{ij}| < \tau_j\) 则程序弃权。\(\tau_j\) 在验证集上 grid search 最大化准确率确定
弃权机制是个挺巧的设计——程序信号太弱时,沉默比乱说话更可靠。
2.4 弱监督聚合:让 Snorkel 派上用场
top-k 程序的投票构成偏好矩阵 \(L \in \{-1, 0, +1\}^{N \times k}\)。这一步直接套用 Snorkel 框架的标签模型:从程序间的一致/分歧模式估计每个程序的准确率,学出聚合权重,推理时输出联合判定。
说实话看到这里我愣了一下——Snorkel 是 2016 年的弱监督方法,作者把它嫁接到 LLM 评审的程序化版本上,逻辑上确实自洽:每个程序就是一个"标注函数(labeling function)",量纲乱、覆盖率不满、互相有冲突,完美匹配 Snorkel 的预设。
2.5 置信度路由:不确定的样本才升级到 LLM
程序委员会对每个样本会输出两个内部信号: - 投票方差:程序间分歧越大,越不确定 - 聚合器后验:后验概率越接近 50%,越不确定
这两个信号零额外监督——纯靠程序之间的共识度判断。低于阈值的样本路由到 LLM 评审,其余由程序决定。阈值连续扫描,可以描绘出"准确率 vs 吞吐量"的完整曲线。
Figure 2 把这套流程画得很清楚:

图 2:PAJAMA 工作流。给定查询 \(q\) 和两个候选响应 \(r^{(1)}, r^{(2)}\),由 LLM 从 6 个策划准则(Relavance、Readability、Completeness、Coherence、Clarity、Structure)合成的程序化评审池产生初始评估,弱监督聚合为联合决策,不确定案例路由至 LLM 评审。
三、实验:追平 13B 评审员,快 47 倍
3.1 程序评审的"性价比曲线"
5 个偏好数据集、4 个模型家族(专有:GPT-4.1、GPT-5 Thinking;开源:OLMo-2、Gemma-3、Qwen2.5),LLM 评审用 vLLM 64 并发,程序评审用 24 CPU 线程并行。
Figure 3 的 6 个子图把"准确率-吞吐量"曲线画在了一张图上——

图 3:五个偏好数据集上准确率 vs 吞吐量。每个子图标题报告选择后保留的程序数量(8~21 个)。红色实心圆为 PAJAMA,灰色虚线为专有 LLM(GPT-4.1、GPT-5 Thinking),彩色折线为各模型家族不同尺寸的 LLM 评审。
| 评估器 | 平均准确率 | 平均吞吐量 (samples/sec) |
|---|---|---|
| GPT-4.1 | 87.68% | 1.83 |
| GPT-5 Thinking | 85.72% | 0.10 |
| OLMo-2-13B | 79.70% | 9.30 |
| Qwen2.5-14B | 87.77% | 8.83 |
| PAJAMA | 78.11% | 439.41 |
几个关键数字: - PAJAMA 平均 78.11% vs OLMo-2-13B 79.70%:准确率差距 1.59 个点 - 速度快 47.25×:程序评审在 24 核 CPU 上跑出了 439 samples/sec - 比最快的 LLM 评审(OLMo-2-13B)还快 47×:vLLM 也才 9.3 samples/sec - 程序覆盖率 >95%:所有数据集上程序能给出非弃权判定的样本比例都极高(最高 99.20%)
我的第一反应是:1.59 个点的差距在很多场景下完全可以接受——花 1/47 的成本换 1.6 个点的差距,对中小团队来说是白送。
3.2 混合评估推进 Pareto 前沿
PAJAMA 不止能当纯程序评审员,更关键的是它能作为路由信号给一个更大的 LLM 兜底。
Figure 4-7 展示了 OLMo-2、Qwen2.5、Gemma-3 三个模型家族内不同尺寸 LLM 作为兜底对象时的路由曲线:

图 4:OLMo-2 家族内的路由。Confidence(红)= 程序后验概率路由;Vote Variance(蓝)= 投票方差路由;Query/Response Length = 启发式路由;Random = 随机路由;黑色虚线圆 = 端点(纯程序或纯 LLM)。
| 配置 | 准确率提升 | 吞吐量提升 |
|---|---|---|
| OLMo-2-1B + PAJAMA | +23.5% | 5.1× |
| OLMo-2-7B + PAJAMA | +5.0% | 2.9× |
| OLMo-2-13B + PAJAMA | +1.3% | 2.3× |
| Qwen2.5-0.5B + PAJAMA | +29.2% | 3.6× |
| Qwen2.5-1.5B + PAJAMA | +19.2% | 4.0× |
| Qwen2.5-3B + PAJAMA | +2.6% | 2.2× |
| Gemma-3-270M + PAJAMA | +26.7% | 2.9× |
| Gemma-3-1B + PAJAMA | +23.5% | 3.3× |

图 5:Qwen2.5 家族内的路由曲线。Qwen2.5-0.5B/1.5B/3B/7B/14B 五个尺寸作为兜底 LLM。

图 6:Gemma-3 家族内的路由曲线。Gemma-3-270M/1B/4B/12B 四个尺寸作为兜底 LLM。
一个挺反直觉的发现:收益最大的不是最大的 LLM,而是中小尺寸的 LLM。OLMo-2-1B + PAJAMA 提升 23.5 个点、准确率从 53% 抬到 77%,吞吐量还翻了 5 倍。这逻辑上很合理——1B 模型本身评分质量差,程序委员会比它强太多,路由决策几乎总是对的;13B 模型本身已经很强,路由的边际收益就小。
最后 Figure 7 把所有模型、所有数据集的 Pareto 前沿汇总:

图 7:混合评估推进 Pareto 前沿。三列分别为 Oracle Router(理论上界)、Vote Variance、Aggregator Posterior 路由信号。红色实线 = PAJAMA frontier,灰色实线 = LLM-only frontier,彩色虚线 = 各模型尺寸单独 frontier。
Oracle Router(只升级程序会判错的对)是上界,PAJAMA 的两种信号都接近这个上界——这意味着程序委员会的"不确定"信号是相当可靠的,比随机路由、query length 启发式、response length 启发式都更接近最优。
3.3 奖励模型蒸馏:50× 便宜,效果反而更好
这是整篇论文让我最意外的一组实验。
设置:从 Prometheus 和 JudgeLM 各采样 20,000 偏好对,用 PAJAMA 的程序评审重新标注,作为 Qwen2.5-3B-Instruct 在 Bradley-Terry 目标下的微调监督。评估分两层: - 域内准确率:在 Prometheus/JudgeLM 测试集上 - 域外泛化:RewardBench(Chat、Chat Hard、Reasoning 三个子集)
| 标注源 | API 调用量 | 估算成本 | Prometheus 域内 | JudgeLM 域内 | RewardBench 均值 |
|---|---|---|---|---|---|
| GPT-4 | 20,000 samples | $363.97 | 97.23% | 90.24% | 54.98% |
| PAJAMA | 80 programs | $7.21(50× 便宜) | 92.20% | 82.79% | 56.65% |
注意最后两列——RewardBench 上 PAJAMA 标签训练的模型反而高出 1.67 个点。JudgeLM 训练版本甚至高出 4.49 个点(61.77% vs 57.28%)。
我的第一反应是怀疑:是不是程序标签噪声更大,反而成了某种正则化?作者没明说,但 RewardBench 的子集结果给了一些线索:
| 类别 | PAJAMA 标签 (Prometheus 训练) | GPT-4 标签 |
|---|---|---|
| Chat | 79.33 | 68.44 |
| Chat Hard | 30.04 | 38.82 |
| Reasoning | 60.58 | 55.70 |
PAJAMA 在 Chat 和 Reasoning 上赢,在 Chat Hard 上输。Chat Hard 是 RewardBench 里专门构造的"看似对但实则错"的样本,GPT-4 标签在这种 adversarial 数据上更有优势;而程序标签因为只评估显式特征(语义漂移、主题一致性等),可能对"看起来对但其实有逻辑陷阱"的样本不够敏感。这是个诚实的 trade-off——你拿 1.5 个点的 Chat Hard 换 10 个点的 Chat,外加 50× 的成本优势,工程上多数场景是划算的。
3.4 偏差可校准:把"评审员的偏见"当成 bug 修
最后一组实验测的是 LLM 评审员的"老大难"——偏差。作者构造了 5 种扰动: - 位置偏差:交换两个候选的顺序 - 富内容偏差:给响应加 markdown、emoji 等 - 引用偏差:引用但不提供证据 - 性别偏差:替换指代性别的人称 - 冗长偏差:把响应拉长
两个指标:Flip Rate(扰动后判定改变的占比,越低越好)、Bias Win Rate(偏差响应最终胜出的占比,越低越好)。
| 方法 | 平均 Flip Rate | 平均 BWR |
|---|---|---|
| OLMo-2-1B | 57.72% | 27.85% |
| OLMo-2-7B | 27.62% | 13.62% |
| OLMo-2-13B | 54.97% | — |
| Qwen2.5-14B | 24.64% | — |
| PAJAMA(未校准) | 39.78% | 12.09% |
| PAJAMA(Claude Code 校准后) | 35.58% | 7.60% |
未校准的 PAJAMA Flip Rate 已经低于多数 LLM——位置偏差 0%(因为程序对顺序不敏感),冗长偏差因为显式惩罚短/长响应也表现不错。
更牛的是校准机制:用 Claude Code 编码代理对程序源代码做迭代编辑,专门针对偏差类型做修补。比如富内容类,把"奖励 markdown 列表"那段逻辑直接删掉,Flip Rate 单项改善 9.39 个点。
作者原话:偏差不再是评估器的"固定属性",而是可修补的 bug。
这个观点我太同意了——LLM 评审员的偏差你想修补都没法动手,程序化评审员的偏差你能直接改源代码。从工程角度,可调试性本身就是一种巨大的优势。
3.5 验证集到底要多大?
附录 D.1 测了一个我很好奇的点:验证集从 100% 缩到 5%,程序选择和聚合器的性能会塌吗?
| 验证集比例 | JudgeLM Acc. | Prometheus Acc. | PandaLM Acc. |
|---|---|---|---|
| 100% | 0.807 | 0.880 | 0.698 |
| 60% | 0.809 | 0.880 | 0.694 |
| 20% | 0.807 | 0.882 | 0.692 |
| 5% | 0.805 | 0.882 | 0.692 |
几十个样本就够——准确率变化不到 0.5 个点。这意味着 PAJAMA 不会反过来被"标注验证集"卡脖子,标注成本主要还是来自程序合成的 \(\mathcal{O}(1)\) 一次性投资。
四、我的判断:漂亮,但有适用边界
4.1 亮点
程序蒸馏这套范式真的挺漂亮。它把 LLM 评审的"成本-准确率-可解释性"三角问题里,可解释性这一角直接砍到了零边际成本。我尤其喜欢它对"偏差可修补"的论证——LLM-as-a-judge 的偏差你只能等下一代模型去修,程序化评审的偏差你今天就能在 IDE 里改。
奖励模型蒸馏那个 +1.67 个点的结果非常 surprising。直觉上程序标签噪声更大,应该作为弱监督训练会输给 GPT-4 标签,但实验结果反过来了。我没看到作者详细解释,可能的解释是: - 程序标签在不同 rubric 间一致性更高(都是同一组合成参数),GPT-4 标签随 prompt 变异性大 - 程序标签的"显式特征"组合反而提供了某种隐式正则化 - 域内评测时 GPT-4 标签占优(97.23% vs 92.20%),但 RewardBench 评测时"看穿陷阱"的能力更依赖真实偏好,程序标签可能更鲁棒
4.2 局限
作者自己列了三点,我也补充一些:
- 依赖底层 LLM 能力。如果 LLM 不理解任务(生成无效程序),整个系统塌掉。对复杂数学/编码任务,程序的特征工程可能泛化不了——这些场景仍需 LLM 兜底。
- 适用范围有限。需要"可直接被 Python 函数评估"的候选——主观性、创造性的任务,程序化评审员会显著失真。
- 路由信号对 Chat Hard 类 adversarial 样本不够敏感(3.3 节已讨论)。
还有一个工程上的隐性风险:80 个程序在不同数据集上的泛化能力有差异。你给一个新领域,可能要重新合成一批程序——一次性投资变成了"每次迁移都要重新投资"。不过作者说 80 个程序在 5 个数据集上零样本迁移都 work,这点需要更多领域验证。
4.3 与同期工作的位置
说实话,把 LLM-as-a-judge 的判断逻辑"固化"成可解释组件这个方向,过去几年有不少尝试: - Prometheus 系列:开源 LLM 评审员,本质还是在训一个 LLM judge,成本/不透明性没解决 - JudgeLM:同上 - 路由/级联评估:FrugalGPT、EcoAssistant 等,更多是 model-level 的 cascade,不涉及"判断逻辑的代码化" - Snorkel 风格弱监督:作者直接借了 Snorkel 框架,但嫁接到 LLM 评审场景上是新的
PAJAMA 的位置可以这样描述:它不是新方法,而是把现有组件(弱监督 + 程序合成 + 置信度路由)拼成了一套专门解决"LLM 评审的成本-不透明性"问题的范式。这种"工程整合 + 准点踩对"的工作,工业上其实价值很高——它让你明天就能在自己的评测 pipeline 里替换掉一部分 LLM 调用。
五、给你的工程启发
如果你的团队在用 LLM-as-a-judge 做大规模评估,PAJAMA 给了三个立刻可用的实践建议:
- 先做"程序 + LLM 兜底"混合评估。不要全切,把 PAJAMA 跑在 80% 明显可自动化评估的样本上,剩下的 20% 仍走 LLM。成本直降 5×,准确率影响很小。
- 把你的 rubric 显式化。你团队的评分标准如果写得出来,就让 LLM 合成对应的程序——这本身就是一次 rubric 审查。
- 把偏差当 bug 管。LLM 评审员的偏差你只能"换模型碰运气",程序化评审员的偏差你能在 PR 里改——把这个工作流嵌进你的 CI/CD。
如果你也在调 reward model、对 API 账单敏感、或者在 debug LLM 评审员的奇怪判定,这套程序化评审的思路值得认真试一下。代码已开源,80 个程序就是 80 个可以审计、可以修改、可以重用的评估函数——比起黑盒 GPT-5,这至少是工程友好的。
觉得有启发的话,欢迎点赞、在看、转发。跟进最新 AI 前沿,关注我。