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

发布时间:2026/7/17 17:57:13

RAG 优化:从评测集到 RAGAS 的完整实战 做 RAG 优化时最容易出现一种假象参数改了不少Demo 里的几个问题也答得更顺了于是大家默认“效果有提升”。比如把 Chunk Size 从 500 调到 800换一版 Embedding再加上 BM25 和 Rerank。改完以后挑几个熟悉的问题试一遍答案确实比之前像样。可一旦问“到底提升了多少”“哪些问题变好了”“有没有问题反而变差”往往就说不清了。我在项目里越来越不相信这种“手感”。原因很简单随手测试的问题可能刚好是系统最擅长的错误码查询变好了长问题却可能退化答案看着没错也可能只是模型凭自身知识答对检索结果根本没有提供有效证据。所以RAG 优化真正的起点不是换模型也不是继续调 Top K而是先建立一把稳定的尺子。至少要回答四件事正确资料有没有被找到找到的内容里有多少真正有用模型有没有基于这些资料回答质量提升是否值得新增的延迟和成本这篇文章就从这四个问题出发搭一套可以重复运行的 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_typeFAQ / PDF / 表格 / API 文档 / 制度 difficulty简单 / 中等 / 困难 risk普通 / 财务 / 法务 / 医疗 / 权限 language中文 / 英文 / 中英混合总体 Recall5 从 0.82 涨到 0.86看起来不错。但如果分桶后发现普通问答提升 8%表格问题下降 12%结论就完全不同。平均分适合看趋势分桶结果才适合找原因。问题从哪里来真实业务数据的优先级最高线上搜索与失败日志、客服工单、人工答疑、点踩和追问都比开发者凭空编出的“标准问题”更有价值。系统还没上线时可以从文档生成问题但要专门补充真实用户的表达变体类型标准问法更接近真实输入的问法口语化如何重置登录密码密码忘了咋整缩写如何配置单点登录SSO 怎么开错别字发票如何申请发漂在哪开精确实体ERR_CONN_RESET_1007 如何处理1007 报错多轮指代Mac 客户端如何清缓存那 Mac 呢版本冲突4.2 版如何配置代理新版代理设置在哪无答案是否支持离线导出没网能不能批量导出第一版做 100300 条就够了。200 条经过业务人员确认、证据清晰的样本远比 5000 条未经审核的合成数据有用。高风险样本最好双人复核有争议的样本单独标记不要为了凑数据强行写出一个“标准答案”。三、检索指标不必全上关键是选对假设某个问题有两个相关文档A和C系统返回前 5 条排名1 2 3 4 5 结果B A D E C 相关否 是 否 否 是Hit RateK最直观前 K 条里只要出现一个相关结果就算命中。它适合回答“有没有找到”但不关心找全没有也不关心答案排第一还是排第五。RecallK看应该找到的证据找回了多少RecallK 前 K 条中的相关结果数 / 全部相关结果数上例中Recall3 0.5Recall5 1.0。多文档总结和多跳问答尤其依赖Recall因为漏掉一条关键证据答案就可能不完整。PrecisionK看送进上下文的内容有多少真正有用PrecisionK 前 K 条中的相关结果数 / K上例的Precision5 0.4。证据虽然找全了但上下文中仍有 60% 的噪声。这类问题通常要从候选数量、过滤规则和 Rerank 入手。MRR只关心第一个正确结果排得多靠前RR 1 / 第一个相关结果的排名 MRR 所有问题 RR 的平均值上例第一个相关结果排第二因此 RR 为 0.5。FAQ、客服等通常只需要一个主要答案的场景MRR 很实用。nDCGK适合存在多级相关性的情况。比如直接且完整的证据记 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 RecallContext 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 \ langchain1.1.0 \ langchain-openai1.1.0 \ langchain-community0.4.1 \ ragas0.3.9 \ pandas2,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_KEYyour-api-key# macOS / Linux export OPENAI_API_KEYyour-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_input、response、retrieved_contexts和reference。旧教程里的question、answer、contexts、ground_truth不要混进来。接着配置 Judgefrom langchain_openai import ChatOpenAI, OpenAIEmbeddings from ragas.llms import LangchainLLMWrapper from ragas.embeddings import LangchainEmbeddingsWrapper judge_llm LangchainLLMWrapper( ChatOpenAI(modelgpt-4.1-mini, temperature0) ) judge_embeddings LangchainEmbeddingsWrapper( OpenAIEmbeddings(modeltext-embedding-3-small) )生成模型和 Judge 不必相同。重要实验最好不要让同一个模型既当选手又当裁判并先用 3050 条人工确认的样本校准 Judge。需要说明的是RAGAS 0.3.9 已经将LangchainLLMWrapper和LangchainEmbeddingsWrapper标记为弃用但这两个类在上述锁定版本中仍能正常使用。本文保留它们是为了与 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(llmjudge_llm) answer_relevancy AnswerRelevancy( llmjudge_llm, embeddingsjudge_embeddings, ) context_precision LLMContextPrecisionWithReference(llmjudge_llm) context_recall LLMContextRecall(llmjudge_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 不能替代确定性指标只要评测集标注了相关文档 IDHit Rate、Recall 和 MRR 就可以直接计算不必调用 LLMdef 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, start1): if doc_id in relevant: return 1.0 / rank return 0.0这些指标便宜、稳定而且能直接告诉你检索器有没有命中标注结果。完整报告应该同时包含确定性检索指标、RAGAS 指标、延迟和成本。六、怎么公平比较不同方案假设要比较三套链路方案 A纯向量检索 方案 B向量检索 BM25 RRF 方案 C混合检索 Rerank知识库快照、评测集、生成模型、Prompt、上下文 Token 预算、权限过滤、Judge 和评测 Prompt 都要固定。否则知识库刚好更新了一批文档也可能被误判成 Rerank 带来的提升。方案Recall5MRRFaithfulnessP95 延迟单次成本A纯向量0.780.690.82420 ms¥0.018B混合检索0.860.760.85560 ms¥0.019C混合 Rerank0.880.840.91910 ms¥0.026表中数字只用于展示报告结构不代表任何方案的通用性能。如果业务要求 P95 小于 700 ms方案 C 即使质量最好也不适合直接全量上线。更现实的做法可能是默认走方案 B只对低置信度或高价值问题启用 Rerank。评测不是一场单纯的分数竞赛。最终要找的是在质量、延迟、成本和风险之间满足业务约束的方案。七、让评测真正进入开发流程一套评测脚本只在上线前跑一次价值很有限。它应该和单元测试一样跟着系统持续更新。可以把数据拆成两部分一份固定回归集用来观察每次改动有没有破坏已有能力一份挑战集专门放表格、多跳、版本冲突、无答案等系统容易失败的问题。线上点踩、转人工和异常引用经过脱敏、复核后也应补进回归集。质量门禁不必照抄别人的阈值可以从自己的业务约束出发。例如总体 Recall5 不得下降超过 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 和生成模型都可能改善一类问题同时破坏另一类问题。一套够用的起步方案其实并不复杂先整理 100300 条真实问题标注参考答案和证据同时计算 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%免费】

相关新闻