基于 Ragas 与通义千问实现 RAG 系统答案正确性自动评估

基于 Ragas 与通义千问实现 RAG 系统答案正确性自动评估

本文基于 Ragas 评估框架与通义千问(qwen-plus)大模型,结合 DashScope text-embedding-v3 向量模型,构建 RAG(检索增强生成)系统的自动化评估流水线。通过 answer_correctness 指标量化评估模型生成答案与标准答案的一致性,并进一步使用 context_recall 和 context_precision 评估检索质量。


一、核心概念:RAG 评估是什么?

RAG(Retrieval-Augmented Generation) 系统将检索与生成结合:先从知识库中检索相关文档,再让 LLM 基于检索结果生成答案。但如何衡量 RAG 系统的输出质量?这就是 Ragas 要解决的问题。

评估维度 指标 说明
答案质量 answer_correctness 生成答案与标准答案的一致程度
检索质量 context_recall 检索到的文档覆盖标准答案的程度
检索精度 context_precision 检索到的文档中相关内容的占比

为什么需要自动评估? 传统方式依赖人工判断,效率低且主观性强。Ragas 通过 LLM + Embedding 的组合,实现自动化、可量化的评估:

  • LLM 判断:让大模型对比生成答案与标准答案的语义差异
  • Embedding 相似度:通过向量余弦相似度衡量语义接近程度
  • 综合评分:两者加权得到最终分数

二、系统架构

#mermaid-svg-MiC7tM5TLJYalxIk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MiC7tM5TLJYalxIk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MiC7tM5TLJYalxIk .error-icon{fill:#552222;}#mermaid-svg-MiC7tM5TLJYalxIk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MiC7tM5TLJYalxIk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MiC7tM5TLJYalxIk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MiC7tM5TLJYalxIk .marker.cross{stroke:#333333;}#mermaid-svg-MiC7tM5TLJYalxIk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MiC7tM5TLJYalxIk p{margin:0;}#mermaid-svg-MiC7tM5TLJYalxIk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MiC7tM5TLJYalxIk .cluster-label text{fill:#333;}#mermaid-svg-MiC7tM5TLJYalxIk .cluster-label span{color:#333;}#mermaid-svg-MiC7tM5TLJYalxIk .cluster-label span p{background-color:transparent;}#mermaid-svg-MiC7tM5TLJYalxIk .label text,#mermaid-svg-MiC7tM5TLJYalxIk span{fill:#333;color:#333;}#mermaid-svg-MiC7tM5TLJYalxIk .node rect,#mermaid-svg-MiC7tM5TLJYalxIk .node circle,#mermaid-svg-MiC7tM5TLJYalxIk .node ellipse,#mermaid-svg-MiC7tM5TLJYalxIk .node polygon,#mermaid-svg-MiC7tM5TLJYalxIk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MiC7tM5TLJYalxIk .rough-node .label text,#mermaid-svg-MiC7tM5TLJYalxIk .node .label text,#mermaid-svg-MiC7tM5TLJYalxIk .image-shape .label,#mermaid-svg-MiC7tM5TLJYalxIk .icon-shape .label{text-anchor:middle;}#mermaid-svg-MiC7tM5TLJYalxIk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MiC7tM5TLJYalxIk .rough-node .label,#mermaid-svg-MiC7tM5TLJYalxIk .node .label,#mermaid-svg-MiC7tM5TLJYalxIk .image-shape .label,#mermaid-svg-MiC7tM5TLJYalxIk .icon-shape .label{text-align:center;}#mermaid-svg-MiC7tM5TLJYalxIk .node.clickable{cursor:pointer;}#mermaid-svg-MiC7tM5TLJYalxIk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MiC7tM5TLJYalxIk .arrowheadPath{fill:#333333;}#mermaid-svg-MiC7tM5TLJYalxIk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MiC7tM5TLJYalxIk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MiC7tM5TLJYalxIk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MiC7tM5TLJYalxIk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MiC7tM5TLJYalxIk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MiC7tM5TLJYalxIk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MiC7tM5TLJYalxIk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MiC7tM5TLJYalxIk .cluster text{fill:#333;}#mermaid-svg-MiC7tM5TLJYalxIk .cluster span{color:#333;}#mermaid-svg-MiC7tM5TLJYalxIk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MiC7tM5TLJYalxIk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MiC7tM5TLJYalxIk rect.text{fill:none;stroke-width:0;}#mermaid-svg-MiC7tM5TLJYalxIk .icon-shape,#mermaid-svg-MiC7tM5TLJYalxIk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MiC7tM5TLJYalxIk .icon-shape p,#mermaid-svg-MiC7tM5TLJYalxIk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MiC7tM5TLJYalxIk .icon-shape .label rect,#mermaid-svg-MiC7tM5TLJYalxIk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MiC7tM5TLJYalxIk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MiC7tM5TLJYalxIk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MiC7tM5TLJYalxIk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 评估数据集
question + answer + ground_truth
Ragas evaluate 入口
通义千问 qwen-plus
LLM 语义判断
DashScope text-embedding-v3
向量相似度计算
answer_correctness 评分
输出评估报告 DataFrame

核心组件:

组件 版本/模型 职责
ragas 评估框架 定义评估指标与评估流程
langchain_community 工具库 封装 Tongyi LLM 和 DashScope Embeddings
datasets HuggingFace 数据集库 构建标准化评估数据集
qwen-plus 通义千问 作为裁判 LLM,判断答案语义正确性
text-embedding-v3 DashScope 向量模型 将文本转为向量,计算语义相似度

三、环境准备

3.1 依赖安装

bash 复制代码
pip install langchain_community datasets ragas -i https://pypi.tuna.tsinghua.edu.cn/simple

3.2 环境变量配置

需要配置 DashScope API Key(通义千问的 API 密钥):

env 复制代码
DASHSCOPE_API_KEY=sk-your-api-key-here

说明: Tongyi LLM 和 DashScopeEmbeddings 会自动从环境变量中读取 DASHSCOPE_API_KEY,无需手动传入。


四、步骤详解

步骤 1:构建评估数据集

评估数据包含三个核心字段:

python 复制代码
data_samples = {
    'question': [
        '杭州最值得去的景点有哪些?',
        '去成都旅游的话,有哪些特色美食推荐?',
        '在西安游览时,参观兵马俑需要提前预约吗?'
    ],
    'answer': [
        '杭州西湖、灵隐寺和千岛湖是比较受欢迎的景点。',
        '成都有很多好吃的,比如火锅、串串香和担担面。',
        '参观兵马俑不需要预约,现场买票就可以进去。'
    ],
    'ground_truth': [
        '杭州必游景点包括西湖、灵隐寺、雷峰塔、千岛湖和宋城,其中西湖是国家5A级景区,建议清晨游览以避开人流。',
        '成都作为美食之都,推荐品尝火锅、串串香、担担面、龙抄手和钟水饺,宽窄巷子和锦里是集中体验地道小吃的好去处。',
        '参观秦始皇兵马俑博物馆必须通过官方平台提前实名预约购票,旺季时需至少提前3天预约,现场不保证有票。'
    ]
}

各字段含义:

字段 说明 示例
question 用户提问 "杭州最值得去的景点有哪些?"
answer RAG 系统生成的答案 "杭州西湖、灵隐寺和千岛湖..."
ground_truth 人工标注的标准答案 "杭州必游景点包括西湖、灵隐寺、雷峰塔..."

设计要点: answer 是不完整或有错误的回答,ground_truth 是完整且准确的标准答案。通过对比两者,评估 RAG 系统的生成质量。


步骤 2:初始化 LLM 与 Embedding

python 复制代码
from langchain_community.llms.tongyi import Tongyi
from langchain_community.embeddings import DashScopeEmbeddings

# 裁判 LLM:通义千问 qwen-plus
llm = Tongyi(model_name="qwen-plus")

# 向量模型:DashScope text-embedding-v3
embeddings = DashScopeEmbeddings(model="text-embedding-v3")

选型说明:

组件 选型 理由
裁判 LLM qwen-plus 语义理解能力强,性价比高
向量模型 text-embedding-v3 DashScope 最新向量模型,中文语义表征好

步骤 3:执行评估

python 复制代码
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import answer_correctness

# 构建评估数据集
dataset = Dataset.from_dict(data_samples)

# 执行评估
score = evaluate(
    dataset=dataset,
    metrics=[answer_correctness],
    llm=llm,
    embeddings=embeddings
)

# 输出评估结果
print(score.to_pandas())

answer_correctness 的计算原理:

  • 语义 F1 分数(权重 75%):LLM 将答案分解为原子陈述,对比 TP/FP/FN
  • 向量相似度(权重 25%):通过 Embedding 余弦相似度衡量整体语义接近度

步骤 4:检索质量评估(扩展)

当评估数据包含 contexts(检索到的文档片段)时,可以进一步评估检索质量:

python 复制代码
from ragas.metrics import context_recall, context_precision

data_samples_with_context = {
    'question': [...],
    'answer': [...],
    'ground_truth': [...],
    'contexts': [
        ['西湖是杭州的核心景区...', '灵隐寺是中国著名的佛教古刹...', '千岛湖以湖泊和岛屿景观著称...'],
        ['成都被誉为"美食之都"...', '串串香起源于四川街头...', '担担面是川菜经典面食...'],
        ['秦始皇兵马俑位于陕西省...', '兵马俑博物馆实行实名制预约购票制度...', '旺季参观需至少提前3天预约...']
    ]
}

score = evaluate(
    dataset=Dataset.from_dict(data_samples_with_context),
    metrics=[context_recall, context_precision],
    llm=Tongyi(model_name="qwen-plus"),
    embeddings=DashScopeEmbeddings(model="text-embedding-v3")
)

检索指标说明:

指标 含义 计算方式
context_recall 检索覆盖度 标准答案中的陈述有多少被检索文档覆盖
context_precision 检索精确度 检索到的文档中有多少真正与问题相关

五、评估结果分析

评估结果

结果分析:

问题 预期分数区间 分析
杭州景点 0.6~0.8 答案覆盖了部分景点,但遗漏了雷峰塔、宋城
成都美食 0.7~0.9 答案基本正确,但遗漏了龙抄手、钟水饺等
兵马俑预约 0.3~0.5 答案事实错误(说不需要预约),与标准答案矛盾

关键发现: 第 3 个问题的 answer 声称"不需要预约",而 ground_truth 明确指出"必须提前预约"。answer_correctness 会对这种事实性错误给予严厉扣分。


六、核心技术点总结

技术点 实现方式 作用
LLM 裁判 qwen-plus 判断语义正确性 替代人工评估,实现自动化
Embedding 相似度 text-embedding-v3 向量对比 补充语义层面的整体相似度衡量
原子陈述分解 LLM 将答案拆解为独立事实 精确计算 TP/FP/FN
F1 + 相似度加权 75% F1 + 25% 向量相似度 兼顾事实准确性和整体语义
HuggingFace Datasets Dataset.from_dict 构建数据 标准化数据格式,便于批量评估
检索质量评估 context_recall + context_precision 分离评估生成和检索两个环节

七、延伸思考

  1. 更多评估指标:Ragas 还支持 faithfulness(忠实度)、answer_relevancy(答案相关性)等指标,可全面评估 RAG 系统
  2. 批量评估:将评估数据集扩大到数百条,统计各指标的平均分和分布
  3. 自定义指标:基于 Ragas 的 Metric API 实现领域特定的评估标准
  4. 对比实验:对比不同 LLM(qwen-plus vs qwen-max)作为裁判的评分差异
  5. 检索优化闭环:通过 context_recall 定位检索不足的 case,针对性补充知识库文档
  6. CI/CD 集成:将 Ragas 评估集成到 RAG 系统的持续集成流程中,每次更新自动回归测试