- 人工智能
- 大模型
- 模型评测
- RAG
【免费下载链接】ragas
Supercharge Your LLM Application Evaluations 🚀
ragas quickstart improve_rag是 Ragas 提供的一个开箱即用的评测模板,它基于 HuggingFace 官方文档问答数据集(hf_doc_qa_eval.csv),在同一套评测流程中对比两种典型的 RAG 架构——单次检索的朴素 RAG(Naive RAG)与由 Agent 控制检索的 Agentic RAG。读完本文,你将掌握:如何用一条命令搭建可运行的 RAG 评测工程、如何分别运行两种模式的评估并对比通过率、如何通过 MLflow 追踪每次 LLM 调用的轨迹,以及如何把知识库、模型、指标替换成你自己的方案。
模板能解决什么问题
很多团队在优化 RAG 系统时面临一个共同困境:升级到"更智能"的 Agent 架构后,无法量化它到底比朴素方案好在哪里。improve_rag模板的核心价值在于把这个问题变成一个可重复的实验:同一个问题集、同一个 BM25 检索器,只切换 RAG 的驱动方式(一次性检索 vs. Agent 自主多轮检索),然后用统一的correctness离散指标给每个回答打pass/fail,最终输出带时间戳的实验结果 CSV。
从源码看,该模板在 CLI 中的完整描述是"Compare naive vs agentic RAG using BM25 retrieval and HuggingFace docs",位于 cli.py 的 quickstart 模板注册表中;而模板主体存放在仓库的 examples/ragas_examples/improve_rag 目录下,包含rag.py(RAG 双模式实现)、evals.py(评测工作流)、pyproject.toml(依赖声明)以及evals/datasets/hf_doc_qa_eval.csv(真实评测数据集)。
创建项目
ragas quickstart命令支持多种模板(rag_eval、agent_evals、text2sql、workflow_eval等),运行时不带模板名会列出全部可用模板。创建本项目有两种等价方式:
# 方式一:使用 uvx,无需预先安装 ragas uvx ragas quickstart improve_rag cd improve_rag # 方式二:已安装 ragas 时 ragas quickstart improve_rag cd improve_rag从 cli.py 的实现看,quickstart还支持--output-dir/-o参数指定创建位置,例如ragas quickstart improve_rag -o ./my-project。命令内部会依次尝试:本地安装的ragas_examples包 → 当前开发仓库的examples/ragas_examples→ 从远端归档下载,找到模板后复制到目标目录,并自动创建evals/datasets、evals/experiments、evals/logs三个子目录;如果目录已存在,会交互式询问是否覆盖。
安装依赖
推荐使用uv(项目已声明[tool.uv] managed = true):
uv sync也可以使用 pip:
pip install -e .依赖声明见模板的 pyproject.toml,核心依赖包括:
ragas[all]>=0.3.0:评测框架本体;openai>=1.0.0:LLM 客户端(AsyncOpenAI);mlflow>=2.0.0:可选的调用追踪;langchain、langchain-community、langchain-text-splitters:BM25 检索器与文档切分;datasets>=2.0.0:加载 HuggingFace 文档语料;rank-bm25>=0.2.2:BM25 排序算法;python-dotenv>=1.0.0:读取.env配置。
注意:openai-agents被单独声明在[project.optional-dependencies] agentic分组中,也就是说Agentic 模式需要额外安装(详见下文"Agentic 模式")。
设置 API Key
模板默认使用 OpenAI 的gpt-4o-mini:
export OPENAI_API_KEY="your-openai-key"evals.py在启动时会校验该环境变量,缺失则直接抛出ValueError(见 evals.py);同时它也会调用load_dotenv(".env"),因此你也可以把 key 写进项目根目录的.env文件。
运行评估
朴素 RAG 模式(默认)
uv run python evals.pyAgentic RAG 模式
uv run python evals.py --agenticAgentic 模式前置要求Agentic 模式依赖
openai-agents包,需要先安装:pip install openai-agents该依赖对应
pyproject.toml中的agentic可选组,也可以用uv sync --extra agentic统一安装。若缺失,rag.py的_setup_agent()会抛出ImportError("agents package required for agentic mode")(见 rag.py)。
evals.py通过简单的命令行参数解析来决定模式:"--agentic" in sys.argv,其余情况一律走 naive(见 evals.py)。两种模式共用同一套评测流程,结果分别写入evals/experiments/YYYYMMDD-HHMMSS_naiverag.csv与evals/experiments/YYYYMMDD-HHMMSS_agenticrag.csv(命名逻辑见run_experiment中的name参数,evals.py)。
可选:开启 MLflow 追踪
想要细粒度观察每次 LLM 调用的输入输出与耗时,可以先启动 MLflow 服务:
mlflow ui --port 5000再运行评估即可。rag.py中的RAG类会在初始化时探测本地 MLflow 服务是否在线(_check_mlflow_server默认探测http://127.0.0.1:5000,超时 0.5 秒),在线则调用mlflow.openai.autolog()自动追踪所有 OpenAI 调用,并把mlflow_trace_id一并塞进每次查询的返回结果(rag.py)。evals.py还会为每条 trace 构造可直接点击的 MLflow 追踪 URL 写入结果 CSV(construct_mlflow_trace_url,evals.py)。
项目结构
improve_rag/ ├── README.md # 项目文档(由 quickstart 命令自动生成) ├── pyproject.toml # 项目配置与依赖声明 ├── rag.py # RAG 实现(naive 与 agentic 双模式) ├── evals.py # 评测工作流 ├── __init__.py # Python 包标记 └── evals/ ├── datasets/ # 测试数据集(hf_doc_qa_eval.csv) ├── experiments/ # 评测结果 CSV └── logs/ # 评测日志理解两种 RAG 模式
朴素 RAG
朴素模式执行一次检索、一次生成,流程固定:
- 查询→ BM25 检索 top-k 文档
- 上下文→ 检索到的文档拼成上下文
- 生成→ LLM 基于上下文生成回答
对应RAG._naive_query的实现(rag.py):先用检索器拿到top_k篇文档,用system_prompt(默认模板为"Answer only based on documents. Be concise.\n\nQuestion: {query}\nDocuments:{context}\nAnswer:")格式化后调用chat.completions.create,最终返回{answer, retrieved_documents, num_retrieved, mlflow_trace_id}。
rag = RAG(llm_client=client, retriever=retriever, mode="naive") result = await rag.query("What is the Diffusers library?")优点:
- 实现简单、速度快
- 延迟可预期
- 成本低(单次 LLM 调用)
缺点:
- 检索词不同(同义表述/术语变体)时可能漏掉相关文档
- 不做查询改写,问法不佳时直接失败
- 只有单一检索策略,没有纠错机会
Agentic RAG
Agentic 模式把检索决策权交给 Agent:
- 查询→ Agent 分析问题
- 搜索→ Agent 自主决定检索什么(可多次搜索)
- 修正→ Agent 根据初步结果修正检索词
- 生成→ Agent 综合检索结果生成最终回答
rag.py中通过agents包的Agent+function_tool实现(rag.py):Agent 名为RAG Assistant,系统指令明确要求"先用精确术语(命令、API、工具名)搜索,必要时尝试 2-3 次不同检索词,只依据检索到的文档作答并保留准确语法与技术细节";检索工具retrieve的 docstring 同样引导 Agent 采用"具体术语 → 工具名 → 替代词"的搜索策略。执行时由agents.Runner.run驱动(_agentic_query,rag.py),由于检索发生在 Agent 内部,返回结果中retrieved_documents为空、num_retrieved为 0。
rag = RAG(llm_client=client, retriever=retriever, mode="agentic") result = await rag.query("What command uploads an ESPnet model?")优点:
- 可尝试多种检索策略
- 更擅长定位具体的专业技术信息
- 能根据初步结果自适应调整检索方向
缺点:
- 延迟更高(多次 LLM 调用)
- 成本更高
- 行为不如朴素模式可预期
评测数据集
模板自带evals/datasets/hf_doc_qa_eval.csv,包含关于 HuggingFace 文档的技术问答,共两个字段:
| 字段 | 说明 |
|---|---|
question | 关于 HuggingFace 工具链的技术问题 |
expected_answer | 标准答案(ground truth) |
数据集中真实存在的问题示例(见 hf_doc_qa_eval.csv):
- "What is the default checkpoint used by the sentiment analysis pipeline?"
- "What command is used to upload an ESPnet model?"
- "What is the purpose of the Diffusers library?"
- "What architecture is the
tokenizers-linux-x64-muslbinary designed for?" - "What method does the EulerAncestralDiscreteScheduler use for sampling?"
这类问题有个共同特点:答案藏在文档的特定位置,且对表述精度敏感(命令名、API 名、默认值),恰好能区分"一次性检索"与"Agent 多轮检索"的能力差异。首次运行时evals.py会尝试从远端拉取该 CSV 到本地(已存在则跳过),随后用Dataset(name="hf_doc_qa_eval", backend="local/csv", root_dir="evals")逐行构建 Ragas 数据集并保存(evals.py)。
理解核心代码
RAG 实现(rag.py)
BM25Retriever
基于 BM25(Best Matching 25)算法做词法检索,构建流程(rag.py):
- 用
datasets.load_dataset("m-ric/huggingface_doc", split="train")加载 HuggingFace 文档语料; - 逐条转成
Document,并把source字段的第二段(如diffusers)写入 metadata; - 用
RecursiveCharacterTextSplitter(chunk_size=1000、chunk_overlap=100、分隔符依次为段落/换行/句点/空格/空串)切分成块; - 按
page_content去重; - 构建
LangchainBM25Retriever索引。
class BM25Retriever: def __init__(self, dataset_name="m-ric/huggingface_doc"): # 加载 HuggingFace 文档 # 切分为 chunk 便于检索 # 构建 BM25 索引 def retrieve(self, query: str, top_k: int = 3): # 返回 top-k 最相关文档注意retrieve()会动态设置self.retriever.k = top_k,默认top_k取构造时的default_k=3。
RAG 类
对外暴露统一接口,内部按模式分发:
class RAG: def __init__(self, llm_client, retriever, mode="naive", system_prompt=None, model="gpt-4o-mini", default_k=3): self.mode = mode if mode == "agentic": self._setup_agent() async def query(self, question: str, top_k: int = 3): if self.mode == "naive": return await self._naive_query(question, top_k) else: return await self._agentic_query(question, top_k)从源码可见完整签名还支持system_prompt(自定义提示词模板)、model(默认gpt-4o-mini)与default_k三个可调参数;query()内部对未知模式抛出ValueError,任何异常都会以{"answer": "Error: ..."}的形式兜底返回而不是中断整个评测(rag.py)。
评测脚本(evals.py)
评测指标使用 Ragas 的离散指标,将模型回答与标准答案对比:
correctness_metric = DiscreteMetric( name="correctness", prompt="""Compare the model response to the expected answer... Return 'pass' if correct, 'fail' if incorrect.""", allowed_values=["pass", "fail"], )完整提示词(evals.py)明确给出三条判据:是否包含标准答案的关键信息、是否基于给定上下文在事实上准确、是否充分回答了提问。评测循环由@experiment()装饰器包裹的evaluate_rag(row, rag, llm)驱动:对每行数据调用rag.query(question, top_k=4)拿到模型回答,再用correctness_metric.ascore(question=..., expected_answer=..., response=..., llm=llm)异步打分,最后把model_response、correctness_score、correctness_reason、mlflow_trace_id、mlflow_trace_url以及截断到 200 字符的检索文档列表一并写入结果(evals.py)。这里的llm由llm_factory("gpt-4o-mini", client=openai_client, temperature=1, top_p=None)构造(evals.py),评测结束时会在日志中打印pass_count/total_count (xx.x%)的汇总通过率。
自定义改造
更换知识库
把 HuggingFace 文档换成你自己的资料,实现一个同签名(retrieve(query, top_k))的检索器即可:
class CustomRetriever: def __init__(self, documents: list[str]): from langchain_community.retrievers import BM25Retriever self.retriever = BM25Retriever.from_texts(documents) def retrieve(self, query: str, top_k: int = 3): self.retriever.k = top_k return self.retriever.invoke(query)RAG只依赖检索器的retrieve(query, top_k)接口(返回可访问page_content的文档列表),因此任意实现——向量检索、混合检索、外部搜索 API——都能无缝接入。
更换模型
在evals.py中改两处即可切换模型:
# 生成端:RAG 构造时指定 rag = RAG(llm_client=client, retriever=retriever, model="gpt-4o") # 评测端:llm_factory 指定 llm = llm_factory("gpt-4o-mini", client=openai_client, temperature=1, top_p=None)需要注意:rag.py中的RAG类当前面向 OpenAI 兼容的AsyncOpenAI客户端编写(内部直接调用chat.completions.create,Agent 模式使用agents包的Agent(model=...))。如果改用其他提供方(如 Anthropic),需要按对应 SDK 适配rag.py中的调用逻辑;而评测端的llm_factory本身支持多提供方,改动成本更低。
添加自定义指标
在correctness之外,可以用 Ragas 的数值指标补充维度,例如完整度评分:
from ragas.metrics import NumericalMetric completeness = NumericalMetric( name="completeness", prompt="""How complete is the response (1-5)? Question: {question} Expected: {expected_answer} Response: {response} Score:""", allowed_values=(1, 5), ) # 加入实验 result = { **row, "correctness": correctness_score.value, "completeness": completeness.score(...).value, }Ragas 指标体系还提供了更多可选能力:通用离散/数值/字符串指标、基于评价标准(rubrics)的指标等,可参考 available metrics 文档 与 自定义/修改指标提示词指南。
修改 Agent 行为
Agent 的检索策略在rag.py的_setup_agent()中定制——改工具描述、系统指令即可控制搜索习惯:
def _setup_agent(self): @function_tool def retrieve(query: str) -> str: """自定义工具描述……""" docs = self.retriever.retrieve(query, self.default_k) return "\n\n".join([doc.page_content for doc in docs]) self._agent = Agent( name="Custom RAG Assistant", instructions="你的自定义指令……", tools=[retrieve] )例如,针对代码库问答可以要求 Agent"优先搜索函数签名与导入路径",针对多语言场景可以要求"同时用中英文术语各搜一次"。
对比结果
依次运行两种模式:
# 朴素模式 uv run python evals.py # 结果保存到 experiments/YYYYMMDD-HHMMSS_naiverag.csv # Agentic 模式 uv run python evals.py --agentic # 结果保存到 experiments/YYYYMMDD-HHMMSS_agenticrag.csv然后用 pandas 快速汇总通过率:
import pandas as pd naive = pd.read_csv("evals/experiments/..._naiverag.csv") agentic = pd.read_csv("evals/experiments/..._agenticrag.csv") print(f"Naive pass rate: {(naive['correctness_score'] == 'pass').mean():.1%}") print(f"Agentic pass rate: {(agentic['correctness_score'] == 'pass').mean():.1%}")除了通过率,CSV 中的correctness_reason(LLM 给出的判分理由)、mlflow_trace_url(单条 trace 的完整调用链)是定位失败根因的两个关键抓手:先看判分理由缩小问题范围,再顺着 trace 检查 Agent 到底检索了什么、生成了什么。这套流程同样适用于生产环境 RAG 的持续观测,可进一步参考 Evaluate and Improve RAG 与 RAG Evaluation Guide。
故障排查
MLflow 警告
看到 MLflow 报 trace 发送失败的警告时,二选一即可:
- 启动 MLflow 服务:
mlflow ui --port 5000 - 直接忽略——没有追踪时评测照常运行
rag.py在 MLflow 不可用时静默降级:_check_mlflow_server探测失败就把_mlflow_enabled置为False,不再调用mlflow.openai.autolog(),并在日志级别上压制了 mlflow 追踪模块的告警(rag.py)。
Agentic 模式无法运行
确认已安装 agents 包:
pip install openai-agents若仍报错,检查是否同时存在多个 Python 环境——uv run与pip安装进的环境必须一致。
首次运行缓慢
首次运行需要下载 HuggingFace 文档数据集(约 300MB)用于构建 BM25 索引,之后会使用本地缓存(datasets库缓存与evals/datasets下的 CSV 均只下载一次)。评估过程中的 LLM 调用延迟取决于所选模型与网络状况。
总结
improve_rag把"RAG 架构选型"从拍脑袋变成可量化实验:固定知识库、固定问题集、固定评测指标,只改变检索的驱动方式,用correctness通过率说话。朴素模式是低成本基线,Agentic 模式则是能力上限,两者的差距就是你为"更聪明的检索"愿意付出的延迟与成本。以此为骨架,替换检索器、模型与指标,就能把同一套评测方法复用到你自己的知识库与业务场景中。
- 人工智能
- 大模型
- 模型评测
- RAG
【免费下载链接】ragas
Supercharge Your LLM Application Evaluations 🚀
相关推荐
使用 Ragas 评估与系统性改进 RAG 应用:从 Naive RAG 到 Agentic RAG 的完整实战指南
使用 Ragas 评估与系统性改进 RAG 应用:从 Naive RAG 到 Agentic RAG 的完整实战指南 本指南基于 Ragas 仓库中的端到端示例
人工智能大模型模型评测RAGLabel Studio 中使用 Ragas 自动化评估 RAG 管道(RAG 评估模板实战指南)
Label Studio 中使用 Ragas 自动化评估 RAG 管道(RAG 评估模板实战指南) 本文将围绕 Label Studio 官方模板库中的 Eva
数据标注人工智能Unity GLTF模型导入终极教程:5分钟掌握GLTFUtility完整指南
Unity GLTF模型导入终极教程:5分钟掌握GLTFUtility完整指南 GLTFUtility是Unity开发者必备的GLTF模型导入工具,能够让你在U
人工智能大模型模型评测RAG
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考