检索召回率优化探究一:基于 LangChain 0.3集成 Milvus 2.5向量数据库构建的智能问答系统

背景

       基于 LangChain 0.3集成 Milvus 2.5向量数据库构建的 NFRA(National Financial Regulatory Administration,国家金融监督管理总局)政策法规智能问答系统,第一个版本的检索召回率是 79.52%,尚未达到良好、甚至是优秀的水平,有待优化、提升。

具体的代码版本(可见);检索评估召回率详细说明(可见)

目标

        检索召回率 >= 85%

实现方法

       本次探究:把文件按法条逐条分块,不考虑块的大小,能否会提高分块文本的检索召回率。而本次探究实现的方法,则对应于 RAG系统整体优化思路图(见下图)的“文档分块”。

RAG系统整体优化思路图

实现思路:

  1. 了解 LangChain 的文本切分器是否支持不考虑块的大小,且使用正则表达式来分块的;
  2. 若上述方法行不通,就考虑不使用 LangChain 的切分器,通过常规的 Python编码来实现文件内容的分块。

执行过程

LangChain 文本切分器

       一开始,尝试看官网的文档,发现它也不像平常看过的 Java帮助文档那样,具体介绍每一个类以及类中的方法等,它写的更加简单与实用。见下图:

图片来源:Text splitters | 🦜️🔗 LangChain

从图中的右侧可知,LangChain 文本切分器的实现分类有:

  1. 基于长度的切分;
  2. 基于文本结构的切分;
  3. 基于文件结构的切分;
  4. 基于语义的切分。

       从上述分类来看,第一类基于长度,就不用考虑了;基于文本结构的切分,是可以考虑的,这类应该就有关于正则表达式。而至于其他两类,显然不符合本次探究的内容,也是不用考虑的。

而进一步了解基于文本结构切分实现,可见下图:

图片来源:Text splitters | 🦜️🔗 LangChain

(大家看这种英文技术文档,不要畏惧,刚开始不熟悉时,可以使用浏览器翻译插件来辅助,等熟悉其中的关键内容,不用翻译也大致能看懂了,也是一种“熟能生巧”)

从上图,可知实现文本结构分类的主要实现类是:RecursiveCharacterTextSplitter。

接着,再进一步了解这个类(具体内容可见)之后,大致上就觉得方法1(考虑基于 LangChain的文本切分器来实现)是行不通了。

       不过,还想看看源代码,万一项目所使用的版本是支持的呢?但是,当看到下图的内容,方法1 就彻底放弃了。

       TextSplitter 类是 RecursiveCharacterTextSplitter 的基类,后者是继承前者实现的。因此,不考虑分块大小是不可行的。

Python 编码实现

        Python编码实现,其实并不难,毕竟实现思路已比较明确。把从文件中读取的文本内容,根据法条的形式逐条分块。技术实现上,使用的是正则表达式。实现的过程,主要是在测试验证中写出合适的正则表达式来分块处理。

主要代码实现如下:

1. 根据文本内容按法条分块:

def split_by_pattern(content: str, pattern: str = r"第\S*条") -> List[str]:"""根据正则表达式切分内容:param content: 文本内容:param pattern: 正则表达式,默认是:r"第\S*条""""# 匹配所有以“第X条”开头的位置matches = list(re.finditer(rf"^{pattern}", content, re.MULTILINE))if not matches:return [content.strip()]result = []for i, match in enumerate(matches):start = match.start()end = matches[i + 1].start() if i + 1 < len(matches) else len(content)part = content[start:end].strip()if part:result.append(part)return result

2. 从目录读取文件并分块:

class CustomDocument:def __init__(self, content, metadata):self.content = contentself.metadata = metadatadef load_and_split(directory: str) -> List[CustomDocument]:"""从指定文件目录加载 PDF 文件并提取、切分文本内容:param directory: 文件目录:return: 返回包含提取、切分后的文本、元数据的 CustomDocument 列表"""result = []# 从目录读取 pdf 文件pdf_file_list = get_pdf_files(directory)# 提取文本for pdf_file in pdf_file_list:document = fitz.open(pdf_file)text_content = ""for page_num in range(len(document)):page = document.load_page(page_num)text_content += page.get_text()# 去除无用的字符text_content = rm_useless_content(text_content)# 把文本保存为 txt 文件,便于优化output_path = os.path.join(config.FILE_OUTPUT_PATH, os.path.basename(pdf_file).replace('.pdf', '.txt'))save_text_to_file(text_content, output_path)# 切分文本内容split_list = split_by_pattern(text_content)# 元数据metadata = {"source": "《" + os.path.basename(pdf_file).replace('.pdf', '') + "》"}for split_content in split_list:result.append(CustomDocument(split_content, metadata))return result

代码编写完成之后,实现方法也就完成了。

       接下来对所有的文件进行读取分块、嵌入、存储到一个新的 Milvus 向量数据库集合(Collection)中,用于检索评估。(具体过程就不在这里展开了,感兴趣的朋友,可以基于第一版项目代码,再结合上述代码实现,修改 config 配置类的集合名称参数,就可以跑起来了。本次的代码会在后续更新到 Gitee项目上,具体时间暂时无法确定)


这里通过 Milvus 向量数据库可视化工具 Attu,可以看到分块嵌入向量化存储后的数据,如下图:

看到这个图,搞过开发的,应该有一种莫名的熟悉感吧…

安装 Attu,直接到官网 github 仓库下载下来,点击安装即可。

注意和自己代码中所使用的版本要一致。

安装成功后,运行如下图:

检索评估(召回率)

        为了确定检索召回率是否真的提高了,采用的对比评估。因此,就要控制好变量与不变量。本次变的是文件文本的分块方式,其他的均保持不变,尤其是评估数据集,和上一版本检索召回率统计所使用的数据集是一致的。评估数据集和检索结果处理文件,均已上传到项目中。

RAG 相关处理说明

变量是:切分策略。

切分策略:直接使用(Python)正则表达式,[r"第\S*条 "],不区分块大小
嵌入模型:模型名称: BAAI/bge-base-zh-v1.5 (使用归一化)
向量存储:向量索引类型:IVF_FLAT (倒排文件索引+精确搜索);

向量度量标准类型:IP(内积); 聚类数目: 100; 存储数据库: Milvus
向量检索:查询时聚类数目: 10; 检索返回最相似向量数目: 2

检索评估结果

数据表单

有效

问题个数

TOP1 个数

TOP1 平均相似度

TOP1

召回率

TOP2

个数

TOP2 平均相似度

TOP2

召回率

TOP N策略个数

TOP N策略召回率

通义

29

20

0.7305

68.97%

2

0.6551

6.90%

22

75.86%

元宝

33

14

0.7121

42.42%

9

0.7011

27.27%

23

69.70%

文心

21

18

0.6997

85.71%

2

0.6622

9.52%

20

95.24%

总计

83

52

0.7141

62.65%

13

0.6728

15.66%

65

78.31%

       从表格数据来看,显然TOP N 策略召回率:78.31% 小于目标检索召回率:85%,而且它还比上一个版本的召回率 79.52%低。

       为何检索召回率,会出现不升反而还下降呢?

以下是在核对检索结果的过程中发现的现象:

  • 原来检索不到的法条,现在可以 top 1检索出来(见下图)。问题一样,分块变小,语义更集中,从而检索相似度会越高;

  • 原来检索出来的法条,现在检索不出来(见下图)。问题一样,分块变小,语义更集中,并不只是问题与真正所需的法条相似度提高,其他法条的相似度可能会更高。这是因为在某个章节中,里面的法条主题是比较集中的。

  • 原来检索不出来的,现在还是未能检索出来(见下图)。单个问题检索,不可避免会出现这样子的问题——双语义差(问题嵌入,语义损失;分块嵌入,语义损失)。

检索评估结论

       本次实现方法检索召回率:78.31% 小于目标检索召回率:85%,同时小于上一次的检索召回率:79.52%,按法条逐条分块并不是一个能提升检索召回率的好方法。

(上述检索评估结论,仅代表文中提到的评估数据集,在文中提及的项目代码的处理方式下得到的对比结果,远不具备广泛性。)

总结

        尽管结果未达到预期的目标,但整个过程下来,也是有收获的,至少知道把文件按条文分块并不是自己所预期的那样,会让检索召回率明显提升。而重要的收获应是:基于现有条件 -> 提出设想 -> 寻找实现方法 -> 实现并验证设想 -> 在验证中得出结论,这一整个流程下来所获得的。

       接下来,会继续按 RAG系统整体优化思路图进行优化,提升检索召回率。根据本次检索结果所观察到的现象,接下来会进行检索前处理

 


文中基于的项目代码地址:https://gitee.com/qiuyf180712/rag_nfra/tree/master

本文关联项目的文章:RAG项目实战:LangChain 0.3集成 Milvus 2.5向量数据库,构建大模型智能应用-CSDN博客

 

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

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

相关文章

《整合Spring Cache:本地缓存、Redis与Caffeine对比实践》

&#x1f680; 整合Spring Cache&#xff1a;本地缓存、Redis与Caffeine对比实践 &#x1f4cc; 前言 在高并发、高性能的系统设计中&#xff0c;缓存始终扮演着不可替代的角色。Spring Cache 作为 Spring 框架原生提供的缓存抽象层&#xff0c;极大简化了缓存接入的复杂度。…

easyexcel填充方式导出-合并单元格并设置边框

填充的模板最后导出效果实体 /*** 账户实体类* author test* date 2025-07-28*/ Getter Setter class Test {/*** 账户类型*/private String accType;/*** 账户余额*/private String money; }导出逻辑 /*** 导出文件逻辑*/ public void exportReport(List<Test> data) { …

Jenkins + SonarQube 从原理到实战一:基于 K8s 部署与使用(含中文插件与 Python 扫描)

前言 公司开发部门希望在 Jenkins 构建过程中自动集成 C/C 的代码扫描&#xff0c;正好我也没接触过 SonarQube&#xff0c;于是记录下从零开始部署 SonarQube 服务并集成到 CI/CD 的过程&#xff0c;供后来者参考。 一、SonarQube 原理与工作机制详解 1.1 什么是 SonarQube&…

Linux(Centos 7.6)命令详解:sz

1.命令作用使用ZMODEM/YMODEM/XMODEM协议发送文件(Send file(s) with ZMODEM/YMODEM/XMODEM protocol)注意: 需要yum install lrzsz (yum provides sz可以查看rz命令是什么rpm包提供的)2.命令语法Usage: sz [options] file ...or: sz [options] -{c|i} COMMAND3.参数详解OPTION…

智能运维中的数据转换

《智能运维实践 苏娜 孙琳 王鸽著 人工智能技术丛书 自然语言处理的常用算法 日志异常检测 根因定位 网络流量异常检测 清华大学出版社》【摘要 书评 试读】- 京东图书 数据转换是数据预处理中的关键步骤&#xff0c;用于将数据从原始格式转换为适合分析和建模的形式。这一过程…

IAR编辑器如何让左侧的工具栏显示出来?

在IAR编辑器中恢复左侧工具栏显示&#xff0c;可通过以下方法操作&#xff1a; 一、通过菜单栏启用工具栏 ‌进入视图菜单‌ 点击顶部菜单栏的 ‌"View"‌ → 在弹出列表中勾选 ‌"Workspace"‌ 若工具栏仍不显示&#xff0c;查看菜单栏右侧是否有 ‌"…

ADB+Python控制(有线/无线) Scrcpy+按键映射(推荐)

要实现电脑通过键盘控制安卓平板屏幕点击的功能&#xff0c;可以采用以下方案&#xff1a; 方案一&#xff1a;ADBPython控制&#xff08;有线/无线&#xff09; 准备工具&#xff1a; 安卓平板开启开发者模式&#xff08;设置→关于平板→连续点击版本号&#xff09;启用USB调…

同态滤波算法详解:基于频域变换的光照不均匀校正

&#x1f3ad; 同态滤波&#xff1a;图像频域的调音师技术“如同调音师在音频处理中分离并调节不同频率成分&#xff0c;同态滤波能够在图像频域中精确分离光照与细节信息。”&#x1f3af; 图像频域调音的技术挑战 在数字图像处理中&#xff0c;光照不均匀问题如同音频中的混响…

Ubuntu简述及部署系统

1.什么是Ubuntu1.1概述Ubuntu属于Debian系列&#xff0c;Debian是社区类Linux的典范&#xff0c;是迄今为止最遵循GNU规范的Linux系统。Debain最早由lan Murdock于1993年创建&#xff0c;分为三个版本分支&#xff08;branch&#xff09;&#xff1a;stable&#xff0c;testing…

Claude Code安装部署

1️⃣安装 Node.js&#xff08;已安装可跳过&#xff09; 确保 Node.js 版本 ≥ 18.0 # Ubuntu / Debian 用户 curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash - sudo apt-get install -y nodejs node --version# macOS 用户 sudo xcode-select --install /b…

MATLAB近红外光谱分析技术及实践技术应用

专题一、MATLAB编程基础与进阶&#xff08;一&#xff09;1、MATLAB 安装、版本历史与编程环境2、MATLAB 基础操作&#xff08;矩阵操作、逻辑与流程控制、函数与脚本文件&#xff09;3、MATLAB文件读写&#xff08;mat、txt、xls、csv、jpg、wav、avi等格式&#xff09;专题二…

SQLFluff

一、SQLFluff 是什么&#xff1f; SQLFluff 是一个​​开源的 SQL 代码质量工具​​&#xff0c;专注于通过自动化方式提升 SQL 代码的可读性、一致性和规范性。其核心功能包括&#xff1a; ​​代码格式化​​&#xff1a;自动调整缩进、空格、换行等格式问题&#xff0c;支…

盲盒抽卡机小程序系统开发:连接线上线下娱乐新桥梁

在互联网技术的推动下&#xff0c;线上线下融合已经成为娱乐行业发展的必然趋势。盲盒抽卡机&#xff0c;这一原本在线下备受欢迎的娱乐项目&#xff0c;通过小程序系统的开发&#xff0c;成功实现了线上线下的无缝对接&#xff0c;成为连接线上线下娱乐的新桥梁。盲盒抽卡机小…

【SSL证书校验问题】通过 monkey-patch 关掉 SSL 证书校验

标签&#xff1a;Python、SSL、monkey-patch、httpx、aiohttp、requests、OpenAI 1 为什么会有这篇文章&#xff1f; 在本地调试 OpenAI 代理、数据抓取、私有服务、访问外网 时&#xff0c;经常会碰到如下报错&#xff1a; SSLCertVerificationError: [SSL: CERTIFICATE_VER…

VMWARE -ESXI-ntp时间同步无法启动异常处理

从服务界面查看NTP服务是停止的&#xff08;手动启动无效&#xff09;尝试到系统-时间设置-添加服务-网络时间协议&#xff0c;添加阿里云NTP服务器&#xff08;网络可达&#xff09; ntp.aliyun.com 点击确定报错-无法更改主机配置出现上面的情况多半是DNS没有设置ssh登录到服…

yolo11分类一键训练工具免安装环境windows版使用教程

这个是windows上用于yolo11分类训练工具&#xff0c;不需要写代码只需要按照要求摆放好分类图片文件夹就可以训练。软件内置cuda和python模块&#xff0c;因此不需要安装python环境和cuda就可以使用。注意需要电脑配备有nvidia显卡才能使用。要求显存>4GB。首先我们打开软件…

2025年-ClickHouse 高性能实时分析数据库(大纲版)

告别等待&#xff0c;秒级响应&#xff01;这不只是教程&#xff0c;这是你驾驭PB级数据的超能力&#xff01;我的ClickHouse视频课&#xff0c;凝练十年实战精华&#xff0c;从入门到精通&#xff0c;从单机到集群。点开它&#xff0c;让数据处理速度快到飞起&#xff0c;让你…

深入理解 Scikit-learn:机器学习实战的科学之道与避坑指南

掌握工具易&#xff0c;领悟其道难——本文带你穿透API表面&#xff0c;直击工业级机器学习实践的核心逻辑。作为一名长期耕耘在机器学习研究与工业应用一线的从业者&#xff0c;我见过太多因误用 sklearn 而导致的模型失效案例。从数据泄露到评估失真&#xff0c;从特征处理失…

Android 调试桥 (adb) 基础知识点

Android 调试桥 (adb) 是一种功能多样的命令行工具&#xff0c;可让您与安卓手机进行通信。常用于辅助测试开发或定位问题。 一、adb的工作原理 &#x1f31f; 启动服务器进程&#xff1a;检查是否adb服务器进程正在运行&#xff0c;若没有则启动。 启动或关闭adb服务&#xff…

AW2013 LED驱动芯片 工作方式介绍

根据您上传的 AW2013 芯片手册&#xff0c;我将为您分三个部分详细解读&#xff1a;一、芯片简介&#xff08;AW2013 概述&#xff09; AW2013 是一款 3 通道的 IC 控制恒流 LED 驱动芯片&#xff0c;支持以下功能&#xff1a;单通道最大恒流输出&#xff1a;15mA&#xff0c;支…