第六章:信息检索器

在上一章中,我们成功完成了知识库摄入流程。这是巨大的进步~

我们精心准备了文档"块"(类似独立的索引卡),并将其存储在两套智能归档系统中:向量数据库(用于基于含义的搜索)和BM25索引(用于基于关键词的搜索)。我们的"数字图书馆"现已完美组织就绪,随时可被检索。

但当用户提出问题时会如何运作?例如,若用户询问:"公司Z在2023年关于营收和利润的关键财务结果是什么?"我们的系统可能有数千甚至数百万张索引卡

它如何快速定位恰好包含答案的少数几张,而不被无关信息干扰?

这正是信息检索器的职责所在

信息检索器解决什么问题?

想象我们身处庞大的数字图书馆,需要快速查找特定信息。我们不想逐本阅读每本书籍,而是需要"超级管理员"或"搜索引擎"能立即指向最相关的页面或段落。

挑战在于:

  1. 理解问题:即使表述宽泛
  2. 扫描整个知识库:遍历所有存储块
  3. 寻找最佳匹配:识别最可能包含答案的块
  4. 快速响应:在秒级而非分钟级提供结果

信息检索器组件即扮演这种"超级管理员"或"搜索引擎"角色。

当问题输入时,它会查询我们已建立的知识库(向量和BM25),寻找可能包含答案的最相关文档块。该组件专为从海量数据中快速高效提取潜在答案而设计。

其核心角色可分解如下:

角色类比功能说明
超级管理员快速定位正确书籍/页面接收问题并搜索"基于含义"(向量)和"基于关键词"(BM25)的索引,寻找相关文档块
相关性评估器判断哪些信息最有帮助使用高级算法(如向量搜索的余弦相似度关键词搜索的BM25评分)确定每个找到的块与原始问题的相关度
数据提取器提取潜在答案检索最相关块的实际文本,附带页码等辅助细节,供后续处理使用

如何使用信息检索器

流水线协调器控制整体流程,但在回答问题时主要依赖信息检索器。开发者不会直接从命令行调用InformationRetriever,它由更大的"问答流程"内部调用

不过我们可以观察其不同部分的编程用法。本项目提供三种主要检索器

  1. BM25Retriever:基于关键词搜索
  2. VectorRetriever:基于语义(含义)搜索
  3. HybridRetriever:混合检索,通常包含进阶重排序步骤

以下示例展示如何查找特定公司报告的财务信息。假设需要查找"公司A在2023年的营收增长数据":

首先确保数据库和原始文档路径已配置(main.py中由流水线协调器管理路径):

from pathlib import Path
from src.retrieval import BM25Retriever, VectorRetriever, HybridRetriever# 知识库存储路径(第五章创建)
vector_db_path = Path("data/vector_db") 
bm25_db_path = Path("data/bm25_db")
documents_path = Path("data/debug/chunked_reports") # 预处理后的块# 目标公司
target_company = "ACME Corp" 
# 用户问题
user_query = "ACME Corp在2023年的营收和利润是多少?"

说明:配置知识库(vector_dbbm25_db)及处理文档(chunked_reports)路径,定义目标公司和查询内容。

1. 使用BM25Retriever(关键词搜索)

该检索器擅长查找精确词汇或短语:

# 创建BM25检索器实例
bm25_retriever = BM25Retriever(bm25_db_dir=bm25_db_path, documents_dir=documents_path
)print(f"\n--- {target_company}的BM25检索结果 ---")
# 获取前3个相关块
bm25_results = bm25_retriever.retrieve_by_company_name(company_name=target_company, query=user_query, top_n=3
)for i, res in enumerate(bm25_results):print(f"结果{i+1}(第{res['page']}页): 相关性={res['distance']:.2f}")print(f"文本: {res['text'][:100]}...") # 显示前100字符

预期输出(简化)

--- ACME Corp的BM25检索结果 ---
结果1(第5页): 相关性=0.75
文本: ...2023年营收增长15%达5亿美元,净利润5000万美元...
结果2(第7页): 相关性=0.68
文本: ...财务表现亮点:2023年营收趋势与盈利能力...
结果3(第12页): 相关性=0.55
文本: ...2023财年及未来展望相关信息...

解析创建BM25Retriever实例,指向BM25索引和文档块。

调用retrieve_by_company_name方法,传入公司名、查询内容和返回数量。该方法高效扫描BM25索引,返回关键词匹配度最高的块。

2. 使用VectorRetriever(语义搜索)

该检索器通过嵌入向量查找语义相似的块,即使不含相同词汇:

# 创建向量检索器实例
vector_retriever = VectorRetriever(vector_db_dir=vector_db_path, documents_dir=documents_path
)print(f"\n--- {target_company}的向量检索结果 ---")
# 获取前3个语义相关块
vector_results = vector_retriever.retrieve_by_company_name(company_name=target_company, query=user_query, top_n=3
)for i, res in enumerate(vector_results):print(f"结果{i+1}(第{res['page']}页): 向量距离={res['distance']:.2f}")print(f"文本: {res['text'][:100]}...")

预期输出(简化)

--- ACME Corp的向量检索结果 ---
结果1(第5页): 向量距离=0.92  
文本: ...去年达成重要财务里程碑,关键指标...
结果2(第7页): 向量距离=0.88
文本: ...截至2023年12月31日的财年收益摘要...
结果3(第10页): 向量距离=0.80
文本: ...年报亮点:经济表现与战略举措...

解析:创建VectorRetriever实例后,调用方法时会将用户查询转换为嵌入向量(使用LLM),在目标公司的FAISS向量库中查找数值"最接近"的块。

3. 使用HybridRetriever(混合重排序)

HybridRetriever结合两者优势,通常使用向量搜索初步检索,再通过LLM重排序提升精度:

# 创建混合检索器实例
hybrid_retriever = HybridRetriever(vector_db_dir=vector_db_path, documents_dir=documents_path
)print(f"\n--- {target_company}的混合检索结果 ---")
# 获取重排序后的前3结果
hybrid_results = hybrid_retriever.retrieve_by_company_name(company_name=target_company, query=user_query, top_n=3,llm_reranking_sample_size=10 # 获取10个初选结果再重排序
)for i, res in enumerate(hybrid_results):print(f"结果{i+1}(第{res['page']}页): 重排序得分={res['score']:.2f}")print(f"文本: {res['text'][:100]}...")

预期输出(简化)

--- ACME Corp的混合检索结果 ---
结果1(第5页): 重排序得分=0.98
文本: ...2023年营收增长15%达5亿美元,净利润5000万美元...
结果2(第7页): 重排序得分=0.95
文本: ...截至2023年12月31日的财年收益摘要...
结果3(第1页): 重排序得分=0.90
文本: ...2023财年表现概览与未来展望...

解析HybridRetriever先用向量检索获取较多候选块llm_reranking_sample_size控制数量),再通过LLMReranker(将在第七章详述)使用LLM评估相关性得分

最终返回精排结果。这种方法通常准确率最高。

底层原理:信息检索器工作机制

信息检索器通过协调src/retrieval.py中的组件实现其功能,本质上是专业化的搜索代理。

信息检索流程:

在这里插入图片描述

1. BM25Retriever 实现解析

该类处理基于关键词的检索:

# 来源:src/retrieval.py(简化版)
import pickle
from pathlib import Path
from rank_bm25 import BM25Okapi class BM25Retriever:def __init__(self, bm25_db_dir: Path, documents_dir: Path):self.bm25_db_dir = bm25_db_dir # BM25索引存储路径self.documents_dir = documents_dir # 文档块路径def retrieve_by_company_name(self, company_name: str, query: str, top_n: int = 3) -> list:# 查找目标公司文档document_path = next((p for p in self.documents_dir.glob("*.json") if company_name in str(p)), None)if not document_path: return []# 加载BM25索引bm25_path = self.bm25_db_dir / f"{document_path.stem}.pkl"with open(bm25_path, 'rb') as f:bm25_index = pickle.load(f)# 加载文档块with open(document_path, 'r', encoding='utf-8') as f:document = json.load(f)chunks = document["content"]["chunks"]# 分词查询并计算相关性tokenized_query = query.split()scores = bm25_index.get_scores(tokenized_query)# 取top_n结果top_indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:top_n]return [{"distance": round(scores[i],4),"page": chunks[i]["page"],"text": chunks[i]["text"]} for i in top_indices]

实现了一个基于BM25算法的文档检索工具,专门用于根据公司名称和查询词检索相关文档片段。

核心类说明

BM25Retriever类包含两个关键参数:

  • bm25_db_dir:存储预先构建好的BM25检索索引的目录
  • documents_dir:存放原始文档数据的目录

检索流程

检索方法retrieve_by_company_name执行以下操作:

  1. 通过公司名称定位对应文档文件(查找.json文件)
  2. 加载该文档对应的BM25预训练索引(.pkl文件)
  3. 读取原始文档的分块内容(chunks字段)
  4. 对查询语句进行简单分词处理
  5. 计算查询词与所有文档块的相关性得分
  6. 返回得分最高的top_n个结果,包含:
    • 相关性分数(保留4位小数)
    • 所在页码
    • 文本内容

特点:

  • 采用BM25算法进行相关性排序(经典信息检索算法)
  • 使用pickle格式存储预计算索引
  • 结果按相关性降序排列
  • 默认返回最相关的3个结果片段

应用场景:

适用于企业文档管理系统,比如根据公司名称快速查找年报/财报中与特定查询词相关的内容片段。

流程定位目标公司文档→加载对应BM25索引→分词查询→计算相关性得分→返回前N结果。

🎢Pickle格式

Python特有的数据序列化方式,能将任何对象(如列表、字典、类实例等)转换为二进制数据保存或传输,使用时再还原回原对象。类似“打包”“拆包”的过程。

同二进制的protobuf传送:ProtoBuf专栏


2. VectorRetriever 实现解析

该类处理基于语义的检索:

# 来源:src/retrieval.py(简化版)
import faiss 
from openai import OpenAI
import numpy as npclass VectorRetriever:def __init__(self, vector_db_dir: Path, documents_dir: Path):self.vector_db_dir = vector_db_dirself.documents_dir = documents_dirself.llm = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # 嵌入模型连接def retrieve_by_company_name(self, company_name: str, query: str, top_n: int = 3) -> list:# 加载目标公司向量库target_report = next((r for r in self._load_dbs() if company_name in r["name"]), None)if not target_report: return []# 生成查询嵌入query_embedding = self.llm.embeddings.create(input=query, model="text-embedding-3-large").data[0].embeddingquery_embedding = np.array(query_embedding, dtype=np.float32).reshape(1, -1)# FAISS向量搜索distances, indices = target_report["vector_db"].search(query_embedding, top_n)return [{"distance": round(distances[0][i],4),"page": target_report["document"]["content"]["chunks"][indices[0][i]]["page"],"text": target_report["document"]["content"]["chunks"][indices[0][i]]["text"]} for i in range(top_n)]

实现了一个基于向量检索的文档查询系统,专门针对公司报告进行语义搜索。

核心逻辑分解

初始化阶段
VectorRetriever类初始化时设置两个路径:向量数据库目录和文档目录

同时创建OpenAI嵌入模型连接用于文本向量化。

检索流程

  1. 通过公司名称定位目标报告库,在预加载的数据库列表中匹配包含指定公司名的报告
  2. 将用户查询文本通过OpenAI的text-embedding-3-large模型转换为1536维向量
  3. 使用FAISS库在目标公司的向量数据库中进行最近邻搜索,找出与查询最相似的top_n个文本片段
1536维向量

由1536个数字组成的有序列表,用于在高维空间中精确表示数据(如文本、图像等),每个数字对应一个特征维度

返回结果
结构化返回包含三个字段的列表:

  • 匹配度分数(欧式距离
  • 原文所在页码
  • 匹配的文本内容

欧式距离就是日常生活中两点之间的直线距离,比如地图上两个地点的最短路径长度。

技术特点

  • 采用稠密向量检索(Dense Retrieval)替代传统关键词匹配
  • 向量维度适配text-embedding-3-large模型的1536维输出
  • 距离计算使用FAISS优化的L2距离(欧式距离)

应用场景

当用户需要查询某公司报告中与特定问题相关的内容时(如"苹果公司的碳排放政策"),系统会返回报告中最相关的文本段落及其位置信息。

流程加载向量库→转换查询为嵌入向量→执行FAISS相似性搜索→返回最邻近结果。

3. HybridRetriever 实现解析

该类结合向量检索与LLM重排序:

# 来源:src/retrieval.py(简化版)
from src.reranking import LLMReranker class HybridRetriever:def __init__(self, vector_db_dir: Path, documents_dir: Path):self.vector_retriever = VectorRetriever(vector_db_dir, documents_dir)self.reranker = LLMReranker() # 第七章详解def retrieve_by_company_name(self, company_name: str, query: str, top_n: int = 6) -> list:# 初步获取更多候选结果vector_results = self.vector_retriever.retrieve_by_company_name(company_name, query, top_n=28)# LLM精细重排序reranked_results = self.reranker.rerank_documents(query, vector_results)return reranked_results[:top_n]

实现了一个混合检索系统,结合向量检索和LLM(大语言模型)重排序技术,用于根据公司名称和查询文本获取最相关的文档。

核心组件

HybridRetriever类包含两个主要组件:

  • vector_retriever:基于向量的文档检索器,负责初步筛选相关文档
  • rerankerLLM重排序器,对初步结果进行精细化排序

工作流程

初始化时指定向量数据库目录和文档目录,创建向量检索器和LLM重排序器实例

retrieve_by_company_name方法执行以下操作:

  • 使用向量检索器获取28个初步候选结果(参数top_n=28
  • 调用LLM重排序器对这些结果进行精细化重新排序
  • 返回最终前6个(默认值)最相关的结果

参数说明

  • company_name:目标公司名称
  • query:用户查询文本
  • top_n:最终返回的结果数量(默认6个)

技术特点

该方法采用了两阶段检索策略:

  1. 宽泛召回:先获取较多候选结果(28个)
  2. 精准排序:用LLM对结果进行质量重排

这种设计平衡了召回率和精确度。

流程:向量检索扩大候选池→LLM评估每个块与问题的深层关联→返回精排结果。

结论

信息检索器是RAG系统的核心搜索引擎,通过结合关键词匹配(BM25)和语义理解(向量)两种检索方式,高效定位知识库中的相关文档块。

特别是采用HybridRetriever进行智能重排序后,系统能确保提取最精准的信息来解答用户问题。该组件在用户问题与文档潜在答案之间架起了关键桥梁。

在掌握如何查找相关信息后,下一步是确保获取最优信息并按相关性精确排序。

有时初步检索会返回多个候选结果,我们需要更智能的方式来排序。

下一章:LLM重排序

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

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

相关文章

Android 高通平台修改音频参数效果文件-优化音频效果

Android 高通平台如何音频效果 修改音频参数效果文件-优化音频效果 按如下方式修改。 开发云 - 一站式云服务平台 diff --git a/vendor/qcom/proprietary/mm-audio/audcal/family-b/acdbdata//MTP/workspaceFile.qwsp b/vendor/qcom/proprietary/mm-audio/audcal/family-b/acdb…

Install Docker Engine on UbuntuMySQL

Install Docker Engine on Ubuntu&&MySQL安装docker安装mysql客户端连接数据库我真气鼠了,今天得到一个血泪的教训,以后一定看官方文档!!!学的课用的centos,指令全是yum,我这边不通用&a…

智能人体感应模块HC-SR501应用指南---使用esp32

人体热释电探头红外感应模块 人体感应开关HC-SR501蓝板新款 绿板-淘宝网 HC-SR501 人体红外感应电子模块传感器热释电探头感应开关RD-624-tmall.com天猫 模块信息 HC-SR501人体感应开关是一种基于红外线技术的自动控制模块,广泛应用于安防、智能家居和自动控制等领…

加速度传感器方向校准方法

保持平板平放在桌面上,将后置摄像头保持在平板的左上后方,或者右上后方,此为机器的正方向 1、以一台重力方向正常的机器做测试,通过DeviceInfoHw这个软件的加速度测试功能【Accelerometer Test】我们可以知道 X方向数据测试&#…

【OpenHarmonyOS应用开发】

OpenHarmonyOS应用开发1.OpenHarmonyOS应用开发环境安装2.初始化项目3.连接润和软件的开发板套件1.OpenHarmonyOS应用开发环境安装 进入HarmonyOS下载鸿蒙应用开发工具DevEco Studio 5.0.7.200版本。 双击打开下载好的可执行文件,点击下一步。 如果已经安装过&am…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | AutoTextEffect(自动打字机)

📅 我们继续 50 个小项目挑战!—— AutoTextEffect组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/。 利用 Vue 3 的 Composition API 和一些简单的 CSS 动画来构…

[RAG] LLM 交互层 | 适配器模式 | 文档解析器(`docling`库, CNN, OCR, OpenCV)

第二章:LLM 交互层 在上一章中,我们学习了作为"项目总控"的管道协调器,它负责协调 RAG 系统中各个功能模块。 其中最重要的协调对象之一,便是负责与大型语言模型(LLM)进行智能交互的LLM 交互层…

Golang 并发快速上手

文章目录1. 为什么要用协程?1.1 进程与线程1.2 协程1.3 线程和协程的区别线程协程1.4 Go 协程(goroutines)和协程(coroutines)2.Go 协程基本内容2.1 channel2.2 select2.3 future 模式3. 实践示例3.1 并发处理多个网络…

ESP32轻松实现UDP无线通信

ESP32支持UDP通信,这是一种轻量级、高效的通信协议,适用于需要快速数据传输但对数据可靠性要求不高的场景。以下是关于ESP32如何实现UDP通信的详细说明: 1. UDP协议简介及其适用场景 UDP(用户数据报协议)是一种无连接的…

Electron实现“仅首次运行时创建SQLite数据库”

在桌面应用中,SQLite因其轻量、嵌入式特性成为本地存储的热门选择。但若重复初始化数据库,会导致数据覆盖或冗余。本文将详解如何让Electron应用仅在首次启动时创建SQLite数据库,后续启动直接连接现有库。一、核心逻辑与实现原理 核心思路&am…

阿里开源AI大模型ThinkSound如何为视频配上灵魂之声

目录 前言 一、当AI解决视频配音的困境 二、引入“思维链”:让AI像专业音效师一样思考 三、背后的技术支撑 四、未来ThinkSound会如何改变我们的世界? 总结 🎬 攻城狮7号:个人主页 🔥 个人专栏:《AI前沿技术要闻…

图论(1):多叉树

多叉树一、基础知识1. 图 & 树2. 模板2.1 建图二、简单循环1. 【模板】树的路径求和2. 道路修建(改)3. 联合权值4. 毛毛虫树三、自顶向下/自底向上1. 医疗中心2. 【模板】树的直径3. 【模板】最大子树和4. 信号放大器一、基础知识 1. 图 & 树 …

楼宇自动化:Modbus 在暖通空调(HVAC)中的节能控制(一)

引言**在当今的建筑领域,楼宇自动化正扮演着愈发关键的角色,它致力于提升建筑的舒适度、安全性以及能源效率。而暖通空调(HVAC)系统作为楼宇自动化中的核心部分,其能耗在整个建筑能耗中占比相当高,据相关数…

【SpringBoot】注册条件+自动配置原理+自定义starter

注册条件注入到容器内实体类型对象的属性都是null,这些对象并没有什么实际的意义,因为实体类的对象就是来封装对象的,结果你这些对象中什么都没有;解决方法是1.给这些属性赋值然后再注入bean但是这些属性又是固定的不是很好&#…

Server reports Content-Length Mismatch 的根源与解决方案

“服务器声明604字节,Yum却期待28680字节”——当包管理器与仓库服务器之间的信任崩塌时,会发生什么?问题重现 yum install package_name ... Interrupted by header callback: Server reports Content-Length: 604 but expected size is: 28…

基于 Python/PHP/Node.js 的淘宝 API 商品数据抓取开发教程

在电商数据分析、竞品监控等场景中,抓取淘宝商品数据是常见需求。淘宝开放平台(Open Platform)提供了标准化的 API 接口,通过合法途径调用可高效获取商品信息。本文将分别基于 Python、PHP、Node.js 三种语言,详解淘宝…

【Tensor的创建】——深度学习.Torch框架

目录 1 Tensor概述 2 Tensor的创建 2.1 基本的创建方式 2.1.1 torch.tensor 2.1.2 torch.Tensor 2.2 创建线性和随机张量 2.2.1 创建线性张量 2.2.2 随机张量 1 Tensor概述 PyTorch会将数据封装成张量(Tensor)进行计算,张量就是元素为…

Python脚本批量修复文件时间戳,根据文件名或拍摄日期

实现以下功能 更正文件的 修改时间批量修改指定文件夹中的特定后缀的文件根据文件名中的日期修改(优先)根据 jpg 文件属性中的拍摄日期修改根据 mp4 文件属性中的创建媒体日期修改模拟运行(Dry Run)模式 依赖 若需要基于jpg文件属…

[Mysql] Connector / C++ 使用

一、Connector / C 使用 要使用 C 语言连接 MySQL,需要使用 MySQL 官网提供的库,可以去官网进行下载:MySQL :: MySQL Community Downloads 我们使用 C 接口库来进行连接,要正确使用,还需要做一些准备工作&#xff1a…

【PDF识别改名】使用京东云OCR完成PDF图片识别改名,根据PDF图片内容批量改名详细步骤和解决方案

京东云OCR识别PDF图片并批量改名解决方案一、应用场景在日常办公和文档管理中,经常会遇到大量 PDF 文件需要根据内容进行分类和命名的情况。例如:企业合同管理系统需要根据合同编号、日期等内容自动命名 PDF 文件图书馆数字化项目需要将扫描的图书章节按…