作者在 116 个未见职位上评估微调模型,发现排序相关性基本持平、误报从 22 降至 10,但关键职位命中从 14 个中的 10 个降至 6 个。模型评分趋于保守,三轮版本均未通过预先设定的验收规则,因此继续使用原模型。
我微调后的 AI 模型在主要指标上与原模型持平,误报减少了一半以上。但在 14 个真正值得关注的岗位中,它只找出了 6 个。原模型找出了 10 个。
0.707 对 0.705:与 Claude 评分的排名相关性。打平。
10 对 22:误报数量。更好。
在 14 个优质岗位中找出 6 个,对比原模型的 10 个。更差。
我微调了一个本地 AI 模型,让它像 Claude 一样评估职位描述,然后用它从未见过的 116 个岗位进行测试。
看平均指标,它像是一次升级。但在真正值得关注的岗位中,它只找出了 14 个中的 6 个。原模型找出了 10 个。
它学会了保守行事。在满分 5 分的评分中,它从未给任何岗位打出高于 4.3 的分数,因此,最好的岗位也停在了门槛下方。
在开始训练之前,我就写好了通过或不通过的判定规则。训练了三个版本,没有一个通过。生产环境继续使用原模型。
我在家里用一台 NVIDIA DGX Spark 运行一个小型 AI 实验室。它的一项任务是为我的求职过程做初筛:本地模型先读一遍新收到的职位描述,只有看起来有希望的岗位,才会交给 Claude 做完整评估。
这个本地模型能用,但有一项隐性成本。要让它像 Claude 一样评分,每次 prompt 都得带上我完整的评分标准:它还没读到职位描述的第一个字,就得先读大约 22,000 tokens 的指令。
微调似乎提供了一条捷径。用 Claude 过去的判断训练模型,把判断能力融入模型本身。这样,prompt 就能从大约 22,000 tokens 缩短到大约 550 tokens。
所以问题很简单,也和每个营收团队面对更便宜的工具时会问的问题一样:它能做出与昂贵工具相同的判断吗?
在开始训练之前,我先写清楚了什么才算“更好”。这也是我评估所有试图替代生产环境现有模型的候选模型时,一直使用的规则:
第二个条件最重要,因为它对应的正是筛选器要做的决策。如果筛选器漏掉一个优质岗位,我就永远看不到这个我可能想去的工作。如果它产生一次误报,代价只是让 Claude 多做一次评估。这两种错误的成本不同,所以我不会把它们同等看待。
我有 Claude 过去的 1,160 次评估可供模型学习。每条记录都包含一份职位描述,以及 Claude 的评分和书面推理。Claude 在满分 5 分中给出 4.0 分或以上的岗位,都算优质岗位。
我随机留出了其中 116 条,里面有 14 个优质岗位,从未将它们用于训练或调优。下文所有结果都来自这 116 条记录。模型使用其余 1,044 条进行训练。
我训练了三个版本:
第一次训练在一台桌面机器上花了大约六个小时。所有对比都使用相同的模型服务配置,因此,各次运行之间唯一变化的就是模型。
严重漏判:将优质岗位评为 3.0 分或以下。原模型的非优质岗位数量显示为 101,而不是 102,是因为它有一次返回的答案格式不正确。
版本 1 曾短暂地骗过我。它的排名相关性与原模型持平。在另一个测试集上,原模型两次完全相同的运行,相关性也会相差 0.04,所以 0.002 的差距可以视为打平。
它还把误报减少了一半以上。放在演示文稿里看,这就是一次升级。
然后再看真正决定结果的那一列:14 个优质岗位,它只找出了 6 个。原模型找出了 10 个。
版本 2 则向另一个方向做了取舍。它找出了 14 个中的 9 个,但误报比版本 1 更多,排序表现也更差。两个版本都通过牺牲优质岗位来减少误报,只是牺牲的程度不同。没有一个版本找出的优质岗位能达到原模型的数量。
四个模型版本的散点图。原模型找出了 14 个优质岗位中的 10 个,产生了 22 次误报。版本 1 找出了 6 个,误报 10 次;版本 2 找出了 9 个,误报 16 次;版本 3 找出了 5 个,误报 13 次。没有一个版本找出的优质岗位能达到原模型的数量。
116 份留出的职位描述,其中 14 个是优质岗位。Michael Inghilterra 的实验室,2026 年 9 月。
在这 116 个岗位中,微调模型从未给任何一个岗位打出超过 4.3 的分数。一次也没有。
这就是失败的全部原因。优质岗位的门槛是 4.0 分。当模型的最高分只有 4.3 时,每个优质岗位都必须挤进一个很窄的区间,才能越过门槛。版本 1 漏掉的 8 个优质岗位中,有 7 个得分在 3.4 到 3.9 之间。都很接近,而且始终落在线下。
原模型的漏判方式不同。它漏掉的四个岗位,偏差都很大:这些优质岗位全被它打了 2 分,满分是 5 分。所以,坦诚地说,这并不是好模型和坏模型之间的比较。原模型不稳定,微调模型太保守。保守在平均指标上看起来更好,因为它从不做出离谱的判断。但在筛选器存在的唯一目的上,它表现更差。
两个模型对同样 14 个优质岗位评分的点图。原模型给其中 10 个岗位打出了 4.0 分或以上,最高达到 5.0 分,但给另外四个岗位打了 2.0 分。微调模型从未给出超过 4.3 的分数,它漏掉的 8 个岗位中,有 7 个落在 3.4 到 3.9 之间,刚好低于 4.0 的门槛。
116 份留出的职位描述中,14 个优质岗位的评分。Michael Inghilterra 的实验室,2026 年 9 月。
对于评分偏低的模型,最直接的修复办法就是事后调整分数。我尝试了四种方法:把所有评分整体上移;拉伸评分,让分布范围与 Claude 一致;用直线拟合 Claude 的评分;以及降低筛选门槛。
这些方法都没能经受住第二个测试集的检验。前三种方法全面失效:调整后的模型,在这个测试集的 12 个优质岗位中,最多只找出了 1 个。降低门槛虽然保住了优质岗位,但误报大约增加到了原来的三倍。
有一个方案看起来很完美。把门槛从 4.0 降到 3.5 后,版本 1 在第二个测试集上保住了全部 12 个优质岗位。但这个门槛是我研究了同一个测试集后才找到的,而一个已经被你研究过的测试集,无法再证明任何东西。我没有把这个结果算进去。
版本 3 原本应该是效率更高的版本。Claude 写出的每份评估都包含一段总结,以及支持每项评分的证据。我想知道,这些文字是不是在浪费模型的能力。于是,我训练了一个只学习评分的版本。它的回答长度大约只有原来的四分之一。
结果,它是四个模型中表现最差的。排名相关性从大约 0.7 降到了 0.472。
最可能的解释是:把证据写出来,正是模型推理并得出评分的方式。去掉书写,也就去掉了思考。这也是为什么,相比只看销售代表给出的成交概率,我更愿意读他对这笔交易的记录。
没有一个版本胜过原模型。我在 9 月 26 日结束了实验,生产环境继续使用原模型,不做改动。
等我收集到一批模型从未见过的新数据,其中包含大约 35 个优质岗位,并新增大约 600 次评估用于训练后,我会重启实验。下一次尝试会保留推理过程,并要求模型更加重视评分,而不是删掉评分周围的所有内容。
我不是 ML 工程师。我的职业经历是营收运营、销售开发和数据分析,而这次失败,是我最熟悉的一类失败。
平均值会掩盖真正重要的交易。营收预测的总额可能准确,但里面每一笔大单都预测错了。赢单率可能保持稳定,但你却丢掉了所有企业级客户的交易。我的模型在平均意义上是对的,却错过了那些我真正愿意接受的岗位。始终要问:排在前面的那些项目,指标表现如何,而不是只看整个列表的指标。
选择与决策对应的指标。筛选器的任务,是不漏掉任何优质岗位。相关性衡量不了这一点,优质岗位召回率才可以。如果我只根据主要指标做判断,就会把一个更差的筛选器上线,还觉得自己做得很好。
在测试之前写好规则。看过结果之后,每个指标都开始显得像是正确的指标。先写下规则,才能阻止自己挑选那个最能美化预期答案的数字。
在试点之前,可以问任何 AI 供应商三个问题:
样本很小。只有 14 个优质岗位时,一个岗位就会让命中率变化大约 7 个百分点。可以认为结果的方向比较可靠,但具体数字只能粗略看待。
基准是 Claude 的判断,不是招聘结果。我衡量的是本地模型是否与 Claude 一致,而不是它们中的任何一个能否预测谁会被录用。
一个任务,一台机器。在一台桌面机器上训练,使每个训练样本的长度上限约为 3,000 tokens。更多内存可以支持更长的样本,这可能改变结果。
微调:用你自己的样本继续训练一个现有模型,让它学会你特定的判断方式。我使用的是 LoRA,这是一种轻量方法,只训练一个小型附加模块,而不是整个模型。
排名相关性:两个评分者对一个列表的排序有多一致,范围从 0(不一致)到 1(顺序完全相同)。
优质岗位召回率:在 Claude 判定为优质的岗位中,模型也给出 4.0 分或以上的有多少。
误报:模型判定为优质,但 Claude 没有判定为优质的岗位。
这个实验运行在 trajecktory 中,这是我构建的开源求职指挥中心。它托管在 GitHub:GitHub 上的 trajecktory。
最初发表于 michaelinghilterra.com。
如需采取进一步行动,你可以考虑屏蔽此人和/或举报滥用行为。