进阶应用 高级

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(块重叠)的目的是?