如何从零搭建一个本地 RAG 知识库
想让大模型回答你私有文档里的问题,直接把全文塞进去既不现实也很贵。RAG(检索增强生成)的做法是:先把文档建成可检索的知识库,提问时只把最相关的片段喂给模型。这篇教程用 Python 从零搭一个能真正跑起来的本地 RAG。
整体架构
RAG 分离线建库和在线问答两个阶段:
graph TD
A[本地文档] --> B[切分成 chunk]
B --> C[向量化 Embedding]
C --> D[存入向量库]
E[用户提问] --> F[问题向量化]
F --> G[检索相似 chunk]
D --> G
G --> H[拼接提示词]
H --> I[大模型生成答案]
前置准备
创建虚拟环境并安装依赖:
python -m venv venv |
- chromadb:轻量的本地向量数据库
- sentence-transformers:本地免费的 Embedding 模型
- openai:调用大模型生成最终答案
步骤一:准备文档
真实项目里可用 langchain 的加载器读取 PDF、Markdown。这里先用一个示例列表说明:
documents = [ |
步骤二:切分成 chunk
长文档要切成小段分别向量化。段太长检索不准,太短语义不全:
def split_docs(docs, chunk_size=100, overlap=20): |
overlap 是相邻 chunk 的重叠字数,避免句子被切断而丢失语义。
步骤三:向量化并入库
用 Embedding 模型把每个 chunk 转成向量,存进 Chroma:
import chromadb |
步骤四:检索相关片段
把问题同样向量化,在库里找出最相似的 top-k:
def retrieve(question, k=2): |
步骤五:拼接提示词并生成
把检索到的片段和问题组装成提示词,交给大模型作答:
import os |
运行后,模型会基于检索到的资料回答,而不是凭空编造。
在线问答的完整流程
graph LR
A[用户提问] --> B[问题向量化]
B --> C[向量库检索 topk]
C --> D[取回相关 chunk]
D --> E[拼进提示词]
E --> F[大模型生成]
F --> G[返回带依据的答案]
优化方向
跑通之后,可以从这几处继续提升效果:
- 切分策略:按句子或段落切,比按字符更合理
- 混合检索:叠加 BM25 关键词检索,弥补向量对专有名词的弱项
- 重排序:检索后用 rerank 模型对 top-k 精排
- 更强的 Embedding:中文场景换用 bge、m3e 等中文模型
小结
一个最小可用的 RAG 只需五步:切分、向量化、入库、检索、生成。本地方案用 Chroma + sentence-transformers 就能零成本跑通,非常适合快速验证。理解了这条链路,日后迁移到 Milvus、Elasticsearch 等生产级组件,就只是规模问题。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 非鱼小站!
评论
WalineDisqus








