我用 RAG 搭了一套个人知识库:让 AI 读完我所有笔记再回答问题
2026/6/8 4:59:27 网站建设 项目流程

我用 RAG 搭了一套个人知识库:让 AI 读完我所有笔记再回答问题

适合有大量笔记/文档/资料,想让 AI 基于你的私有知识库回答问题的人。
本文从零搭建一套 RAG 系统,附完整 Python 代码,500 行以内搞定。

为什么需要 RAG

直接问 ChatGPT 问题,它只能用训练数据回答。问它"我上周写的那篇关于 MCP 的文章总结一下",它不知道,因为那是你的私有数据。

RAG(Retrieval-Augmented Generation,检索增强生成)解决的就是这个问题:先从你的知识库里检索相关内容,再把检索结果喂给 AI 生成回答

用户提问 → 检索知识库 → 找到相关片段 → 喂给 AI → AI 基于你的资料回答

类比一下:RAG 就像给 AI 配了一个"私人图书馆",它回答问题之前先去图书馆查资料。

RAG 的核心流程

整个 RAG 分 3 步:

步骤做什么用什么
1. 索引把文档切块、向量化、存入数据库Embedding 模型 + 向量数据库
2. 检索用户提问时,找到最相关的文档块余弦相似度搜索
3. 生成把检索结果 + 用户问题一起喂给 AILLM(GPT-4/Claude 等)

步骤 1:文档索引

文档切块

长文档不能整篇塞给 AI,需要切成小块(chunk)。每块 200-500 字,有重叠。

defsplit_text(text,chunk_size=300,overlap=50):"""将文本切块,每块 chunk_size 字,重叠 overlap 字"""chunks=[]start=0whilestart<len(text):end=start+chunk_size chunk=text[start:end]chunks.append(chunk)start=end-overlap# 重叠部分returnchunks# 示例text=open("my_article.md",encoding="utf-8").read()chunks=split_text(text,chunk_size=300,overlap=50)print(f"切成了{len(chunks)}个块")

向量化

把每个文本块转成一个向量(一组数字),用于后续的相似度搜索。

fromopenaiimportOpenAI client=OpenAI()defget_embedding(text):"""用 OpenAI 的 Embedding 模型把文本转成向量"""response=client.embeddings.create(model="text-embedding-3-small",input=text)returnresponse.data[0].embedding# 示例vector=get_embedding("MCP 是 Anthropic 推出的开放协议")print(f"向量维度:{len(vector)}")# 通常是 1536 维

存入向量数据库

我用的是 ChromaDB,纯 Python,不需要额外安装服务。

importchromadb# 创建数据库db=chromadb.PersistentClient(path="./knowledge_db")collection=db.get_or_create_collection("my_docs")# 索引文档defindex_document(file_path,doc_id):text=open(file_path,encoding="utf-8").read()chunks=split_text(text)fori,chunkinenumerate(chunks):vector=get_embedding(chunk)collection.add(ids=[f"{doc_id}_{i}"],embeddings=[vector],documents=[chunk],metadatas=[{"source":file_path,"chunk_index":i}])print(f"已索引{file_path},共{len(chunks)}个块")# 批量索引importglobforfileinglob.glob("knowledge_base/*.md"):index_document(file,doc_id=file.split("/")[-1].replace(".md",""))

步骤 2:检索

用户提问时,把问题向量化,然后搜索最相似的文档块。

defsearch(query,top_k=5):"""搜索知识库,返回最相关的 top_k 个文档块"""query_vector=get_embedding(query)results=collection.query(query_embeddings=[query_vector],n_results=top_k)returnresults["documents"][0]# 示例results=search("MCP 协议怎么配置",top_k=3)fori,docinenumerate(results):print(f"--- 结果{i+1}---")print(doc[:200])

步骤 3:生成

把检索结果和用户问题一起喂给 AI。

defrag_answer(question):"""基于知识库回答问题"""# 1. 检索relevant_docs=search(question,top_k=5)context="\n\n---\n\n".join(relevant_docs)# 2. 生成prompt=f"""基于以下参考资料回答问题。如果资料中没有相关内容,就说"我没有找到相关信息"。 参考资料:{context}问题:{question}回答:"""response=client.chat.completions.create(model="gpt-4",messages=[{"role":"user","content":prompt}])returnresponse.choices[0].message.content# 使用answer=rag_answer("MCP 协议的 mcp.json 怎么配置?")print(answer)

完整项目结构

rag-system/ ├── index.py # 文档索引脚本 ├── search.py # 检索模块 ├── generate.py # 生成模块 ├── main.py # 主入口 ├── knowledge_db/ # 向量数据库(自动生成) ├── knowledge_base/ # 你的知识库文档 │ ├── article1.md │ ├── article2.md │ └── notes/ │ └── meeting.md └── requirements.txt

requirements.txt

openai>=1.0 chromadb>=0.4

效果对比

同一个问题,直接问 AI vs RAG 回答:

问题直接问 AIRAG 回答
“我之前写的 MCP 文章说了什么?”“我没有你之前文章的信息”“你之前的文章讲了 mcp.json 配置、3 个实战案例…”
“我的知识库里有哪些关于 AI Agent 的资料?”无法回答“你有 3 篇相关文章:Agent Pipeline、Skill 体系、多 Agent 框架对比”
“我的选题打分标准是什么?”无法回答“你的四维度打分:热门度/匹配度/差异化/实操性,合格线 30 分”

踩坑记录

坑 1:切块太碎,上下文丢失

症状:检索到的片段只有半句话,AI 无法理解。

原因:chunk_size 太小(比如 50 字),语义不完整。

解决:chunk_size 设 200-500 字,确保每块有完整的语义单元。

坑 2:切块太大,检索不精确

症状:检索到的块包含大量无关内容,AI 回答时被干扰。

原因:chunk_size 太大(比如 2000 字),一个块里混了多个话题。

解决:chunk_size 控制在 300 字以内,overlap 设 50 字保持上下文连贯。

坑 3:Embedding 模型选错

症状:中文搜索结果不相关。

原因:用的 Embedding 模型对中文支持不好。

解决:用text-embedding-3-small(OpenAI)或bge-large-zh(中文专用)。

坑 4:向量数据库占满磁盘

症状:索引了几千篇文章后,磁盘空间不足。

原因:每篇文章切出几十个块,每个块一个 1536 维向量,存储量很大。

解决:定期清理不再需要的旧版本索引,或者用压缩存储。

坑 5:检索结果重复

症状:top_k=5 返回的 5 个结果内容几乎一样。

原因:文档里有大段重复内容(比如复制粘贴的段落)。

解决:索引前去重,或者检索后做相似度过滤(相似度 > 0.95 的只保留一个)。

坑 6:AI 回答时编造知识库内容

症状:AI 说"根据你的知识库",但引用的内容实际上知识库里没有。

原因:AI 的幻觉问题,它会"脑补"知识库内容。

解决:在 prompt 里明确写"如果资料中没有相关内容,就说没找到",并且要求 AI 标注引用来源。

进阶优化

优化方向做法效果
混合搜索向量搜索 + 关键词搜索结合提升召回率
重排序检索后用 reranker 模型重新排序提升精确度
多轮对话记住对话历史,连��检索支持追问
增量索引只索引新增/修改的文档节省时间和成本
元数据过滤按标签/日期/类型过滤检索范围精准定位

总结

3 条核心经验:

  1. chunk_size 是最关键的参数。太小上下文丢失,太大检索不精确。300 字 + 50 字重叠是我的最佳实践。

  2. Embedding 模型决定搜索质量。中文场景用text-embedding-3-smallbge-large-zh,别用通用模型。

  3. RAG 不是万能的。如果知识库本身质量差(过时、错误、不完整),RAG 只会让 AI 更自信地输出错误答案。先保证知识库质量,再搭 RAG。


你有搭过 RAG 系统吗?遇到过什么问题?评论区交流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询