Chroma 教程

版本那些事

🎉摘要:本文整理Chromadb 1.5.9从0.x升级至1.x时需注意的关键变化:核心由Rust重写、鉴权移除、集合命名严格、存储不兼容、add/upsert/update行为差异、默认不返回嵌入向量、自动持久化及多租户默认开启等,避免数据迁移与接口调用中的隐蔽错误。

写这份笔记时是 chromadb 1.5.9。

几个版本相关的点,看到老教程时要留个心眼:

1.0.0(正式版2025年3月,预发布版4月)

核心服务端由Python改为Rust重写,读写性能、并发稳定性大幅提升;

破坏性变更:内置鉴权功能被移除,旧鉴权环境变量全部失效:

CHROMA_SERVER_AUTHN_PROVIDER、CHROMA_SERVER_AUTHN_CREDENTIALS、CHROMA_AUTH_TOKEN_TRANSPORT_HEADER

1.0+ 版本如果需要接口鉴权,必须在反向代理/网关层自行实现(Nginx、Traefik等)(第 10 章给方案)。


1.1.13 之前

在 1.1.13 版本之前,get_collection() 方法不会自动恢复你建集合时用的嵌入函数,得手动再传一遍。

现在新版本会把它存在服务端配置里,客户端自动解析。

你要是还在老版本上,记得每次  get_collection(name=..., embedding_function=ef) 传递 embedding_function 嵌入函数。


集合命名规则

在 1.x 里校验得很严,长度必须 3~512,只能含 a-zA-Z0-9._-,且首尾必须是字母或数字。我第一次写 create_collection("t1") 直接被拒:

import chromadb

client = chromadb.EphemeralClient()
col = client.create_collection("t1")

运行示例,输出如下:

chromadb.errors.InvalidArgumentError: Validation error: 
name: Expected a name containing 3-512 characters from [a-zA-Z0-9._-], 
starting and ending with a character in [a-zA-Z0-9]. Got: t1


存储格式完全不兼容

1.x(含1.5.9)依然存在 chroma.sqlite3 文件,但它只存元数据、集合信息、文档ID、metadata、全文索引;向量与 HNSW 索引保存在独立的 UUID 命名目录下。

0.x 版本的 chroma.sqlite3 的表结构完全不一样,不能直接拷贝给1.x 打开,没有自动原地迁移。旧数据只能通过旧版本客户端全量 get 读出,再用新版客户端 add/upsert 导入。

注意:不要手动改 chroma.sqlite3、不要直接用 sqlite 工具删记录。 Rust 内核会维护 sqlite 与磁盘上向量段文件的一致性;手动修改 sqlite 会导致元数据与向量文件脱节,集合直接损坏、查不出来。  


add /upsert/update 的行为差异(非常容易踩坑)

  • add():如果 ID 已存在 → 静默丢弃,不报异常,不会覆盖,日志也不一定提示;

  • update():如果 ID 不存在 → 直接忽略,不会新增;

  • upsert():存在就更新,不存在就新增; 老教程很多直接用 add 做幂等写入,升级 1.x 后会出现 “更新无效” 的隐蔽 bug,幂等场景一律用 upsert。


get () /query () 默认不返回 embeddings

老版本默认带回向量;1.x include 默认只包含 metadatas, documents,embeddings 需要显式写:

client.get(ids=["q1"], include=["embeddings", "documents", "metadatas"])

否则 embeddings 字段是 None,调试半天找不到向量。


PersistentClient 自动持久化,不再需要 .persist ()

0.x 需要手动调用 client.persist() 持久化;1.x Rust 内核自动持久化,.persist() 方法已经被移除,抄老代码会直接抛方法不存在异常。


多租户、多数据库默认开启

该架构底层 0.x 就存在,但 1.x 远程 HTTP 服务场景必须重视。

服务初始化后自带预置:default_tenant、default_database。 HttpClient 连接远端 Chroma 时,即使你不写 tenant/database 参数,客户端也会默认传入 default_tenant + default_database。

如果集合是创建在其他自定义租户/数据库下,两边不匹配就会出现“集合明明存在但 get_collection 找不到”的隐蔽问题。

很多 0.x 老教程完全不提租户与数据库,远程部署时极易踩坑。 

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号