
我用 RAG 搭了一套个人知识库让 AI 读完我所有笔记再回答问题适合有大量笔记/文档/资料想让 AI 基于你的私有知识库回答问题的人。本文从零搭建一套 RAG 系统附完整 Python 代码500 行以内搞定。为什么需要 RAG直接问 ChatGPT 问题它只能用训练数据回答。问它我上周写的那篇关于 MCP 的文章总结一下它不知道因为那是你的私有数据。RAGRetrieval-Augmented Generation检索增强生成解决的就是这个问题先从你的知识库里检索相关内容再把检索结果喂给 AI 生成回答。用户提问 → 检索知识库 → 找到相关片段 → 喂给 AI → AI 基于你的资料回答类比一下RAG 就像给 AI 配了一个私人图书馆它回答问题之前先去图书馆查资料。RAG 的核心流程整个 RAG 分 3 步步骤做什么用什么1. 索引把文档切块、向量化、存入数据库Embedding 模型 向量数据库2. 检索用户提问时找到最相关的文档块余弦相似度搜索3. 生成把检索结果 用户问题一起喂给 AILLMGPT-4/Claude 等步骤 1文档索引文档切块长文档不能整篇塞给 AI需要切成小块chunk。每块 200-500 字有重叠。defsplit_text(text,chunk_size300,overlap50):将文本切块每块 chunk_size 字重叠 overlap 字chunks[]start0whilestartlen(text):endstartchunk_size chunktext[start:end]chunks.append(chunk)startend-overlap# 重叠部分returnchunks# 示例textopen(my_article.md,encodingutf-8).read()chunkssplit_text(text,chunk_size300,overlap50)print(f切成了{len(chunks)}个块)向量化把每个文本块转成一个向量一组数字用于后续的相似度搜索。fromopenaiimportOpenAI clientOpenAI()defget_embedding(text):用 OpenAI 的 Embedding 模型把文本转成向量responseclient.embeddings.create(modeltext-embedding-3-small,inputtext)returnresponse.data[0].embedding# 示例vectorget_embedding(MCP 是 Anthropic 推出的开放协议)print(f向量维度:{len(vector)})# 通常是 1536 维存入向量数据库我用的是 ChromaDB纯 Python不需要额外安装服务。importchromadb# 创建数据库dbchromadb.PersistentClient(path./knowledge_db)collectiondb.get_or_create_collection(my_docs)# 索引文档defindex_document(file_path,doc_id):textopen(file_path,encodingutf-8).read()chunkssplit_text(text)fori,chunkinenumerate(chunks):vectorget_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_idfile.split(/)[-1].replace(.md,))步骤 2检索用户提问时把问题向量化然后搜索最相似的文档块。defsearch(query,top_k5):搜索知识库返回最相关的 top_k 个文档块query_vectorget_embedding(query)resultscollection.query(query_embeddings[query_vector],n_resultstop_k)returnresults[documents][0]# 示例resultssearch(MCP 协议怎么配置,top_k3)fori,docinenumerate(results):print(f--- 结果{i1}---)print(doc[:200])步骤 3生成把检索结果和用户问题一起喂给 AI。defrag_answer(question):基于知识库回答问题# 1. 检索relevant_docssearch(question,top_k5)context\n\n---\n\n.join(relevant_docs)# 2. 生成promptf基于以下参考资料回答问题。如果资料中没有相关内容就说我没有找到相关信息。 参考资料{context}问题{question}回答responseclient.chat.completions.create(modelgpt-4,messages[{role:user,content:prompt}])returnresponse.choices[0].message.content# 使用answerrag_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.txtrequirements.txtopenai1.0 chromadb0.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 字保持上下文连贯。坑 3Embedding 模型选错症状中文搜索结果不相关。原因用的 Embedding 模型对中文支持不好。解决用text-embedding-3-smallOpenAI或bge-large-zh中文专用。坑 4向量数据库占满磁盘症状索引了几千篇文章后磁盘空间不足。原因每篇文章切出几十个块每个块一个 1536 维向量存储量很大。解决定期清理不再需要的旧版本索引或者用压缩存储。坑 5检索结果重复症状top_k5 返回的 5 个结果内容几乎一样。原因文档里有大段重复内容比如复制粘贴的段落。解决索引前去重或者检索后做相似度过滤相似度 0.95 的只保留一个。坑 6AI 回答时编造知识库内容症状AI 说根据你的知识库但引用的内容实际上知识库里没有。原因AI 的幻觉问题它会脑补知识库内容。解决在 prompt 里明确写如果资料中没有相关内容就说没找到并且要求 AI 标注引用来源。进阶优化优化方向做法效果混合搜索向量搜索 关键词搜索结合提升召回率重排序检索后用 reranker 模型重新排序提升精确度多轮对话记住对话历史连检索支持追问增量索引只索引新增/修改的文档节省时间和成本元数据过滤按标签/日期/类型过滤检索范围精准定位总结3 条核心经验chunk_size 是最关键的参数。太小上下文丢失太大检索不精确。300 字 50 字重叠是我的最佳实践。Embedding 模型决定搜索质量。中文场景用text-embedding-3-small或bge-large-zh别用通用模型。RAG 不是万能的。如果知识库本身质量差过时、错误、不完整RAG 只会让 AI 更自信地输出错误答案。先保证知识库质量再搭 RAG。你有搭过 RAG 系统吗遇到过什么问题评论区交流。