【手把手RAG搭建】从零手搓本地知识库(第三篇):ChromaDB 记忆中枢与极速检索实战 上一篇【手把手RAG搭建】从零手搓本地知识库第二篇CPU极速语义切片与向量化实战导读向量算出来了然后呢难道每次问答都要把几万条数据全扫一遍吗这是《从零构建个人知识库》系列的第三篇。今天我们将引入 RAG 系统的“海马体”——轻量级私有化向量数据库 ChromaDB。它不需要启动任何复杂的后台服务纯 Python 运行完美契合我们的 CPU 环境。跟着本文敲完代码你的知识库就真正拥有了“过目不忘”和“一秒回忆”的能力。为什么我们需要专门的向量数据库很多新手会问“我把向量存在列表或者 JSON 文件里不行吗”理论上可以但在实际工程中这会导致灾难性的后果检索极慢传统数据库无法直接理解语义。如果用 JSON 存储每次查询都需要计算目标向量与所有历史向量的距离暴力搜索耗时随数据量线性增长。内存爆炸高维浮点数数组如果全部加载到内存普通电脑很快就会 OOM内存溢出。我们的解法使用专为 AI 设计的向量数据库。它们内置了 HNSW分层可导航小世界图等近似最近邻ANN索引算法能在海量数据中实现毫秒级的相似度召回。对于个人项目ChromaDB是目前最完美的选择零配置、支持本地持久化、原生集成 LangChain。第一步安装并初始化 ChromaDB首先确保你的环境中已经安装了 ChromaDBpipinstallchromadb pipinstalllangchain-chroma接下来我们创建一个专门管理向量库的模块。在项目根目录创建src/vectorstore.pyimportosimportshutilfromlangchain_chromaimportChromafromlangchain_huggingfaceimportHuggingFaceEmbeddingsdefclear_vector_store(persist_directory./chroma_db): 【仅用于清理】在重新入库前安全地清空旧的向量库文件夹 ifos.path.exists(persist_directory):print(f 检测到旧向量库正在清空:{persist_directory})try:shutil.rmtree(persist_directory)exceptPermissionError:print(⚠️ 警告文件夹正被占用跳过物理删除。)defget_vector_store(persist_directory./chroma_db): 初始化或连接本地的 ChromaDB 向量数据库 :param persist_directory: 向量数据的本地持久化路径 # 复用第二篇的 Embedding 模型 (注意维度必须一致)embedding_modelHuggingFaceEmbeddings(model_name./models/bge-small-zh-v1.5,model_kwargs{device:cpu},encode_kwargs{normalize_embeddings:True})print(f 正在连接/创建本地向量库:{persist_directory})vectorstoreChroma(persist_directorypersist_directory,embedding_functionembedding_model,collection_namelocal_kb_collection)returnvectorstore️避坑提示新版 LangChain 已将 Chroma 独立为langchain-chroma包。请务必执行pip install langchain-chroma否则导入时会报错。同时实例化时传入的embedding_function必须与存入数据时使用的模型完全一致否则检索结果将毫无意义。第二步将切片数据写入记忆中枢现在我们把前两篇清洗、切分好的文本块批量写入数据库。ChromaDB 会自动调用 Embedding 模型将其转化为向量并建立索引。更新main.py进行入库测试fromsrc.loadersimportLocalDocLoaderfromsrc.cleanerimportclean_documentsfromsrc.splitterimportsemantic_splitfromsrc.vectorstoreimportget_vector_store,search_knowledge_base,clear_vector_storeif__name____main__:# 1. 获取处理后的文档块 (复用前文逻辑)raw_docsLocalDocLoader.load(./data/test_doc.md)cleaned_docsclean_documents(raw_docs)chunkssemantic_split(cleaned_docs,chunk_size500,chunk_overlap50)# 在入库前主动清空旧数据clear_vector_store()# 2. 初始化向量库vectorstoreget_vector_store()# 3. 批量写入数据print(开始向量化并写入 ChromaDB...)vectorstore.add_documents(chunks)# 4. 验证数据量countvectorstore._collection.count()print(f写入完成当前向量库共包含{count}条记录。)运行后你会发现项目根目录下多了一个chroma_db文件夹。这就是你专属的本地知识大脑即使重启电脑数据也安然无恙。第三步实现“输入问题秒出答案”的语义检索数据存进去了如何精准找出来我们来编写一个语义搜索函数。在src/vectorstore.py中追加以下方法defsearch_knowledge_base(query:str,top_k:int3): 基于自然语言问题进行语义检索 :param query: 用户的提问 :param top_k: 返回最相关的 K 个片段 vectorstoreget_vector_store()print(f\n 正在检索: {query})resultsvectorstore.similarity_search(query,ktop_k)fori,docinenumerate(results):sourcedoc.metadata.get(source,Unknown)print(f[{i1}] 来源:{source}| 匹配内容预览:{doc.page_content[:80]}...)returnresults再次更新main.py底部加入检索测试# 5. 模拟用户提问进行检索user_query如何配置本地的开发环境relevant_docssearch_knowledge_base(user_query,top_k3)当你运行这段代码看到控制台精准地打印出与你提问语义高度相关的文档片段时恭喜你你已经打通了 RAG 系统中最核心的“检索Retrieval”环节。系列预告这是《从零构建个人知识库》系列的第三篇下一篇我将详细讲解如何接入开源 LLM利用 LCEL 语法组装 Prompt真正实现“检索增强生成”。点击关注更新时第一时间收到通知带你一步步把这个项目真正跑在你的电脑上