在 LangChain 中實現 RAG(檢索增強生成,Retrieval-Augmented Generation)的核心思路是:讓大模型在生成回答前,先從外部知識庫(如文檔、數據庫等)中檢索相關信息,再基于檢索到的內容生成更準確、更可靠的回答。LangChain 提供了豐富的組件和工具鏈,支持多種 RAG 實現方法,適配不同場景(如簡單文檔問答、多源信息整合、對話式問答等)。以下是常見的方法及具體實現步驟:
一、基礎 RAG:單文檔/單源檢索增強
適用場景:簡單的文檔問答(如單篇論文、手冊、長文本的精準問答),核心是“加載→分割→嵌入→存儲→檢索→生成”的完整流程。
具體做法:
-
文檔加載(Document Loading)
用 LangChain 的DocumentLoaders
加載目標文檔(支持 PDF、TXT、Word、網頁等多種格式),將文檔轉換為 LangChain 標準的Document
對象(包含文本內容page_content
和元數據metadata
)。
常用工具:PyPDFLoader
(PDF)、TextLoader
(TXT)、UnstructuredFileLoader
(多格式)、WebBaseLoader
(網頁)等。from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("論文.pdf") # 加載 PDF 文檔 documents = loader.load() # 得到 Document 列表
-
文檔分割(Text Splitting)
長文檔直接嵌入會丟失上下文,需用TextSplitter
分割為短片段(chunk)。關鍵是控制chunk_size
(片段長度)和chunk_overlap
(片段重疊度,保留上下文關聯)。
常用工具:RecursiveCharacterTextSplitter
(通用分割,按標點/換行遞歸分割)、CharacterTextSplitter
(簡單字符分割)等。from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, # 每個片段 1000 字符 chunk_overlap=200 # 重疊 200 字符,保留上下文 ) splits = text_splitter.split_documents(documents) # 分割后的 Document 列表
-
文本嵌入(Embedding)
將分割后的文本片段轉換為向量(嵌入),以便后續通過向量相似度檢索相關內容。需用嵌入模型生成向量。
常用工具:OpenAIEmbeddings
(OpenAI 的 embedding 模型)、HuggingFaceEmbeddings
(開源模型如 BERT、Sentence-BERT)等。from langchain.embeddings import OpenAIEmbeddings embeddings = OpenAIEmbeddings() # 使用 OpenAI 的 embedding 模型
-
向量存儲(Vector Storage)
將嵌入向量和對應的文本片段存儲到向量數據庫(VectorStore),支持高效的相似度檢索。
常用工具:輕量本地庫Chroma
、FAISS
;云端服務Pinecone
、Weaviate
、Milvus
等。from langchain.vectorstores import Chroma # 初始化向量庫并添加文檔(自動完成嵌入和存儲) vectorstore = Chroma.from_documents( documents=splits, embedding=embeddings, persist_directory="./chroma_db" # 本地存儲路徑 ) vectorstore.persist() # 持久化存儲
-
構建檢索器(Retriever)
從向量庫中檢索與問題相關的文本片段,作為 RAG 的“檢索”環節。LangChain 的VectorStore
可直接轉換為Retriever
。retriever = vectorstore.as_retriever( search_kwargs={"k": 3} # 檢索最相關的 top 3 片段 )
-
生成回答(Generation)
用大模型(LLM)結合檢索到的內容生成回答,通過RetrievalQA
鏈串聯“檢索→生成”流程。from langchain.chat_models import ChatOpenAI from langchain.chains import RetrievalQA llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) # 大模型 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", # 將檢索到的內容全部傳入模型 retriever=retriever, return_source_documents=True # 返回檢索到的源文檔(可選) ) # 提問并獲取回答 query = "這篇論文的核心創新點是什么?" result = qa_chain({"query": query}) print(result["result"]) # 回答內容 print(result["source_documents"]) # 檢索到的源文檔
二、進階 RAG:多階段檢索與精準優化
適用場景:當基礎 RAG 檢索相關性不足(如文檔量大、歧義問題)時,通過多階段檢索或重排序提升精度。
具體做法:
-
多查詢檢索(Multi-Query Retrieval)
對原始問題生成多個相似查詢(由 LLM 自動擴展),用多個查詢檢索后合并結果,覆蓋更多相關片段。from langchain.retrievers.multi_query import MultiQueryRetriever # 用 LLM 生成多個查詢 retriever_from_llm = MultiQueryRetriever.from_llm( retriever=vectorstore.as_retriever(), llm=ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) ) # 用多查詢檢索結果回答 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=retriever_from_llm )
-
上下文壓縮檢索(Contextual Compression)
先檢索初步結果,再用“重排序模型(Reranker)”或“過濾模型”對結果二次篩選,保留最相關的片段。
常用工具:ContextualCompressionRetriever
結合CohereRerank
、RankGPT
等重排序工具。from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import CohereRerank # 初始化重排序器(需 Cohere API 密鑰) compressor = CohereRerank(model="rerank-english-v2.0", top_n=3) # 構建壓縮檢索器 compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=vectorstore.as_retriever(search_kwargs={"k": 10}) # 先檢索 top 10 ) # 用壓縮后的結果生成回答 qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=compression_retriever )
-
混合檢索(Hybrid Retrieval)
結合“向量檢索(語義相似)”和“關鍵詞檢索(精確匹配)”,兼顧語義理解和精準關鍵詞匹配(如專業術語)。
常用工具:Pinecone
、Weaviate
等支持混合檢索的向量庫,或用LangChain
的MultiRetriever
組合。
三、多源 RAG:跨類型/跨庫信息整合
適用場景:需要從多個數據源(如文檔、數據庫、API、表格等)檢索信息,整合后生成回答(如企業知識庫+產品數據庫的問答)。
具體做法:
-
多向量庫檢索(Multi-VectorStore Retrieval)
為不同類型的文檔(如技術手冊、用戶案例、API 文檔)創建獨立向量庫,檢索時并行查詢并合并結果。# 初始化多個向量庫 vectorstore_tech = Chroma.from_documents(tech_docs, embeddings, persist_directory="./tech_db") vectorstore_case = Chroma.from_documents(case_docs, embeddings, persist_directory="./case_db") # 構建多檢索器 from langchain.retrievers import MultiRetriever retrievers = [ vectorstore_tech.as_retriever(search_kwargs={"k": 2}), vectorstore_case.as_retriever(search_kwargs={"k": 2}) ] multi_retriever = MultiRetriever(retrievers=retrievers) # 用多檢索器生成回答 qa_chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=multi_retriever)
-
結構化+非結構化混合檢索
結合非結構化文檔(向量檢索)和結構化數據(如 SQL 數據庫、CSV 表格),用SQLDatabaseChain
或TableQA
處理結構化查詢,再與文檔檢索結果整合。from langchain.chains import SQLDatabaseChain from langchain.sql_database import SQLDatabase # 連接 SQL 數據庫 db = SQLDatabase.from_uri("sqlite:///產品庫存.db") sql_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True) # 定義路由邏輯:判斷問題需要文檔檢索還是數據庫查詢 from langchain.chains import RouterChain, LLMRouterChain, MultiPromptChain from langchain.prompts import PromptTemplate # 路由提示:讓 LLM 判斷問題類型 route_prompt = PromptTemplate( template="""判斷問題需要查詢文檔還是數據庫:{input} 輸出 'doc' 或 'sql'""", input_variables=["input"] ) router_chain = LLMRouterChain.from_llm(llm, route_prompt) # 整合鏈:根據路由結果調用對應工具 chains = {"doc": qa_chain, "sql": sql_chain} multi_chain = MultiPromptChain(router_chain=router_chain, destination_chains=chains) # 提問(如“產品A的庫存有多少?”→ 路由到 SQL;“產品A的使用場景?”→ 路由到文檔) result = multi_chain.run("產品A的庫存和使用場景分別是什么?")
四、對話式 RAG:帶歷史記憶的檢索增強
適用場景:對話場景(如客服機器人),需要結合歷史對話上下文動態檢索,確保回答連貫性(如“上一個問題提到的功能如何操作?”)。
具體做法:
用 ConversationalRetrievalChain
替代基礎 RetrievalQA
,自動處理對話歷史,生成包含歷史上下文的檢索查詢。
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory # 初始化對話記憶(存儲歷史對話)
memory = ConversationBufferMemory( memory_key="chat_history", # 記憶鍵名 return_messages=True, # 返回消息對象 output_key="answer" # 輸出鍵名(與鏈對齊)
) # 構建對話式 RAG 鏈
conv_chain = ConversationalRetrievalChain.from_llm( llm=llm, retriever=retriever, memory=memory, return_source_documents=True
) # 多輪對話示例
query1 = "這篇論文的研究背景是什么?"
result1 = conv_chain({"question": query1})
print(result1["answer"]) query2 = "基于這個背景,作者提出了什么方法?" # 依賴上一輪歷史
result2 = conv_chain({"question": query2})
print(result2["answer"])
五、多模態 RAG:整合文本、圖片、表格等跨類型信息
適用場景:文檔包含圖片、表格、公式等非文本內容(如 PDF 中的圖表、PPT 中的圖片),需檢索多模態信息生成回答。
具體做法:
- 多模態文檔加載:用
UnstructuredFileLoader
或PyPDFLoader
加載含多模態內容的文檔,保留圖片/表格元數據。 - 多模態嵌入:對文本用常規嵌入模型,對圖片用視覺嵌入模型(如 CLIP),存儲到支持多模態的向量庫(如
Qdrant
、Weaviate
)。 - 多模態檢索:檢索時同時匹配文本和圖片向量,生成回答時引用圖片內容(如“圖1展示了XXX流程”)。
# 示例:加載含圖片的 PDF 并保留圖片元數據
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("帶圖片的文檔.pdf", extract_images=True) # 提取圖片
documents = loader.load() # 多模態向量庫存儲(以 Qdrant 為例)
from langchain.vectorstores import Qdrant
from langchain.embeddings import HuggingFaceBgeEmbeddings # 文本嵌入
from PIL import Image
import clip # 視覺嵌入模型 # 文本嵌入 + 圖片嵌入邏輯(需自定義處理)
# ...(省略圖片嵌入細節) # 構建多模態檢索器并生成回答
qdrant = Qdrant.from_documents(...)
retriever = qdrant.as_retriever()
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
總結
LangChain 實現 RAG 的核心是通過“組件化”靈活組合文檔處理、檢索、生成環節,關鍵方法可歸納為:
- 基礎流程:加載→分割→嵌入→存儲→檢索→生成;
- 精度優化:多查詢、重排序、混合檢索;
- 多源整合:多向量庫、結構化+非結構化混合;
- 場景適配:對話式記憶、多模態檢索。
實際應用中需根據文檔類型、問答場景選擇合適的方法,并通過調整 chunk_size
、檢索 k
值、重排序策略等優化效果。