实用指南:实践篇:利用ragas在自己RAG上实现LLM评估②

news/2025/10/7 8:15:16/文章来源:https://www.cnblogs.com/yxysuanfa/p/19128162


本系列阅读:
理论篇:RAG评估指标,检索指标与生成指标①
实践篇:利用ragas在自己RAG上实现LLM评估②

首先我们可以共识LLM的评估最好/最高效的方式就是再利用LLM的强大能力,而不是用传统指标。
假设我们不用LLM评估我们只有两条方式可实现:

  1. 传统指标,如Bleu。需输入标准答案(通常也是人工审核答案是不是标准的,或者是人工制造标准答案),缺点是效果有限,用了都知道效果惨不忍睹。
  2. 纯人工打分。缺点是耗时,带有主观性。

使用ragas做评估

推荐一个包ragas。但是它的教程文档确实写得不太好,可能是jupyter格式,直接在py中运行,总是会报少变量之类。我这边都改动了下,确保我们py文件可以运行。
在这里插入图片描述
ragas(Retrieval Augmented Generation Assessment)是社区最著名的评估方案,内置了我们常见的评估指标。
在这里插入图片描述
利用了LLM评估,因此不需要人工打标。其出名是因为封装了LLM做评估,简单易用(当然其实这些也是我们可以造轮子实现的~)。

代码链接https://github.com/blackinkkkxi/RAG_langchain/blob/main/learn/evaluation/RAGAS-langchian.ipynb

在自己的数据集上评估

完整可运行的代码见本文的完整代码小节,代码可运行。而1~3我们会拆开完整代码讲解,代码主要用于讲解完整代码,可能不能运行。

完整代码

在使用我的代码你只需要把deepseekapi换成你自己的即可。

import os
import re
from langchain_community.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
from langchain.chat_models import init_chat_model
from ragas import evaluate
from ragas.llms import LangchainLLMWrapper
from ragas import EvaluationDataset
from ragas.metrics import LLMContextRecall, Faithfulness, FactualCorrectness
class RAG:
def __init__(self, api_key=None):
"""使用DeepSeek模型和BGE嵌入初始化RAG系统"""
# 设置环境变量
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
# 初始化对话模型
self.llm = init_chat_model(
model="deepseek-chat",
api_key=api_key,
api_base="https://api.deepseek.com/",
temperature=0,
model_provider="deepseek",
)
# 初始化嵌入模型
self.embedding_model = HuggingFaceEmbeddings(
model_name="BAAI/bge-large-zh-v1.5"
)
# 初始化文本分割器
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
# 初始化向量存储和检索器
self.vectorstore = None
self.retriever = None
self.qa_chain = None
# 设置提示模板
self.template = """
根据以下已知信息,简洁并专业地回答用户问题。
如果无法从中得到答案,请说"我无法从已知信息中找到答案"。
已知信息:
{
context
}
用户问题:{
question
}
回答:
"""
self.prompt = PromptTemplate(
template=self.template,
input_variables=["context",
"question"]
)
def load_documents_from_url(self, url, persist_directory="./chroma_db"
):
"""从网页URL加载文档并创建向量存储"""
# 从网页加载文档
loader = WebBaseLoader(url)
documents = loader.load(
)
# 将文档分割成块
chunks = self.text_splitter.split_documents(documents)
# 创建向量存储
self.vectorstore = Chroma.from_documents(
documents=chunks,
embedding=self.embedding_model,
persist_directory=persist_directory
)
# 创建检索器
self.retriever = self.vectorstore.as_retriever(
)
# 创建问答链
self.qa_chain = RetrievalQA.from_chain_type(
llm=self.llm,
chain_type="stuff",
retriever=self.retriever,
chain_type_kwargs={
"prompt": self.prompt
}
)
print(f"成功从 {url} 加载并处理文档"
)
def ask(self, question):
"""便捷的提问方法"""
result = self.qa_chain.invoke({
"query": question
}
)
return result["result"]
def relevant_docs_with_scores(self, query, k=1
):
"""计算相关文档及其相似度分数,返回处理后的文档信息"""
docs_with_scores = self.vectorstore.similarity_search_with_score(query, k=k)
# 处理文档内容
processed_docs = []
for i, (doc, score)
in enumerate(docs_with_scores, 1
):
# 清理文档内容
content = doc.page_content.strip(
)
# 去除回车符、换行符和多余的空白字符
content = content.replace('\n',
' '
).replace('\r',
' '
).replace('\t',
' '
)
# 合并多个连续空格为单个空格
content = re.sub(r'\s+',
' ', content)
processed_docs.append({
'index': i,
'score': score,
'content': content
}
)
return processed_docs
# 使用示例
if __name__ == "__main__":
api_key = "X"
queries = [
"为什么Transformer需要位置编码?",
"QKV矩阵是怎么得到的?",
"注意力机制的本质是什么?",
"对于序列长度为n的输入,注意力机制的计算复杂度是多少?",
"在注意力分数计算中,为什么要除以√d?",
"多头注意力机制的主要作用是什么?",
"解码器中的掩码自注意力是为了什么?",
"编码器-解码器注意力中,Query来自哪里?",
"GPT系列模型使用的是哪种架构?",
"BERT模型适合哪类任务?"
]
# 初始化RAG
rag = RAG(api_key)
# 从URL加载文档
rag.load_documents_from_url("https://blog.csdn.net/ngadminq/article/details/147687050"
)
expected_responses = [
"Transformer的输入是并行处理的,不像RNN有天然的序列关系,因此需要位置编码来为模型提供词元在序列中的位置信息,确保模型能理解词的先后顺序。",
"QKV矩阵通过将输入向量分别与三个不同的权重矩阵W_q、W_k、W_v进行线性投影得到,这三个权重矩阵是模型的可学习参数,在训练过程中不断优化。",
"注意力机制的本质是为序列中的每个词找到重要的上下文信息,通过计算词与词之间的相关性分数,实现对重要信息的聚焦和整合。",
"注意力机制的计算复杂度是O(n²),因为序列中每个词都需要与所有其他词计算注意力分数,形成n×n的注意力矩阵。",
"除以√d是为了提升训练稳定性,防止注意力分数过大导致softmax函数进入饱和区,确保梯度能够有效传播。",
"多头注意力机制可以从多个角度捕捉不同类型的词间关联,比如语义关系、句法关系等,增强了模型的表达能力和理解能力。",
"解码器中的掩码自注意力是为了防止当前位置关注未来位置的信息,确保在自回归生成过程中每个位置只能看到当前及之前的信息。",
"在编码器-解码器注意力中,Query来自解码器的前一层输出,而Key和Value来自编码器的最终输出,这样解码器就能利用编码器处理的源序列信息。",
"GPT系列模型使用仅解码器架构,专门针对文本生成任务设计,通过掩码自注意力机制实现从左到右的序列生成。",
"BERT模型适合分类和理解类任务,如文本分类、命名实体识别、情感分析、问答等,因为它使用双向编码器可以同时关注上下文信息。"
]
dataset = []
for query, reference in zip(queries, expected_responses):
# 获取相关文档及分数并打印
relevant_docs = rag.relevant_docs_with_scores(query)
relevant_docs = relevant_docs[0]['content']
response = rag.ask(query)
dataset.append(
{
"user_input": query,
"retrieved_contexts": [relevant_docs],
"response": response,
"reference": reference
}
)
evaluation_dataset = EvaluationDataset.from_list(dataset)
llm = init_chat_model(
model="deepseek-chat",
api_key=api_key,
api_base="https://api.deepseek.com/",
temperature=0,
model_provider="deepseek",
)
evaluator_llm = LangchainLLMWrapper(llm)
result = evaluate(dataset=evaluation_dataset, metrics=[LLMContextRecall(
), Faithfulness(
), FactualCorrectness(
)],
llm=evaluator_llm)
print(result)

以下是运行的结果:
在这里插入图片描述
根据我们的结果指标可以针对指标有优化方向

代码讲解
1. RAG系统构建
核心组件初始化
class RAG:
def __init__(self, api_key=None
):
# DeepSeek聊天模型
self.llm = init_chat_model(
model="deepseek-chat"
,
api_key=api_key,
api_base="https://api.deepseek.com/"
,
temperature=0
,
model_provider="deepseek"
,
)
# BGE中文嵌入模型
self.embedding_model = HuggingFaceEmbeddings(
model_name="BAAI/bge-large-zh-v1.5"
)
# 文本分割器
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500
,
chunk_overlap=50
)

技术要点:

  • 使用DeepSeek作为生成模型,temperature=0确保输出稳定性
  • BGE-large-zh-v1.5是目前中文嵌入效果较好的开源模型
  • 文本分块策略:500字符块大小,50字符重叠防止信息丢失
文档处理流程
def load_documents_from_url(self, url, persist_directory="./chroma_db"
):
# 1. 网页内容加载
loader = WebBaseLoader(url)
documents = loader.load(
)
# 2. 文档分块
chunks = self.text_splitter.split_documents(documents)
# 3. 向量化存储
self.vectorstore = Chroma.from_documents(
documents=chunks,
embedding=self.embedding_model,
persist_directory=persist_directory
)
# 4. 构建检索链
self.qa_chain = RetrievalQA.from_chain_type(
llm=self.llm,
chain_type="stuff"
,
retriever=self.retriever,
chain_type_kwargs={
"prompt": self.prompt
}
)
2. 评估数据集构建

数据集需要包含四个核心要求

dataset.append({
"user_input": str
, # 用户查询,即我们备好的一系列问题
"retrieved_contexts": [strstr]
, # 检索到的上下文,list格式
"response": str
, # 系统回答
"reference": str # 标准答案,人工制造,我这里使用cluade生成的
}
)
3. RAGAS评估实现
1. 评估数据集创建
from ragas import EvaluationDataset
evaluation_dataset = EvaluationDataset.from_list(dataset)
2. 评估器配置
from ragas.llms import LangchainLLMWrapper
evaluator_llm = LangchainLLMWrapper(llm)

关键点: RAGAS使用LLM作为评估器,需要将LangChain模型包装成RAGAS兼容格式

3. 执行评估

代码使用了三个核心评估指标:

LLMContextRecall(上下文召回率)

  • 作用: 评估检索到的上下文是否包含回答问题所需的信息
  • 计算方式: 通过LLM判断标准答案中的信息有多少能在检索上下文中找到
  • 公式: Context Recall = 可在上下文中找到的标准答案句子数 / 标准答案总句子数

Faithfulness(忠实度)

  • 作用: 衡量生成回答与检索上下文的一致性,防止幻觉
  • 计算方式: 检查回答中的每个声明是否能在提供的上下文中得到支持
  • 公式: Faithfulness = 有上下文支持的声明数 / 总声明数

FactualCorrectness(事实正确性)

  • 作用: 评估生成回答的事实准确性
  • 计算方式: 将生成回答与标准答案进行事实层面的比较
  • 评估维度: 包括事实的正确性、完整性和相关性
from ragas.metrics import LLMContextRecall, Faithfulness, FactualCorrectness
result = evaluate(
dataset=evaluation_dataset,
metrics=[LLMContextRecall(
)
, Faithfulness(
)
, FactualCorrectness(
)]
,
llm=evaluator_llm
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整教程:数据结构:递归的种类(Types of Recursion)

完整教程:数据结构:递归的种类(Types of Recursion)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

专业模板网站制作wordpress apple pro

当代年轻人的生活方式是怎样的?靠地铁通勤,靠咖啡续命早上睁不开眼,咖啡来一杯中午昏昏欲睡,咖啡来一杯晚上熬夜加班,咖啡来一杯喝完这杯,还有一杯“宁可食无肉,不可早无星”是当代年轻人的座右…

网站建设首选wordpress首页不显示指定分类

1、对比 tairzookeper性能高 低可靠性低 高 2、zookeper实现分布式锁 特点: Zookeeper能保证数据的强一致性,用户任何时候都可以相信集群中每个节点的数据都是相同的。 加锁 客户端在ZooKeeper一个特定的节点下创建临时顺序节点&…

Nova Premier模型安全评估结果解析

本文通过第三方评估机构对Nova Premier模型进行黑盒压力测试和红队演练,展示了该模型在安全防护方面的卓越表现,包括在恶意指令抵抗和有害内容生成防护方面的技术细节。独立评估证明 Nova Premier 的安全性 - 某中心…

改写自己的浏览器插件工具 myChromeTools - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

做移动网站优化排名网站建设需要编码不

基本数据类型 Java 基础数据按类型可以分为四大类:布尔型、整数型、浮点型、字符型,这四大类包含 8 种基础数据类型。 布尔型:boolean整数型:byte、short、int、long浮点型:float、double字符型:char 八种…

网站设计需要那些人绍兴seo推广

hash 模式 【推荐】 路由效果 在不刷新页面的前提下,根据 URL 中的 hash 值,渲染对应的页面 http://test.com/#/login 登录页http://test.com/#/index 首页 核心API – window.onhashchange 监听 hash 的变化,触发视图更新 window.onhas…

通过litestream 进行sqlite-vec 数据备份以及恢复

通过litestream 进行sqlite-vec 数据备份以及恢复实际上就是一个简单的测试,litestream 支持流式复制,比较适合对于sqlite进行备份,同时litestream 还支持对象存储的remote 模式,比较方便 环境准备minioservices: …

相册网站开发那个网站开发三味

强制类型转换形式:(类型说明符) (表达式)举例说明:1) int a;a (int)1.9;2)char *b;int *p;p (int *) b; //将b的值强制转换为指向整型数据的指针类型,后赋给p注示:类型说明符和表达式都必须加括号,表达式为单个变量可…

做购物网站适合的服务器网站建设需求模版

目录 前言 一、创建上下文类 1.自定义MyContext上下文类继承IdentityDbContext 2.在Program中添加AddDbContext服务 二、使用Migration数据迁移 1.在控制台中 依次使用add-migration 、updatebase 命令 2.如何修改表名 3.如何自定义字段 三、使用Identity实现登录、修改密码 …

对于路由使用的ref的疑问

<script setup>import { ref, computed } from vueimport Home from ./Home.vueimport About from ./About.vueimport NotFound from ./NotFound.vueconst routes = { /: Home, /about: About}const currentPa…

天津到天津天津网站开发iis v6 新建网站

大数据管理数据处理过程图大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察力。大数据处理的主要流程包括数据收集、数据存储、数据处理、数据应用等主要环节。随着业务的增长,大量和流程、规…

自建购物网站福建响应式网站制作

目录 详细布置&#xff1a; 1. 层序遍历 2. 226. 翻转二叉树 3. 101. 对称二叉树 详细布置&#xff1a; 1. 层序遍历 昨天练习了几种二叉树的深度优先遍历&#xff0c;包括&#xff1a; ​​​​​​前中后序的递归法前中后序的迭代法前中后序迭代的统一写法 今天&…

扁平化企业网站从零开始制作wordpress主题

文章目录 360篡改浏览器主页方法1锁定浏览器主页 方法2注册表修改 360广告和弹窗360极速版 小结 360篡改浏览器主页 如果您使用360,且不想卸载它,那么当你启动360后,它可能会篡改你的浏览器(比如edge)的主页start page为360早期可能是通过修改快捷方式的target等属性,但是现在…

新网站建设验收公司手机网站模板

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

公司专业网站建设百度分享代码 wordpress

背景&#xff1a; 想知道四川省包含哪些水系&#xff0c;以及各个水系的分布&#xff0c;起点、流经省市、终点等 {label: "嘉陵江",value: "嘉陵江",},{label: "渠江",value: "渠江",},{label: "涪江",value: "涪江&q…

Paypal 设置不自动换汇

进入 PayPal 网页版自动付款设置。选择结算商户,查看兑换选项,修改为使用银行的兑换方式。

网站建设培训赚钱吗怎么才能在百度上做引流呢

目录 引出Redis持久化方式Redis入门1.Redis是什么&#xff1f;2.Redis里面存Java对象 Redis进阶1.雪崩/ 击穿 / 穿透2.Redis高可用-主从哨兵3.持久化RDB和AOF4.Redis未授权访问漏洞5.Redis里面安装BloomFilte Redis的应用1.验证码2.Redis高并发抢购3.缓存预热用户注册验证码4.R…

威县网站建设报价微信app开发价格表

我们需要将Python对象序列化为字节流&#xff0c;这样就可以将其保存到文件中、存储到数据库中或者通过网络连接进行传输。 解决方案 序列化最普遍的做法是使用 pickle 模块。为了将一个对象保存到一个文件中&#xff0c;可以这样做&#xff1a; import pickledata ... # Some…

国外网站参考住房城乡与建设厅网站首页

压缩方式是网络视频服务器和网络摄像机的核心技术&#xff0c;压缩方式很大程度上决定着图像的质量、压缩比、传输效率、传输速度等性能&#xff0c;它是评价网络视频服务器和网络摄像机性能优劣的重要一环。 随着多媒体技术的发展&#xff0c;相继推出了许多压缩编码标准&…