文章目录
-
- 一、Chroma概述
-
- [1.1 Chroma介绍](#1.1 Chroma介绍)
- [1.2 为什么选择 Chroma?](#1.2 为什么选择 Chroma?)
- [1.3 核心概念理解](#1.3 核心概念理解)
- [1.4 Chroma 在生产环境的表现如何?](#1.4 Chroma 在生产环境的表现如何?)
- [二、 基本使用](#二、 基本使用)
-
- [2.1 Chroma的安装](#2.1 Chroma的安装)
- [2.2 快速上手](#2.2 快速上手)
- [2.3 创建 Collection](#2.3 创建 Collection)
- [2.4 查询(query)](#2.4 查询(query))
- [2.5 高级过滤(where)](#2.5 高级过滤(where))
- [2.6 更新与删除](#2.6 更新与删除)
- [2.7 获取现有数据(get)](#2.7 获取现有数据(get))
- [三、 进阶操作](#三、 进阶操作)
-
- [3.1 指定嵌入模型](#3.1 指定嵌入模型)
- [3.2 持久化存储](#3.2 持久化存储)
- [3.3 连接 LangChain](#3.3 连接 LangChain)
一、Chroma概述
1.1 Chroma介绍
Chroma 是一个轻量级、开源、专为 AI 应用设计的向量数据库,主打"开发者友好"和"快速集成"。它被广泛用于 RAG(检索增强生成)、语义搜索、推荐系统等场景,尤其适合与 LlamaIndex、LangChain 等框架配合使用。
官方资源:
1.2 为什么选择 Chroma?
- 极简:不需要配置服务器、Docker 或云账号。几行代码即可完成向量化存储与检索 。
- 开发模式友好:默认将数据保存在本地文件中,重启电脑数据不丢。
- 生态集成:与 LangChain、LlamaIndex 等 AI 框架无缝集成。
- 自带 Embedding:如果不指定,它会自动使用默认的嵌入模型把文本转向量,对新手极度友好。
- 原生支持多模态:文本、图像、音频 embedding 均可存储。
- 元数据过滤:支持按标签、时间、来源等条件筛选。
- 开源免费:Apache 2.0 许可,无商业限制
局限: 不适合超大规模(>1亿向量),无分布式集群
1.3 核心概念理解
1、Client(客户端)
chromadb.Client():默认使用 内存存储(进程内,重启丢失)chromadb.HttpClient(host="...", port=8000):连接远程服务
2、Collection(集合)
- 类似传统数据库的"表"
- 每个 collection 有:
- 名称(唯一)
- Embedding 函数(可选)
- 向量维度(自动推断或指定)
- 距离度量方式(
l2,ip,cosine)
3、Document / Embedding / Metadata / ID
| 字段 | 类型 | 说明 |
|---|---|---|
documents |
List[str] | 原始文本(用于自动生成 embedding) |
embeddings |
List[List[float]] | 手动传入的向量(若提供,则忽略 documents) |
metadatas |
List[Dict] | 附加信息(如来源、作者、时间),用于搜索时的精准过滤。 |
ids |
List[str] | 唯一标识符(必须提供),如果重复添加会报错。 |
注意 :
documents和embeddings二选一,不能同时为空。
1.4 Chroma 在生产环境的表现如何?
- 优点:单机性能极佳。
- 缺点 :它是为单机 设计的。如果你需要分布式(比如 10 台服务器组成一个集群,存 PB 级数据),Chroma 可能扛不住,建议换用 Milvus 或 Qdrant。
- 适用场景:个人项目、企业内部知识库(数据量在百万级到千万级向量以内)。
二、 基本使用
2.1 Chroma的安装
bash
pip install chromadb
(注:如果你想用 Chroma 的服务器模式,还需要 pip install chromadb-client)
2.2 快速上手
案例1:我们创建一个集合,存几句话,然后进行语义搜索。
python
import chromadb
# 1. 创建客户端 (默认在内存中,也可以指定路径持久化到磁盘)
# 持久化模式:client = chromadb.PersistentClient(path="./my_chroma_data")
client = chromadb.Client()
# 2. 创建或获取一个集合
collection = client.get_or_create_collection(name="my_documents")
# 3. 添加数据
# ids: 必须唯一
# documents: 原始文本 (Chroma 会自动帮你调用模型把它转为向量)
# metadatas: 附带的信息 (比如分类、来源),用于过滤
collection.add(
documents=[
"谷歌发布了新的 AI 模型",
"苹果公司今天举行了秋季发布会",
"今天的天气真不错,适合去公园"
],
metadatas=[{"source": "tech"}, {"source": "tech"}, {"source": "life"}],
ids=["doc1", "doc2", "doc3"]
)
# 4. 查询 (语义搜索)
results = collection.query(
query_texts=["手机发布了什么新产品?"], # 用户的问题
n_results=2 # 返回最相似的前2条
)
print(results)
输出结果解析:会发现,虽然你问的是"手机",但 Chroma 智能地匹配到了"苹果公司...发布会",因为它们在语义上最接近。
案例2:
python
import chromadb
from chromadb.utils import embedding_functions
# 1. 初始化客户端(内存模式)
client = chromadb.Client()
# 2. 创建集合(自动处理 embedding)
collection = client.create_collection(
name="docs",
embedding_function=embedding_functions.SentenceTransformerEmbeddingFunction(
model_name="all-MiniLM-L6-v2"
)
)
# 3. 添加文档(自动向量化)
collection.add(
documents=["Hello, world!", "How are you?", "AI is amazing!"],
metadatas=[{"source": "greeting"}, {"source": "question"}, {"source": "opinion"}],
ids=["id1", "id2", "id3"]
)
# 4. 语义搜索
results = collection.query(
query_texts=["Tell me about AI"],
n_results=2
)
print(results['documents']) # 返回最相关的句子
输出:
[['AI is amazing!', 'Hello, world!']]
2.3 创建 Collection
python
collection = client.create_collection(
name="my_docs",
metadata={"hnsw:space": "cosine"}, # 距离函数:cosine / l2 / ip
embedding_function=embedding_functions.DefaultEmbeddingFunction() # 默认用 all-MiniLM-L6-v2
)
常用 embedding 函数:
DefaultEmbeddingFunction()→all-MiniLM-L6-v2SentenceTransformerEmbeddingFunction("paraphrase-multilingual-MiniLM-L12-v2")→ 多语言OpenAIEmbeddingFunction(api_key="...", model_name="text-embedding-3-small")
如何清空 collection?
python
client.delete_collection("my_docs")
# 或(不推荐)
collection.delete(where={"$and": []}) # 删除所有
2.4 查询(query)
1、基础语义搜索
python
results = collection.query(
query_texts=["What is Chroma?"],
n_results=3,
where={"category": "tool"} # 元数据过滤
)
2、返回字段说明
python
{
'ids': [['doc2']],
'distances': [[0.35]], # 越小越相似
'metadatas': [[{'category': 'tool', 'year': 2025}]],
'documents': [['Chroma is easy to use.']]
}
2.5 高级过滤(where)
python
# 等值
where={"source": "blog"}
# 范围(仅数值)
where={"year": {"$gte": 2024}}
# 逻辑组合
where={"$and": [{"category": "tool"}, {"year": {"$gt": 2023}}]}
注意:Chroma 的 where 语法类似 MongoDB,但功能有限(不支持全文搜索)。
2.6 更新与删除
python
# 更新(必须提供完整新值)
collection.update(
ids=["doc1"],
documents=["Python is awesome!"],
metadatas=[{"category": "programming", "updated": True}]
)
# 删除
collection.delete(ids=["doc1"])
# 或按条件删除(实验性)
collection.delete(where={"category": "deprecated"})
2.7 获取现有数据(get)
python
# 获取全部
all_data = collection.get()
# 按 ID 获取
data = collection.get(ids=["doc2"])
# 按元数据过滤
data = collection.get(where={"year": 2025})
三、 进阶操作
3.1 指定嵌入模型
虽然 Chroma 有默认模型,但在中文环境下,或者为了更高的精度,我们通常指定自己的模型(比如 OpenAI 或 HuggingFace 的中文模型)。
python
import chromadb
from chromadb.utils import embedding_functions
# 使用 OpenAI 的 embedding (需要 API Key)
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="你的-api-key",
model_name="text-embedding-3-small"
)
# 创建集合时指定 embedding 函数
collection = client.get_or_create_collection(
name="my_openai_collection",
embedding_function=openai_ef
)
3.2 持久化存储
默认的 chromadb.Client() 是存在内存里的,程序一关数据就没了。在实际项目中,你需要持久化。
方法:使用 PersistentClient
python
import chromadb
# 指定一个文件夹路径
client = chromadb.PersistentClient(path="/path/to/save_data")
# 后续操作完全一样,数据会自动保存到磁盘的 /path/to/save_data 目录下
# 下次启动程序时,只要指向这个路径,数据就会自动加载
3.3 连接 LangChain
这是 Chroma 最常用的用法之一。
python
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 1. 准备文本
with open("my_book.txt") as f:
raw_text = f.read()
# 2. 切分文本
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
splits = text_splitter.split_text(raw_text)
# 3. 直接存入 Chroma
vectordb = Chroma.from_texts(
texts=splits,
embedding=OpenAIEmbeddings(), # 指定 OpenAI
persist_directory="./chroma_db" # 持久化路径
)
# 4. 相似度搜索
docs = vectordb.similarity_search("这本书讲了什么?")
print(docs[0].page_content)