1. 从"凭感觉调优"到"可量化度量":RAG评测的痛点与转机
做RAG落地最让人头疼的一件事,不是文档切得不好,不是Embedding模型选得不对,而是——当用户反馈"回答质量不稳定"时,你根本说不清问题出在哪一环。是检索召回了一堆无关片段?还是大模型没忠实依据上下文回答?还是用户的问题本身就不是一个适合RAG回答的问题?
我最早做RAG项目时,评测方式是典型的"人工抽样+肉眼判断":拉一批测试问题,一个个跑,一个个看,然后凭感觉说"好像还行"。这套方法在小规模demo阶段勉强够用,一旦进入生产环境维护期,问题就暴露了:你改了chunk大小,效果是变好了还是变差了?换了个Embedding模型,检索准确率提升了多少?Prompt里加了一句约束,会不会反而导致忠实性下降?这些问题如果没有一套标准化的评测机制,根本无从回答。
后来我开始接触Ragas和DeepEval这两个评测框架,意识到一件事:RAG评测这件事本身,是可以工程化的。把评测指标固化下来,把测试集管理起来,把评测脚本跑进CI流水线里,每次代码变更、参数调整、模型替换都能自动拉出一份质量报告——这时候RAG系统才算真正进入了"可度量、可回归、可追踪"的阶段。
这篇文章就围绕我实际搭建的一套RAG质量评测流水线展开,覆盖三个核心部分:评测指标的底层原理与选型、Ragas与DeepEval双框架的实战脚本设计、以及如何把评测流程嵌进GitHub CI实现自动化回归。适合正在做RAG落地、被"效果评估"困扰的团队参考,也适合想系统了解RAG评测体系的开发者阅读。
2. 为什么同时用Ragas和DeepEval:两套框架的评测哲学差异
先说结论:Ragas和DeepEval不是二选一的关系,而是互补关系。我最终选择双框架并行,不是因为哪个框架不够好,而是因为它们各自擅长的层面确实不一样。
2.1 Ragas:以RAG链路为核心的指标设计
Ragas(RAG Assessment的缩写词)在设计之初,就是冲着"评估RAG系统整体质量"去的。它的核心指标分两个维度:一个是评测检索组件,一个是评测生成组件。
检索侧的指标是Context Precision(上下文精确率)和Context Recall(上下文召回率)。简单说,精确率衡量的是"检索出来的这些片段里,有多少是真正相关的",召回率衡量的是"所有应该被检索到的相关片段,到底被找回来了多少"。这两个指标直接对标传统信息检索领域的Precision和Recall,但Ragas把它适配到了RAG场景——通过LLM作为评判员,判断每个检索片段与标准答案之间的相关性。
生成侧的指标是Faithfulness(忠实性)和Answer Relevance(答案相关性)。Faithfulness检查的是"生成的答案是否严格基于检索到的上下文,有没有自己编造内容",Answer Relevance检查的是"答案是否真正回应了用户的问题,而不是答非所问"。
这套指标体系的底层逻辑是:把一个端到端的RAG系统拆开,分别度量各个内部环节,从而定位问题源头。如果Faithfulness低,问题大概率出在Prompt设计或模型能力上;如果Context Recall低,问题大概率出在检索链路(切分策略、Embedding模型、TopK设置)上。
2.2 DeepEval:更像一个完整的LLM测试单元测试框架
DeepEval的定位和Ragas有些不同。它的核心概念是Test Case和Metric,用起来的感觉像是在给LLM写单元测试。你定义好测试输入、期望输出(或者不定义,让LLM自己评估)、检索到的上下文,然后选择相应的指标进行评估。
DeepEval的指标体系更宽泛一些,除了RAG常见的Answer Relevancy、Faithfulness、Contextual Precision、Contextual Recall,还有Bias(偏见检测)、Toxicity(毒性检测)、RAGAS系列指标(没错,DeepEval里直接内置了Ragas指标的实现)等。它还支持自定义指标,这意味着你可以针对自己的业务定义专用评估标准。
更关键的是,DeepEval提供了Pytest集成功能。这意味着你不需要自己写一套评测调度逻辑,只需要把每个测试用例写成Pytest参数化测试,然后运行pytest命令,就能把评测报告集成到JUnit XML里——这在CI/CD环境里简直不要太顺手。
2.3 双框架并行的工作分工
在实际流水线里,我的分工是这样的:
| 职责 | 使用框架 | 原因 |
|---|---|---|
| 生成侧指标评估(忠实性、答案相关性) | Ragas | Ragas对RAG场景的指标定义更成熟,论文支撑完善,Faithfulness评估的思路更适合RAG链路诊断 |
| 检索侧指标评估(上下文精确率/召回率) | Ragas | 指标定义清晰,与LangChain集成方便 |
| CI中的单元测试式回归 | DeepEval | 原生Pytest集成,失败阈值控制简单,JUnit报告生成方便 |
| 自定义业务指标(如答案关键词覆盖率) | DeepEval | 自定义Metric的接口简洁,Python装饰器风格上手快 |
当然,如果你只想用一个框架,也完全跑得通。Ragas在生成侧指标上更专业,DeepEval在工程集成上更顺手。双框架并行的代价是多维护一套依赖和配置,对于评测体系刚起步的团队,我建议先选一个跑通再做扩展——不需要一开始就上双框架。
3. 指标选型的底层逻辑:理解评测指标"到底在评什么"
很多人在选RAG评测指标时是盲目的——看到别人用什么指标就跟着用什么。但指标选型本质上取决于一个更根本的问题:你希望RAG系统在哪个环节上做到什么标准?
3.1 忠实性(Faithfulness):最不该被忽视的指标
Faithfulness的评估逻辑是:把生成的答案拆解成若干条独立陈述(claim),然后逐一检查每条陈述是否能从检索到的上下文中找到依据。找到依据的陈述占比越高,Faithfulness分数越高。
这个指标特别重要,是因为RAG系统的核心价值就是"基于知识库回答",如果模型频繁脱离知识库自由发挥,那RAG就退化成了一般的LLM聊天,知识库的存在意义也就没了。我见过太多RAG项目,答案看起来流畅自然,但深入核对后发现大量内容根本不在知识库里——这时候Faithfulness必然低得离谱。
Faithfulness低通常有几种原因:一是Prompt里没有强约束"仅基于上下文回答";二是检索到的上下文太少,模型被迫根据自己的知识来补全;三是知识库本身内容与问题相关度不够,模型"接不住话"就只能自圆其说。
3.2 答案相关性(Answer Relevancy):评估"是否答非所问"
Answer Relevancy的评估逻辑稍有不同:它会基于生成的答案反向生成若干相关问题,然后计算这些问题与原问题之间的相似度。如果答案能让LLM推断出"用户可能问的问题"和实际问题高度重合,说明答案本身就是切题的。
这个指标有两个特点需要注意。第一,它的评估依赖LLM的理解能力,所以评测用的LLM(即"评判模型")质量很重要,我一般会用GPT-4级别或Claude级别的模型来当评判者,不太建议用太弱的模型。第二,反向生成问题的思路在开放式问答里表现良好,但在"多选一"或者事实型检索问答里,偶尔会出现误判——因为模型可能用不同的措辞表达了正确的意思,导致反向生成的问题与原问题文字相似度不高。
3.3 上下文相关性:定位检索环节的质量
Contextual Precision和Contextual Recall解决的是"检索到了没"的问题。
Contextual Precision的逻辑是:把检索结果中与标准答案相关的片段排到越靠前的位置,分数就越高。这其实在评估Rerank(重排)环节的效果——如果第一轮向量检索召回了10个片段,其中5个相关,但重排后这5个全被排到了后五位,那Contextual Precision就会很低,说明Rerank配置有问题。
Contextual Recall的逻辑则是:标准答案中涉及的每一个关键信息点,是否都能在检索到的上下文中找到。这个指标衡量的是召回是否充分。如果一个问题的答案涉及三个事实,但上下文只能支撑两个,这个指标的分数就会打折扣。它是我排查"切分粒度问题"的第一抓手——如果Contextual Recall持续偏低,大概率是文档切分粒度太粗或太细,导致关键信息被切断或遗漏。
3.4 别迷信单一指标:需要建立指标组合的"体检思维"
单一指标高不代表系统好。比如Answer Relevancy很高,但Faithfulness低——这说明模型回答得很"全面"但内容很多是编的。再比如Contextual Recall高但Faithfulness低——说明信息都检索到了,但Prompt约束或模型能力导致生成时偏离了上下文。
我比较推荐的组合是:检索侧看Contextual Recall + Contextual Precision,生成侧看Faithfulness + Answer Relevancy。这样一套下来,能覆盖"召回是否充分—排序是否合理—生成是否忠实—回答是否切题"的完整RAG链路。再多加指标,比如噪声敏感度、完整性等,会让每次评测耗时成倍增加,实际维护起来很累。评测不是指标越多越好,而是够用且能定位问题就好。
4. 评测集设计与管理:把测试数据当成一等公民对待
评测流水线里最容易被低估的环节是测试集。没有一套高质量的评测集,再好的评测框架也是白搭——这就像写单元测试却没有测试用例,框架做得再好也没意义。
4.1 测试集的三种来源与配比
我建议测试集由三部分构成:
真实用户问题沉淀:从线上日志或人工整理中抽取真实用户的提问,这是最宝贵的评测数据。配比建议占总测试集的50%以上。
专家构造的标准问题:针对知识库中的核心知识点,由业务专家或领域专家构造一批"必须回答正确"的问题,配比约30%。
边界与异常问题:包括模糊问题、多轮隐含指代、无答案问题、知识库覆盖不到的问题,配比约20%。这类问题主要用来测试系统的"拒答能力"和"防幻觉能力"——知道什么不知道,其实比什么都敢答更难得。
4.2 标准答案与参考答案的标注规范
有了原始问题还不够,还需要为标准问题标注参考答案或者关键信息点。
Ragas有一种模式叫TestsetGenerator,可以从文档中自动合成测试集——让LLM基于文档内容生成问题和对应的答案。这个方式适合冷启动,但生成的测试集质量良莠不齐,我一般只会在没有真实用户数据时使用它做底料,不会用它替代人工标注。
在标注参考答案时,有一个技巧值得分享:不要只写一个"标准答案"文本,而是建议拆成若干个关键信息点(key points)。比如,针对"什么是Grouped Query Attention"这个问题,参考答案可以拆成"GQA是一种注意力机制优化方案""它将Key和Value头分组共享""目的是减少KV Cache显存占用""是MHA和MQA的折中方案"这四个信息点。这样标注的好处是,在评测Contextual Recall时,可以精确到"哪个信息点没被召回",定位问题的粒度更细。
4.3 评测集的版本管理与增量更新
测试集不是一次性工作,它需要伴随系统的演进而持续更新。我采用的方案是把测试集以JSON或YAML格式放在代码仓库里,由专门的testset/目录管理。字段结构大致如下:
- question: "什么是Grouped Query Attention?" expected_key_points: - "GQA是一种注意力机制优化方案" - "它将Key和Value头分组共享" - "目的是减少KV Cache显存占用" - "是MHA和MQA的折中方案" source_docs: - "docs/llm/attention.md" tag: "core-knowledge"每次知识库文档更新,对应领域的测试问题也需要顺带review一遍,看是否有"原本有答案,文档更新后答案信息点变了"的情况。这一步不跟上,评测集就会慢慢失真,到后面评测分数再高也说明不了问题。
5. 实战脚本编写:Ragas + DeepEval 双引擎评测的完整实现
下面是我实际跑通的一套评测脚本设计。整个流程分四步:准备测试集、运行Ragas评测、运行DeepEval评测、聚合报告。
5.1 环境依赖安装
# Python 3.10+ 环境 pip install ragas deepeval langchain langchain-openai datasets # 如果使用LLM作为评判模型,还需要配置环境变量 export OPENAI_API_KEY="your-api-key"特别提一句:Ragas和DeepEval的版本更新很快,接口变化也挺频繁。我最初写这套脚本时,Ragas用的还是0.1.x版本,接口和现在0.2.x就有不少差异。建议安装时锁定版本,避免流水线突然跑挂。我的requirements.txt里会写死具体版本号:
ragas==0.2.14 deepeval==2.4.6 langchain==0.3.215.2 测试集加载与格式化
先把评测集从YAML或JSON加载成Python对象,转成Ragas和DeepEval各自需要的格式。
import json from datasets import Dataset from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall from ragas import evaluate # 假设testset.json是评测集文件,每项包含question、answer、contexts等字段 with open("testset.json", "r", encoding="utf-8") as f: testset = json.load(f) # Ragas需要HuggingFace Dataset格式 ragas_dataset = Dataset.from_list([ { "question": item["question"], "answer": item["answer"], # RAG系统生成的回答 "contexts": item["contexts"], # RAG系统检索到的上下文片段列表 "ground_truth": item["ground_truth"], # 参考答案 } for item in testset ])这里有个设计细节值得说明:评测集文件里的answer和contexts不应该预先存好,而应该是在每次评测时实时从RAG系统获取。也就是说,评测脚本的流程是:加载测试问题 → 调用RAG系统生成回答和检索上下文 → 把回答和上下文交给评测框架打分。这样才能保证评测的是"当前代码状态下"的RAG系统,而不是上一次评测的缓存数据。
5.3 Ragas核心评测脚本
from ragas.metrics import ( faithfulness, answer_relevancy, context_precision, context_recall, ) metrics = [ faithfulness, answer_relevancy, context_precision, context_recall, ] result = evaluate( ragas_dataset, metrics=metrics, llm=critic_llm, # 评判模型,建议用强模型 embeddings=embedding_model, # 用于部分指标间相似度计算 ) # 打印总分 print("Ragas Scores:") print(result) # 查看单条明细,定位问题问题 df = result.to_pandas() df.to_csv("ragas_scores_detail.csv", index=False)一个非常容易踩坑的地方:Ragas内部调LLM时,默认可能使用OPENAI_API_KEY环境变量,而且LLM评判时并发有限制,跑大批量测试集会非常慢。我的处理方法是给评判环节单独指定一个更强的模型,同时控制并发参数:
from langchain_openai import ChatOpenAI critic_llm = ChatOpenAI(model="gpt-4o", temperature=0) result = evaluate( ragas_dataset, metrics=metrics, llm=critic_llm, embeddings=embeddings, raise_exceptions=False, column_map={ "question": "question", "answer": "answer", "contexts": "contexts", "ground_truth": "ground_truth", }, )注意temperature=0,评判模型必须用确定性较高的配置,否则同样一批数据两次评测分数会漂移得很厉害。这是评测可复现性的前提。
5.4 DeepEval核心评测脚本
DeepEval部分走的是Pytest风格。我会为每一类指标写一个独立的测试文件:
# test_eval_rag.py import pytest from deepeval import assert_test from deepeval.metrics import ( FaithfulnessMetric, AnswerRelevancyMetric, ContextualPrecisionMetric, ContextualRecallMetric, ) from deepeval.test_case import LLMTestCase def build_test_cases(): """从testset构建DeepEval测试用例,并调用RAG系统获取实时响应""" test_cases = [] for item in load_testset(): answer, contexts = run_rag_system(item["question"]) test_case = LLMTestCase( input=item["question"], actual_output=answer, retrieval_context=contexts, expected_output=item["ground_truth"], ) test_cases.append((item["question"], test_case)) return test_cases @pytest.mark.parametrize("question,test_case", build_test_cases()) def test_faithfulness(question, test_case): metric = FaithfulnessMetric(threshold=0.8) assert_test(test_case, [metric])这样每条测试问题都会作为一条独立的Pytest用例执行,用例失败时可以看到是哪一个问题导致的指标不达标,和常规代码测试的工作流完全一致。
阈值设置这块我建议这么定:先把当前系统的评测分数基线跑出来,然后浮动5%-10%作为阈值。一开始不用卡得太死,因为测试集质量本身也在迭代中。我最初把Faithfulness的阈值设在0.9,结果天天跑挂,后来仔细看了失败用例才发现,有些测试问题本身标注的质量就有问题——参考信息点不全,导致模型回答其实是对的,但和标注对不上。先把测试集本身的质量打磨好,再提高阈值,顺序不能反。
5.5 双框架结果聚合与报告输出
Ragas输出的是Pandas DataFrame,DeepEval输出的是Pytest报告和JSON格式的明细。为了在CI里统一查看,我会写一个聚合脚本,把两边的结果合并成一份总报告:
import json import pandas as pd def merge_reports(ragas_csv_path, deepeval_json_path): ragas_df = pd.read_csv(ragas_csv_path) with open(deepeval_json_path, "r", encoding="utf-8") as f: deepeval_data = json.load(f) # 每个问题的DeelEval指标分数 deepeval_df = pd.DataFrame([ { "question": item["input"], "deepeval_faithfulness": item["metrics_data"]["Faithfulness"]["score"], "deepeval_answer_relevancy": item["metrics_data"]["Answer Relevancy"]["score"], } for item in deepeval_data["test_runs"] ]) merged = ragas_df.merge(deepeval_df, on="question", how="outer") merged.to_csv("merged_eval_report.csv", index=False) return merged合并报告的意义在于:同一个测试问题上,Ragas和DeepEval给出的Faithfulness分数可能会不同。当两边分数差异很大时(比如一边0.9一边0.5),这本身就是一个信号——说明这个问题处在"评估不确定性"较高的区域,值得人工介入检查。我在实际项目中就用这个方法挖出过几个标注有争议的测试问题。
6. 嵌入CI流水线:让质量回归成为提交代码的"必过关卡"
脚本能跑只是第一步,真正让评测体系发挥威力的是把它嵌进CI/CD流程。我的目标是:任何涉及RAG系统配置或代码的改动,每次合并之前都要自动跑一遍评测,只有全部指标达到阈值,才允许合并进主干分支。
6.1 GitHub Actions工作流设计
我用的CI是GitHub Actions,工作流定义大概长这样:
name: rag-eval-ci on: pull_request: paths: - "rag/**" - "configs/**" - "testset/**" - "prompts/**" push: branches: [main] paths: - "rag/**" - "configs/**" - "testset/**" jobs: evaluate: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | pip install -r requirements.txt - name: Run Ragas Evaluation env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | python scripts/run_ragas_eval.py - name: Run DeepEval Pytest env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | pytest test_eval_rag.py --junit-xml=deepeval-report.xml - name: Upload Evaluation Reports uses: actions/upload-artifact@v4 with: name: eval-reports path: | ragas_scores_detail.csv merged_eval_report.csv deepeval-report.xmlpaths字段的过滤很重要。不是每次代码提交都要跑完整评测,RAG评测耗时较长且消耗LLM API额度,只在与RAG相关的文件变更时才触发,能省下大量时间和成本。
6.2 并发与成本控制
RAG评测是典型的LLM密集型任务。比如测试集有50个问题,每个问题要跑4个指标,每个指标内部还涉及多次LLM调用,总调用次数经常达到几百上千次。在CI里跑一次,光API开销可能就要几美元甚至更多。所以成本控制是评测流水线设计里不能回避的问题。
我的做法是分三级:
- PR级快速评测:从测试集中抽取10-15个"冒烟问题",只跑Faithfulness和Answer Relevancy两个核心指标,5-10分钟内出结果,只拦截明显劣化。
- 主干合并级完整评测:推送main分支时跑全量测试集和全部指标,产出完整报告。
- 定时深度评测:每天凌晨跑一次更重度的评测,包括多组参数对比(不同chunk size、不同TopK、不同Embedding模型),输出详细对比报告。
通过分级设计,既保证了CI反馈的及时性,又把成本控制在了可接受范围内。
6.3 评测报告的可视化与追踪
CI里产生的评测报告,如果只是放在Artifacts里供人下载,价值会大打折扣。我现在的做法是把每次评测结果写入一个集中的追踪服务,比如Langfuse或Arize Phoenix这类LLM可观测性平台,它们能把评测分数、追踪链路、检索到的上下文、模型输出、Token消耗关联起来。
以Langfuse为例,我可以在评测脚本里为每次评测创建一条Trace,把问题、检索上下文、模型回答、各项指标分数全部挂到这条Trace上。后续要排查"某次线上回答质量差"的时候,直接按问题关键词搜索Trace,一眼就能看到当时检索到了哪些文档、模型是怎么生成的、各项评分是多少。这个排查效率比翻代码日志高了一个量级。
用Arize Phoenix的路径也类似,它的评估结果展示面板更适合横对比不同实验版本。我一般是这样分配的:Langfuse用于线上单条问题的追踪诊断,Arize Phoenix用于评测集的批量离线分析,Promptfoo则适合在Prompt迭代时做快速A/B评测。三套工具有重叠但定位不同,核心思路是——评测数据一定要有归处,不能跑完就丢弃。
7. 实际踩过的坑:LLM评测的不确定性与针对性解法
评测流水线搭建过程中,我踩过的坑不少,其中有些属于"不上手就根本预料不到"的类型,这里挑几个最有代表性的分享。
7.1 评测分数漂移:同一份代码,两次评测结果差很多
有段时间我发现,CI里同一份代码跑两次评测,Faithfulness居然能从0.85漂到0.62。最开始怀疑是代码有随机性,排查了很久,最后定位到根源是评判LLM的temperature没有设为0。
Ragas和DeepEval底层评判都依赖LLM,而LLM在非零温度下生成的判断本身就有随机性。同一个答案,LLM评判的思路可能略有不同,导致分数波动。解决方式很简单:所有评判模型的temperature统一设为0,追求确定性。另外尽量用版本固定的评判模型,不要用那种"自动升级"的模型别名,否则哪天模型悄悄更新了,你很难区分分数变化是RAG系统导致的还是评判模型导致的。
7.2 评判模型能力不足:弱模型评不出细微差异
我犯过的另一个错误是,为了省成本,初始阶段用一个中等规模的开源模型充当评判模型。结果所有指标分数都在0.7-0.8之间,几乎没有区分度——差的回答和好的回答分数差不多,评测等于白跑。
后来对照试验发现,GPT-4级别的评判模型能明显识别出回答中的逻辑跳跃和事实张冠李戴,而弱模型往往只做"表面措辞判断"。评测这件事上的投入不能省,评判模型至少要比被评测的生成模型强一个档次。如果预算实在紧张,可以适当减少测试集规模,但不要压缩评判模型的档次。
7.3 多轮对话与Agentic RAG场景的评测盲区
标准的Ragas和DeepEval指标主要针对单轮问答。但现在的RAG系统越来越多地引入多轮记忆、甚至Agentic RAG(自主规划多步检索),这些场景下,现成指标就有些力不从心了。
比如多轮对话里,用户第二轮问"那它的性能对比呢?"——这里的"它"指代第一轮提到的某个模型。如果评测时单独拿这个问题去测,上下文信息不足,指标自然很难看。针对这个盲区,我的做法是:在评测集里标注"对话历史"字段,DeepEval的测试模型也支持带上对话历史。脚本里把前序轮次作为conversation_history传入,至少能让评测更贴近真实使用场景。
Agentic RAG的评测则更复杂,不仅看最终答案质量,还要看中间检索规划和工具调用是否合理。现阶段我在这块的思路是:不追求自动化全面覆盖,而是把Agent的每步中间动作记录成结构化日志,再针对关键步骤单独写一批"过程校验指标",和DeepEval的自定义指标结合做半自动化评估。这部分还在演进中,目前没有完美解法,但至少比纯人工翻日志强不少。
8. 评测流水线的下一步演化方向
整套流水线搭起来之后,我最大的感受是:评测这件事本身也在不断"内卷"——指标会过时、测试集会老化、评判模型的局限会暴露。所以流水线设计之初,就要留出持续迭代的空间。
一个我目前正在探索的方向是自动化测试集生成与去重。Ragas提供的TestsetGenerator可以基于知识库自动合成问题,但直接生成的测试集冗余度很高——同一知识点可能被生成20个句式不同的问法,跑评测时既浪费API额度,又拉低指标区分度。我的思路是:先用合成器生成候选问题,再用Embedding做聚类去重,每个簇只保留最有代表性的问题,人工抽验后并入测试集。这样测试集能以较低成本持续扩充,覆盖新上线的知识库内容。
另一个方向是把评测分数与线上真实反馈关联起来。评测集毕竟是离线构造的,和真实用户问题的分布存在偏差。理想状态是在线上埋点采集用户的"隐式反馈"(追问、复制答案、反馈按钮等),然后把线上问题自动回流到评测集里。这样一来,评测体系就形成了一个闭环:线上发现问题 → 流入评测集 → 触发CI回归 → 定位根因 → 修复验证 → 发布上线。RAG系统的质量就在这个循环里持续螺旋上升。
这套流水线上线后,我团队对RAG系统的改动频率明显提高了——以前改个chunk参数要商量半天,因为没人敢保证"觉得效果更好了"是真的更好。现在每次改动都有评测分数背书,有理有据,返工和争论都少了很多。如果你也在做RAG实战且正在为"效果说不清"发愁,建议从最小的单指标评测先跑起来,再逐步扩展,这个投入的性价比绝对比反复人工抽测要高得多。