LLM Agent 匹配评分与人工判断背离的根因分析与修正实践

发布时间:2026/11/2 13:31:51
LLM Agent 匹配评分与人工判断背离的根因分析与修正实践 1. 一次评测翻车引出的真问题28 条 JD人工逐条打分再用 Agent 跑一遍匹配分最后算出来 Spearman 相关系数 ρ-0.085。这个数字第一次出现在我面前的时候我盯着屏幕看了大概半分钟脑子里只有一个念头要么是我算错了要么是 Agent 根本没在干我以为它在干的事。先说清楚这个场景是什么。JD 就是招聘岗位描述Agent 在这里扮演的是简历-岗位匹配器的角色输入一份候选人画像和一条 JD输出一个 0 到 100 的匹配分。人工判断则是找了几位有招聘经验的同事凭经验给同样的组合打分。Spearman 相关系数衡量的是两组排序之间的一致性取值在 -1 到 1 之间越接近 1 说明排序越一致接近 0 说明基本没关系负数则意味着排序方向相反。ρ-0.085 意味着什么意味着 Agent 认为匹配度高的岗位人工判断反而倾向于认为匹配度低虽然这个负相关很弱但弱负相关和弱正相关在业务上的含义是天差地别的。如果只是 ρ0.3我会说 Agent 还不够准但方向对了ρ-0.085 说明方向可能都是歪的。这篇文章我想把这次评测从头到尾拆一遍为什么会出现这种结果Spearman 在这里到底该怎么用LLM 驱动的 Agent 做匹配分时最容易踩哪些坑以及我后来是怎么一步步把这个问题定位并修正的。适合正在做 Agent 匹配、LLM 评分、Prompt 工程相关工作的同学参考也适合任何打算用 LLM 输出数值型评分的人——因为这个坑比你想的普遍得多。2. 评测设计28 条 JD 是怎么选出来的2.1 样本量与统计功效的现实妥协28 条这个数字不是拍脑袋定的但也不是理想值。做相关性分析样本量直接决定结论的可信度。Spearman 相关系数的显著性检验在 n28 的情况下ρ 的 95% 置信区间宽得吓人。我用 R 快速算过n28 时即使观测到 ρ0.4置信区间大概也在 0.02 到 0.68 之间也就是说你根本无法排除真实相关性接近 0的可能。那为什么还是用 28 条因为人工打分的成本太高。每条 JD 需要人工评估多个候选人维度的匹配度一位有经验的招聘同事认真打完一条大概要 8 到 15 分钟。28 条乘以多个候选人组合已经是好几个人大半天的产出。这是真实项目里最常见的约束统计上想要 200 条资源上只能给 30 条。提示样本量不足时不要只报一个 ρ 值就下结论。至少把置信区间一起算出来否则很容易把噪声当成信号。2.2 JD 的选取维度与分层逻辑28 条 JD 我按三个维度做了分层目的是让样本尽量覆盖真实业务分布而不是全挑某一类岗位层级初级、中级、高级、专家各占一定比例职能方向技术、产品、运营、设计避免全是技术岗导致结论偏窄JD 写法有的写得非常具体明确列出技术栈和年限有的写得很模糊大量熟悉相关领域有较强的沟通能力这类软性描述这个分层很关键。后来复盘时我发现Agent 在具体型 JD上的表现明显好于模糊型 JD如果当初全挑具体型 JDρ 可能不会这么难看。分层让我看到了这个差异而不是被一个平均值掩盖。2.3 人工打分的执行方式人工打分这块我踩过一个坑值得单独说。第一轮我让三位同事各自独立打分结果三个人之间的评分一致性用 Kendalls W 衡量只有 0.5 出头。这说明人工判断本身就不是一个稳定的基准如果基准自己都在抖拿它去评判 Agent 是不公平的。后来我改成了两阶段先让三位同事各自打分然后开一个 30 分钟的校准会把分歧超过 20 分的条目拿出来讨论形成统一口径再重新打一遍。校准后的一致性提升到了 0.78 左右。最终用于和 Agent 对比的是校准后的人工分。注意拿人工分当 ground truth 之前先验证人工分自己的一致性。基准不稳后面所有分析都是空中楼阁。3. Spearman 相关性分析为什么选它以及它的陷阱3.1 为什么不用 Pearson很多人第一反应是用 Pearson 相关系数但它衡量的是线性关系而且对异常值极其敏感。匹配分这种数据人工分和 Agent 分的量纲、分布都可能不一样比如人工分集中在 60 到 85 之间Agent 分可能铺满 0 到 100。这种情况下 Pearson 会被分布差异带偏。Spearman 用的是秩rank只关心排序不关心具体数值差多少。对于匹配度排序是否一致这个问题Spearman 是更合适的选择。这也是为什么标题里明确用了 Spearman。3.2 ρ-0.085 的直观含义把 28 条 JD 按人工分排序再按 Agent 分排序如果两个排序完全一致ρ1完全相反ρ-1毫无关系ρ≈0。ρ-0.085 意味着两个排序之间几乎没有任何正向对应关系甚至略微反向。我做过一个可视化把 28 个点画成散点图横轴人工分纵轴 Agent 分图上一团乱麻完全看不出趋势线。这个图比任何数字都直观地说明了问题Agent 的评分和人工判断基本是两套独立的逻辑。3.3 一个容易被忽略的统计陷阱这里有个坑我必须点出来如果 Agent 分大量重复比如很多条都给了 75 分Spearman 的秩会出现大量并列相关系数的计算会失真。我检查了原始数据Agent 分里有 9 条都是 75 分还有 6 条都是 80 分。这种分数扎堆是 LLM 打分的典型症状——模型倾向于输出几个安全的整数而不是连续分布。并列秩一多Spearman 的方差会变大ρ 的估计就更加不可靠。所以 ρ-0.085 这个数字本身可能还叠加了分数扎堆带来的噪声。这一点在排查时给了我重要线索。4. Agent 匹配分的实现链路拆解4.1 整体架构从 JD 到分数经过了什么我当时的 Agent 链路大致是这样的JD 解析把 JD 文本喂给 LLM抽取结构化字段技能要求、年限、学历、软性要求等候选人画像解析同样用 LLM 把简历抽成结构化字段匹配打分把两份结构化数据拼进 Prompt让 LLM 输出一个 0 到 100 的匹配分并要求给出理由后处理对分数做简单的归一化和截断看起来挺合理问题就藏在这条链路的每一环里。4.2 Prompt 设计最可疑的一环打分环节的 Prompt 大概是这个结构你是一位资深招聘专家。请根据以下岗位要求和候选人信息 给出一个 0-100 的匹配度分数。 岗位要求 {jd_structured} 候选人信息 {candidate_structured} 请输出 JSON 格式{score: 分数, reason: 理由}这个 Prompt 有几个致命问题当时我没意识到没有评分标准rubric什么叫 80 分什么叫 60 分模型完全靠自己脑补。不同 JD 之间模型的心理标尺可能完全不同。没有锚点示例没有给任何 few-shot 例子模型对分数区间的理解是漂移的。要求输出理由但理由和分数是解耦的模型可能先写一段漂亮的理由然后随便给个分两者并不一致。单次调用没有自洽性检查同一个输入跑两次分数可能差 15 分。4.3 结构化抽取的精度损失JD 解析和简历解析这两步用的是 LLM 做信息抽取。这里有个隐蔽的问题抽取本身就是有损的。JD 里负责核心业务系统的架构设计需要有高并发场景经验这句话抽成结构化字段可能变成{技能: [架构设计, 高并发]}丢掉了核心业务场景这些限定词。当匹配打分只基于抽取后的结构化字段时模型看到的已经是二手信息了。人工判断时看的是原始 JD 全文信息量根本不在一个量级。这是 ρ 为负的一个结构性原因。5. 定位问题我做了哪些对照实验5.1 实验一让 Agent 只排序不打分第一个实验我把任务从打 0-100 分改成给 28 条 JD 排序。结果 ρ 提升到了 0.31。这个提升说明Agent 的相对判断能力比绝对打分能力强。让它说这条比那条更匹配比让它说这条是 78 分要靠谱。这给了我一个重要方向也许不该让 LLM 直接输出绝对分数。5.2 实验二加入评分 rubric第二个实验我在 Prompt 里加了明确的评分标准评分标准 - 90-100技能完全匹配年限超出要求有相关行业背景 - 70-89技能基本匹配年限符合个别技能需补充 - 50-69核心技能匹配但有明显缺口 - 30-49仅部分技能匹配 - 0-29基本不匹配加完之后ρ 从 -0.085 提升到了 0.22。有改善但离可用还差得远。而且分数扎堆的问题依然存在模型还是喜欢给 75、80 这种整数。5.3 实验三多次采样取中位数第三个实验同一个输入让模型跑 5 次取中位数。ρ 提升到 0.29。这个实验证明了 LLM 打分的不稳定性——单次结果噪声很大多次采样能压掉一部分噪声。但代价是成本翻了 5 倍而且 ρ 还是不够高。5.4 实验四拆解维度分别打分第四个实验是最关键的。我不再让模型给一个总分而是拆成几个维度分别打分再加权技能匹配度权重 0.4年限匹配度权重 0.2行业背景匹配度权重 0.2软性要求匹配度权重 0.2每个维度单独让模型打分最后加权求和。ρ 提升到了 0.41。这是所有实验里提升最大的一次。为什么拆维度有效因为让模型一次性综合判断太多因素时它会偷懒抓住一两个显眼特征就给分。拆开之后每个维度的问题更聚焦模型的判断也更稳定。实验改动ρ主要发现基线原始 Prompt-0.085方向都是歪的实验一改为排序任务0.31相对判断强于绝对打分实验二加评分 rubric0.22有改善但分数仍扎堆实验三5 次采样取中位数0.29降噪有效但成本高实验四拆维度加权0.41提升最大方向正确6. 根因分析为什么 LLM 打分和人工判断会背离6.1 LLM 的分数锚定效应LLM 在打分时有一个强烈的倾向锚定在训练数据里常见的分数分布上。招聘场景的语料里匹配度这类评分大量集中在 70 到 85 之间模型就学会了往这个区间挤。结果就是不管什么 JD分数都差不多区分度极低。人工判断则不同人会根据具体 JD 拉开差距特别匹配的给 90明显不匹配的给 40 以下。这种敢于拉开差距恰恰是 LLM 缺失的。6.2 信息不对称结构化抽取丢了什么前面提过Agent 打分基于抽取后的结构化字段而人工看的是全文。我做过一个对比把同一条 JD 的原文和抽取结果并排看发现丢失的信息包括语气和强调必须优先加分项这些词的分量上下文关联某个技能是核心还是了解即可隐含要求能接受快节奏暗示加班文化这些信息人工能感知Agent 感知不到。信息基础不同判断自然背离。6.3 人工判断本身的隐性标准还有一个反向的问题人工判断也有它自己的偏差。招聘同事打分时会不自觉地受这个岗位急不急招团队现在缺什么人影响这些是 JD 文本里没有的。所以人工分也不是纯粹的文本匹配度它掺杂了业务上下文。这意味着即使 Agent 完美地做了文本匹配它和人工分也不可能完全一致因为两者衡量的根本不是同一个东西。这一点想清楚之后我对 ρ 的期望值做了调整追求 0.7 以上是不现实的0.5 到 0.6 可能就是这类任务的天花板。7. 修正方案把 ρ 从负拉到可用的完整实操7.1 重构 Prompt从给个分到按标准逐项评最终的 Prompt 我改成了这样你是一位资深招聘专家需要评估候选人与岗位的匹配度。 请严格按照以下维度逐项评分每个维度独立判断不要综合。 维度一技能匹配0-100 - 岗位要求的核心技能候选人具备几项逐项列出。 - 具备的技能是精通还是了解 维度二年限匹配0-100 - 岗位要求年限 vs 候选人实际年限 - 超出或不足分别如何扣分 维度三行业背景0-100 - 候选人过往行业与岗位行业的相关性 维度四软性要求0-100 - 岗位提到的软性要求候选人是否有对应证据 输出 JSON { skill_score: 0-100, skill_detail: 逐项说明, year_score: 0-100, year_detail: 说明, industry_score: 0-100, industry_detail: 说明, soft_score: 0-100, soft_detail: 说明 }注意几个设计点每个维度都要求逐项列出给出证据这是逼模型做细粒度推理而不是拍脑袋。维度之间明确说独立判断不要综合避免模型把四个维度揉成一个模糊印象。7.2 加权计算把维度分合成总分拿到四个维度分后加权公式def compute_total(skill, year, industry, soft): weights { skill: 0.4, year: 0.2, industry: 0.2, soft: 0.2, } total ( skill * weights[skill] year * weights[year] industry * weights[industry] soft * weights[soft] ) return round(total, 1)权重不是拍脑袋定的。我做了敏感性分析把权重在合理范围内微调看 ρ 的变化。技能权重从 0.3 到 0.5 之间ρ 都比较稳定说明这个维度确实是主导因素。年限权重超过 0.3 后 ρ 开始下降说明年限在人工判断里的分量没那么重。7.3 多次采样与一致性过滤即使拆了维度单次调用还是有噪声。我的做法是每个维度跑 3 次取中位数。同时对 3 次结果做一致性检查如果某个维度 3 次分数的极差超过 30 分说明模型在这个维度上很不确定标记出来人工复核。import statistics def robust_score(scores): if max(scores) - min(scores) 30: return None # 标记为不确定转人工 return statistics.median(scores)这个过滤机制帮我抓出了大约 15% 的模型自己也拿不准的条目这些条目转人工处理整体准确率提升明显。7.4 保留原始文本减少抽取损失针对信息损失问题我改成了结构化字段 原始文本双通道输入。Prompt 里既给抽取后的字段也附上 JD 原文和简历原文的关键段落。模型可以交叉参考减少因抽取丢失信息导致的误判。代价是 Prompt 变长token 消耗增加。但实测下来这一步对 ρ 的贡献大概有 0.05 到 0.08值得。8. 常见问题与排查技巧实录8.1 分数扎堆怎么办这是 LLM 打分最普遍的问题。除了前面说的拆维度还有几个技巧要求输出小数让模型输出一位小数比如 78.5比整数更难扎堆提供分数分布示例在 Prompt 里说明本次评估的分数应大致分布在 30 到 95 之间避免集中在 70-80后处理拉伸如果分数还是集中在窄区间做一次线性拉伸把 [70, 85] 映射到 [40, 95]提示分数拉伸是治标不治本但作为快速改善手段在早期验证阶段很有用。8.2 ρ 一直上不去先查这三件事排查顺序我总结成了这个表排查项检查方法常见问题人工基准一致性算人工分之间的 Kendalls W低于 0.7 说明基准不稳分数分布画直方图看是否扎堆扎堆严重则 Spearman 失真任务定义确认 Agent 和人工在评同一件事一个评文本匹配一个评业务匹配这三项里第三项最容易被忽略但往往是根因。我那次 ρ 为负很大一部分就是任务定义不一致导致的。8.3 Prompt 被判定违规或闪退做这类评测时Prompt 里如果包含大量简历信息偶尔会触发平台的内容审核出现invalid prompt: your prompt was flagged这类报错。我的处理方式对输入做脱敏去掉真实姓名、联系方式、公司全称把长 Prompt 拆成多段分段调用准备好重试逻辑遇到闪退自动换一种表述重试8.4 并发场景下的稳定性如果要批量跑几百条 JD串行太慢需要并发。但 LLM 接口在并发下容易出现超时和限流。我的经验是并发数控制在 5 到 10 之间太高反而因为重试导致整体变慢加指数退避重试第一次失败等 1 秒第二次等 2 秒第三次等 4 秒把每条 JD 的处理做成幂等失败重跑不会产生重复数据9. 我踩过的坑和几条实在建议第一个坑是过早下结论。ρ-0.085 出来的时候我第一反应是Agent 不行差点直接放弃这条路。后来做对照实验才发现问题不在 Agent 本身而在任务设计和 Prompt 上。如果当时放弃了就不会有后面 ρ0.41 的结果。第二个坑是把人工分当绝对真理。人工分自己的一致性只有 0.5 的时候我还在拿它当基准去评判 Agent这本身就不公平。先校准基准再谈对比这个顺序不能反。第三个坑是忽视分数分布。Spearman 对并列秩敏感我一开始没检查分数扎堆导致 ρ 的解读有偏差。后来养成习惯算相关系数之前先画分布图。几条实在建议做 LLM 评分类任务优先考虑排序而不是绝对打分能用 rubric 就别让模型自由发挥拆维度几乎总是比综合打分好多次采样取中位数是性价比很高的降噪手段最后永远先验证你的基准靠不靠谱。这个项目后续我还在继续做下一步想试试用 pairwise 比较的方式替代绝对打分——让模型两两比较哪条 JD 更匹配再用 Bradley-Terry 模型还原出全局排序。理论上这能进一步压掉绝对打分的噪声等跑完有结果再单独写一篇。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询