Ragas 大模型评测框架深度调研指南
目录
- [一、Ragas 是什么](#一、Ragas 是什么 "#%E4%B8%80ragas-%E6%98%AF%E4%BB%80%E4%B9%88")
- 二、核心评估指标
- 三、安装与配置
- 四、完整使用流程
- 五、自定义评估指标
- 六、最佳实践
- 七、进阶功能
- 八、常见问题
- 九、相关资源
一、Ragas 是什么
Ragas (Retrieval-Augmented Generation Assessment)是一个专门用于评估 RAG(检索增强生成)系统 性能的 Python 开源框架。
1.1 核心价值
| 价值点 | 说明 |
|---|---|
| 评估驱动开发 | 将评估融入开发流程,而非事后补充 |
| 自动化测试 | 自动测试 RAG 系统的各个组件 |
| 多模型支持 | 支持本地和云端大模型作为评估器 |
| 可量化指标 | 提供数值化的性能评估指标 |
| 易于集成 | 与 LangChain、LlamaIndex 等框架无缝对接 |
1.2 适用场景
┌─────────────────────────────────────────────────────────┐
│ Ragas 适用场景 │
├─────────────────────────────────────────────────────────┤
│ ✓ 知识库问答系统评估 │
│ ✓ 企业级 RAG 应用性能监控 │
│ ✓ 不同检索策略对比分析 │
│ ✓ LLM 幻觉检测 │
│ ✓ CI/CD 自动化测试 │
└─────────────────────────────────────────────────────────┘
二、核心评估指标
2.1 指标体系概览
scss
Ragas 评估指标体系
│
┌──────────────────┼──────────────────┐
│ │
检索质量指标 生成质量指标
│ │
├─ Context Precision ├─ Faithfulness
│ (上下文精确度) │ (忠实度)
│ │
├─ Context Recall ├─ Answer Relevancy
│ (上下文召回率) │ (答案相关性)
│ │
└─ Context Entity Recall └─ Factual Correctness
(上下文实体召回) (事实正确性)
2.2 检索质量指标
Context Precision(上下文精确度)
定义:衡量检索到的上下文与问题的相关性
diff
评分标准:
- 高分:检索到的文档都高度相关,没有噪音
- 中分:部分相关,存在一些不相关内容
- 低分:检索结果包含大量不相关内容
应用场景:
- 评估向量数据库检索效果
- 对比不同 embedding 模型
- 优化 chunk size 和 overlap 参数
Context Recall(上下文召回率)
定义:衡量检索信息的完整性,是否覆盖回答所需的所有关键信息
diff
评分标准:
- 高分:检索到的信息足够回答问题
- 中分:部分信息缺失,但可勉强回答
- 低分:关键信息缺失,无法准确回答
Context Entity Recall(上下文实体召回)
定义:专门评估实体(如人名、地名、时间等)的召回情况
2.3 生成质量指标
Faithfulness(忠实度)
定义:衡量答案是否基于检索到的上下文,检测幻觉问题
python
# 评估问题示例
"答案中的所有声明是否都能在检索到的上下文中找到依据?"
评分维度:
- 事实一致性
- 无额外编造信息
- 逻辑推理正确性
Answer Relevancy(答案相关性)
定义:衡量答案与问题的相关程度
python
# 评估方法
1. 将答案转换为反向问题
2. 计算反向问题与原问题的相似度
3. 评分范围:0-1,越高越好
Factual Correctness(事实正确性)
定义:衡量答案的事实准确性,通常需要参考标准答案
2.4 指标选择建议
| 评估目标 | 推荐指标组合 |
|---|---|
| 检索系统优化 | Context Precision + Context Recall |
| 幻觉检测 | Faithfulness |
| 用户体验评估 | Answer Relevancy + Faithfulness |
| 完整评估 | 全部指标 |
三、安装与配置
3.1 基础安装
bash
# 标准安装
pip install ragas
# 完整安装(包含示例和额外依赖)
pip install ragas[examples]
# 从源码安装
git clone https://github.com/explodinggradients/ragas.git
cd ragas
pip install -e .
3.2 版本要求
yaml
核心依赖:
Python: ">=3.8"
langchain: ">=0.1.0"
langchain-openai: ">=0.0.5"
可选依赖:
openai: 用于 GPT 模型
anthropic: 用于 Claude 模型
sentence-transformers: 用于本地 embedding
3.3 配置评估器 LLM
方式一:使用 OpenAI
python
import os
from langchain_openai import ChatOpenAI
from ragas.llms import LangchainLLMWrapper
# 配置环境变量
os.environ["OPENAI_API_KEY"] = "your-api-key"
# 初始化 LLM
llm = ChatOpenAI(
model="gpt-4o",
temperature=0,
max_tokens=1024
)
# 包装为 Ragas 评估器
evaluator_llm = LangchainLLMWrapper(llm)
方式二:使用本地模型(Ollama)
python
from langchain_community.llms import Ollama
from ragas.llms import LangchainLLMWrapper
# 使用本地 Ollama 模型
llm = Ollama(
model="llama3.2",
temperature=0
)
evaluator_llm = LangchainLLMWrapper(llm)
方式三:使用 Azure OpenAI
python
from langchain_openai import AzureChatOpenAI
from ragas.llms import LangchainLLMWrapper
llm = AzureChatOpenAI(
azure_endpoint="your-endpoint",
api_key="your-api-key",
api_version="2024-02-15-preview",
deployment_name="your-deployment"
)
evaluator_llm = LangchainLLMWrapper(llm)
3.4 配置 Embedding 模型
python
import openai
from ragas.embeddings import OpenAIEmbeddings
# OpenAI Embeddings
openai_client = openai.OpenAI(api_key="your-api-key")
embeddings = OpenAIEmbeddings(client=openai_client)
# 或者使用 HuggingFace
from ragas.embeddings import HuggingfaceEmbeddings
embeddings = HuggingfaceEmbeddings(
model_name="BAAI/bge-large-zh-v1.5"
)
四、完整使用流程
4.1 构建简单 RAG 系统
python
import numpy as np
from langchain_openai import ChatOpenAI
from ragas.embeddings import OpenAIEmbeddings
import openai
class SimpleRAG:
"""
简单的 RAG 系统实现
遵循单一职责原则,每个方法只做一件事
"""
def __init__(self, model: str = "gpt-4o"):
"""
初始化 RAG 系统
Args:
model: 使用的 LLM 模型名称
"""
self.llm = ChatOpenAI(model=model)
openai_client = openai.OpenAI()
self.embeddings = OpenAIEmbeddings(client=openai_client)
self.doc_embeddings = None
self.docs = None
def load_documents(self, documents: list[str]) -> None:
"""
加载文档并计算向量
Args:
documents: 文档列表
"""
self.docs = documents
self.doc_embeddings = self.embeddings.embed_texts(documents)
def _compute_similarity(self, query_embedding: np.ndarray,
doc_embedding: np.ndarray) -> float:
"""
计算查询和文档的余弦相似度
Args:
query_embedding: 查询向量
doc_embedding: 文档向量
Returns:
相似度分数
"""
return np.dot(query_embedding, doc_embedding) / (
np.linalg.norm(query_embedding) * np.linalg.norm(doc_embedding)
)
def get_most_relevant_docs(self, query: str, top_k: int = 1) -> list[str]:
"""
检索最相关文档
Args:
query: 用户查询
top_k: 返回文档数量
Returns:
最相关的文档列表
"""
if self.docs is None or self.doc_embeddings is None:
raise ValueError("请先调用 load_documents 加载文档")
query_embedding = self.embeddings.embed_text(query)
similarities = [
self._compute_similarity(query_embedding, doc_emb)
for doc_emb in self.doc_embeddings
]
# 获取 top_k 个最相关文档的索引
top_indices = np.argsort(similarities)[-top_k:][::-1]
return [self.docs[i] for i in top_indices]
def generate_answer(self, query: str, relevant_docs: list[str]) -> str:
"""
基于检索到的文档生成答案
Args:
query: 用户查询
relevant_docs: 相关文档列表
Returns:
生成的答案
"""
context = "\n\n".join(relevant_docs)
prompt = f"问题: {query}\n\n参考文档:\n{context}\n\n请根据参考文档回答问题。"
messages = [
("system", "你是一个有帮助的助手,仅基于提供的文档回答问题。"),
("human", prompt),
]
ai_msg = self.llm.invoke(messages)
return ai_msg.content
def query(self, query: str, top_k: int = 1) -> dict:
"""
完整的查询流程
Args:
query: 用户查询
top_k: 检索文档数量
Returns:
包含答案和检索文档的字典
"""
relevant_docs = self.get_most_relevant_docs(query, top_k)
answer = self.generate_answer(query, relevant_docs)
return {
"query": query,
"answer": answer,
"retrieved_docs": relevant_docs
}
4.2 准备测试数据
python
from ragas import EvaluationDataset
import pandas as pd
def prepare_test_dataset(rag: SimpleRAG,
queries: list[str],
references: list[str] | None = None) -> EvaluationDataset:
"""
准备评估数据集
Args:
rag: RAG 系统实例
queries: 测试查询列表
references: 参考答案列表(可选)
Returns:
EvaluationDataset 对象
"""
dataset = []
for i, query in enumerate(queries):
# 执行查询
result = rag.query(query, top_k=3)
# 构建数据样本
sample = {
"user_input": query,
"retrieved_contexts": result["retrieved_docs"],
"response": result["answer"]
}
# 如果有参考答案,添加到样本中
if references and i < len(references):
sample["reference"] = references[i]
dataset.append(sample)
return EvaluationDataset.from_list(dataset)
# 示例使用
if __name__ == "__main__":
# 示例文档
sample_docs = [
"阿尔伯特·爱因斯坦提出了相对论,这改变了我们对时间、空间和引力的理解。",
"玛丽·居里是一位物理学家和化学家,她在放射性研究方面做出了开创性工作,并获得了两次诺贝尔奖。",
"艾萨克·牛顿制定了运动定律和万有引力定律,奠定了经典力学的基础。",
"查尔斯·达尔文在《物种起源》一书中提出了自然选择进化论。",
"阿达·洛芙莱斯因其在查尔斯·巴贝奇早期机械计算机分析机上的工作,被认为是第一位计算机程序员。"
]
# 测试查询
sample_queries = [
"谁提出了相对论?",
"谁是第一位计算机程序员?",
"艾萨克·牛顿对科学有什么贡献?",
"谁因放射性研究获得了两次诺贝尔奖?"
]
# 参考答案(可选)
expected_responses = [
"阿尔伯特·爱因斯坦提出了相对论",
"阿达·洛芙莱斯被认为是第一位计算机程序员",
"艾萨克·牛顿制定了运动定律和万有引力定律",
"玛丽·居里因放射性研究获得了两次诺贝尔奖"
]
# 初始化 RAG 系统
rag = SimpleRAG()
rag.load_documents(sample_docs)
# 准备评估数据集
evaluation_dataset = prepare_test_dataset(
rag=rag,
queries=sample_queries,
references=expected_responses
)
print(f"数据集准备完成,共 {len(evaluation_dataset)} 个样本")
4.3 执行评估
python
from ragas import evaluate
from ragas.metrics import (
LLMContextRecall,
Faithfulness,
FactualCorrectness,
AnswerRelevancy,
ContextPrecision
)
def run_evaluation(dataset: EvaluationDataset,
evaluator_llm,
metrics: list | None = None) -> dict:
"""
运行 Ragas 评估
Args:
dataset: 评估数据集
evaluator_llm: 评估器 LLM
metrics: 评估指标列表
Returns:
评估结果字典
"""
if metrics is None:
# 默认使用核心指标
metrics = [
LLMContextRecall(),
Faithfulness(),
FactualCorrectness()
]
results = evaluate(
dataset=dataset,
metrics=metrics,
llm=evaluator_llm
)
return results
# 示例使用
if __name__ == "__main__":
# 配置评估器
evaluator_llm = LangchainLLMWrapper(
ChatOpenAI(model="gpt-4o", temperature=0)
)
# 定义评估指标
metrics = [
ContextPrecision(),
LLMContextRecall(),
Faithfulness(),
AnswerRelevancy(),
]
# 运行评估
results = run_evaluation(
dataset=evaluation_dataset,
evaluator_llm=evaluator_llm,
metrics=metrics
)
# 输出结果
print("=" * 50)
print("Ragas 评估结果")
print("=" * 50)
for metric, score in results.items():
print(f"{metric}: {score:.4f}")
print("=" * 50)
# 保存结果
results_df = results.to_pandas()
results_df.to_csv("rag_evaluation_results.csv", index=False)
4.4 完整示例脚本
python
"""
完整的 Ragas 评估示例脚本
演示从构建 RAG 到评估的完整流程
"""
import os
import pandas as pd
from typing import Optional
import numpy as np
from langchain_openai import ChatOpenAI
from ragas.embeddings import OpenAIEmbeddings
from ragas import EvaluationDataset, evaluate
from ragas.llms import LangchainLLMWrapper
from ragas.metrics import (
ContextPrecision,
LLMContextRecall,
Faithfulness,
AnswerRelevancy
)
import openai
class RAGEvaluator:
"""
RAG 系统评估器
封装完整的评估流程
"""
def __init__(self,
llm_model: str = "gpt-4o",
evaluator_model: str = "gpt-4o"):
"""
初始化评估器
Args:
llm_model: RAG 系统使用的 LLM
evaluator_model: 评估器使用的 LLM
"""
# 初始化 RAG 系统 LLM
self.rag_llm = ChatOpenAI(model=llm_model)
# 初始化评估器 LLM
self.evaluator_llm = ChatOpenAI(
model=evaluator_model,
temperature=0
)
evaluator_wrapper = LangchainLLMWrapper(self.evaluator_llm)
# 初始化 Embeddings
openai_client = openai.OpenAI()
self.embeddings = OpenAIEmbeddings(client=openai_client)
self.doc_embeddings = None
self.docs = None
def load_knowledge_base(self, documents: list[str]) -> None:
"""加载知识库"""
self.docs = documents
self.doc_embeddings = self.embeddings.embed_texts(documents)
def _retrieve_docs(self, query: str, top_k: int = 3) -> list[str]:
"""检索相关文档"""
query_emb = self.embeddings.embed_text(query)
similarities = [
np.dot(query_emb, doc_emb) /
(np.linalg.norm(query_emb) * np.linalg.norm(doc_emb))
for doc_emb in self.doc_embeddings
]
top_indices = np.argsort(similarities)[-top_k:][::-1]
return [self.docs[i] for i in top_indices]
def _generate_response(self, query: str, contexts: list[str]) -> str:
"""生成响应"""
context_text = "\n\n".join(contexts)
prompt = f"基于以下文档回答问题:\n\n{context_text}\n\n问题:{query}"
messages = [
("system", "你是一个有帮助的助手。仅基于提供的文档回答问题,不要编造信息。"),
("human", prompt)
]
response = self.rag_llm.invoke(messages)
return response.content
def build_dataset(self,
queries: list[str],
references: Optional[list[str]] = None) -> EvaluationDataset:
"""构建评估数据集"""
dataset = []
for i, query in enumerate(queries):
contexts = self._retrieve_docs(query)
response = self._generate_response(query, contexts)
sample = {
"user_input": query,
"retrieved_contexts": contexts,
"response": response
}
if references and i < len(references):
sample["reference"] = references[i]
dataset.append(sample)
return EvaluationDataset.from_list(dataset)
def evaluate(self,
dataset: EvaluationDataset,
metrics: Optional[list] = None) -> dict:
"""执行评估"""
if metrics is None:
metrics = [
ContextPrecision(),
LLMContextRecall(),
Faithfulness(),
AnswerRelevancy()
]
results = evaluate(
dataset=dataset,
metrics=metrics,
llm=LangchainLLMWrapper(self.evaluator_llm)
)
return results
def run_full_pipeline(self,
documents: list[str],
queries: list[str],
references: Optional[list[str]] = None,
save_path: str = "results.csv") -> dict:
"""运行完整的评估流程"""
# 1. 加载知识库
self.load_knowledge_base(documents)
# 2. 构建数据集
dataset = self.build_dataset(queries, references)
# 3. 执行评估
results = self.evaluate(dataset)
# 4. 保存结果
results_df = results.to_pandas()
results_df.to_csv(save_path, index=False)
return results
# 使用示例
def main():
"""主函数示例"""
# 设置 API Key
os.environ["OPENAI_API_KEY"] = "your-api-key"
# 示例知识库
documents = [
"Python 是一种高级编程语言,由 Guido van Rossum 于 1991 年首次发布。",
"JavaScript 是一种脚本语言,主要用于 Web 开发,由 Brendan Eich 在 1995 年创建。",
"Rust 是一种系统编程语言,注重安全、并发和性能,由 Mozilla 开发。",
"Go 是由 Google 开发的静态类型编程语言,以其简洁性和高效性著称。",
"TypeScript 是 JavaScript 的超集,添加了静态类型,由 Microsoft 开发。"
]
# 测试查询
queries = [
"谁创建了 Python?",
"JavaScript 主要用于什么?",
"Rust 的主要特点是什么?"
]
# 参考答案
references = [
"Guido van Rossum 在 1991 年创建了 Python",
"JavaScript 主要用于 Web 开发",
"Rust 的主要特点是安全、并发和性能"
]
# 初始化评估器
evaluator = RAGEvaluator(
llm_model="gpt-4o",
evaluator_model="gpt-4o"
)
# 运行完整评估流程
results = evaluator.run_full_pipeline(
documents=documents,
queries=queries,
references=references,
save_path="evaluation_results.csv"
)
# 打印结果
print("\n" + "=" * 60)
print("Ragas 评估报告")
print("=" * 60)
for metric_name, score in results.items():
print(f"{metric_name:30s}: {score:.4f}")
print("=" * 60)
if __name__ == "__main__":
main()
五、自定义评估指标
5.1 离散指标(DiscreteMetric)
python
from ragas.metrics import DiscreteMetric
# 创建自定义通过/失败指标
correctness_metric = DiscreteMetric(
name="correctness",
prompt="""检查响应是否包含评分标准中提到的要点。
只返回 'pass' 或 'fail'。
响应: {response}
评分标准: {grading_notes}""",
allowed_values=["pass", "fail"],
)
# 使用自定义指标
score = correctness_metric.score(
llm=evaluator_llm,
response="Python 是由 Guido van Rossum 创建的",
grading_notes="- 必须提及 Guido van Rossum\n- 必须提及编程语言"
)
print(f"评分结果: {score.value}") # 输出: pass 或 fail
5.2 连续指标(ContinuousMetric)
python
from ragas.metrics import ContinuousMetric
# 创建自定义 0-1 评分指标
completeness_metric = ContinuousMetric(
name="completeness",
prompt="""评估响应的完整性(0-1 分)。
问题: {question}
响应: {response}
参考答案: {reference}
评分标准:
- 1.0: 完全覆盖所有要点
- 0.5: 覆盖部分要点
- 0.0: 未覆盖任何要点
只返回数字分数。""",
)
# 使用自定义指标
score = completeness_metric.score(
llm=evaluator_llm,
question="什么是 Python?",
response="Python 是一种编程语言",
reference="Python 是一种高级编程语言,由 Guido van Rossum 创建"
)
print(f"完整性得分: {score.value}")
5.3 带推理的指标
python
from ragas.metrics import MetricWithLLM
class CustomMetric(MetricWithLLM):
"""自定义带推理的评估指标"""
name = "custom_metric"
def _score(self, row: dict, llm) -> float:
"""计算分数"""
prompt = f"""
评估以下响应的质量:
问题: {row['user_input']}
上下文: {row['retrieved_contexts']}
响应: {row['response']}
给出 0-1 的分数,并简要说明理由。
"""
response = llm.generate(prompt)
# 解析响应提取分数
score = self._extract_score(response)
return score
def _extract_score(self, response: str) -> float:
"""从 LLM 响应中提取分数"""
import re
match = re.search(r'(\d+\.?\d*)', response)
if match:
return float(match.group(1))
return 0.0
六、最佳实践
6.1 评估驱动开发流程
markdown
┌─────────────────────────────────────────────────────────┐
│ 评估驱动开发(EDD)流程 │
└─────────────────────────────────────────────────────────┘
1. 定义评估目标
│
▼
2. 准备测试数据集
│
▼
3. 实现基础 RAG 系统
│
▼
4. 运行基准评估
│
▼
5. 分析瓶颈
│
▼
6. 优化迭代
│
▼
7. 重新评估 → 循环至步骤 5
6.2 测试数据集准备
数据集质量标准
| 维度 | 标准 |
|---|---|
| 覆盖度 | 覆盖不同类型的问题(事实型、推理型、开放型) |
| 难度梯度 | 包含简单、中等、困难样本 |
| 边界情况 | 包含无答案、多答案等特殊情况 |
| 数据量 | 建议至少 50-100 个测试样本 |
测试样本分类
python
# 分类示例
test_samples = {
"factual": [ # 事实型问题
"Python 的创建者是谁?",
"JavaScript 什么时候发布?"
],
"reasoning": [ # 推理型问题
"为什么 Rust 被认为更安全?",
"比较 Python 和 Go 的适用场景"
],
"open_ended": [ # 开放型问题
"选择合适的编程语言需要考虑哪些因素?",
"解释静态类型和动态类型的区别"
],
"edge_cases": [ # 边界情况
"如何用 Brainfuck 编写 Web 应用?", # 知识库中无答案
"什么是这门语言?", # 模糊指代
]
}
6.3 性能优化建议
1. 批量评估
python
# 使用批量 API 提高评估速度
from ragas import RunConfig
results = evaluate(
dataset=dataset,
metrics=metrics,
llm=evaluator_llm,
run_config=RunConfig(
batch_size=10, # 批量大小
timeout=30, # 超时时间(秒)
)
)
2. 并行评估
python
import asyncio
from concurrent.futures import ThreadPoolExecutor
async def parallel_evaluation(datasets, metrics):
"""并行评估多个数据集"""
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [
executor.submit(evaluate, ds, metrics, evaluator_llm)
for ds in datasets
]
results = [f.result() for f in futures]
return results
3. 缓存机制
python
from functools import lru_cache
@lru_cache(maxsize=1000)
def cached_evaluate(query: str, context: str, response: str):
"""带缓存的评估函数"""
# 评估逻辑
pass
6.4 本地模型使用
python
"""
使用本地模型降低成本
适用于:敏感数据、成本控制、低延迟场景
"""
# 使用 Ollama 本地模型
from langchain_community.llms import Ollama
# 配置本地评估器
local_evaluator = Ollama(
model="llama3.2:latest",
temperature=0,
num_ctx=4096
)
# 使用本地模型进行评估
results = evaluate(
dataset=dataset,
metrics=[ContextPrecision(), Faithfulness()],
llm=LangchainLLMWrapper(local_evaluator)
)
七、进阶功能
7.1 与 LangChain 集成
python
from langchain_core.vectorstores import VectorStore
from langchain_core.retrievers import BaseRetriever
from ragas import evaluate
from ragas.integrations.langchain import EvaluatorChain
# 创建评估链
evaluator_chain = EvaluatorChain(
metrics=[ContextPrecision(), Faithfulness()],
evaluator_llm=evaluator_llm
)
# 在 LangChain 管道中使用
from langchain_core.runnables import RunnablePassthrough
rag_chain = (
{
"query": RunnablePassthrough(),
"context": retriever | (lambda docs: "\n".join([d.page_content for d in docs]))
}
| prompt
| llm
| evaluator_chain # 添加评估
)
7.2 持续监控
python
"""
将 Ragas 集成到 CI/CD 流程
"""
import json
from datetime import datetime
class CICDEvaluator:
"""CI/CD 评估器"""
def __init__(self, baseline_file: str = "baseline.json"):
self.baseline_file = baseline_file
self.baseline = self._load_baseline()
def _load_baseline(self) -> dict:
"""加载基准分数"""
try:
with open(self.baseline_file) as f:
return json.load(f)
except FileNotFoundError:
return {}
def save_baseline(self, scores: dict) -> None:
"""保存基准分数"""
with open(self.baseline_file, 'w') as f:
json.dump(scores, f, indent=2)
def check_regression(self, current_scores: dict,
threshold: float = 0.05) -> dict:
"""检查性能回归"""
regressions = {}
for metric, current_score in current_scores.items():
if metric in self.baseline:
baseline_score = self.baseline[metric]
if current_score < baseline_score - threshold:
regressions[metric] = {
"baseline": baseline_score,
"current": current_score,
"diff": current_score - baseline_score
}
return regressions
def run_ci_check(self, dataset: EvaluationDataset) -> bool:
"""运行 CI 检查"""
# 执行评估
results = evaluate(dataset=dataset, metrics=metrics)
# 检查回归
regressions = self.check_regression(results)
if regressions:
print("❌ 发现性能回归:")
for metric, info in regressions.items():
print(f" {metric}: {info['baseline']:.3f} → {info['current']:.3f}")
return False
else:
print("✅ 所有指标正常")
self.save_baseline(results)
return True
# 在 CI 脚本中使用
if __name__ == "__main__":
evaluator = CICDEvaluator()
passed = evaluator.run_ci_check(evaluation_dataset)
if not passed:
exit(1) # CI 失败
7.3 多模型对比
python
"""
对比不同模型的性能
"""
import matplotlib.pyplot as plt
def compare_models(dataset: EvaluationDataset,
model_configs: list[dict]) -> pd.DataFrame:
"""
对比多个模型
Args:
dataset: 测试数据集
model_configs: 模型配置列表
[{"name": "gpt-4", "model": "gpt-4"},
{"name": "gpt-3.5", "model": "gpt-3.5-turbo"}]
"""
results = []
for config in model_configs:
# 使用该模型构建 RAG
rag = SimpleRAG(model=config["model"])
# 评估
scores = evaluate(
dataset=dataset,
metrics=metrics,
llm=LangchainLLMWrapper(ChatOpenAI(model=config["model"]))
)
# 记录结果
scores["model"] = config["name"]
results.append(scores)
return pd.DataFrame(results)
# 使用示例
model_configs = [
{"name": "GPT-4", "model": "gpt-4"},
{"name": "GPT-3.5", "model": "gpt-3.5-turbo"},
{"name": "Claude-3", "model": "claude-3-opus-20240229"}
]
comparison_df = compare_models(evaluation_dataset, model_configs)
# 可视化
comparison_df.plot(x="model", kind="bar")
plt.title("模型性能对比")
plt.ylabel("分数")
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.savefig("model_comparison.png")
7.4 A/B 测试
python
"""
对新版本进行 A/B 测试
"""
class ABTest:
"""A/B 测试框架"""
def __init__(self, control_rag, treatment_rag, dataset):
self.control = control_rag
self.treatment = treatment_rag
self.dataset = dataset
def run(self, sample_size: int = 100) -> dict:
"""运行 A/B 测试"""
# 随机采样
samples = self.dataset.sample(min(sample_size, len(self.dataset)))
# 评估对照组
control_results = self._evaluate_system(self.control, samples)
# 评估实验组
treatment_results = self._evaluate_system(self.treatment, samples)
# 统计显著性测试
return self._analyze_results(control_results, treatment_results)
def _evaluate_system(self, rag, samples):
"""评估单个系统"""
results = []
for _, row in samples.iterrows():
result = rag.query(row["query"])
results.append(result)
return results
def _analyze_results(self, control, treatment):
"""分析结果"""
from scipy import stats
analysis = {}
for metric in control.keys():
# t 检验
t_stat, p_value = stats.ttest_ind(
control[metric],
treatment[metric]
)
analysis[metric] = {
"control_mean": np.mean(control[metric]),
"treatment_mean": np.mean(treatment[metric]),
"p_value": p_value,
"significant": p_value < 0.05
}
return analysis
八、常见问题
8.1 安装问题
Q: pip install 失败怎么办?
bash
# 尝试升级 pip
python -m pip install --upgrade pip
# 使用国内镜像
pip install ragas -i https://pypi.tuna.tsinghua.edu.cn/simple
# 使用 conda
conda install -c conda-forge ragas
Q: 导入错误?
python
# 检查版本兼容性
import ragas
print(ragas.__version__)
# 重新安装
pip uninstall ragas
pip install ragas --no-cache-dir
8.2 评估问题
Q: 评估分数异常(全是 0 或 1)?
python
# 检查 1: 验证数据格式
print(evaluation_dataset[0])
# 检查 2: 查看 LLM 响应
# 设置更详细的日志
import logging
logging.basicConfig(level=logging.DEBUG)
# 检查 3: 调整 temperature
evaluator_llm = ChatOpenAI(
model="gpt-4",
temperature=0 # 确保为 0
)
Q: 评估速度太慢?
python
# 方案 1: 使用批量处理
from ragas import RunConfig
results = evaluate(
dataset=dataset,
metrics=metrics,
run_config=RunConfig(batch_size=20)
)
# 方案 2: 使用更快的模型
evaluator_llm = ChatOpenAI(model="gpt-3.5-turbo")
# 方案 3: 并行评估
# (参考 6.3 节代码)
Q: 内存不足?
python
# 分批评估
batch_size = 50
all_results = []
for i in range(0, len(dataset), batch_size):
batch = dataset[i:i+batch_size]
results = evaluate(batch, metrics, evaluator_llm)
all_results.append(results)
# 合并结果
final_results = merge_results(all_results)
8.3 API 问题
Q: OpenAI API 限流?
python
import time
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10))
def evaluate_with_retry(dataset, metrics, llm):
return evaluate(dataset=dataset, metrics=metrics, llm=llm)
Q: 如何使用其他 LLM?
python
# 使用 Anthropic Claude
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(
model="claude-3-opus-20240229",
api_key="your-api-key"
)
# 使用本地模型 (Ollama)
from langchain_community.llms import Ollama
llm = Ollama(model="llama3.2")
九、相关资源
9.1 官方资源
| 资源 | 链接 |
|---|---|
| GitHub 仓库 | github.com/explodinggr... |
| 官方文档 | docs.ragas.io |
| 快速入门 | docs.ragas.io/en/stable/g... |
| API 参考 | docs.ragas.io/en/stable/r... |
9.2 中文教程
| 标题 | 链接 |
|---|---|
| RAG系统效果难评?2025年必备的RAG评估框架与工具详解 | zhuanlan.zhihu.com/p/189252947... |
| RAG评测终极指南!Ragas+RAGFlow实战 | blog.csdn.net/m0_59235945... |
| 深度测评RAG应用评估框架:指标最全面的Ragas | cloud.tencent.com/developer/a... |
| 使用本地私有大模型进行RAGAS评估 | blog.csdn.net/qq_46024883... |
9.3 视频教程
| 平台 | 标题 | 链接 |
|---|---|---|
| B站 | 2025年最全最细的大模型RAG教程 | www.bilibili.com/video/BV1D3... |
| YouTube | How to Evaluate a RAG Application | www.youtube.com/watch?v=5fp... |
9.4 社区与支持
| 资源 | 链接 |
|---|---|
| Discord 社区 | discord.gg/ragas |
| Stack Overflow | [tag:ragas] |
| 论坛讨论 | github.com/explodinggr... |
附录
A. 快速参考
python
# 常用导入
from ragas import evaluate, EvaluationDataset
from ragas.metrics import (
ContextPrecision,
LLMContextRecall,
Faithfulness,
AnswerRelevancy,
FactualCorrectness
)
from ragas.llms import LangchainLLMWrapper
from langchain_openai import ChatOpenAI
# 标准评估流程
evaluator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o"))
results = evaluate(
dataset=evaluation_dataset,
metrics=[
ContextPrecision(),
LLMContextRecall(),
Faithfulness()
],
llm=evaluator_llm
)
B. 评估指标速查表
| 指标 | 类型 | 范围 | 适用场景 |
|---|---|---|---|
| Context Precision | 检索 | 0-1 | 检索质量评估 |
| Context Recall | 检索 | 0-1 | 检索完整性 |
| Faithfulness | 生成 | 0-1 | 幻觉检测 |
| Answer Relevancy | 生成 | 0-1 | 答案质量 |
| Factual Correctness | 生成 | 0-1 | 事实准确性 |
C. 配置模板
yaml
# ragas_config.yaml
evaluation:
# 评估器配置
evaluator:
model: "gpt-4o"
temperature: 0
max_tokens: 1024
# 指标配置
metrics:
- context_precision
- context_recall
- faithfulness
- answer_relevancy
# 运行配置
run_config:
batch_size: 10
timeout: 30
max_retries: 3
# 输出配置
output:
format: "csv"
path: "./results"
save_detailed: true
文档结束
如有问题或建议,欢迎反馈!