很多时候,我们让模型写出一段话,只是为了从里面拿到一个判断。

TypeSafe 在九月发布的 Jev,就是围绕这件事设计的:输入上下文和问题,直接得到选择、评分或概率。它把决策当作专门的任务,也重视概率是否可信,以及如何在同一份上下文上高效处理多个判断。

在了解它的原理、尝试自己实现的过程中,我有一个疑问:这种判断,一定需要额外微调才能做到吗?

语言模型本来就在学习,给定一段上下文之后,接下来不同文字出现的概率。我的直觉是,如果选项本身是有文字、有语义的,模型读完问题和选项后,应该已经会对不同答案产生不同的概率倾向。一个训练得足够好的模型,也许已经能够通过它学到的语言分布,区分哪个选项更符合当前的问题。

那么,我们能不能直接读出这种分布里的倾向,用它来作选择,而不必为了决策再做一次 fine-tuning?

这是我最想验证的想法:判断所需要的能力,也许本来就在模型里。我们平时让它把答案生成成文字,但也许可以直接把这个判断取出来。

此外,在看 Jeff、Laya 这些经过专门训练的模型时,我还有另一个怀疑:它们会不会过于适应了微调所针对的那类任务,出现很强的过拟合(overfitting)?在熟悉的任务上表现好,换成我的问题,又会怎样?

于是,我用自己关心的一组问题做主测试,没有沿用它们微调所针对的那套任务。首先看现有模型的分布倾向能不能直接用于判断,也看看专用模型换一组任务后,还能保留多少优势。

先把模型已有的判断读出来

我用了现成的 Qwen 和 Gemma,没有再做决策微调,也没有训练一个新的分类头。

做法很直接:让模型读取上下文、问题和可选答案,然后从最后一个位置的输出中,取出各个答案标签对应的分数,也就是 logits。用这些分数作选择,不再让模型把答案逐字生成出来。

这里仍然要经过完整的模型前向计算;能够缓存的输入前缀可以复用。省掉的是后续生成文字的过程。这些分数能用来比较答案,但还不能直接当成判断正确的概率。

我想看的是:不做额外微调,模型原有的分布倾向,能不能在我自己的任务里变成有用的判断?

换一组问题,结果会怎样?

我把这两个直接评分的版本,与 Jeff、Laya 等本地决策模型放到同一组自建问题上比较。下面是主要结果,数字取整。

这里的 Jeff 是独立项目;这轮没有直接测试 TypeSafe 的 Jev。

本地决策模型实测结果
模型 / 配置 正确率 热态耗时中位数
Jeff 0.8B v1.1 60% 128 毫秒
Jeff 2B v1.1 65% 295 毫秒
OpenDecider small(8-bit) 77% 707 毫秒
CLM 8B(原生输入) 17% 570 毫秒
CLM 8B(JSON 输入) 17% 664 毫秒
Laya multilingual 37% 17 毫秒
Laya English 35% 58 毫秒
Laya Typed Decisions 51% 65 毫秒
Qwen 3.5 9B(直接评分,无额外微调) 61% 217 毫秒
Gemma 4 26B-A4B(直接评分,无额外微调) 75% 259 毫秒

本机为 M2 Max、64 GiB 内存。表中正确率基于 300 条固定测试输入;耗时统计重复测试中的有效调用,不含加载和上下文准备。Laya English 因输入长度拒绝的请求仍计入正确率,CLM 的正确结果全部来自回退。模型大小、量化与输入格式不同,这不是微调效果的受控比较。

这组结果里,我最在意的是:专用小模型确实可以很快,但有用的判断能力,并不一定需要通过额外训练才能获得。 Gemma 的直接评分已经接近这组配置里的最高正确率。它还没有解决所有问题,却足够让我认真考虑:能不能先用好已有的模型?

作为参照,我也测了公开的 Typed Decisions 数据集。Laya Typed Decisions 在那里约为 77%,换到我的这组问题后约为 51%。这个落差加深了我对任务过拟合的怀疑。不过,任务、语言和输入条件同时发生了变化,这次对比还不能单独证明原因就是过拟合。它让我更在意的是:熟悉题集上的成绩,能不能带到我实际需要的任务里?

再往下看,有些模型能选出答案,却不擅长判断什么时候不该直接作选择。我的两个通用模型基线也有这种问题。这一点比继续比较几个百分点更值得在意:工作流需要的,不只是一个能选答案的模型。

同一个模型,也能走更快的路

我还用同一份 Gemma 权重,比较了直接评分与完整生成流程。这是另一组离线测试,不能和上表混成一个成绩。

同一 Gemma 模型的两条路径
同一 Gemma,两个调用方式 正确率 热态耗时中位数
直接读取答案分数 75% 186 毫秒
完整生成流程 37% 2,166 毫秒

两种方式都对 53 条测试输入各测两次,失败也计入耗时。完整生成流程还包含解析、校验和必要的修复,两边的运行库与缓存也不同;这不是只改变“是否生成文字”的实验。直接评分的上下文准备另计,未命中缓存时约需 5 秒。

对我来说,这个对照最有意思的地方,是同一个模型的能力,可以用不同方式取出来。为了得到一个判断,未必每次都要经过完整的生成流程。

但直接评分也有范围。遇到无法用现有选项表达的请求,这组测试里它没有处理好;完整生成流程在这些请求上也没有表现可靠。所以这张表说明的是,一条受限的判断路径值得保留,还不能说明它能够替代全部生成能力。

快一次,值得多一个模型吗?

如果任务稳定,而且只需要高频地做判断,一个小而快的专用模型当然很有吸引力。

但我更关心另一种情况:本地工作流里,本来就有一个模型需要负责回复。

同一句输入,可能需要一个决定,也可能需要一段回答。系统先要分清这件事,才知道应该走哪条路径。把它交给两个模型,就要考虑路由、切换、回退和维护;如果两个模型都在本地,还要考虑它们是否都得留在内存里。

如果已有模型本来就必须运行,而且已经能做出有用的判断,那么即使它的单次决策慢一点,把判断和回复留在同一个模型里,也可能更合适。

Jev 本身也有把判断结果用于路由的设计。问题在于,这一层能给具体工作流带来多少净收益。同一个模型同样需要区分何时判断、何时回复,也不会自动解决路由问题。

这轮实验还没有比较完整的单模型与双模型工作流,但我已经据此作出了目前的选择。

到目前为止,我的工作流里没有再额外增加一个专用决策模型。 我调整了现有模型的调用方式,在需要作出选择时,直接读取答案标签的 logits,让它也能输出决策。


在写这篇文章的这段时间里,一篇名为 《LLM-as-Jev: LLMs Are Already Jev-Style Decision Models—When and How to Fine-Tune Them》的论文也发布了。它的一个主要发现与我的实验结果相近:能力较强的现成语言模型,即使不做额外微调,也能直接给出有用的决策。