news 2026/7/17 17:57:02

RAG 优化:从评测集到 RAGAS 的完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RAG 优化:从评测集到 RAGAS 的完整实战

做 RAG 优化时,最容易出现一种假象:参数改了不少,Demo 里的几个问题也答得更顺了,于是大家默认“效果有提升”。

比如把 Chunk Size 从 500 调到 800,换一版 Embedding,再加上 BM25 和 Rerank。改完以后,挑几个熟悉的问题试一遍,答案确实比之前像样。可一旦问“到底提升了多少”“哪些问题变好了”“有没有问题反而变差”,往往就说不清了。

我在项目里越来越不相信这种“手感”。原因很简单:随手测试的问题可能刚好是系统最擅长的;错误码查询变好了,长问题却可能退化;答案看着没错,也可能只是模型凭自身知识答对,检索结果根本没有提供有效证据。

所以,RAG 优化真正的起点不是换模型,也不是继续调 Top K,而是先建立一把稳定的尺子。至少要回答四件事:

  1. 正确资料有没有被找到?
  2. 找到的内容里有多少真正有用?
  3. 模型有没有基于这些资料回答?
  4. 质量提升是否值得新增的延迟和成本?

这篇文章就从这四个问题出发,搭一套可以重复运行的 RAG 评测流程。

一、先别急着看最终答案

假设用户问:

Windows 客户端出现 ERR_CONN_RESET_1007,应该怎么处理?

系统回答:

请关闭系统代理、清理客户端缓存,然后重新登录。

答案没有问题,但它背后的链路可能完全不同:

  • 检索到了 4.2 版操作手册,模型按资料作答;
  • 检索到了旧版文档,模型靠参数知识碰巧答对;
  • 新旧文档同时被召回,模型这一次恰好选对了。

从用户眼前这一句话看,三种情况没有区别;从系统可靠性看,只有第一种值得信任。后两种换个问法、换个模型,甚至只是提高一点 Temperature,就可能露出问题。

因此,一次完整评测至少要拆成三层:

检索层看正确证据是否进入候选集、排名是否足够靠前,常用 Hit Rate、Recall、MRR 和 nDCG。

生成层看回答是否忠于上下文、是否真正回答问题、是否覆盖参考答案,常用 Faithfulness、Answer Relevancy 和 Answer Correctness。

业务层才看问题解决率、转人工率、追问率、P95 延迟和单次成本等线上结果。

这三层解决的是不同问题。检索层回答“找没找到”,生成层回答“用没用对”,业务层回答“值不值得上线”。只保留一个总分,定位问题时几乎一定会抓瞎。

二、评测集才是优化的地基

评测集不需要一开始就做得很大,但必须让不同方案在同一批问题、同一套标注下比较。一条实用的样本可以长这样:

{ "id": "support-001", "question": "Windows 客户端出现 1007 错误怎么办?", "reference_answer": "关闭系统代理,清理客户端缓存后重新登录。", "relevant_doc_ids": ["error-guide-4.2"], "relevant_chunk_ids": ["error-guide-4.2#section-6#chunk-2"], "answerable": true, "filters": { "platform": "windows", "status": "active" }, "tags": ["error_code", "short_query"] }

这里有三类信息尤其容易被省略:文档与 Chunk 的相关 ID、问题是否可回答,以及用于分桶分析的标签。

文档 ID 和 Chunk ID 都要留

系统命中一份 80 页的产品手册,不代表它找到了答案。如果真正包含处理步骤的 Chunk 没进上下文,生成模型仍然无从作答。

relevant_doc_ids用来判断方向是否正确,relevant_chunk_ids则判断证据是否真的到位。只做文档级标注,结果通常会比实际效果乐观。

别让所有问题都有答案

如果评测集里每个问题都能在知识库中找到答案,你测出来的只是“回答能力”,而不是“知道什么时候不该回答”。

第一版可以放入 10%~20% 的无答案样本,例如:知识库尚未覆盖的新功能、缺少必要条件的问题、无权限访问的资料、带有错误前提的问题。对这些样本,合格的行为可能是说明证据不足、追问必要信息或转人工。

用标签暴露平均分背后的问题

建议至少按查询类型、文档类型、难度和风险打标签:

query_type:语义问题 / 关键词 / 错误码 / 多跳 / 多轮 document_type:FAQ / PDF / 表格 / API 文档 / 制度 difficulty:简单 / 中等 / 困难 risk:普通 / 财务 / 法务 / 医疗 / 权限 language:中文 / 英文 / 中英混合

总体 Recall@5 从 0.82 涨到 0.86,看起来不错。但如果分桶后发现普通问答提升 8%,表格问题下降 12%,结论就完全不同。平均分适合看趋势,分桶结果才适合找原因。

问题从哪里来

真实业务数据的优先级最高:线上搜索与失败日志、客服工单、人工答疑、点踩和追问,都比开发者凭空编出的“标准问题”更有价值。

系统还没上线时,可以从文档生成问题,但要专门补充真实用户的表达变体:

类型标准问法更接近真实输入的问法
口语化如何重置登录密码?密码忘了咋整
缩写如何配置单点登录?SSO 怎么开
错别字发票如何申请?发漂在哪开
精确实体ERR_CONN_RESET_1007 如何处理?1007 报错
多轮指代Mac 客户端如何清缓存?那 Mac 呢?
版本冲突4.2 版如何配置代理?新版代理设置在哪
无答案是否支持离线导出?没网能不能批量导出

第一版做 100~300 条就够了。200 条经过业务人员确认、证据清晰的样本,远比 5000 条未经审核的合成数据有用。高风险样本最好双人复核,有争议的样本单独标记,不要为了凑数据强行写出一个“标准答案”。

三、检索指标不必全上,关键是选对

假设某个问题有两个相关文档AC,系统返回前 5 条:

排名:1 2 3 4 5 结果:B A D E C 相关:否 是 否 否 是

Hit Rate@K最直观:前 K 条里只要出现一个相关结果就算命中。它适合回答“有没有找到”,但不关心找全没有,也不关心答案排第一还是排第五。

Recall@K看应该找到的证据找回了多少:

Recall@K = 前 K 条中的相关结果数 / 全部相关结果数

上例中Recall@3 = 0.5Recall@5 = 1.0。多文档总结和多跳问答尤其依赖Recall,因为漏掉一条关键证据,答案就可能不完整。

Precision@K看送进上下文的内容有多少真正有用:

Precision@K = 前 K 条中的相关结果数 / K

上例的Precision@5 = 0.4。证据虽然找全了,但上下文中仍有 60% 的噪声。这类问题通常要从候选数量、过滤规则和 Rerank 入手。

MRR只关心第一个正确结果排得多靠前:

RR = 1 / 第一个相关结果的排名 MRR = 所有问题 RR 的平均值

上例第一个相关结果排第二,因此 RR 为 0.5。FAQ、客服等通常只需要一个主要答案的场景,MRR 很实用。

nDCG@K适合存在多级相关性的情况。比如直接且完整的证据记 3 分,只覆盖部分答案记 2 分,主题相关但无法回答记 1 分。它既看相关性,也看排序位置,比简单命中更接近真实的检索体验。

实际项目不必把所有指标塞进仪表盘。单答案 FAQ 可以先看 Hit Rate 和 MRR;多文档问答重点看 Recall 和 nDCG;进入最终上下文的内容则重点看 Precision。指标越多不等于判断越准,能对应到具体优化动作才有价值。

四、生成质量到底在评什么

检索正确,不代表答案一定正确。生成阶段至少要分清下面几件事。

Faithfulness:有没有脱离资料发挥

上下文只说“支持 Windows 和 macOS”,回答却补了一句“也支持 Linux”,即使现实中碰巧如此,对当前 RAG 链路来说仍然是不忠实的。Faithfulness 检查的是回答中的事实能否得到上下文支持。

Answer Relevancy:有没有正面回答

用户问“年假有多少天”,模型完整复述了休假申请流程,却没有给出天数。这段回答可能句句有出处,但仍然没有解决问题。

Answer Correctness:和参考答案是否一致

这个指标通常需要reference_answer。参考答案应包含必须出现的事实,不必写成长篇范文,更不要要求生成答案逐字匹配。

Context Precision 与 Context Recall

Context Precision 关心检索上下文中是否混入太多噪声,Context Recall 关心回答需要的事实是否都被上下文覆盖。它们和基于文档 ID 的 Precision、Recall 视角不同,最好同时保留。

如果产品要求附带来源,还应单独检查 Citation Correctness:引用是否存在、版本是否有效、片段是否真的支撑对应结论、用户是否有查看权限。答案末尾挂几个链接,不等于引用可靠。

五、用 RAGAS 把评测跑起来

RAGAS 把 Faithfulness、Answer Relevancy、Context Precision、Context Recall 等指标封装成了可批量执行的流程。它适合扩大评测覆盖面,但不是“客观裁判”:Judge 模型、Prompt、参考答案质量和模型版本变化都会影响得分。

下面基于LangChain 1.1.0、langchain-openai 1.1.0 和 RAGAS 0.3.9验证。RAGAS 的 API 迭代较快,langchain-community的模块结构也发生过变化,因此这里锁定完整依赖组合,而不是只限制大版本范围。

pip install \ "langchain==1.1.0" \ "langchain-openai==1.1.0" \ "langchain-community==0.4.1" \ "ragas==0.3.9" \ "pandas>=2,<3"

这里特意将langchain-community固定为 0.4.1。RAGAS 0.3.9 仍会导入langchain_community.chat_models.vertexai,而该模块在 0.4.2 中已经移除;如果不锁定版本,安装可能成功,运行时却会出现ModuleNotFoundError

运行前还需要设置 OpenAI API Key。不要把密钥直接写进代码或提交到仓库:

# Windows PowerShell $env:OPENAI_API_KEY="your-api-key"
# macOS / Linux export OPENAI_API_KEY="your-api-key"

准备两条样本:

samples = [ { "user_input": "Windows 客户端出现 1007 错误怎么办?", "response": "关闭系统代理,清理客户端缓存后重新登录。", "retrieved_contexts": [ ( "Windows 客户端出现 ERR_CONN_RESET_1007 时," "先关闭系统代理,清理客户端缓存,然后重新登录。" ), "网络连接失败时,可检查防火墙、DNS 和代理配置。", ], "reference": "关闭系统代理,清理客户端缓存后重新登录。", }, { "user_input": "客户端支持 Linux 离线导出吗?", "response": "现有资料中没有说明 Linux 离线导出能力。", "retrieved_contexts": ["桌面客户端当前支持 Windows 和 macOS。"], "reference": "知识库信息不足,应明确说明无法确认。", }, ]

这里使用的是新版字段user_inputresponseretrieved_contextsreference。旧教程里的questionanswercontextsground_truth不要混进来。

接着配置 Judge:

from langchain_openai import ChatOpenAI, OpenAIEmbeddings from ragas.llms import LangchainLLMWrapper from ragas.embeddings import LangchainEmbeddingsWrapper judge_llm = LangchainLLMWrapper( ChatOpenAI(model="gpt-4.1-mini", temperature=0) ) judge_embeddings = LangchainEmbeddingsWrapper( OpenAIEmbeddings(model="text-embedding-3-small") )

生成模型和 Judge 不必相同。重要实验最好不要让同一个模型既当选手又当裁判,并先用 30~50 条人工确认的样本校准 Judge。

需要说明的是,RAGAS 0.3.9 已经将LangchainLLMWrapperLangchainEmbeddingsWrapper标记为弃用,但这两个类在上述锁定版本中仍能正常使用。本文保留它们,是为了与 LangChain 1.1.0 组成一套经过验证、可以复现的示例;后续升级 RAGAS 时,应按照对应版本文档迁移到llm_factory和新的 Embedding Provider。

最后执行四个指标:

import asyncio from ragas.dataset_schema import SingleTurnSample from ragas.metrics import ( AnswerRelevancy, Faithfulness, LLMContextPrecisionWithReference, LLMContextRecall, ) faithfulness = Faithfulness(llm=judge_llm) answer_relevancy = AnswerRelevancy( llm=judge_llm, embeddings=judge_embeddings, ) context_precision = LLMContextPrecisionWithReference(llm=judge_llm) context_recall = LLMContextRecall(llm=judge_llm) async def evaluate_sample(item): sample = SingleTurnSample(**item) return { "faithfulness": await faithfulness.single_turn_ascore(sample), "answer_relevancy": await answer_relevancy.single_turn_ascore(sample), "context_precision": await context_precision.single_turn_ascore(sample), "context_recall": await context_recall.single_turn_ascore(sample), } async def main(): results = [] for item in samples: results.append(await evaluate_sample(item)) print(results) asyncio.run(main())

上面的asyncio.run(main())适合保存为 Python 脚本后直接运行。如果在 Jupyter Notebook 中执行,由于 Notebook 已经启动事件循环,最后一行应改为:

await main()

样本量上来以后,还要补并发限制、超时、重试、结果缓存、单样本错误隔离和费用统计。低分样本最好保存 Judge 的判断理由,否则最后只剩一个分数,很难排查。

RAGAS 不能替代确定性指标

只要评测集标注了相关文档 ID,Hit Rate、Recall 和 MRR 就可以直接计算,不必调用 LLM:

def hit_rate_at_k(retrieved_ids, relevant_ids, k): return float(bool(set(retrieved_ids[:k]) & set(relevant_ids))) def recall_at_k(retrieved_ids, relevant_ids, k): relevant = set(relevant_ids) if not relevant: return 0.0 return len(set(retrieved_ids[:k]) & relevant) / len(relevant) def reciprocal_rank(retrieved_ids, relevant_ids): relevant = set(relevant_ids) for rank, doc_id in enumerate(retrieved_ids, start=1): if doc_id in relevant: return 1.0 / rank return 0.0

这些指标便宜、稳定,而且能直接告诉你检索器有没有命中标注结果。完整报告应该同时包含确定性检索指标、RAGAS 指标、延迟和成本。

六、怎么公平比较不同方案

假设要比较三套链路:

方案 A:纯向量检索 方案 B:向量检索 + BM25 + RRF 方案 C:混合检索 + Rerank

知识库快照、评测集、生成模型、Prompt、上下文 Token 预算、权限过滤、Judge 和评测 Prompt 都要固定。否则,知识库刚好更新了一批文档,也可能被误判成 Rerank 带来的提升。

方案Recall@5MRRFaithfulnessP95 延迟单次成本
A:纯向量0.780.690.82420 ms¥0.018
B:混合检索0.860.760.85560 ms¥0.019
C:混合 + Rerank0.880.840.91910 ms¥0.026

表中数字只用于展示报告结构,不代表任何方案的通用性能。

如果业务要求 P95 小于 700 ms,方案 C 即使质量最好,也不适合直接全量上线。更现实的做法可能是:默认走方案 B,只对低置信度或高价值问题启用 Rerank。

评测不是一场单纯的分数竞赛。最终要找的是在质量、延迟、成本和风险之间满足业务约束的方案。

七、让评测真正进入开发流程

一套评测脚本只在上线前跑一次,价值很有限。它应该和单元测试一样,跟着系统持续更新。

可以把数据拆成两部分:

一份固定回归集,用来观察每次改动有没有破坏已有能力;

一份挑战集,专门放表格、多跳、版本冲突、无答案等系统容易失败的问题。线上点踩、转人工和异常引用经过脱敏、复核后,也应补进回归集。

质量门禁不必照抄别人的阈值,可以从自己的业务约束出发。例如:

总体 Recall@5 不得下降超过 1% 错误码分桶 MRR 不得低于 0.85 无答案拒答准确率不得低于 0.90 高风险样本必须通过人工审核 P95 延迟不得超过 800 ms 单次平均成本不得增加超过 20%

每次运行还要记录数据集版本、知识库快照、Chunk 策略、Embedding、索引、Retriever、Reranker、Prompt、生成模型、Judge 和代码版本。否则几周后再看到一条Faithfulness = 0.91,很可能已经不知道它是怎么跑出来的。

LLM-as-a-Judge 也要定期抽检。它可能偏爱长答案,可能偏好与自己风格相似的表达,也可能因为模型升级改变评分尺度。自动评测适合做大范围回归和筛查,财务、法务、医疗等高风险结论仍然需要领域人员确认。

八、总结

RAG 难优化,不是因为没有参数可调,而是因为可调的地方太多。Chunk、Embedding、Top K、混合检索、Rerank、Prompt 和生成模型都可能改善一类问题,同时破坏另一类问题。

一套够用的起步方案其实并不复杂:先整理 100~300 条真实问题,标注参考答案和证据;同时计算 Recall、MRR 等确定性指标与 RAGAS 指标;按标签查看退化;最后把质量、延迟和成本放在同一张报告里比较。

不必一开始就搭评测平台。一份版本化的 JSONL、一个可重复运行的脚本、一份能看到 Bad Case 的对比报告,已经比“改完随手问几个问题”可靠得多。

评测不是 RAG 优化的收尾工作,而是每一次“效果变好了”能够成立的前提。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 17:52:41

VibeThinker-3B高级应用:长文本处理与复杂任务拆解指南

VibeThinker-3B高级应用&#xff1a;长文本处理与复杂任务拆解指南 【免费下载链接】VibeThinker-3B 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/VibeThinker-3B VibeThinker-3B是一款基于Qwen2架构的轻量级AI模型&#xff0c;特别优化了长文本处理和…

作者头像 李华
网站建设 2026/7/17 17:50:03

CANN Ascend C int转bfloat16函数

__int2bfloat16_ru 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitc…

作者头像 李华
网站建设 2026/7/17 17:49:59

小程序毕业设计-基于 SpringBoot + 微信小程序乡村医患沟通与线上就诊预约小程序设计 乡镇智慧医疗预约咨询平台的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/17 17:49:20

小程序毕设项目:基于 SpringBoot + 小程序的教学公开课运维系统 校园优质公开课浏览收藏平台的设计与实现 (源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/17 17:47:14

2026 四款云手机风控防护横评 桃心云分层隔离防关联功能深度实测

多账号运营最核心痛点为平台风控检测、账号批量限流封禁&#xff0c;市面多数云手机仅做基础设备参数伪装&#xff0c;防护逻辑单一。本次选取多多云、红手指、繁星云、桃心云四款主流产品&#xff0c;围绕底层沙箱隔离、行为时序错开、IP 分组管控、异常行为预警四大风控维度统…

作者头像 李华