课程0基础Agent开发课 / 生产化部署 / RAG评估-用RAGAS量化你的知识库质量
— 14 min read

RAG评估-用RAGAS量化你的知识库质量

RAG 系统有大量可调参数,每个参数都会影响最终效果:chunk size(文档切块大小)、overlap 大小(相邻块的重叠内容,防止信息在切割处丢失)、切分策略、top-k(每次检索返回最相关的前k个文档)、相似度阈值、embedding 模型、reranker(重排序器,对初次检索结果再次精排提升准确性)、Prompt、LLM 选择……这些参数的组合是指数级的,不可能全部手动试。

RAG 评估:用 RAGAS 量化你的知识库质量

RAG 系统有大量可调参数,每个参数都会影响最终效果:chunk size(文档切块大小)、overlap 大小(相邻块的重叠内容,防止信息在切割处丢失)、切分策略、top-k(每次检索返回最相关的前k个文档)、相似度阈值、embedding 模型、reranker(重排序器,对初次检索结果再次精排提升准确性)、Prompt、LLM 选择……这些参数的组合是指数级的,不可能全部手动试。

没有量化评估,RAG 优化就是在黑暗里摸索——改了几个月参数,却不确定哪次改动是真的有效,哪次只是感觉好了但其实没变化。RAGAS(Retrieval Augmented Generation Assessment)就是目前最常用的 RAG 自动化评估框架,能用数据驱动优化决策。


1.1 RAGAS 的四个核心指标

RAGAS 评估体系

检索质量

生成质量

端到端质量

Context Precision
上下文精确率

Context Recall
上下文召回率

Faithfulness
忠实度

Answer Relevancy
答案相关性

Answer Correctness
答案正确性

Answer Similarity
答案相似度

RAGAS 定义了四个核心指标,从不同维度衡量 RAG 系统的质量。

RAG系统质量

生成质量

检索质量

Faithfulness 忠实度

Answer Relevancy 答案相关性

Context Precision 上下文精确率

Context Recall 上下文召回率

答案是否基于检索文档,没有编造

答案是否回答了用户的问题

检索到的文档中,有多少是有用的

需要的信息有没有被检索到

1.1.1 Faithfulness(忠实度)

衡量什么: 答案中的每一个陈述,是否都能在检索到的文档中找到依据。

分数范围: 0-1,越高越好。

怎么计算: RAGAS 把答案拆成若干个原子陈述,然后逐一判断每个陈述是否能被检索到的文档支持。支持的陈述数 / 总陈述数 = Faithfulness 分数。

举例:

用户问:"我们公司的年假政策是什么?"
检索到的文档说:"员工入职满一年后,每年有 10 天年假。"
LLM 回答:"根据公司政策,入职满一年后有 10 天年假。另外,高级员工还有额外 5 天。"

这个回答的 Faithfulness 分数会低,因为"高级员工额外 5 天"这个陈述在检索文档里找不到依据,属于 LLM "编造"的内容。

如果这个指标低,说明: 检索到的文档不足以支撑回答,LLM 在凭自己的知识或者"猜测"来填充答案。解决方向是提升检索质量,或者在 Prompt 里明确要求"只根据提供的文档回答,无法回答就说不知道"。

1.1.2 Answer Relevancy(答案相关性)

衡量什么: 答案是否真正回答了用户的问题。

分数范围: 0-1,越高越好。

怎么计算: RAGAS 用 LLM 从答案反推出可能的问题,然后看这些反推出的问题和原始问题有多相似。如果答案确实回答了问题,反推出的问题应该和原始问题接近。

举例:

用户问:"如何申请年假?"
LLM 回答:"公司的年假政策规定,满一年有 10 天年假,满三年有 15 天年假……"

这个回答 Faithfulness 可能很高(内容都来自文档),但 Answer Relevancy 低,因为用户问的是"如何申请"(流程),而不是"有多少天"(政策)。

如果这个指标低,说明: Prompt 设计有问题,LLM 没有抓住用户意图;或者检索到的文档有信息但方向不对,Prompt 没有引导 LLM 聚焦到用户真正关心的点。

1.1.3 Context Precision(上下文精确率)

衡量什么: 检索到的文档中,有多少是真正和回答这个问题相关的(信噪比)。

分数范围: 0-1,越高越好。

怎么计算: 检索到的文档里,判断每个文档是否对生成正确答案有贡献,有贡献的比例就是精确率。

举例:

检索到 3 个文档,top-k=3。其中文档 1 和文档 2 包含回答问题需要的信息,文档 3 是一个不相关的文档(碰巧包含了一些相同关键词)。Context Precision = 2/3 ≈ 0.67。

如果这个指标低,说明: 检索噪声大,系统召回了很多不相关的文档。可以考虑:提高相似度阈值、使用 reranker 过滤、缩小 top-k、优化 embedding 模型。

1.1.4 Context Recall(上下文召回率)

衡量什么: 回答这个问题所需要的信息,有多少被检索到了。

分数范围: 0-1,越高越好。

需要: 这个指标需要 ground_truth(标准答案),用来判断"需要什么信息"。

怎么计算: 把标准答案拆成若干陈述,判断每个陈述能否在检索到的文档中找到支持。找到支持的比例就是召回率。

如果这个指标低,说明: 知识库里有答案,但没有被检索到。可以考虑:增大 top-k、调整 chunk size(太大可能把关键信息稀释了)、换更好的 embedding 模型。


1.2 如何构建评估数据集

RAGAS 需要一批测试数据,格式是:

python
{
    "question": "用户问题",
    "answer": "RAG系统的回答",
    "contexts": ["检索到的文档1", "检索到的文档2", ...],
    "ground_truth": "标准答案(Context Recall需要)"
}

构建方式:

手工标注(最可靠): 从用户真实问题里抽取 50-100 个有代表性的问题,人工写标准答案,记录每次 RAG 系统的检索结果和回答。工作量大,但质量高,适合作为黄金测试集。

RAGAS 自动生成: RAGAS 提供了测试集生成工具,从你的文档自动生成问答对(以下为 RAGAS v0.2+ 的写法):

python
from ragas.testset import TestsetGenerator
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.document_loaders import DirectoryLoader

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

# 自动生成测试集(RAGAS v0.2+ API)
generator = TestsetGenerator.from_langchain(
    generator_llm=ChatOpenAI(model="gpt-4o-mini"),
    critic_llm=ChatOpenAI(model="gpt-4o-mini"),
    embeddings=OpenAIEmbeddings()
)
testset = generator.generate_with_langchain_docs(
    documents,
    test_size=50
)

注意:RAGAS v0.1 使用 TestsetGenerator.with_openai()evolutions 参数,v0.2 之后 API 有较大变化,如遇旧版代码请参考官方文档对应版本。


1.3 完整评估代码

python
# evaluate_rag.py
# 以下代码适用于 RAGAS v0.2+
# v0.1 的 evaluate() 接口有所不同,请参考对应版本文档
import os
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall
)
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA

os.environ["OPENAI_API_KEY"] = "sk-your-key"

# ——— 初始化RAG系统 ———
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(
    persist_directory="./chroma_db",
    embedding_function=embeddings
)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
rag_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
    return_source_documents=True
)

# ——— 准备评估数据集 ———
# 实际使用时,这里应该是你标注好的测试集
test_questions = [
    "公司的年假政策是什么?",
    "如何申请请假?",
    "试用期是多少天?",
    "加班费怎么计算?",
    "员工福利有哪些?"
]

ground_truths = [
    "入职满一年后每年10天年假,满三年15天,满五年20天。",
    "需要提前三天在OA系统提交申请,经直属上级审批。",
    "试用期为三个月,双方协商一致可以缩短。",
    "工作日加班按1.5倍,休息日加班按2倍,法定节假日按3倍。",
    "包括五险一金、补充医疗保险、年度体检、餐补、交通补贴。"
]

# ——— 运行RAG并收集结果 ———
eval_data = {
    "question": [],
    "answer": [],
    "contexts": [],
    "ground_truth": []
}

for question, ground_truth in zip(test_questions, ground_truths):
    result = rag_chain.invoke({"query": question})

    eval_data["question"].append(question)
    eval_data["answer"].append(result["result"])
    eval_data["contexts"].append([
        doc.page_content for doc in result["source_documents"]
    ])
    eval_data["ground_truth"].append(ground_truth)
    print(f"已评估:{question}")

# ——— 转成Dataset格式 ———
dataset = Dataset.from_dict(eval_data)

# ——— 运行RAGAS评估 ———
result = evaluate(
    dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall
    ],
    llm=ChatOpenAI(model="gpt-4o-mini"),
    embeddings=OpenAIEmbeddings()
)

# ——— 输出结果 ———
print("\n===== RAGAS评估结果 =====")
print(f"Faithfulness(忠实度):      {result['faithfulness']:.3f}")
print(f"Answer Relevancy(答案相关性): {result['answer_relevancy']:.3f}")
print(f"Context Precision(上下文精确率): {result['context_precision']:.3f}")
print(f"Context Recall(上下文召回率): {result['context_recall']:.3f}")

# 保存详细结果
df = result.to_pandas()
df.to_csv("rag_evaluation_results.csv", index=False, encoding="utf-8")
print("\n详细结果已保存到 rag_evaluation_results.csv")

运行:

bash
pip install ragas langchain langchain-openai langchain-community chromadb datasets
python evaluate_rag.py

输出示例:

code
===== RAGAS评估结果 =====
Faithfulness(忠实度):       0.823
Answer Relevancy(答案相关性): 0.756
Context Precision(上下文精确率): 0.667
Context Recall(上下文召回率):  0.714

1.4 评估结果怎么用

拿到分数之后,根据哪个指标低来确定优化方向:

Faithfulness 低(< 0.7)

LLM 在编造内容,没有忠实于检索到的文档。

排查方向:

  • 检索到的文档是否真的包含回答问题的信息?如果没有,就是检索质量问题
  • Prompt 里是否明确要求"只根据提供文档回答"?加上这个约束通常能提升 Faithfulness
  • LLM 的 temperature 是否太高?降低 temperature 可以减少"创造性发挥"

Answer Relevancy 低(< 0.7)

答案没有回答用户的问题,方向跑偏了。

排查方向:

  • 分析低分的具体案例,看 LLM 在回答什么(通常是检索到了相关主题但不同角度的文档)
  • 考虑在检索前做问题改写,更精准地表达用户意图
  • 调整 Prompt,明确要求"针对用户的具体问题直接回答"

Context Precision 低(< 0.6)

检索到了太多噪声文档。

排查方向:

  • 提高相似度阈值,过滤掉低相关性的文档
  • 引入 reranker(如 Cohere Rerank)对检索结果重排序
  • 适当减小 top-k

Context Recall 低(< 0.6)

知识库里有答案但没检索到。

排查方向:

  • 增大 top-k(检索更多候选文档)
  • 检查 chunk size 是否合适,太小可能把完整知识点切碎了
  • 考虑换更好的 embedding 模型(比如从 text-embedding-ada-002 升级到 text-embedding-3-large)
  • 混合检索(向量检索 + BM25 关键词检索,BM25 是一种基于词频统计的传统文本匹配算法,与向量检索互补,能找到精确包含关键词的文档)通常能提升召回

1.5 LLM-as-Judge:RAGAS 内部的评估机制

RAGAS 计算这四个指标的方式,本质上是用一个 LLM(Judge LLM)来评估另一个 LLM 的输出。

以 Faithfulness 为例,RAGAS 的内部逻辑是:

RAG系统的答案

Judge LLM拆分答案为原子陈述

陈述1: 年假10天

陈述2: 满三年15天

陈述3: 高级员工额外5天

检索到的文档

Judge LLM判断每个陈述
是否能被文档支持

陈述1: 支持

陈述2: 支持

陈述3: 不支持,文档中没有

Faithfulness = 2/3 = 0.67

这个方法有个前提:Judge LLM 要足够强。RAGAS 默认用 GPT-4,用 GPT-4o-mini 评估会便宜但可能准确性下降。

这也意味着:RAGAS 的评估结果本身是有噪声的,不是绝对精准的。但它的价值在于提供了一个一致、可重复的评估基准。同等条件下比较不同配置的分数,是有意义的。


1.6 持续评估,不是一次性的

RAG 系统会持续迭代:知识库更新、Prompt 调整、模型升级。每次改动都应该跑一遍评估,对比分数变化。

建议的持续评估流程:

  1. 维护一个黄金测试集(50-100 个问答对),放到版本控制里
  2. 每次改动后跑 RAGAS 评估,记录四个指标
  3. 对比前后指标变化,只有明确提升才合并改动
  4. 定期(比如每月)用新的用户问题更新测试集

RAGAS 评估是 RAG 优化的量化工具。有了这个工具,每次改动的效果都有数据支撑,而不是依赖主观判断。

本页目录