一文掌握向量数据库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)
相关推荐
虹科网络安全5 小时前
艾体宝洞察 | Redis vs Valkey:解决 ElastiCache 的无序扩张与资源效率问题
数据库·redis·spring
xu_ws5 小时前
2G服务器优化MySQL内存配置指南
数据库·mysql
TG:@yunlaoda360 云老大5 小时前
华为云国际站代理商的ESW主要有什么作用呢?
网络·数据库·华为云
漂亮的小碎步丶6 小时前
【8】分库分表与百亿级话单数据处理详解
数据库
计算机毕设指导66 小时前
基于微信小程序+django连锁火锅智慧餐饮管理系统【源码文末联系】
java·后端·python·mysql·微信小程序·小程序·django
colourmind6 小时前
记录一次vscode debug conda python 使用报错问题排查
vscode·python·conda
智航GIS6 小时前
2.1 变量与数据类型
开发语言·python
风月歌6 小时前
php医院预约挂号系统小程序源代码(源码+文档+数据库)
数据库·微信小程序·小程序·毕业设计·php·源码