ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

RAG 从零搭建:8 步搞定知识库问答

2026/8/5 9:48:03 拓冰建站 浏览量
RAG 从零搭建:8 步搞定知识库问答

后端转AI第一课:RAG是面试重中之重,也是第一个简历项目的核心。

RAG是什么

RAG = 给模型查资料再答。模型不记得你的文档,那就先检索相关片段,拼进提示词,再让模型回答——答案有依据、能溯源、不胡说。

8步全链路

① 文档解析 → ② 切片分块 → ③ Embedding → ④ 向量库存储

→ ⑤ 语义检索 → ⑥ 召回重排 → ⑦ Prompt拼接 → ⑧ 大模型生成

① 文档解析(PDF/Word→文本)

from langchain_community.document_loaders import PyPDFLoader

documents.extend(PyPDFLoader(path).load())

documents.extend(Docx2txtLoader(path).load())

documents.extend(TextLoader(path, encoding="utf-8").load())

# 坑:表格/图片里的字读不出,需要OCR或多模态

② 切片分块(200-500字+重叠)

from langchain_huggingface import HuggingFaceEmbeddings

splitter = RecursiveCharacterTextSplitter(

chunk_size=300, # 块大小

chunk_overlap=50, # 重叠防切断语义

separators=["\n\n", "\n", "。", "!", "?", " ", ""]

)

chunks = splitter.split_documents(documents)

# 坑:块太大召回糙,太小丢上下文

③ Embedding(中文用bge)

from langchain_community.embeddings import HuggingFaceBgeEmbeddings

embeddings = HuggingFaceEmbeddings(
model_name=embed_model_name,
model_kwargs={"device": "cpu"}, # 无显卡固定cpu
encode_kwargs={"normalize_embeddings": True} # BGE模型强制归一化向量
)

# 中文场景用bge/m3e,比通用英文模型准

④ 向量库存储(Chroma最轻)

from langchain_chroma import Chroma

vectorstore = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings
)

⑤⑥ 语义检索 + 重排

retriever = vectorstore.as_retriever(

search_kwargs={"k": 5} # 初召回K块

)

# 重排(Rerank):用交叉编码器挑最相关Top-N

from langchain_community.cross_encoders import HuggingFaceCrossEncoder

from langchain.retrievers import ContextualCompressionRetriever

from langchain.retrievers.document_compressors import CrossEncoderReranker

reranker = CrossEncoderReranker(

model=HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-base"),

top_n=3

)

compression_retriever = ContextualCompressionRetriever(

base_compressor=reranker, base_retriever=retriever

)

⑦⑧ Prompt拼接 + 生成

from langchain_community.document_loaders import (
PyPDFLoader,
TextLoader,
Docx2txtLoader,
)

prompt = ChatPromptTemplate.from_messages([

("system", """你是一个知识库问答助手。

只根据提供的资料回答,资料里没有的,明确说"不知道"。

回答末尾标注引用来源。"""),

("user", "资料:\n{context}\n\n问题:{question}")

])

llm = ChatOpenAI(model="qwen-max", temperature=0.2)

def ask(question: str):

docs = compression_retriever.invoke(question)

context = "\n".join(f"[{i+1}] {d.page_content}" for i, d in enumerate(docs))

chain = prompt | llm

return chain.invoke({"context": context, "question": question})

完整示例

question = "什么是RAG?"

answer = ask(question)

print(answer.content)

关键认知:RAG的"稳"靠检索质量,不是模型多强。召回差,模型再强也胡说。

过关清单

☐ 上传PDF能解析出文本

☐ 分块有重叠,参数可配置

☐ 中文Embedding(bge)检索语义相关

☐ 回答带引用来源

☐ 知识库无答案时明确说"不知道"

📌 配套Demo代码:(Star支持🔥backend-to-ai-guide/rag-demo/README.md at main · cxy-ai-gongfang/backend-to-ai-guide · GitHub

下一篇:RAG优化实战——去幻觉/提召回/成本控制。

欢迎关注专栏,持续更新。