RAG 实战:文档加载、切分与向量化
用 DocumentLoaders、RecursiveCharacterTextSplitter 与向量库,端到端跑通一个 RAG 问答链。
第一步:加载文档
from langchain_community.document_loaders import (
TextLoader, PyPDFLoader, WebBaseLoader
)
docs = TextLoader("knowledge.txt", encoding="utf-8").load()
# docs: List[Document],每个 Document 有 page_content 与 metadata
第二步:切分
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=80,
separators=["\n\n", "\n", "。", ",", ""], # 中文友好
)
chunks = splitter.split_documents(docs)
print(len(chunks))
第三步:向量化并入库
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = FAISS.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
第四步:组装 RAG 链
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
prompt = ChatPromptTemplate.from_messages([
("system", "仅根据以下资料回答问题,资料中没有就说不知道:\n\n{context}"),
("human", "{question}"),
])
def format_docs(docs):
return "\n\n".join(d.page_content for d in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt | llm | StrOutputParser()
)
print(rag_chain.invoke("退货流程是怎样的?"))
这份骨架适用于几乎所有 RAG 项目,值得逐行吃透。
📝 课后练习
quiz-1 文档切分时设置 chunk_overlap(块重叠)的目的是?