12_我怎么给RAG建评测集_从实体重叠到LLM-as-judge
我怎么给 RAG 建评测集从实体重叠到 LLM-as-judgeW2 结束时我手上有一套能跑的评测50 条 golden set、召回 66%、忠实度下界 0.988。数字都挺好看。但我盯着那张表看了半天说不清一件事——这套尺子能量出我真正想知道的东西吗答案是不能。它有三个盲区而且每一个都藏着看起来不错的陷阱。这篇讲我怎么把尺子换掉以及换完之后回头体检发现自己的评测集本身是偏的。更新注2026-09-27这篇写完后golden set 已从 50 条扩到120 条judge 也完成了真实 API 全量复测。文中保留了发现问题时的原始数据作为过程记录最新数字在对应小节里以「复测」标出结尾有完整对照表。一、hitk 的三个盲区W2 我主要用 hitk召回5衡量检索。它只能回答该找的块找到了吗而在三个方向上它是瞎的盲区具体表现后果只测检索不测生成块召对了模型照样可能答错、瞎编检索满分也可能全在编命中一个就算对跨文档题只召到一个来源照样判通过掩盖了多来源答不全——W2 里 multi 全中率 0~25% 就是这么被总分 66% 盖住的只有质量没有成本效果涨了但成本涨十倍、p95 飙到 3 秒这系统不能上线第三个盲区最容易被忽略评测不测成本等于鼓励你把效果堆到不计代价。我见过太多优化完效果涨了 5 个点的结论没提单次成本从 ¥0.0009 涨到了 ¥0.009。二、回头体检我的评测集本身是偏的换尺子之前我先做了一件事——写个体检脚本scripts/golden_stats.py看看这 50 条到底长什么样。跑出来是这样【类型分布】 term 25 条 50.0% semantic 15 条 30.0% multi 3 条 6.0% boundary 5 条 10.0% conflict 2 条 4.0% 【来源分布】 deepseek 12 条 24.0% zhipu 20 条 40.0% bailian 18 条 36.0%加上三条告警线问题就出来了告警含义难例只占 20%10/50低于 30%天花板效应简单题上各方案都 80%差距被噪声吃掉deepseek 只占 24%低于 25%该平台覆盖不足评测分数在它上面不代表真实水平deepseek 缺 conflict、zhipu 缺 boundaryconflict平台 × 题型有空格存在结构性盲区这是我最想强调的一点评测集偏了你自己是感觉不到的。你只会看到召回 66%这个数字然后去优化它。但这个 66% 是在一半是送分题、deepseek 只占四分之一的集子上跑出来的——它描述的是你的评测集不是你的系统。所以我把复盘写成了脚本而不是靠感觉。来源偏、难度偏、平台×题型有空格这三种偏法都会让评测失真而它们都是能自动查出来的。到 120 条的缺口也算出来了term 还差 25 条、semantic 15、multi 12、boundary 10、conflict 8合计 70 条来源上 deepseek 差 28、zhipu 20、bailian 22。复测缺口补上了告警清零后来我把这 70 条真补上了。同一条命令再跑一次告警从 4 条变成 0 条golden set 120 条 目标 120 条 【类型分布】 term 50 / semantic 30 / multi 15 / boundary 15 / conflict 10 【来源分布】 deepseek 38(31.7%) zhipu 40(33.3%) bailian 42(35.0%) 【偏斜告警】 无告警分布达标难例占比20% → 33.3%deepseek24% → 31.7%之前两家缺的题型也补齐了。补集过程中踩到一个很阴的坑合并完一跑测试test_golden_expected_chunk_really_contains_answer直接红了——120 条里有 36 条的关键词不在标准答案块里。块里写的是1.5~2出题时标注成了1.5-2。关键词不在块里 这道题永远判不中。它不报错、看不出来只会悄悄把召回率拉低。所以写完题和题能用之间还差一道校验。顺带一个口径变化120 条下差 1 条 0.83 个百分点50 条时是 2 个百分点。样本变大后能分辨的真实差异也变小了——之前5 个百分点以内不下结论的门槛现在可以收紧到 2~3 个百分点。三、换尺子手写 LLM-as-judge 三指标W2 的忠实度 0.988是实体重叠算出来的下界——它能抓住凭空冒出来的数字抓不住用原文的词拼出的错误结论。后者才是 RAG 幻觉里最危险的一种数字都对结论是错的肉眼根本看不出来。要测出这种幻觉只能让 LLM 当裁判。这就是 W3 第一天的活app/evals/judge.py三个指标。指标测什么补哪个盲区faithfulness答案每句话能否由上下文推出真·忠实度替换下界answer_relevancy答案有没有正面回答、有没有跑题生成端跑题context_recall标准答案的关键信息被覆盖了多少多来源完整性软性召回三个指标统一成**「拆解 → 逐条判定」两段式**先把答案拆成原子陈述再逐句问 LLM这句能不能从上下文推出返回 YES/NO 聚合。为什么不让 LLM 直接打 0~1 的分数两个坑一是尺度漂移同一答案两次打分 0.7 和 0.9没法复现二是不可解释分数低了不知道哪句在编。拆成二值判定后分数 支持句数 / 总句数稳定、可复现、能定位到具体哪句翻了车。顺带一提context_recall和标准recall5的区别recall5是 chunk_id 精确命中二值context_recall是关键信息是否被覆盖软性。后者能捕捉 small-to-big 里父块覆盖了子块信息、但子块没进 top-k的情况——这两个指标不是重复劳动。为什么手写而不用 RAGASRAGAS 能做这三件事但它强依赖 LangChain 生态。我手写了一是省依赖二是 W1 就定了规矩——重点是对比「不用框架我自己怎么实现」面试会问。手写 vs 框架的取舍本身就是素材。四、一个必须提前说清的心理预期换更严的尺子数字会下降。我在动手前预估真·faithfulness 会把 0.988 压到 0.85 上下——实测是 92.4%比我预估的高但确实比下界 0.988低。这不是退步是换了一把更准的尺子。评测的价值恰恰在于敢用严尺子量自己——你用下界指标看到 0.988其实是自己骗自己。五、跑完之后120 条全量复测的真实数字judge 真调了 API也跑完了 120 条全量。先回答当初的两个担心模型确实会乖乖只答 YES/NO判定解析零失败拆陈述也没有出现合并成一行的退化——context_recall 没退化。全量结果120 条hybrid指标W2 baseline50 条现在120 条召回566.0%69.2%忠实度 faithfulness0.988下界92.4%真·LLM-as-judge答案相关性 relevancy—51.8%上下文召回 context_recall—76.7%跨文档全中0~25%3 条12.5%15 条拒答率20.0%22.5%p95 延迟1465ms1755ms召回从 66% 到 69.2%说明原来的 66% 不是小样本虚高——这个数字现在可以拿出去讲了。而跨文档全中只有 12.5%且这次是 15 条 multi 题跑出来的之前只有 3 条。样本从 3 条扩到 15 条这个弱点就被确认了而不是说不清跨文档综合依然是全链路最大的短板。这是我后续要主攻的方向。成本上还有一条值得单独说单次 ¥0.01217 ├ 检索/策略 ¥0.00000 ├ 生成 ¥0.00110 ← 系统运行成本 └ 评测 ¥0.01108 ← judge 开销不上生产评测成本 ≠ 运行成本。不分开统计你会看到单次成本涨了十几倍然后以为系统变贵了——其实涨的 91% 是 judge 的钱跟系统没关系。一个没解决的问题relevancy 偏低answer_relevancy只有 51.8%我一度以为是答案真的跑题。查下去发现不是——是这个方法的内生局限从答案反推的问题必然丢限定语。答案通常只有一句话“最小命中前缀是 64 token”而原问题带范围“DeepSeek 的上下文硬盘缓存最小命中前缀是多少”。反推出的是最小命中前缀是多少丢了DeepSeek 硬盘缓存。用二值判定是否语义等价模型会诚实地判 NO明明切题的答案被记 0 分。这正是 RAGAS 原版用 **embedding 余弦连续值**而不是二值判定的原因。我改成三档软性SAME 1.0 / PARTIAL 0.5 / DIFFERENT 0.0后手工用例从 0~0.33 回到 0.67~1.00但绝对值仍偏低。这个我还没解决下一步是拿 RAGAS 对拍一遍。一句话总结评测集不是攒够 50 条题就完事了。它得能分辨方案差距难例够不够、不能有平台盲区来源均不均、尺子得敢量真问题LLM-as-judge 而非下界。这三条我每条都踩过。而且建完不等于完工——扩集之后我才发现 36 条题的关键词根本不在答案块里那批题原本是永远判不中的。

相关新闻

C++代码实现MATLAB中fitrgam函数功能

C++代码实现MATLAB中fitrgam函数功能

// fitrgam.cpp // 自包含 GAM 实现:循环梯度提升 决策树桩 // 逻辑对应 MATLAB fitrgam: // - 每个预测变量独立提升(cyclic boosting) // - 基学习器为决策树桩 (max_depth 1) // - 默认迭代 300 次,学习率 …

2026/10/10 2:48:05 阅读更多 →
旋转数组最优解:三次翻转实现原地O(1)空间交换

旋转数组最优解:三次翻转实现原地O(1)空间交换

第一次在面试里遇到旋转数组这道题,是好几年前的事了。当时我的思路还停留在“开一个新数组,把每个元素放到正确位置”的阶段,一两分钟写完,自我感觉良好。结果面试官轻轻补了一句:“能不能不用额外空间?”…

2026/10/10 2:48:05 阅读更多 →
IDEA中文乱码排查指南:从编码链路到解决方案

IDEA中文乱码排查指南:从编码链路到解决方案

1. 先从那个"�"说起:乱码问题到底卡在编码链路的哪一环你看到的这个标题末尾就带了一个"�",这其实是乱码问题里最经典的一个标志性字符。在IDEA里遇到中文乱码,大多数人的第一反应是"文件坏了…

2026/10/10 2:48:05 阅读更多 →

最新新闻

HTML打印票据实战:银行汇款单页面开发与A4打印适配

HTML打印票据实战:银行汇款单页面开发与A4打印适配

银行汇款单这种“票据型页面”确实是个被很多人低估的小项目。最近我在给公司内部做转账申请流程,业务方丢过来一个需求:员工要能在线填写汇款信息,同时支持直接打印成一张能和纸质汇款单对得上的A4单据,拿去走签字审批。他们以前…

2026/10/10 3:32:19 阅读更多 →
FreeRTOS内核源码结构深度拆解:核心模块、移植层与配置裁剪实战

FreeRTOS内核源码结构深度拆解:核心模块、移植层与配置裁剪实战

1. 从一个“看不透”的内核说起很多人第一次把 FreeRTOS 的源码包解压开,看到那一堆.c和.h文件,第一反应是懵的。tasks.c三千多行,queue.c两千多行,port.c里全是看不懂的汇编和寄存器操作,再加上FreeRTOSConfig.h里密密…

2026/10/10 3:32:19 阅读更多 →
VB6无法加载mscomctl.ocx?从COM注册到64位系统排查全攻略

VB6无法加载mscomctl.ocx?从COM注册到64位系统排查全攻略

前阵子接一个老项目,打开工程刚准备改界面,VB6直接弹了个提示,大意是“无法加载mscomctl.ocx”,紧接着工具箱里的TreeView、ListView、StatusBar、Toolbar全部消失。找了一圈,有人说是DLL没注册,有人说是文…

2026/10/10 3:32:19 阅读更多 →
基于Java的电子合同电子签名系统源码自研与多端接入实践

基于Java的电子合同电子签名系统源码自研与多端接入实践

自打开始接电商、供应链这块的项目,合同这事儿就一直绕不开。以前图省事,直接用第三方电子签SaaS,按份数付费,一年下来账单挺吓人。后来接到一个客户需求,要求合同签署能力要嵌到他们的小程序、公众号、APP、H5里&…

2026/10/10 3:32:19 阅读更多 →
Java架构下Redis持久化方案整合实战与避坑指南

Java架构下Redis持久化方案整合实战与避坑指南

项目标题写的是“Java架构设计:Redis持久化方案整合实战”,但经历过的人都知道,真正到了线上,这四个字往往意味着一段“删库跑路未遂”或“凌晨三点被DBA叫起来看日志”的回忆。我最早接触Redis持久化,是在一个秒杀场景…

2026/10/10 3:32:19 阅读更多 →
Linux终端效率进阶:从Readline快捷键到tmux复用实战

Linux终端效率进阶:从Readline快捷键到tmux复用实战

如果你和我一样,每天有大量时间泡在Linux终端里,那你一定有过这种体验:好不容易理清思路准备敲一条长命令,发现要修改中间一个参数,只能一下一下按方向键挪;或者刚想起昨天用过一条很长的命令,翻…

2026/10/10 3:31:19 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →