[RAG system] 信息檢索器 | BM25 Vector | Pickle格式 | HybridRetriever重排序

第六章:信息檢索器

在上一章中,我們成功完成了知識庫攝入流程。這是巨大的進步~

我們精心準備了文檔"塊"(類似獨立的索引卡),并將其存儲在兩套智能歸檔系統中:向量數據庫(用于基于含義的搜索)和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 文件圖書館數字化項目需要將掃描的圖書章節按…