【大语言模型_7】利用ragas框架评测rag系统指标

发布于:2025-03-20 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、介绍

      ragas是一个用来评估RAG系统的框架,允许不在依赖人工注释的情况下,通过一套指标评估检索模块和生成模块的性能及其质量。

二、准备

     数据准备:需要准备评估数据集,数据集格式如下
[
    {
        "question": "安全智算一体机的主要特点是什么?",
        "contexts": [
            "安全智算一体机是以“算力硬件平台+智算平台”为基座,融合“计算、存储、网 络、安全、智能”五大能力,旨在为客户提供高性能、安全可靠的一体化智算中心建设方\n案。产品通过集计算、存储、网络一体的云资源池承载核心业务应用;集成 DeepSeek 大模 型,可帮助客户实现 AI 模型从部署到训练全流程的工作,降低技术使用门槛;在安全防御 上,产品内生云主机安全、网络安全、数据安全及微隔离等安全能力,支持天问安全大模  型,有效保障智算平台的自身安全和业务安全。\n大模型架构演进"
        ],
        "answer": "",  #需要由rag应用给出答案填充
        "ground_truths": [
            "安全智算一体机的主要特点是以'算力硬件平台+智算平台'为基座,融合'计算、存储、网络、安全、智能'五大能力,旨在提供高性能、安全可靠的一体化智算中心建设方案。"
        ],
        "reference": "" # 需要rag应用给出检索上下文进行填充
    }
]

   

环境准备
   需要准备一个可以接入的推理模型和embedding模型,用来评测指标

三、指标介绍


   上下文精确度【context precision】:用embedding模型通过余弦相似度来搜索与query相似的文本。用来衡量上下文中所有真实的消息是否排在了较高位置。

   上下文召回率【context recall 】:就是通过embedding模型检索到的上下文是否包含真实答案。

用来衡量检索到的上下文与被视为事实真相的标注答案的一致性程度。他根据标注答案和检索到的上下文来计算。

   回答忠实度【faithfulness】:回答忠实度。将搜索到的上下文和问题丢给大语言模型,大语言模型回答的内容与上下文的比较,用来衡量生成答案和给定上下文之间的事实一致性

    回答相关性【anser relevance】:问题与答案之间的相关性,评估生成的答案与给定提示的相关程度。如果答案不完整或包含冗余信息,就会赋予较低的分数。

关系如图所示

ragas指标整体评估

三、代码展示:

import json
import re
from ragas.metrics import (
    context_precision,
    answer_relevancy,
    faithfulness,
    context_recall,
)
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from ragas import evaluate
from ragas.run_config import RunConfig
from datasets import Dataset


import requests


# 1. 数据集定义(示例数据)
dataset = [
    {
        "question": "安全智算一体机的主要特点是什么?",
        "contexts": [
            "安全智算一体机是以“算力硬件平台+智算平台”为基座,融合“计算、存储、网 络、安全、智能”五大能力,旨在为客户提供高性能、安全可靠的一体化智算中心建设方\n案。产品通过集计算、存储、网络一体的云资源池承载核心业务应用;集成 DeepSeek 大模 型,可帮助客户实现 AI 模型从部署到训练全流程的工作,降低技术使用门槛;在安全防御 上,产品内生云主机安全、网络安全、数据安全及微隔离等安全能力,支持天问安全大模  型,有效保障智算平台的自身安全和业务安全。\n大模型架构演进"
        ],
        "answer": "",
        "ground_truths": [
            "安全智算一体机的主要特点是以'算力硬件平台+智算平台'为基座,融合'计算、存储、网络、安全、智能'五大能力,旨在提供高性能、安全可靠的一体化智算中心建设方案。"
        ],
        "reference": ""
    }
]



# 2. 模型接口调用函数,用来获取rag应用的answer
def call_rag_model(question):
    url = "http://ip/api/v1/chats_openai/9464f38003c511f0b32f0ae12490b42a/chat/completions"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer ragflow-Q4NzdmMGNlZmZkNjExZWZiNGRjMGFlMT",
    }
    data = {
        "model": "DS",
        "messages": [{"role": "user", "content": question}],
        "stream": False,
    }

    response = requests.post(url, headers=headers, data=json.dumps(data))
    if response.status_code == 200:
        result = response.json()
        # 假设模型返回格式与 OpenAI 兼容
        return result["choices"][0]["message"]["content"].strip()
    else:
        raise Exception(f"模型调用失败: {response.status_code}, {response.text}")


# 3. 模型接口调用函数,用来获取rag应用的context
def retrieve_knowledge(question):
    """
    根据问题检索知识库中的相关片段(基于RAGFlow接口)

    参数:
        question (str): 用户输入的问题 [[2]][[7]]

    返回:
        dict: 检索结果(包含知识片段及评分)
    """
    # 固定参数(根据知识库配置)
    url = "http://ip/api/v1/retrieval"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer ragflow-Q4NzdmMGNlZmZkNjExZWZiNGRjMGFlMT"
    }
    dataset_ids = ["0f5aee2e03c511f0929e0ae12490b42a"]
    document_ids = ["341d13ea03c511f0b39c0ae12490b42a"]

    # 构造请求数据(形参与实参分离)[[9]]
    data = {
        "question": question,
        "dataset_ids": dataset_ids,
        "document_ids": document_ids
    }

    try:
        # 发送POST请求(超时设置提高健壮性)[[8]]
        response = requests.post(
            url,
            headers=headers,
            data=json.dumps(data),
            timeout=10
        )
        response.raise_for_status()  # 触发HTTP错误异常 [[4]]
        return response.json()

    except requests.exceptions.HTTPError as e:
        print(f"HTTP错误: {e.response.status_code} - {e.response.text}")  # [[4]]
        return {"error": "HTTP请求失败"}
    except requests.exceptions.RequestException as e:
        print(f"网络请求异常: {str(e)}")  # [[8]]
        return {"error": "网络连接失败"}





# 4. 生成答案和文本并填充数据集
for sample in dataset:
    try:
        generated_answer = call_rag_model(sample["question"])
        generated_answer = re.sub(r'<think>.*</think>', '', generated_answer, flags=re.DOTALL)
        sample["answer"] = generated_answer  # 填充生成答案
        print(f"问题: {sample['question']}\n生成答案: {generated_answer}")
        generated_reference = retrieve_knowledge(sample["question"])
        generated_reference = generated_reference["data"]["chunks"][0]["content"]
        sample["reference"] = generated_reference
        print(f"问题: {sample['question']}\n生成referece: {generated_reference}")
    except Exception as e:
        print(f"处理问题失败: {sample['question']}, 错误: {e}")




# 5. 注册embedding模型和llm模型,供ragas框架调取。

# 注册ragas框架评测llm
generator_llm = ChatOpenAI(model="DS", api_key="EMPTY", base_url="http://ip/v1",max_tokens=8000,temperature=0.5)
# 注册ragas框架评测embedding
embeddings = OpenAIEmbeddings(model="bce-embedding-base_v1",api_key="EMPTY", base_url="http://ip/v1")


# 6. 使用 RAGAS 进行评测
metrics = [
    context_precision,
    answer_relevancy,
    faithfulness,
    context_recall,
]

run_config = RunConfig(
    max_retries=5,
    max_wait=120,
    log_tenacity=True
)


valid_dataset = [s for s in dataset if s["answer"]]


if valid_dataset:
    result = evaluate(Dataset.from_list(valid_dataset), metrics=metrics,llm=generator_llm,run_config=run_config,embeddings=embeddings)
    print("\n评测结果:")
    print(f"上下文相关性: {result['context_precision']:.2f}")
    print(f"答案相关性: {result['answer_relevancy']:.2f}")
    print(f"答案正确性: {result['faithfulness']:.2f}")
    print(f"上下文利用率: {result['context_recall']:.2f}")
else:
    print("无有效样本可评测")