别再只会调大模型了:用 Python 搭一套自己的知识库问答系统(RAG 实战指南)
别再只会调大模型了:用 Python 搭一套自己的知识库问答系统(RAG 实战指南)
大家好,我是 Echo_Wish。
这两年很多人玩大模型,张口就是“接个 API 就行”。
但真正落地的时候你会发现一个残酷现实:
大模型很聪明,但它对你公司的资料一无所知。
你让它回答:
- 公司内部规范?
- 产品技术白皮书?
- 项目历史文档?
- 你的博客沉淀?
它只能开始“编”。
这时候,RAG(Retrieval-Augmented Generation)就登场了。
今天我带你从 0 开始,用 Python 搭一个自己的知识库问答系统。
不整虚的,直接实战。
一、RAG 到底是什么?一句话讲明白
RAG = 检索 + 大模型生成。
流程非常简单:
用户问题
↓
向量检索(从知识库找相关内容)
↓
把检索结果拼进 prompt
↓
交给大模型生成答案
也就是说:
模型负责“说话”,知识库负责“内容”。
你不给模型资料,它只能瞎猜;
你给它精准资料,它就能像专家一样回答。
二、系统整体架构长什么样?
先看一个简化版结构图:
核心组件就四块:
- 文档加载
- 文本切块
- 向量化(Embedding)
- 向量检索 + LLM 生成
我们一步步来。
三、第一步:准备文档
假设我们有一堆 Markdown / PDF / TXT 文档。
先装几个依赖:
pip install langchain faiss-cpu sentence-transformers openai
四、第二步:文档切块(Chunking)
很多人忽略这一点。
如果你把整本 PDF 一次性 embedding,
检索效果会差得离谱。
正确做法是:切块。
from langchain.text_splitter import RecursiveCharacterTextSplitter
text = open("knowledge.txt", "r", encoding="utf-8").read()
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=100
)
docs = splitter.create_documents([text])
print("切块数量:", len(docs))
为什么要 overlap?
因为语义是连续的,
你不做重叠,信息会断层。
五、第三步:生成向量(Embedding)
Embedding 是 RAG 的灵魂。
我们用 sentence-transformers 举例:
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer("all-MiniLM-L6-v2")
texts = [doc.page_content for doc in docs]
embeddings = model.encode(texts)
print("向量维度:", embeddings.shape)
此时,每个文本块都变成了一个向量。
这就是“语义表示”。
六、第四步:构建向量数据库
这里我们用 FAISS。
import faiss
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(np.array(embeddings))
print("向量库大小:", index.ntotal)
现在你已经有了一个可搜索的知识库。
七、第五步:实现检索
当用户提问时:
query = "公司数据库怎么做备份?"
query_vec = model.encode([query])
D, I = index.search(np.array(query_vec), k=3)
for idx in I[0]:
print("命中内容:", texts[idx])
这一步会返回最相关的 3 段文本。
注意:
RAG 的好坏,80% 在检索。
如果检索错了,后面再强的大模型都没用。
八、第六步:交给大模型生成答案
把检索到的内容拼进 prompt:
import openai
context = "\n".join([texts[i] for i in I[0]])
prompt = f"""
基于以下资料回答问题:
{context}
问题:{query}
"""
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
print(response["choices"][0]["message"]["content"])
此时,大模型不是“猜”,
而是“基于资料回答”。
这就是 RAG 的核心价值。
九、做成一个简单问答系统
我们封装一下:
def ask_question(query):
query_vec = model.encode([query])
D, I = index.search(np.array(query_vec), k=3)
context = "\n".join([texts[i] for i in I[0]])
prompt = f"""
基于以下资料回答问题:
{context}
问题:{query}
"""
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
return response["choices"][0]["message"]["content"]
你已经拥有一个基础知识库问答系统。
十、真实落地要注意什么?
说点真话。
很多人做 RAG 做着做着发现:
- 检索不准
- 答案乱拼
- 重复内容多
- 上下文不连贯
这时候你要做三件事:
1️⃣ 优化切块策略
不是固定 500 字就完事。
有时候按标题切更好。
2️⃣ 用更强的 Embedding 模型
Embedding 决定检索质量。
3️⃣ 做 rerank
可以再加一层排序模型,提升命中质量。
十一、我的一点感受
我自己做过很多 RAG 项目。
最大的误区是:
把 RAG 当成“接 API”。
其实它更像一个“搜索系统 + 提示工程”的融合体。
你需要理解:
- 向量空间
- 语义相似度
- Prompt 结构
- 数据治理
RAG 做得好,是企业级生产力工具。
做得不好,就是一个高级“拼接器”。
十二、未来怎么玩?
再往前一步,可以加:
- 多知识库路由
- 权限控制
- 实时更新
- 增量向量索引
- Agent 自动调用
RAG 不是终点。
它是企业智能化的入口。
结尾
如果你还没做过 RAG,我建议你一定动手试一次。
当你第一次看到模型准确引用你自己的文档回答问题时——
那种感觉,就像你亲手造了一个“会读书的助理”。
- 点赞
- 收藏
- 关注作者
评论(0)