一文掌握向量数据库Chroma的详细使用

文章目录

    • 一、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] 唯一标识符(必须提供),如果重复添加会报错。

注意documentsembeddings 二选一,不能同时为空。

1.4 Chroma 在生产环境的表现如何?

  • 优点:单机性能极佳。
  • 缺点 :它是为单机 设计的。如果你需要分布式(比如 10 台服务器组成一个集群,存 PB 级数据),Chroma 可能扛不住,建议换用 MilvusQdrant
  • 适用场景:个人项目、企业内部知识库(数据量在百万级到千万级向量以内)。

二、 基本使用

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-v2
  • SentenceTransformerEmbeddingFunction("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)
相关推荐
百结21435 分钟前
Mysql数据库操作
数据库·mysql·oracle
keep one's resolveY1 小时前
时区问题解决
数据库
Leinwin1 小时前
OpenClaw 多 Agent 协作框架的并发限制与企业化规避方案痛点直击
java·运维·数据库
qq_417695051 小时前
机器学习与人工智能
jvm·数据库·python
漫随流水1 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
ego.iblacat1 小时前
MySQL 服务基础
数据库·mysql
yy我不解释2 小时前
关于comfyui的mmaudio音频生成插件时时间不一致问题(一)
python·ai作画·音视频·comfyui
Maverick063 小时前
Oracle Redo 日志操作手册
数据库·oracle
紫丁香3 小时前
AutoGen详解一
后端·python·flask
FreakStudio3 小时前
不用费劲编译ulab了!纯Mpy矩阵micronumpy库,单片机直接跑
python·嵌入式·边缘计算·电子diy