【langchain 1.0】ChromaDB 原生 API 实战:为 LangChain 向量库打造管理工具集

一、背景介绍

在前面的文章中,我们已经通过 LangChain 的封装接口,完成了从 PDF 读取、文本分割、向量化到向量库存储的完整 RAG 索引构建流程。LangChain 的 Chroma 类提供了便捷的 add_documents 和 similarity_search 等方法,让我们无需关心底层细节就能快速上手。

但在实际开发和运维中,我们往往需要直接操作向量数据库------查看有哪些集合、每个集合有多少条记录、清理过期数据等。这些"管理型"操作如果也通过 LangChain 的封装层来做,就显得有些绕远了。

本文将基于 ChromaDB 原生 Python API,实现几个简单实用的管理工具:列出集合、查看记录数、删除集合。这些工具与 LangChain 的封装层操作的是同一个数据库文件,可以无缝混用。


二、方案分析:为什么需要原生 API?

2.1 LangChain 封装 vs 原生 API 的关系

LangChain 的 Chroma 类本质上是对 chromadb 原生库的薄封装。两者操作的是同一个持久化目录,可以互相访问对方写入的数据:

复制代码
LangChain 封装层(之前代码)
    ↓ 底层调用
原生 chromadb(本次代码)
    ↓ 操作
磁盘文件(./chroma_langchain_db)
维度 LangChain 封装 原生 chromadb
定位 面向 RAG 应用开发,提供与 LLM 链式集成的便捷接口 面向数据库管理,提供更细粒度的操作能力
代码量 少,一行 add_documents 完成向量化+存储 多,需要手动处理客户端、集合、嵌入等
灵活性 受限于 LangChain 的抽象设计 完全暴露 ChromaDB 的全部能力
适用场景 快速构建检索链路 数据库运维、调试、管理工具开发

2.2 ChromaDB 核心概念映射

理解原生 API 前,先厘清 ChromaDB 的核心概念与关系型数据库的类比:

ChromaDB 概念 关系型数据库类比 说明
Client 数据库连接 连接到一个 Chroma 数据库实例
Collection 表(Table) 存储一组相关的向量和文档
Document 行(Row) 一条记录,包含文本、向量、元数据
embedding_function 索引规则 定义如何将文本转换为向量

三、实操步骤:管理工具的实现

3.1 环境准备

确保已安装原生 chromadb 库(LangChain 的依赖通常已包含,但建议显式安装):

bash 复制代码
uv add chromadb
# 或 pip install chromadb

3.2 工具一:列出所有集合

连接持久化数据库,遍历所有集合并输出名称和记录数:

python 复制代码
import chromadb


def list_collections(db_path: str):
    """
    列出向量库中的所有集合及其记录数。
    
    Args:
        db_path: ChromaDB 持久化目录路径(与 LangChain 的 persist_directory 对应)
    """
    client = chromadb.PersistentClient(db_path)   # 连接到磁盘上的数据库
    collections = client.list_collections()        # 获取所有集合对象
    
    print(f"ChromaDB 向量库 {db_path} 共有 {len(collections)} 个 collection")
    for i, collection in enumerate(collections):
        print(f"  Collection {i + 1}: {collection.name},共有 {collection.count()} 条记录")


# 查看之前 LangChain 代码创建的集合
list_collections("./chroma_langchain_db")

输出示例:

复制代码
ChromaDB 向量库 ./chroma_langchain_db 共有 1 个 collection
  Collection 1: example_collection,共有 516 条记录

关键 API 解析:

  • PersistentClient(path):连接到磁盘上的持久化数据库,与 LangChain 中 persist_directory 参数对应的是同一个路径;
  • list_collections():返回所有集合对象(注意返回的是对象列表,而非仅名称列表);
  • collection.count():返回该集合中的文档(向量)数量。

3.3 工具二:删除指定集合

清理不再需要的集合,释放磁盘空间:

python 复制代码
def delete_collection(db_path: str, collection_name: str):
    """
    删除指定名称的集合及其所有记录。
    
    Args:
        db_path: ChromaDB 持久化目录路径
        collection_name: 要删除的集合名称
    """
    try:
        client = chromadb.PersistentClient(db_path)
        client.delete_collection(collection_name)
        print(f"✅ Collection '{collection_name}' 及其所有记录已删除")
    except Exception as e:
        print(f"❌ 删除 Collection '{collection_name}' 失败:{e}")


# 使用示例
delete_collection("./chroma_langchain_db", "example_collection")

异常处理说明:

  • 若集合不存在,delete_collection 会抛出异常,需用 try-except 捕获;
  • 删除操作不可逆,集合内的所有向量、文档和元数据将一并清除。

四、验证效果:封装层与原生 API 的混用

以下代码演示了 LangChain 封装与原生 API 操作同一数据库的兼容性:

python 复制代码
from langchain_chroma import Chroma
from langchain_ollama import OllamaEmbeddings
import chromadb

# 1. 用 LangChain 封装层写入数据
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vector_store = Chroma(
    collection_name="hybrid_test",
    embedding_function=embeddings,
    persist_directory="./chroma_langchain_db"
)

from langchain_core.documents import Document
vector_store.add_documents([
    Document(page_content="Hello from LangChain", metadata={"source": "test"})
])

# 2. 用原生 API 读取并验证
client = chromadb.PersistentClient("./chroma_langchain_db")
collection = client.get_collection("hybrid_test")
print(f"通过原生 API 读取:{collection.name} 有 {collection.count()} 条记录")
# 输出:通过原生 API 读取:hybrid_test 有 1 条记录

# 3. 用原生 API 删除
client.delete_collection("hybrid_test")
print("已清理测试数据")

验证结论: LangChain 封装层与原生 chromadb 操作的是同一个底层存储,数据完全互通,可以根据场景灵活选择接口层级。


五、总结

本文实现了两个最基础的 ChromaDB 管理工具------列集合 和删集合 。它们的意义不仅在于功能本身,更在于建立一种认知:LangChain 是便捷的封装,但不应成为理解的屏障。当需要调试、运维或实现框架未覆盖的功能时,直接操作原生 API 是更直接、更可控的选择。

后续可以基于此扩展更多管理功能,如:

  • 按条件查询集合内的具体文档内容
  • 批量更新文档的元数据
  • 导出/导入集合数据
  • 监控集合的存储占用和索引性能

六、参考文献

  1. Chroma 官方文档 - Persistent Client
  2. Chroma 官方文档 - List Collections
  3. LangChain Chroma 集成文档
相关推荐
sbjdhjd1 小时前
从签名重放到 Agent Harness:一堂安全课程如何把前端逆向、MCP 与工程约束串起来
网络安全·ai·github·agent·webshell·mcp·harness
滴啦嘟啦哒2 小时前
【具身笔记】【π0.5 微调与仿真】五、在MuJoCo中实现可视化仿真
笔记·python·vla·具身
奇牙coding2 小时前
Codex CLI 升级后多文件编辑静默失效:config.yaml 枚举变更排查与修复指南
java·前端·javascript·ai
全栈练习生2 小时前
AI安全与红队测试
python·ai
费曼学习法2 小时前
把「发送成功」当「送达」?我排查 IM 长消息被静默吞掉的完整过程
python·ai编程·自动化运维
鸽鸽程序猿2 小时前
【项目】【在线判题系统】b端题目增删改
开发语言·python
NetX行者2 小时前
Python 工程化入门:从脚本到规范的 Python 项目结构
网络·python
七夜zippoe2 小时前
Spring AI 是什么?Java 工程师的 AI 开发第一站
java·人工智能·spring·ai·开发
海带紫菜菠萝汤2 小时前
PostgreSQL 19 延期一个月:AI 把找 bug 变便宜了,修 bug 还是人工价
人工智能·ai·程序员·架构·大模型
MasonYyp2 小时前
asyncio并发协程
python