跳转至

Ragas RAG 评估

为什么要学

构建 RAG(检索增强生成)系统容易,但如何知道它工作得好不好?手动评估耗时且不可扩展。Ragas 解决的核心问题是:

  • 量化 RAG 质量:用数字衡量检索和生成的质量
  • 自动化评估:无需人工逐条审核,LLM-as-Judge 自动打分
  • 诊断定位:区分"检索差"还是"生成差",精确优化
  • 持续监控:每次改动都能跑评估,防止回归
  • 标准化指标:业界通用的 RAG 评估指标体系

无论你用什么框架构建 RAG,Ragas 都能帮你回答"这个 RAG 系统到底好不好用"。

核心概念

白话解释

把 RAG 评估想象成"考试阅卷": - Context Precision(上下文精确度):检索到的文档中,有多少是真正相关的? - Context Recall(上下文召回):回答所需的信息,检索到了多少? - Faithfulness(忠实度):回答是否忠于检索到的上下文?(不瞎编) - Answer Relevancy(回答相关性):回答和问题相关吗?

核心概念对照表

指标评估什么分数含义优化方向
Context Precision检索精度相关文档占比优化检索/重排序
Context Recall检索召回是否检索到所需信息扩大检索范围
Faithfulness生成忠实度回答是否基于上下文减少幻觉
Answer Relevancy回答相关性回答是否切题优化prompt
Answer Correctness回答正确性与参考答案对比整体优化
Context Entities Recall实体召回关键实体是否被检索到实体级检索优化

安装配置

安装

pip install ragas

# 完整安装(含所有依赖)
pip install ragas[all]

# 指定LLM后端
pip install ragas langchain-openai

环境配置

# Ragas使用LLM进行评估,需要配置API
export OPENAI_API_KEY="sk-..."

# 或使用其他模型
export RAGAS_LLM_PROVIDER="openai"  # openai/azure/bedrock

验证安装

from ragas.metrics import faithfulness, answer_relevancy
from ragas import evaluate

print("Ragas安装成功!")
print(f"可用指标: faithfulness, answer_relevancy, ...")

快速上手

准备评估数据

from datasets import Dataset

# RAG评估需要的数据格式
eval_data = {
    "question": [
        "什么是向量数据库?",
        "RAG的优势是什么?"
    ],
    "answer": [
        "向量数据库是专门用于存储和查询高维向量的数据库系统,支持相似性搜索。",
        "RAG通过检索外部知识来增强LLM的回答能力,减少幻觉。"
    ],
    "contexts": [
        ["向量数据库是一种专门处理向量数据的数据库,支持高效的相似性搜索和最近邻查询。常见的向量数据库包括Pinecone、Weaviate、ChromaDB等。"],
        ["RAG(检索增强生成)将检索系统与LLM结合,通过检索相关文档来提供上下文,从而生成更准确的回答。主要优势包括:减少幻觉、知识可更新、可追溯来源。"]
    ],
    "ground_truth": [
        "向量数据库是专门设计用来存储、管理和查询高维向量数据的数据库系统。",
        "RAG的主要优势包括减少LLM幻觉、可以更新知识而无需重新训练、回答可追溯来源。"
    ]
}

dataset = Dataset.from_dict(eval_data)

运行评估

from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
)

# 一行代码完成评估
result = evaluate(
    dataset=dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall,
    ]
)

print(result)
# {'faithfulness': 0.92, 'answer_relevancy': 0.88, 
#  'context_precision': 0.85, 'context_recall': 0.90}

# 查看每条数据的详细分数
df = result.to_pandas()
print(df)

理解评估结果

# 分析结果
df = result.to_pandas()

# 找出低分的案例
low_faithfulness = df[df['faithfulness'] < 0.5]
print("忠实度低的案例(可能有幻觉):")
print(low_faithfulness[['question', 'answer']])

low_recall = df[df['context_recall'] < 0.5]
print("召回率低的案例(检索不够):")
print(low_recall[['question', 'contexts']])

进阶用法

1. 自动生成测试数据

from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple, reasoning, multi_context
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.document_loaders import DirectoryLoader

# 加载你的文档
loader = DirectoryLoader("./docs/", glob="**/*.md")
documents = loader.load()

# 配置生成器
generator_llm = ChatOpenAI(model="gpt-4o-mini")
critic_llm = ChatOpenAI(model="gpt-4o")
embeddings = OpenAIEmbeddings()

generator = TestsetGenerator.from_langchain(
    generator_llm=generator_llm,
    critic_llm=critic_llm,
    embeddings=embeddings
)

# 自动生成测试集
testset = generator.generate_with_langchain_docs(
    documents=documents,
    test_size=20,
    distributions={
        simple: 0.5,      # 简单问题
        reasoning: 0.25,   # 需要推理的问题
        multi_context: 0.25 # 需要多文档的问题
    }
)

# 转为Dataset
eval_dataset = testset.to_dataset()
print(eval_dataset)

2. 自定义评估指标

from ragas.metrics import Metric
from ragas.metrics.base import MetricWithLLM
from dataclasses import dataclass

@dataclass
class ConcisenessMetric(MetricWithLLM):
    name: str = "conciseness"

    async def _ascore(self, row, callbacks=None):
        # 用LLM评估回答的简洁度
        prompt = f"""评估以下回答的简洁度(0-1分):
        问题: {row['question']}
        回答: {row['answer']}

        评分标准: 1=非常简洁,0=过于冗长
        只返回一个数字。"""

        result = await self.llm.agenerate_text(prompt)
        return float(result.strip())

# 使用自定义指标
conciseness = ConcisenessMetric()
result = evaluate(dataset=dataset, metrics=[conciseness])

3. 使用本地模型评估

from langchain_community.llms import Ollama
from langchain_community.embeddings import OllamaEmbeddings
from ragas import evaluate
from ragas.metrics import faithfulness

# 使用本地Ollama模型作为评估LLM
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

local_llm = LangchainLLMWrapper(Ollama(model="llama3.2"))
local_embeddings = LangchainEmbeddingsWrapper(OllamaEmbeddings(model="nomic-embed-text"))

# 指定评估用的LLM
faithfulness_metric = faithfulness
faithfulness_metric.llm = local_llm
faithfulness_metric.embeddings = local_embeddings

result = evaluate(
    dataset=dataset,
    metrics=[faithfulness_metric]
)

4. 端到端 RAG Pipeline 评估

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision

# 构建RAG Pipeline
def build_rag():
    embeddings = OpenAIEmbeddings()
    vectorstore = Chroma(embedding_function=embeddings)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
    llm = ChatOpenAI(model="gpt-4o-mini")
    return retriever, llm

# 收集评估数据
def collect_eval_data(questions, retriever, llm):
    data = {"question": [], "answer": [], "contexts": []}

    for q in questions:
        # 检索
        docs = retriever.get_relevant_documents(q)
        contexts = [doc.page_content for doc in docs]

        # 生成
        answer = llm.invoke(f"基于以下上下文回答问题:\n上下文:{contexts}\n问题:{q}")

        data["question"].append(q)
        data["answer"].append(answer.content)
        data["contexts"].append(contexts)

    return Dataset.from_dict(data)

# 评估
questions = ["什么是向量数据库?", "如何优化RAG检索?"]
retriever, llm = build_rag()
eval_dataset = collect_eval_data(questions, retriever, llm)

result = evaluate(
    dataset=eval_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision]
)
print(result)

5. CI/CD 集成

# test_rag_quality.py
import pytest
from ragas import evaluate
from ragas.metrics import faithfulness, context_recall

def test_rag_quality():
    """RAG质量门禁测试"""
    dataset = load_test_dataset()  # 你的测试数据

    result = evaluate(
        dataset=dataset,
        metrics=[faithfulness, context_recall]
    )

    # 设置质量门槛
    assert result['faithfulness'] > 0.8, \
        f"忠实度{result['faithfulness']:.2f}低于阈值0.8"
    assert result['context_recall'] > 0.7, \
        f"召回率{result['context_recall']:.2f}低于阈值0.7"

6. 与 Langfuse 集成

from ragas.integrations.langfuse import RagasTrace

# 评估结果自动上报到Langfuse
result = evaluate(
    dataset=dataset,
    metrics=[faithfulness, answer_relevancy],
    callbacks=[RagasTrace()]  # 自动追踪到Langfuse
)

常见问题

Q1: 评估成本太高?

  • 使用 gpt-4o-mini 而非 gpt-4o 做评估
  • 减少测试集大小(先评估 20-50 条)
  • 使用本地模型评估(质量略低但免费)
  • 对简单指标使用规则而非 LLM

Q2: 没有 ground_truth 怎么办?

不是所有指标都需要 ground_truth:

指标需要ground_truth需要contexts
faithfulness不需要需要
answer_relevancy不需要不需要
context_precision需要需要
context_recall需要需要

Q3: 评分不稳定怎么办?

  • 多次评估取平均值
  • 增大测试集
  • 使用更强的模型做评估
  • 检查评估 prompt 是否清晰

Q4: 如何解读低分?

faithfulness 低 → 模型在"编造"信息,优化:
  - 加强检索相关性
  - 在prompt中强调"只基于给定信息回答"

context_recall 低 → 检索遗漏了关键信息,优化:
  - 增加检索数量(k值)
  - 优化切块策略
  - 改进embedding模型

answer_relevancy 低 → 回答偏题,优化:
  - 改进prompt模板
  - 减少无关上下文的干扰

参考资源