
我做了将近两年的搜索评测见过太多模型在演示时“无所不知”一到真实业务场景就原形毕露。所以当我第一次看到“Futuresearch Evals”这个概念时心里下意识就冒出一句话早该有人把这套事情做成一个标准化框架了。简单说Futuresearch Evals 是一个面向下一代搜索系统的评估体系它的目标不是测单一模型有多强而是测“搜索生成引用”这一整条链路到底能不能让用户省心。我把它落地成了自己项目里的评测脚本、标准数据集和一套可复现的指标计算方法这篇文章就把整个思路和实操过程掰开揉碎讲一讲希望能给正在做RAG、做Agent搜索、甚至只是纠结“怎么证明我的搜出来是对的”的朋友一点参考。这套东西解决了什么问题呢最直接的是你的生成式搜索返回了一大段看起来合理的答案但你怎么知道里面有多少是编的怎么量化引用是否准确怎么在迭代的时候快速判断新版本比旧版本好还是差这些靠人眼抽查永远不够必须有一套可重复、可比较的评估方案。Futuresearch Evals 就是为此存在的它适合正在搭建搜索评测体系的技术人员、算法工程师、以及所有被“我明明加上RAG了为什么还是胡说八道”折磨的团队。1. 为什么需要一套新的搜索评估体系我踩过最深的坑是拿着传统搜索的指标硬套生成式搜索结果。当时团队内部守着CTR、P10这些老指标不撒手结果模型输出的答案质量翻了倍点击率却掉了一截。原因很简单用户不用再点进去看原文了答案就在页面上点击率自然下降。这种情况下老指标不但不能反映好坏还会误导优化方向。1.1 传统检索指标在生成式搜索面前失灵了传统搜索讲究的是“召回-排序”指标也围绕着相关性打转PK、MAP、NDCG、MRR这些都是拿人工标注的相关性等级和系统排序结果去比对。可到了生成式搜索系统输出的是“一段话”不是“一列链接”这时候有几个问题特别尴尬相关性没法简单定义。一段综合答案里包含了多个信息点可能每个点对用户都部分相关拿二元相关标注去标怎么标都是错。排序不再是最终形态。用户看到的是答案不是十条结果NDCG算得再漂亮答案里信息错位也没用。用户任务变了。以前的搜索是“找到某条信息”生成式搜索是“完成某个任务/得到某个判断”需要端到端评估。我试过硬着头皮用NDCG去打分结果是标注同学直接崩溃。他们抱怨说“这个答案给的很好但是我不知道该标在第几条位置上。”所以必须换思路。1.2 Futuresearch Evals 的核心思路三层评估在被迫交了几次学费之后我逐步总结出一套适合生成式搜索的三层评估做法。第一层是信息正确性考察答案里的每个原子事实是否真实可溯源第二层是交互质量考察答案是否完整回答了用户的问题、结构是否清晰、有没有歧义第三层是任务完成度考察用户在真实场景里能不能拿着这个答案做成事。这三层不是互相替代的关系而是从局部到整体的递进。Futuresearch Evals 把三层拆成三种独立的评估能力Fact-level evaluation断言级查证把答案拆成若干断言claim逐个去匹配检索证据。Answer-level evaluation整体评分参考综合质量、覆盖度、冗余度。Task-level evaluation定义端到端任务比如“用户想买一款适合跑步的降噪耳机”看模型能否给出合理的筛选维度并直出结论。这样做的好处是当答案质量波动时可以快速定位到底坏在哪一层。是事实错了还是边界没覆盖到还是最终建议不落地。只出一个总分是没法定位的三层分开才方便迭代。2. 评测集构建从真实query到人工标注我见过不少团队一开始就从网上抓一堆问题当评测集结果跑出来的分数连自己都不信。评测集不是越多越好关键是分层、可控、可追溯。Futuresearch Evals 的语料构建我分成了四步收集种子请求、多路扩写、过滤去重、分层标注。2.1 种子query的采集与扩展种子query最靠谱的来源其实是日志。没有日志的情况下也可以靠业务同学写、靠行业报告提炼。我在项目里用的是一份脱敏的业务搜索日志按点击率和停留时间筛出需求真实的长尾问题再拿这些作为种子用大模型做同义改写和场景扩展。具体做法时我会写一条很直接的生成指令类似这样prompt 你是一个资深搜索运营专家。 给定用户真实搜索词扩展成10个不同表述方式、不同详细程度的变体。 要求 1. 保留核心意图允许补充时间、地点、条件等约束 2. 覆盖口语化、书面化、关键词堆叠三种风格 3. 输出为JSON数组每项只包含一个字符串 原始搜索词{query} 这一步会搞出来大量噪声所以必须配合去重。我不信任纯字符串去重而是先把所有结果做embedding再用聚类方式过滤相似度超过0.9的样本保证评测集里的query多样性。这一步做完通常能得到几千条覆盖十几个细分场景的种子集。2.2 标注流程与质量控制很多教程会建议直接用LLM做评测、人工做复核这没错但人工部分怎么设计才是关键。我用的标注工具有两个级别一个用于事实断言一个用于整体体验。事实断言标注通常是勾选“证据片段中有没有这句话的依据”整体体验则是从1到5打分附加一句必须写的理由。质量控制上我盯三个指标标注一致性同一条数据至少两人标算Cohens Kappa低于0.6就需要重新对标注规范标注置信度让标注者同时填写“确定/不确定”不确定率超过10%的批次打回标注漂移每天抽5%的已标数据复标发现随着时间推移标准悄悄变化我吃过最大的亏是标注标准没写清楚“事实”和“推断”的区别。有人把“该耳机适合运动”标为事实有人标为观点。后来规范里明确一切产品参数、属性、事件都算事实主观评价和总结性建议都不算事实只算观点。这样一来一致性直接升了一个台阶。3. 核心指标设计与计算方式指标设计这part是Futuresearch Evals的核心也是跟传统搜索引擎评估差异最大的地方。我不想学术界那一套无人能复现的公式所以我用的指标都是能拿一段输出、一条JSON就能算出来的。3.1 忠实度与答案覆盖度忠实度Faithfulness其实解决的是“有没有编”的问题。做法是先让一个提取模型把生成的答案切成一个一个原子断言然后再拿这些断言去跟检索来的参考文档做蕴含匹配。包含一个断言就算一分最后用真值断言的占比作为忠实度。注意不是匹配关键词是拿另一个NLI模型判断是否被文档语义蕴含。我在项目里直接用开源模型跑了一个快速的分类器from transformers import pipeline nli pipeline(text-classification, modelMoritzLaurer/DeBERTa-v3-base-mnli-fever-anli) def check_faithful(claim, evidence): result nli(f{claim} /s {evidence}) label result[0][label] return label entailment答案覆盖度Coverage则是反过来看用户问题的信息需求被满足了几个维度。我会先拆解query里的必要信息项比如“适合跑步的降噪耳机”至少需要覆盖“降噪效果”“跑步场景舒适度”“续航”“价格”。覆盖度就是这些维度的命中率。严格来说这一步需要人工或规则拆维度但跑通以后可以交由LLM完成。3.2 引用准确率与幻觉容忍度生成式搜索另一个重灾区是引用。模型经常给出一个看似靠谱的引用点进去发现根本没说那句话。我定义了一个引用准确率对答案中的每一个引用标记去查被引用的文档内容是否真的包含对应的断言。不是看标题是看具体句子。计算方式可以按每个reference粒度统计引用准确率 命中断言数 / 总引用数如果答案里包含了未经检索信息支持的内容但又没标注引用这种情况我记为幻觉。幻觉容忍度不是必须为零实际上不同场景容忍度差异很大。比如健康建议和投资建议容忍度极低娱乐八卦和社区导购容忍度可以放松一些。所以我会在评测配置里加一个业务等级参数0为零容忍1为可容忍轻微总结性幻觉。3.3 端到端任务成功率三层评估里最贴近用户感知的就是任务成功率。这里不限制模型怎么生成只看用户目标是否达成。我会把测试集里的query拆成两类信息获取类和决策推荐类。信息获取类看关键信息是否准确完整决策推荐类看是否给出明确倾向并附带理由。这个指标我用多种方式交叉验证。人工标注当然是最准的但如果评测集大可以用约束较强的LLM-as-Judge来近似。我写过一个judge prompt明确要求模型必须使用“给定标准答案”和“用户意图”两个文件输出“完成/未完成理由”。事后抽查了一百条跟人工标注的一致性在0.85以上算是一个可接受的水位。4. 实操过程跑通一次完整的Eval纸上谈兵说得够多了把整套流程跑一遍才是正事。这里分享一次完整的Eval流程从环境准备到结果输出我用的都是相对常见的开源库稍加配置就能复现。4.1 环境与配置首先我要保证检索服务、生成模型和评估模型三者分开。检索服务我用的是本地开源的ES配合embedding模型生成模型走内部推理接口评估模型单独租了一台A10跑NLI和打分队列。整体环境大概长这样# Python 3.10 pip install elasticsearch transformers torch pandas评测配置我建议全部用JSON文件管理方便不同版本间快速diff。下面是一段配置节选{ eval_name: futuresearch_v1, dataset_path: ./data/queries.jsonl, retrieval: { top_k: 5, min_score: 0.7 }, generation: { max_length: 1024, temperature: 0.2 }, scoring: { faithfulness_model: MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli, task_model: qwen2.5-72b-instruct } }4.2 编写评测脚本评测脚本的核心逻辑是“对每一条query执行检索生成然后分别跑三层评分”。我把它拆成了两个Python文件一个负责生成回答一个负责打分。不能让生成和打分耦合在一个进程里否则模型切换时容易互相干扰。下面是生成部分的简化版def generate_answer(query, retriever, generator): docs retriever.search(query, top_kcfg[retrieval][top_k]) context \n\n.join(docs[text]) prompt f请基于下列资料回答问题需要标注引用编号。资料如下\n{context}\n\n问题{query} return generator(prompt, max_length1024)打分部分要处理三件独立的事情Fact层提取答案中的断言逐一跑NLI判断是否被证据文本蕴含。Answer层直接调LLM打分模型输入queryanswerjudge规则输出分数。Task层调用带函数定义的LLM抽取任务结果并比对成功条件。如果你不想从零写也可以直接基于开源评估框架比如ragas或者DeepEval做二次开发。但我会建议至少把检索结果和生成结果存成快照否则排查问题的时候根本拿不到输入输出。4.3 结果分析与可视化一次评估跑下来会得到几百条样本的详细打分。我不建议只看总分至少要看“分数分布”和“失败样本聚类”。我在项目里会把低分样本单独抽出来做聚类看看是哪些query导致分数偏低。经常发现的问题无非三类query有歧义、资料缺失、检索召回差。一个很有用的展示方式是画一个二维散点图X轴是忠实度Y轴是覆盖度或任务成功率。这样能直观看到大部分答案聚集在哪个区域。如果散布在左下角说明整个系统的基础能力有问题如果分布很散说明不同query之间的表现差异大需要优先处理。我还会记录每一条样本的生成参数温度、top_p方便复现。这些经验非常重要因为同一个prompt温度稍微调一调忠实度就能波动好几个点。5. 常见问题与排查技巧实录这部分内容都是我从实际反馈里一条条记下来的有些坑看着不起眼真能卡住你一整天。5.1 模型随机性导致评估不稳定不少人跑评估的时候会发现今天分数0.82明天同一套数据变成0.79。这个不一定是你系统变差了很可能只是采样随机性。生成模型温度调高后回答的措辞变化会直接影响断言拆解和NLI判断。我的对策是评估时把temperature设为0.2甚至0再做三次独立运行取中位数而不是均值。出于复用考虑也可以设定固定的随机种子确保同一个模型版本在同样输入下输出尽量一致。虽然完全复现不可能但至少把随机因素控制在可接受范围内。5.2 评估集污染问题这点极其关键。如果你的评测集被模型训练语料覆盖了那模型相当于“背过答案”分数完全失真。我在构建Futuresearch Evals后期意识到那些来自公开搜索日志的query只要被互联网真实验证过就很容易被后续训练的模型见过。处理方案有两种。一是构建动态评测集每季度更新一批不对外公开的新query二是加“遗忘校验”拿一批明显超出模型训练时间线的query做基线如果这类query分数显著高于普通query说明可能发生数据泄露。不管哪种方案都要给评测集加上生成时间戳并记录每一版模型的评测历史别拿陈年数据反复测。5.3 人为打分 vs 自动评估怎么选自动评估跑得快但有时候会犯低级错误人为打分准确度高但成本也高。我的经验是快节奏迭代阶段完全依赖自动评估但每周抽100条做一次人工复核用于校准自动评估的偏移。如果发现自动评估出现系统性偏差比如对某类query总是打高分就及时调整prompt或标注规则。有一个小技巧在自动评估的输出里强制加入了“置信度”字段。模型对自己打出的分数给出置信度置信度低的样本优先进入人工复核队列。这样人工不看全部样本只看容易出错的边界样本效率会高很多。我试过一开始就让标注团队介入结果大量样本被标记为“不确定”焦点全跑偏。后来改成“自动初筛人工复核边界样本”整体评估效率至少提升一倍。6. 写在新一版迭代之前的话我目前的流程已经跑通但仍在不断调整。Futuresearch Evals 最大的意义不是给出一个万能的分数而是让团队在讨论“搜索好不好”时有了共同语言。以前开会大家各凭感觉你说“效果很好”是因为你随手测了几个case我说“效果不行”是因为我那几个case刚好翻车。有了统一评估集和指标咱们就事论事看同一份报告聊同一个问题。最后再分享一个小技巧每次跑Eval不管结果好坏一定要把失败样本单独存在一个文件夹里并附上检索到的参考资料片段。这些失败样本就是更新评测集、优化模型的富矿。不要老盯着指标涨跌多翻翻失败样本你会发现很多问题在指标上根本看不出来比如答案重复、语气不对、引导性太强。这些问题不像事实错误那么容易被量化但用户第一眼感受非常明显。只有把失败样本当成长期资产Futuresearch Evals 这套体系才能真正在你的场景里落地生根。