跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

RAG 评估指南:解析评估指标与代码示例

RAG 系统评估涉及检索评估和响应评估。检索评估关注上下文相关性,常用指标包括精确度、召回率、MRR 和 MAP。响应评估关注忠实度和答案相关性。通过 LangSmith 平台可以方便地创建测试数据集并运行自动化评估器(如 cot_qa),从而迭代改进 RAG 系统的性能与可靠性。 RAG 优化策略、评估指标计算方法以及 LangSmith 的具体实施代码。

月亮邮递员发布于 2025/2/6更新于 2026/9/351 浏览
RAG 评估指南:解析评估指标与代码示例

RAG 评估指南:解析评估指标与代码示例

一、RAG 痛点介绍

在构建检索增强生成(Retrieval-Augmented Generation, RAG)系统时,我们常面临数据质量差、检索不准、生成幻觉等问题。为了优化 RAG 效果,必须建立科学的评估体系。

二、RAG 痛点优化策略

针对常见的 RAG 痛点,以下是最佳实践总结及关键优化点:

1. 数据处理

在使用数据之前,确保数据是干净和结构化的。这包括去除噪音、处理缺失值、标准化格式等。

分段和标注: 将长文档分成较小的段落(chunks),并为每个段落添加相关标签或元数据,以便更好地进行检索和生成。

import pandas as pd

# 读取数据
data = pd.read_csv('data.csv')

# 数据清洗
data.dropna(inplace=True)  # 去除缺失值
data['text'] = data['text'].str.lower()  # 转换为小写
data['text'] = data['text'].str.replace(r'\d+', '', regex=True)  # 去除数字

# 数据分段和标注
def chunk_text(text, chunk_size=200):
    words = text.split()
    chunks = [' '.join(words[i:i + chunk_size]) for i in range(0, len(words), chunk_size)]
    return chunks

data['chunks'] = data['text'].apply(chunk_text)

2. Chunk Size 设置

Chunk-size 的设置需要平衡信息量和检索效率。一般来说,较短的 chunk 可以提高检索的准确性,但可能会丢失上下文信息;较长的 chunk 可以保留更多的上下文,但可能会增加冗余信息。常见的 chunk 大小在 100 到 300 个词之间,根据具体应用场景进行调整。

# 设置 chunk 大小
chunk_size = 150  


 ():
    words = text.split()
    chunks = [.join(words[i:i + chunk_size])  i  (, (words), chunk_size)]
     chunks

data[] = data[].apply( x: chunk_text(x, chunk_size))
# 例如设置为 150 个词
# 分段函数
def
chunk_text
text, chunk_size
' '
for
in
range
0
len
return
'chunks'
'text'
lambda

3. Embedding 模型选择

选择合适的模型:常用的 embedding 模型包括 BERT、RoBERTa、Sentence-BERT 等。选择时需要考虑模型的性能、训练数据和计算资源。

from sentence_transformers import SentenceTransformer

# 使用 Sentence-BERT 模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')

# 对数据进行 embedding
embeddings = model.encode(data['chunks'].sum())

对于特定领域的应用,可以考虑对预训练模型进行微调,以提高嵌入的相关性和准确性。

4. Prompt 设计

设计有效的 prompt 以引导生成模型产生所需的回答。Prompt 应尽量清晰、具体,避免模糊或开放性太强。

# 示例 prompt 设计
prompt_template = "请根据以下内容回答问题:\n\n内容:{}\n\n问题:{}"

def create_prompt(content, question):
    return prompt_template.format(content, question)

# 使用示例
content = "这是一个示例内容。"
question = "这段内容的主要观点是什么?"
prompt = create_prompt(content, question)

5. 检索 TopN 设置

TopN 设置决定了在生成过程中使用多少个最相关的文档段落。常见的 topN 值在 3 到 10 之间,根据检索效果和生成质量进行调整。

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

# 假设我们有一个查询的 embedding
query_embedding = model.encode("示例查询")

# 计算相似度
similarities = cosine_similarity([query_embedding], embeddings)[0]

# 设置 topN 值
topN = 5

# 获取最相似的 topN 个结果
topN_indices = np.argsort(similarities)[-topN:][::-1]
topN_chunks = [data['chunks'].sum()[i] for i in topN_indices]

6. LLM 模型选择

选择合适的生成模型:常用的大语言模型(LLM)包括 GPT-3.5、GPT-4、4o 等。选择时需要考虑模型的生成能力、推理速度和计算资源。

混合使用模型:在一些场景下,可以同时使用多个模型来提高生成效果,例如结合检索模型和生成模型的优势。

7. RAG 检索生成效果优化策略

  • 选择更大的模型: 如果现有模型的生成效果不理想,可以尝试使用更大的预训练模型,这通常会带来更好的生成质量和上下文理解能力。
  • 使用不同的 embedding 模型: 根据实际应用场景和数据特点,尝试使用不同的 embedding 模型,以找到最适合的模型来提高检索精度。
  • 调整 chunk-size: 重新评估和调整 chunk 的大小,以找到信息量和检索效率之间的最佳平衡点。

通过不断地实验和优化,可以找到最适合特定应用场景的 RAG 配置,从而实现更好的检索和生成效果。

三、为什么需要对 RAG 系统评估

评估是 AI 开发流程中的一个非常关键步骤,它被用于检查当前策略相对于其他策略的有效性,或在当你对流程进行更改时进行评估。因此在进行 LLM 项目的开发和改进时,必须要有衡量其表现的方法。

为了评估 RAG 系统,我们通常使用两种类型的评估:

  1. 检索评估
  2. 响应评估

与传统的机器学习技术不同,传统技术有明确定量的度量指标(如 Gini 系数、R 平方、AIC、BIC、混淆矩阵等),评估 RAG 系统更加复杂。这种复杂性的原因在于 RAG 系统生成的响应是非结构化文本,需要结合定性和定量指标来准确评估其性能。

为了有效评估 RAG 系统,我们通常遵循 TRIAD 框架。该框架由三个主要组成部分组成:

  • 上下文相关性: 这个组件评估 RAG 系统的检索部分。它评估从大型数据集中准确检索到的文档。这里使用的度量指标包括精确度、召回率、MRR 和 MAP。
  • 忠实度(基于检索): 这个组件属于响应评估。它检查生成的响应是否准确无误,并且基于检索到的文档。通过人工评估、自动事实检查工具和一致性检查等方法来评估忠实度。
  • 答案相关性: 这也是响应评估的一部分。它衡量生成的响应对用户的查询提供了多少有用的信息。使用的度量指标包括 BLEU、ROUGE、METEOR 和基于嵌入的评估。

检索评估

检索评估适用于 RAG 系统的检索器组件,该组件通常使用向量数据库。这些评估衡量检索器在响应用户查询时识别和排名相关文档的效果。检索评估的主要目标是评估上下文相关性,即检索到的文档与用户查询的匹配程度。它确保提供给生成组件的上下文是相关和准确的。

精确度 (Precision)

精确度衡量了检索到的文档的准确性。它是检索到的相关文档数量与检索到的文档总数之比。

这意味着精确度评估了系统检索到的文档中有多少实际与用户查询相关。例如,如果检索器检索到了 10 个文档,其中 7 个是相关的,那么精确度将是 0.7 或 70%。

def calculate_precision(retrieved_docs, relevant_docs):
    """
    计算精确度
    
    参数:
    retrieved_docs (list): 检索到的文档列表
    relevant_docs (list): 相关文档列表
    
    返回:
    float: 精确度
    """
    # 计算检索到的相关文档数量
    relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
    
    # 计算精确度
    precision = len(relevant_retrieved_docs) / len(retrieved_docs) if retrieved_docs else 0
    return precision

# 示例数据
retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']
relevant_docs = ['doc2', 'doc4', 'doc6']

# 计算精确度
precision = calculate_precision(retrieved_docs, relevant_docs)
print(f"精确度:{precision:.2f}")

精确度评估的是'系统检索到的所有文档中,有多少实际上是相关的?'

在可能导致负面后果的情况下,精确度尤为重要。例如,在医学信息检索系统中,高精确度至关重要,因为提供不相关的医学文档可能导致错误信息和潜在的有害结果。

召回率 (Recall)

召回率衡量了检索到的文档的全面性。它是检索到的相关文档数量与数据库中相关文档的总数之比。

这意味着召回率评估了数据库中存在的相关文档有多少被系统成功检索到。

def calculate_recall(retrieved_docs, relevant_docs):
    """
    计算召回率
    
    参数:
    retrieved_docs (list): 检索到的文档列表
    relevant_docs (list): 相关文档列表
    
    返回:
    float: 召回率
    """
    # 计算检索到的相关文档数量
    relevant_retrieved_docs = [doc for doc in retrieved_docs if doc in relevant_docs]
    
    # 计算召回率
    recall = len(relevant_retrieved_docs) / len(relevant_docs) if relevant_docs else 0
    return recall

# 示例数据
retrieved_docs = ['doc1', 'doc2', 'doc3', 'doc4', 'doc5']
relevant_docs = ['doc2', 'doc4', 'doc6', 'doc7']

# 计算召回率
recall = calculate_recall(retrieved_docs, relevant_docs)
print(f"召回率:{recall:.2f}")

召回率评估的是'数据库中存在的所有相关文档中,系统成功检索到了多少个?'

在可能错过相关信息会产生成本的情况下,召回率至关重要。例如,在法律信息检索系统中,高召回率至关重要,因为未能检索到相关的法律文件可能导致不完整的案例研究,并可能影响法律诉讼的结果。

精确度和召回率的平衡

通常需要平衡精确度和召回率,因为改善其中一个指标有时会降低另一个指标。目标是找到适合特定应用需求的最佳平衡。这种平衡有时可以用 F1 分数来量化,F1 分数是精确度和召回率的调和平均值。

平均倒数排名 (MRR)

平均倒数排名(MRR)是一种评估检索系统效果的度量指标,它考虑了第一个相关文档的排名位置。当只有第一个相关文档是主要关注的情况下,MRR 特别有用。倒数排名是第一个相关文档被找到的排名的倒数。MRR 是多个查询的这些倒数排名的平均值。

MRR 评估的是'平均来说,系统多快能够在响应用户查询时检索到第一个相关文档?'

例如,在基于 RAG 的问答系统中,MRR 至关重要,因为它反映了系统能够多快地向用户呈现正确答案。如果正确答案更频繁地出现在列表的顶部,MRR 值将更高,表示检索系统更有效。

平均准确率 (MAP)

平均准确率(MAP)是一种评估多个查询的检索精确度的度量指标。它同时考虑了检索的精确度和检索文档的顺序。MAP 定义为一组查询的平均准确率得分的平均值。

MAP 评估的是'平均来说,系统在多个查询中排名靠前的文档的精确度如何?'

例如,在基于 RAG 的搜索引擎中,MAP 至关重要,因为它考虑了检索的精确度和不同排名的检索结果,确保相关文档在搜索结果中更高地显示,从而通过首先呈现最相关的信息来提高用户体验。

响应评估

响应评估适用于系统的生成组件。这些评估衡量系统根据检索到的文档提供的上下文有效地生成响应的能力。我们将响应评估分为两种类型:忠实度(基于检索)和答案相关性。

忠实度(基于检索)

忠实度评估生成的响应是否准确,并且基于检索到的文档。它确保响应不包含幻觉或错误信息。这个度量指标至关重要,因为它将生成的响应追溯到其来源,确保信息基于可验证的真实情况。忠实度有助于防止幻觉,即系统生成听起来合理但事实上不正确的响应。

为了衡量忠实度,通常使用以下方法:

  • 人工评估: 专家手动评估生成的响应是否事实准确,并且是否正确引用了检索到的文档。
  • 自动事实检查工具: 这些工具将生成的响应与已验证事实的数据库进行比较,以识别不准确之处。
  • 一致性检查: 这些评估模型是否在不同查询中始终提供相同的事实信息。
答案相关性

答案相关性衡量生成的响应对用户的查询有多好,并提供有用的信息。

四、使用 LangSmith 进行评估

了解了这些评估指标,该如何进行评估,可以先通过使用 LangSmith 进行评估。LangSmith 是一个开发者平台,允许您调试、测试、评估和监控大语言模型 (LLM) 应用程序,并且能够与 LangChain 无缝集成,助您从开发原型顺利过渡到实际生产应用。

在 LLM 任务中,测量准确性的一个挑战来自非结构化文本的影响。问答系统可能生成冗长的响应,使得传统的指标如 BLEU 或 ROUGE 变得不可靠。在这种情况下,使用标注良好的数据集和大语言模型 (LLM) 辅助评估器可以帮助您评估系统的响应质量。

针对一个 RAG 系统进行评估,主要步骤如下:

  1. 创建一个测试用的数据集。
  2. 定义您的问答系统。
  3. 使用 LangSmith 运行评估。
  4. 迭代改进系统。

1. 在 LangChain 代码中加入使用 LangSmith

第一步:获取一个 LangChain 的 API Key,登录 LangSmith 创建 API key。

第二步:设置以下参数后,LangSmith 会自动进行跟踪管理。

import os
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'
os.environ['LANGCHAIN_API_KEY'] = '<your-api-key>'
os.environ['LANGCHAIN_PROJECT'] = "my project name"

2. 准备测试数据

这里整理了三种准备测试数据的方式:数据导入,代码创建和使用 LangSmith 辅助创建。

第一种方法:CSV 文件导入 可以通过后台界面直接上传 CSV 文件作为测试集。

第二种方法:代码创建 下面的代码执行后,也可以在 LangSmith 中新建一个 Retrieval QA Questions 的测试集。

# 问题与答案
examples = [
    (
        "What is LangChain?",
        "LangChain is an open-source framework for building applications using large language models. It is also the name of the company building LangSmith.",
    ),
    (
        "Can I trace my Llama V2 llm?",
        "So long as you are using one of LangChain's LLM implementations, all your calls can be traced",
    ),
]

# 数据库创建部分
from langsmith import Client
client = Client()

import uuid
dataset_name = f"Retrieval QA Questions {str(uuid.uuid4())}"
dataset = client.create_dataset(dataset_name=dataset_name)
for q, a in examples:
    client.create_example(
        inputs={"question": q}, outputs={"answer": a}, dataset_id=dataset.id
    )

第三种方法:使用 LangSmith 辅助创建 创建的步骤如下:

  1. 建立 RAG 系统。
  2. 准备问题并执行查询,如:rag_chain.invoke("Ollama 支持哪些模型?")。
  3. LangSmith 后台根据处理的结果,对测试数据进行管理,添加,修改等。

3. 使用 LangSmith 进行评估

测试数据准备好之后,就可以开始对系统进行评估了。LangSmith 的后台可以生成评估的代码。

RAG QA 问答的正确性评估器(Evaluator)包含三个版本:'qa'、'context_qa'、'cot_qa'。

  • 'qa'评估器: 指示大语言模型 (LLM) 根据参考答案直接将响应评为'正确'或'错误'。
  • 'context_qa'评估器: 指示 LLM 使用参考'上下文'来确定响应的正确性。用于只有上下文和解答,没有答案的情况。
  • 'cot_qa'评估器: 与'context_qa'评估器类似,但它指示 LLMChain 在得出最终结论前使用思维链'推理'。这通常会导致响应更好地与人工标签匹配,但会稍微增加 Token 和运行成本。

4. 完整代码示例

import langsmith
from langchain import chat_models, prompts, smith
from langchain.schema import output_parser
from langchain_community.llms import Ollama
from langchain_community.embeddings import OllamaEmbeddings
import bs4
from langchain import hub
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

from langchain_community.document_loaders import UnstructuredHTMLLoader
loader = UnstructuredHTMLLoader("./240327-ollama-20question.html")
docs = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OllamaEmbeddings(model="mofanke/acge_text_embedding"))
retriever = vectorstore.as_retriever()

from langchain.prompts import ChatPromptTemplate
template = """你是一个回答问题的助手。请使用以下检索到的背景信息来回答问题。如果你不知道答案,直接说你不知道。请用最多三句话来保持回答的简洁性。
问题:{question} 

背景:{context} 

答案:"""

prompt = ChatPromptTemplate.from_template(template)

#llm = chat_models.ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm = Ollama(model="qwen:72b", temperature=0)

# Post-processing
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# Chain
rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 执行查询
rag_chain.invoke("Ollama 支持哪些模型?")

# 定义评估设置(评估器,评估用的 LLM 等)
eval_config = smith.RunEvalConfig(
    evaluators=[
        "cot_qa"
    ],
    custom_evaluators=[],
    eval_llm=Ollama(model="qwen:72b", temperature=0)
)

client = langsmith.Client()
chain_results = client.run_on_dataset(
    dataset_name="Self-RAG-Ollama-20QA",
    llm_or_chain_factory=rag_chain,
    evaluation=eval_config,
    project_name="test-crazy-rag-qw72b-qw72b",
    concurrency_level=5,
    verbose=True,
)

五、总结

开发 RAG 系统本身并不困难,但评估 RAG 系统对于性能、实现持续改进、与业务目标保持一致、平衡成本、确保可靠性和适应新方法至关重要。这个全面的评估过程有助于构建强大、高效和以用户为中心的 RAG 系统。建议在实际项目中建立自动化评估流水线,定期监控关键指标的变化,从而确保持续交付高质量的 AI 服务。

目录

  1. RAG 评估指南:解析评估指标与代码示例
  2. 一、RAG 痛点介绍
  3. 二、RAG 痛点优化策略
  4. 1. 数据处理
  5. 读取数据
  6. 数据清洗
  7. 数据分段和标注
  8. 2. Chunk Size 设置
  9. 设置 chunk 大小
  10. 分段函数
  11. 3. Embedding 模型选择
  12. 使用 Sentence-BERT 模型
  13. 对数据进行 embedding
  14. 4. Prompt 设计
  15. 示例 prompt 设计
  16. 使用示例
  17. 5. 检索 TopN 设置
  18. 假设我们有一个查询的 embedding
  19. 计算相似度
  20. 设置 topN 值
  21. 获取最相似的 topN 个结果
  22. 6. LLM 模型选择
  23. 7. RAG 检索生成效果优化策略
  24. 三、为什么需要对 RAG 系统评估
  25. 检索评估
  26. 精确度 (Precision)
  27. 示例数据
  28. 计算精确度
  29. 召回率 (Recall)
  30. 示例数据
  31. 计算召回率
  32. 精确度和召回率的平衡
  33. 平均倒数排名 (MRR)
  34. 平均准确率 (MAP)
  35. 响应评估
  36. 忠实度(基于检索)
  37. 答案相关性
  38. 四、使用 LangSmith 进行评估
  39. 1. 在 LangChain 代码中加入使用 LangSmith
  40. 2. 准备测试数据
  41. 问题与答案
  42. 数据库创建部分
  43. 3. 使用 LangSmith 进行评估
  44. 4. 完整代码示例
  45. Post-processing
  46. Chain
  47. 执行查询
  48. 定义评估设置(评估器,评估用的 LLM 等)
  49. 五、总结

更多推荐文章

查看全部
  • AI 提示工程实战:如何与大模型高效对话
  • NWPU VHR-10 遥感目标检测数据集介绍与 YOLO 训练实战
  • AI 产品经理转型指南:核心技能与行业落地场景解析
  • 大模型在智能财务领域的应用思路与落地实践
  • NVIDIA RTX PC 开源 AI 工具升级:LLM 与扩散模型性能优化
  • Janus-Pro-7B 快速上手:图片问答与文生图功能详解
  • 基于 FastGPT 与 MCP 协议构建工具增强型智能体
  • OpenClaw 跨平台安装指南:Windows、macOS 与 Linux
  • 最大公约数与最小公倍数的计算及 C/C++ 实现
  • 女兽医转行互联网后端与 AI 大模型的职业经历复盘
  • AI 绘画工作台:Z-Image-Turbo 云端协作方案
  • 基于 Nuxt 与 WebAssembly 的浏览器端图片压缩工具实现
  • 2024 年诺贝尔物理学奖:霍普菲尔德与欣顿的神经网络贡献
  • NSP 新范式:AI 世界模型构建与物理规律建模指南
  • YOLOv8 目标检测 PySide6 可视化 GUI 界面实现
  • npm 安装 OpenClaw 遇到 Git 报错的解决方案
  • Web 前端基础核心知识点梳理
  • XGBoost 机器学习核心原理与实战指南
  • OpenClaw 配置指南:接入第三方 API 使用大模型
  • 无线蜂窝网络:原理、架构与代际演进

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online