不止能切文本:多向量檢索如何讓RAG搞定復雜PDF 原創(chuàng)
在日常工作里,我們經(jīng)常會接觸到各種文檔:研究論文、財報、產(chǎn)品手冊……它們往往不是“純文本”,而是夾雜了段落、表格、標題、甚至圖片。這類“半結(jié)構(gòu)化數(shù)據(jù)”,對于傳統(tǒng)的 RAG(Retrieval-Augmented Generation,檢索增強生成) 來說,是一個相當棘手的問題。
為什么?想象一下,如果一個普通的文本切分工具把表格切開一半,或者直接把一張大表格當成純文本去嵌入,結(jié)果就是語義檢索時一團糊,模型很可能拿不到真正需要的上下文。最終生成的答案,自然也就“答非所問”。
這篇文章就帶你深入理解:如何用 智能解析 + 多向量檢索器(multi-vector retriever),在 LangChain 框架里構(gòu)建一個更聰明、更可靠的 半結(jié)構(gòu)化數(shù)據(jù) RAG 管道。
1、為什么半結(jié)構(gòu)化數(shù)據(jù)會成為RAG的難點?
傳統(tǒng)的RAG流水線主要面向“純文本”,它在半結(jié)構(gòu)化文檔上常常翻車,原因主要有兩個:
1)切分失真普通的文本切分器可能在錯誤的位置把表格一分為二,這等于直接破壞了表格中的關鍵數(shù)據(jù)。
2)語義噪聲如果直接把整張大表嵌入向量空間,得到的語義表示往往模糊不清。這樣一來,檢索環(huán)節(jié)可能根本找不到關鍵上下文,模型回答自然就不準。
現(xiàn)實場景中,這種問題比你想象得更普遍:
- 在金融行業(yè),財報中的表格決定了核心答案;
- 在科研場景,實驗數(shù)據(jù)幾乎都放在表格里;
- 在企業(yè)產(chǎn)品手冊中,參數(shù)對照表同樣是核心信息。
這意味著,如果不能妥善處理表格、段落并存的復雜文檔,RAG系統(tǒng)的價值將大打折扣。
2、解決方案:智能解析 + 多向量檢索
面對這一挑戰(zhàn),核心思路其實很簡單:不要一刀切,而是分類處理。
我們可以把解決方案分為兩個關鍵步驟:
- 智能解析(Unstructured庫)使用?
?partition_pdf?? 等方法,不僅能識別出段落,還能準確區(qū)分出表格,并保留它們的原始結(jié)構(gòu)。這樣就避免了盲目切分導致的信息丟失。 - 多向量檢索器(Multi-Vector Retriever)每個元素既存儲一份“摘要”向量(用于檢索),也保留原始完整內(nèi)容(用于答案生成)。檢索階段靠摘要高效定位,生成階段再調(diào)取完整表格或段落。這樣既保證檢索速度,又能讓模型真正“看見全貌”。
可以把它想象成查書目錄 vs 翻正文:先靠目錄找到相關章節(jié),再翻到完整內(nèi)容細讀。
3、構(gòu)建RAG管道的五個步驟

下面結(jié)合 LLaMA2 研究論文 的 PDF,走一遍完整的實現(xiàn)流程。
Step 1:環(huán)境準備
安裝必要的依賴,包括 LangChain 框架、Unstructured 解析庫、Chroma 向量存儲等:
! pip install langchain langchain-chroma "unstructured[all-docs]" pydantic lxml langchainhub langchain_openai -q
! apt-get install -y tesseract-ocr poppler-utils這里的 ??tesseract-ocr??? 和 ??poppler-utils?? 用于OCR和PDF處理。
Step 2:文檔解析
使用 ??partition_pdf?? 對PDF進行智能解析。它會自動識別 段落(CompositeElement) 和 表格(Table):
from unstructured.partition.pdf import partition_pdf
raw_pdf_elements = partition_pdf(
filename="/content/LLaMA2.pdf",
extract_images_in_pdf=False,
infer_table_structure=True,
chunking_strategy="by_title",
max_characters=4000,
new_after_n_chars=3800,
combine_text_under_n_chars=2000,
)輸出結(jié)果顯示:解析出了 85個文本塊 和 2張表格。這為后續(xù)處理打下了干凈的基礎。
Step 3:生成摘要
長表格和長段落不適合直接嵌入,因此我們用LangChain構(gòu)建一個 摘要生成鏈。
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template(
"Summarize the following element concisely:\n\n{element}"
)
model = ChatOpenAI(temperature=0, model="gpt-4.1-mini")
summarize_chain = {"element": lambda x: x} | prompt | model | StrOutputParser()這樣就能得到更輕量、清晰的語義摘要,提升檢索精度。
Step 4:構(gòu)建多向量檢索器
使用 Chroma 保存摘要向量,InMemoryStore 保存原文,并通過ID進行關聯(lián):
from langchain.retrievers.multi_vector import MultiVectorRetriever
from langchain_chroma import Chroma
from langchain.storage import InMemoryStore
retriever = MultiVectorRetriever(
vectorstore=Chroma(collection_name="summaries"),
docstore=InMemoryStore(),
id_key="doc_id",
)這樣檢索時先命中摘要,再回溯到原文。
Step 5:運行完整RAG鏈
構(gòu)建問答鏈,輸入問題時:
- 檢索摘要 →
- 找到對應原文 →
- 提交給LLM生成答案。
from langchain_core.runnables import RunnablePassthrough
prompt = ChatPromptTemplate.from_template(
"Answer the question based on context:\n\n{context}\n\nQuestion: {question}\n"
)
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| ChatOpenAI(temperature=0, model="gpt-4")
| StrOutputParser()
)
chain.invoke("What is the number of training tokens for LLaMA2?")結(jié)果:系統(tǒng)準確定位到了論文中的表格,并提取了訓練數(shù)據(jù)規(guī)模這一關鍵信息。
4、這種方法的價值在哪里?
相比“簡單切分 + 直接嵌入”,這種 半結(jié)構(gòu)化數(shù)據(jù) RAG 的方法帶來三大優(yōu)勢:
- 上下文完整模型在生成答案時真正“看見”了完整表格或段落,不會因為缺失而答錯。
- 檢索精準摘要比原始長文塊更適合做向量搜索,大幅降低噪聲。
- 通用性強適用于財報、學術論文、專利、技術手冊等各類混合文檔場景。
未來,如果結(jié)合多模態(tài)(比如圖片里的圖表)、更智能的布局解析,這種方法的潛力將更大。
5、展望與思考
隨著企業(yè)數(shù)字化的深入,復雜文檔數(shù)據(jù) 將越來越常見。財務、法律、醫(yī)療、科研等行業(yè)尤其如此。傳統(tǒng)RAG如果停留在“純文本思維”,很快會遇到天花板。
這篇文章展示的“智能解析 + 多向量檢索”方案,不僅提升了RAG的精度,也讓復雜文檔真正可用??梢灶A見,在未來的知識管理和智能問答系統(tǒng)里,這類方案會成為標配。
那么,問題來了:如果讓你在公司里落地這樣的方案,你覺得最先適合的場景會是什么?是財報分析、科研文檔,還是內(nèi)部技術文檔?
本文轉(zhuǎn)載自??Halo咯咯?? 作者:基咯咯

















