LangChain Chroma 向量库实战指南:初始化、入库、检索与 Retriever 全解析

张开发
2026/4/17 1:06:31 15 分钟阅读

分享文章

LangChain Chroma 向量库实战指南:初始化、入库、检索与 Retriever 全解析
文章目录一、它怎么用1本地内存模式适合调试2本地持久化适合小中型项目 / 本地知识库vector_store 本质上是一个**向量数据库实例对象Vector Store Instance**用来**存储和检索 embedding 向量**。3连 Chroma Server适合服务化部署4直接包成 Retriever适合 RAG 链as_retriever() 是什么把“向量数据库”转换成一个**统一接口的检索器对象。**二、**Chroma 向量数据库类**最常用的方法有哪些重要A. 建库类方法from_documents(...)from_texts(...)B. 写入类方法项目中使用add_documents(...)documents :你要写入向量库的内容Document 列表ids :给每条文档一个唯一 ID主键项目的内容add_texts(...) (相关补充)C. 维护类方法update_documents(...)delete(...)D. 检索类方法similarity_search(...)similarity_search_with_score(...)向量检索 / 其他搜索方法E. 接链类方法as_retriever(...)as_retriever的常见参数项目使用三、这些方法分别用在什么地方场景 1首次建知识库场景 2知识库增量同步场景 3直接检索场景 4RAG 问答链四、你写项目时最该记住的 3 个点1Chroma 是“向量库对象”不是“完整 RAG”2add_documents 和 as_retriever 是最常用的两个接口3如果要长期复用库别忘了 persist_directory五、一个最小可用示例给你一个最实战的理解langChain 官方的Chroma 向量库适配类。它负责把文本 /Documentembedding 模型Chroma 存储后端这三件事接起来让你能完成入库、更新、删除、检索、转 Retriever这些动作。LangChain 的向量库统一接口里最基础的就是add_documents、delete、similarity_search而 Chroma 这个类是在这个统一接口之上对 Chroma 做的官方实现。(LangChain 文档)一、它怎么用最常见有 4 种用法。1 / 2 / 3是Chroma的三种连接/存储方式初始化向量库4是在前面某一种Chroma实例之上再包装成 Retriever 的调用方式1本地内存模式适合调试fromlangchain_chromaimportChromafromlangchain_openaiimportOpenAIEmbeddings embeddingsOpenAIEmbeddings(modeltext-embedding-3-large)vector_storeChroma(collection_nameexample_collection,embedding_functionembeddings,)这时数据只在当前进程里程序停了基本就没了适合快速实验。LangChain 官方文档就是这么初始化的。(LangChain 文档)2本地持久化适合小中型项目 / 本地知识库vector_storeChroma(collection_nameexample_collection,embedding_functionembeddings,persist_directory./chroma_langchain_db,)vector_store本质上是一个向量数据库实例对象Vector Store Instance用来存储和检索 embedding 向量。它里面存的是什么文本原始数据向量embeddingmetadata可选persist_directory一加数据会持久化到本地目录下次启动可以继续用同一个库。(LangChain 文档)collection_nameexample_collection”向量库里的“库名 / 表名”。vector_store一个“向量数据库对象实例。项目代码细节3连 Chroma Server适合服务化部署vector_storeChroma(collection_nameexample_collection,embedding_functionembeddings,hostlocalhost,port8000,)如果你跑的是 Chroma server而不是本地嵌入式存储就走host/port/ssl/headers这套连接参数。官方文档明确提到host并说明还可以配port、ssl、headers。(LangChain 文档)1️⃣hostlocalhost服务器地址在哪台机器localhost你自己电脑127.0.0.1 也是你自己电脑192.168.1.10 局域网另一台机器api.xxx.com 远程服务器2️⃣port8000服务器端口这个服务开在哪个“门”常见8000Chroma 默认5432PostgreSQL6379Redis等价于http://localhost:80004直接包成 Retriever适合 RAG 链retrievervector_store.as_retriever(search_typemmr,search_kwargs{k:4,fetch_k:20})docsretriever.invoke(用户问句)as_retriever()是什么把“向量数据库”转换成一个统一接口的检索器对象。这个最常见于 RAG。因为很多链、Agent、问答流程接收的是Retriever不是原始VectorStore。官方文档和核心基类都支持这种用法。(LangChain 文档)翻译成人话 LangChain 里的这些东西RAG链Agent问答系统它们**不关心你用什么数据库**它们只要求给我一个能帮我查资料的东西这个东西就是 Retriever。 为什么不直接用 VectorStore❌ VectorStore向量库是“数据库”vector_store.similarity_search(...) 问题每种数据库写法不一样Chroma / FAISS / Pinecone 都不同✅ Retriever是“统一接口”retriever.invoke(问题) 好处不管底层是什么数据库上层代码都一样用Retriever 的整套逻辑包括 invoke但不止它不关心底层数据库实现的那一层代码二、Chroma 向量数据库类最常用的方法有哪些重要你关心的可以分成“建库 / 写入 / 维护 / 检索 / 接链”五类。A. 建库类方法from_documents(...)直接从Document列表创建向量库。fromlangchain_core.documentsimportDocument docs[Document(page_contentLangChain 是一个 LLM 应用框架,metadata{source:doc1}),Document(page_contentChroma 是一个向量数据库,metadata{source:doc2}),]vector_storeChroma.from_documents(documentsdocs,embeddingembeddings,collection_namedemo,persist_directory./db,)适合你已经做完切分了手上就是Document列表一次性初始化知识库API 摘要说明它会从文档列表创建 Chroma带persist_directory时会持久化。(LangChain 参考文档)from_texts(...)直接从字符串列表建库。vector_storeChroma.from_texts(texts[第一段文本,第二段文本],embeddingembeddings,metadatas[{source:a},{source:b}],collection_namedemo,)适合只是快速实验还没引入Document结构这个也是常用工厂方法。(LangChain)B. 写入类方法项目中使用add_documents(...)这是 LangChain 向量库统一接口里明确列出来的方法。适合增量更新知识库文档切分后批量入库首次建库后持续写入新内容官方向量库总文档把它列为标准接口项目中也使用到它。(LangChain 文档)把Document列表写入向量库。new_docs[Document(page_content这是新增知识,metadata{tag:new})]vector_store.add_documents(documentsnew_docs,ids[doc-1])documents:你要写入向量库的内容Document 列表 举例new_docs [ Document(page_content这是新增知识,metadata{tag:new}) ] 就是一条知识文本 metadataids:给每条文档一个唯一 ID主键 举例ids [doc-1] 意思这条 Document 的编号是doc-1为什么需要 ids✅ 1用于更新覆盖add_documents(...,ids[doc-1])如果doc-1已存在 会被覆盖更新✅ 2用于删除vector_store.delete(ids[doc-1]) 可以精确删某条数据✅ 3避免重复数据 不传 ids可能每次都会新增重复 传 ids可以控制唯一性项目的内容# 将内容存入向量库vector_store.py)self.vector_store.add_documents(split_document)self.spliterRecursiveCharacterTextSplitter(chunk_sizechroma_conf[chunk_size],chunk_overlapchroma_conf[chunk_overlap],separatorschroma_conf[separators],length_functionlen,)split_document:list[Document]self.spliter.split_documents(documents)**RecursiveCharacterTextSplitter是 LangChain 官方提供的类,**它属于**LangChain 官方的 text splitter 模块,**它来自langchain_text_splitters官方拆分出来的模块.add_texts(...)(相关补充)很多时候源码里也会有add_texts本质是收原始字符串再内部转文档。实际工程里更推荐add_documents因为 metadata 更清晰。这个在from_texts的说明里能看出它是底层常用路径。(LangChain)C. 维护类方法update_documents(...)更新已有文档。updated_docs[Document(page_content更新后的内容,metadata{source:doc1,version:2})]vector_store.update_documents(ids[doc-1],documentsupdated_docs)适合原文档内容变了metadata 需要改重建整个库太贵只想局部更新这个方法在官方 API 搜索结果里是明确存在的。(LangChain 参考文档)delete(...)按 ID 删除。vector_store.delete(ids[doc-1])适合删除过期知识删除错误切片做知识库同步这是 LangChain 向量库统一接口的一部分。(LangChain 文档)D. 检索类方法similarity_search(...)最基础的语义检索。docsvector_store.similarity_search(什么是向量数据库,k3,filter{source:doc2})返回最相似的文档列表。k控制返回条数filter用 metadata 过滤。LangChain 总文档明确说明了这两个典型参数。(LangChain 文档)适合直接做召回自己控制后续 rerank / prompt 拼接不想先转 retrieversimilarity_search_with_score(...)返回“文档 分数”。docs_and_scoresvector_store.similarity_search_with_score(什么是 Chroma,k3)适合你想看相似度/距离要做阈值裁剪要调试召回质量LangChain 的 Chroma 集成页列出了这个查询模式。(LangChain 文档)向量检索 / 其他搜索方法Chroma 集成页还列出了 “Search by vector” 和 “Other search methods”说明除了文本查询还支持直接按向量查、以及其他搜索变体。具体可用性以当前 API 版本为准。(LangChain 文档)E. 接链类方法as_retriever(...)as_retriever()是什么把“向量数据库”转换成一个统一接口的检索器对象。这个最常见于 RAG。因为很多链、Agent、问答流程接收的是Retriever不是原始VectorStore。官方文档和核心基类都支持这种用法。(LangChain 文档)翻译成人话 LangChain 里的这些东西RAG链Agent问答系统它们**不关心你用什么数据库**它们只要求给我一个能帮我查资料的东西这个东西就是 Retriever。把向量库包装成 Retriever。retrievervector_store.as_retriever(search_typesimilarity,search_kwargs{k:4})vector_store还是那个向量库as_retriever()把它包装成统一的检索器接口search_typesimilarity表示用“普通相似度检索”search_kwargs{k: 4}表示返回最相关的 4 条文档。as_retriever的常见参数as_retriever()这是实际项目里最重要的方法之一。因为很多上层组件接的是 retriever 接口。官方说明支持的search_type常见参数包括similaritysimilarity按向量相似度直接取最像的前 k 条。适合大多数普通 RAGFAQ 检索你先想要“稳定、直接”的结果。search_typemmrMMR 是Maximal Marginal Relevance。比如你的知识库里有很多内容很像的 chunk普通 similarity 可能会返回 4 条几乎重复的段落MMR 会先多取一些候选再挑出“既相关又不那么重复”的结果。官方示例里也专门给了lambda_mult、fetch_k的用法。适合文档切得很碎相似片段很多想减少上下文重复。search_typesimilarity_score_threshold这个模式会先做相似度检索再按分数阈值过滤。含义只返回“相似度达到某个标准”的结果。官方文档说明这个模式通常搭配score_threshold使用相关性分数范围是[0, 1]1最相似0最不相似。retrievervector_store.as_retriever( search_typesimilarity_score_threshold, search_kwargs{ score_threshold:0.8, k:4 } )适合你不想“硬凑结果”没有足够相关内容时宁可少返回甚至不返回search_kwargs常见包括k返回条数fetch_kMMR 先取多少候选lambda_multMMR 里“相关性 vs 多样性”的平衡score_threshold分数阈值filtermetadata 过滤这些都来自 LangChain 核心as_retriever参考说明。(LangChain 参考文档)项目使用defget_retriever(self):returnself.vector_store.as_retriever(search_kwargs{k:chroma_conf[k]})三、这些方法分别用在什么地方最实用的理解方式是按 RAG 流程看。场景 1首次建知识库流程加载原始文档文本切分Chroma.from_documents(...)或Chroma(...) add_documents(...)这里Chroma的角色是向量库存储层。RecursiveCharacterTextSplitter是切分层embedding 模型负责向量化。官方 Chroma 集成页和 LangChain 的知识库教程都按这个套路组织。(LangChain 文档)场景 2知识库增量同步流程找出新增/修改/删除的文档新文档用add_documents修改文档用update_documents删除文档用delete这里它承担的是索引维护层。(LangChain 文档)场景 3直接检索流程用户提问similarity_search(...)结果交给你自己的排序/拼 prompt 逻辑这里它承担的是召回层。(LangChain 文档)场景 4RAG 问答链流程retriever vector_store.as_retriever(...)把 retriever 传给 RAG chain / retrieval chain / agentLLM 基于召回上下文作答这里它承担的是Retriever 后端。LangChain 官方文档专门说了“Query by turning into retriever”以及“Usage for retrieval-augmented generation”。(LangChain 文档)四、你写项目时最该记住的 3 个点1Chroma是“向量库对象”不是“完整 RAG”它只负责存和找不负责提示词编排、对话记忆、答案生成。也就是说Chroma召回Retriever统一检索接口LLM / Chain生成答案这是 LangChain 组件拆分的核心。(LangChain 文档)2add_documents和as_retriever是最常用的两个接口前者管“入库”后者管“接到链里”。你图里圈这两个方向是对的。统一接口文档里add_documents、delete、similarity_search是基本盘Chroma 页里又把as_retriever单独拿出来讲。(LangChain 文档)3如果要长期复用库别忘了persist_directory否则每次重启都得重建索引。这是本地开发里最容易踩的点之一。(LangChain 文档)五、一个最小可用示例fromlangchain_chromaimportChromafromlangchain_openaiimportOpenAIEmbeddingsfromlangchain_core.documentsimportDocument embeddingsOpenAIEmbeddings(modeltext-embedding-3-large)docs[Document(page_contentLangChain 是一个 LLM 应用开发框架,metadata{source:intro}),Document(page_contentChroma 是一个向量数据库适合语义检索,metadata{source:db}),]vector_storeChroma(collection_namedemo_collection,embedding_functionembeddings,persist_directory./chroma_db,)vector_store.add_documents(docs,ids[1,2])resultsvector_store.similarity_search(什么是向量数据库,k2)fordocinresults:print(doc.page_content,doc.metadata)retrievervector_store.as_retriever(search_typemmr,search_kwargs{k:2,fetch_k:5})retrieved_docsretriever.invoke(LangChain 是干什么的)fordocinretrieved_docs:print(doc.page_content)这段代码对应的就是Chroma(...)初始化向量库add_documents(...)入库similarity_search(...)直接检索as_retriever(...)接入 RAG 检索接口这些能力都在官方 Chroma 集成文档和 LangChain 的向量库接口文档里。(LangChain 文档)给你一个最实战的理解如果你现在在做一个“文档问答 / 知识库客服 / 本地 RAG”项目可以把它理解成TextSplitter把长文切块Embeddings把块变向量langchain_chroma.Chroma把这些向量存起来并支持相似检索as_retriever()把“存储检索”包装成标准检索器LLM Chain / Retrieval Chain拿检索结果去生成回答所以这个“官方集成类”在架构里处在向量库适配层 / 检索基础设施层。(LangChain 文档)

更多文章