游乐游手机版
首页/AI热点日报/热点详情

RAG落地不可或缺的一款开源AI原生向量数据库Chroma

类型:热点整理2026-07-09
在AI应用迅速普及的今天,向量数据库正成为支撑RAG技术落地的基础设施之一。今天我们来重点聊一聊Chroma——这款轻量级、上手门槛低、同时又不失性能的AI原生向量数据库。从核心概念、安装配置到增删改查操作,再到一个完整的实战案例,希望这篇文章能为打算落地RAG方案的读者提供一份清晰的参考。 一、C

在AI应用迅速普及的今天,向量数据库正成为支撑RAG技术落地的基础设施之一。今天我们来重点聊一聊Chroma——这款轻量级、上手门槛低、同时又不失性能的AI原生向量数据库。从核心概念、安装配置到增删改查操作,再到一个完整的实战案例,希望这篇文章能为打算落地RAG方案的读者提供一份清晰的参考。

一、Chroma 核心概念与优势

1. 什么是 Chroma?

Chroma 是一款专注于高维向量数据存储与检索的开源数据库。它的核心能力就在于语义相似性搜索——说白了,就是把文本、图像等数据转成向量后,快速找到和查询最相似的匹配项。这在RAG(检索增强生成)场景下尤为关键,大模型需要从外部知识库中检索上下文,搞懂哪些内容最相关。和传统按关键词匹配的数据库不同,Chroma 用的是向量距离(比如余弦相似度、欧氏距离)来衡量数据之间的关联度。

GitHub地址和官方文档这里就不列了,直接在搜索引擎里就能找到。

2. 核心优势

  • 轻量嵌入,上手门槛低:以 Python/JS 包的形式嵌入到代码中,不需要额外部署独立的数据库服务,适合快速验证原型。
  • 集成灵活:支持接入自定义的嵌入模型(如 OpenAI、HuggingFace 上的模型),同时兼容 LangChain 等主流框架。
  • 查询效率高:底层采用 HNSW 算法构建索引,检索百万级向量可以做到毫秒级响应,在实际生产中也完全能打。
  • 双模式运行:内存模式适合调试和实验,持久化模式则能将数据落盘,满足生产环境的要求。

二、安装和基础配置

1、安装Chroma

Chroma 同时支持 Windows 和 Ubuntu 操作系统,前提是 Python 版本不低于 3.9。

创建虚拟环境以及安装:

#创建虚拟环境
conda create -n chromadb python==3.10

#激活
conda activate chromadb

#安装chromadb
pip install chromadb

这里需要特别说明一点:Chroma 默认是一个本地嵌入式数据库,本身并不像 PostgreSQL 那样以客户端-服务器模式原生支持远程访问。但官方也提供了客户端-服务器模式(Client-Server Mode)。启动服务端的方式如下:

#服务器端启动,默认端口号8000
chroma run --path /db_path

2、初始化客户端

内存模式(调试、实验场景)

import chromadb
client = chromadb.Client()

持久化模式(生产环境):创建时可以指定本地的存储路径:

import chromadb

# 数据保存至本地目录,path填写绝对路径
client = chromadb.PersistentClient(path="/path/to/sa ve")

Client-Server模式:前面两种都属于本地模式,服务端和客户端必须在同一台机器上。而 C/S 模式下,两者可以独立部署,通过 HttpClient 来访问:

import chromadb
chroma_client = chromadb.HttpClient(host='localhost', port=8000)

三、增删改查操作

1. 创建集合(Collection)

集合是 Chroma 里组织数据的基本单元,可以理解成传统数据库中的一张表。这里的集合名称有严格约束:

  • 名称长度需在 3 到 63 个字符之间。
  • 必须以小写字母或数字开头和结尾,中间可以包含点、破折号、下划线。
  • 不能包含两个连续的点。
  • 不能是有效的 IP 地址。

Chroma 集合通过一个名称加上一个可选的嵌入函数来创建。需要注意,如果提供了嵌入函数,之后每次获取集合时都必须带上它。

# 创建
collection = client.create_collection(name="my_collection", embedding_function=emb_fn)

# 获取
collection = client.get_collection(name="my_collection", embedding_function=emb_fn)

# 若没有则创建,若有则获取
collection = chroma_client.get_or_create_collection(name="my_collection2")

如果没有显式提供嵌入函数,Chroma 会使用默认的 sentence transformer 模型 all-MiniLM-L6-v2——但这个模型主要针对英文场景,所以实际项目中一般会自定义嵌入函数:

import chromadb
from sentence_transformers import SentenceTransformer

class SentenceTransformerEmbeddingFunction:
    def __init__(self, model_path: str, device: str = "cuda"):
        self.model = SentenceTransformer(model_path, device=device)
    def __call__(self, input: list[str]) -> list[list[float]]:
        if isinstance(input, str):
            input = [input]
        return self.model.encode(input, convert_to_numpy=True).tolist()

# 创建/加载集合(含自定义嵌入函数)
embed_model = SentenceTransformerEmbeddingFunction(
    model_path=r"D:\Test\LLM\Train\testllm\llm\BAAI\bge-m3",
    device="cuda"  # 无 GPU 改为 "cpu"
)
# 创建客户端和集合
client = chromadb.Client()
collection = client.create_collection("my_knowledge_base", 
                                      metadata={"hnsw:space": "cosine"},
                                      embedding_function=embed_model)

创建集合时,可以配置如下参数:

  • name:集合名称,必填项。
  • embedding_function:指定嵌入函数,不填则使用默认嵌入模型。
  • metadata:元数据,比如索引方式等,非必填。
from datetime import datetime
collection = client.create_collection(
    name="my_collection", 
    embedding_function=emb_fn,
    metadata={
        "description": "my first Chroma collection",
        "created": str(datetime.now())
    }  
)

集合还有几个常用的方法:

  • peek() - 返回集合中前 10 个项目。
  • count() - 返回集合中的项目总数。
  • modify() - 重命名集合。
collection.peek() 
collection.count() 
collection.modify(name="new_name")

2、写入数据

写入时可以指定以下参数:

  • documents:原始的文本块。
  • metadatas:描述文本块的元数据,键值对形式。
  • ids:文本块的唯一标识,每个文档必须有一个唯一 ID。如果重复添加相同的 ID,只有第一次写入的值会被保留。
  • embeddings:如果文本已经完成向量化,可以直接写入向量结果。如果不填,写入时会用指定的(或默认的)嵌入函数对 documents 做向量化。
collection.add(
    documents=["lorem ipsum...", "doc2", "doc3", ...],
    metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    ids=["id1", "id2", "id3", ...])

或者:

collection.add(
    embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
    metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    ids=["id1", "id2", "id3", ...])

3、修改数据

这里需要提供 ids(文本唯一标识):

collection.update(
    ids=["doc1"],  # 使用已存在的ID
    documents=["RAG是一种检索增强生成技术222"])

4、更新插入方法

Chroma 还支持 upsert(更新插入)操作——如果项目已经存在就更新它,不存在则新建:

collection.upsert(
    ids=["id1", "id2", "id3", ...],
    embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
    metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    documents=["doc1", "doc2", "doc3", ...],
)

5、删除数据

Chroma 支持通过 ID 从集合中删除项目,对应的嵌入、文档和元数据都会被一并清除。同时也支持 where 过滤器。如果没有提供 ID,它会删除所有满足 where 筛选条件的项目。

# 提供ids
collection.delete(ids=["doc1"])

# where 条件删除
collection.delete(
    ids=["id1", "id2", "id3",...],
    where={"chapter": "20"}
)

6、查询数据

(1)查询所有数据

all_docs = collection.get()
print("集合中所有文档:", all_docs)

(2)根据 ids 查询

collection.get(ids=["id1", "id2", "id3", ...],
               where={"style": "style1"})

(3)查询嵌入

使用 query 方法可以进行多种方式的查询,比如指定 query_embedding:

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    n_results=10,
    where={"metadata_field": "is_equal_to_this"},
    where_document={"$contains":"search_string"})
  • 查询会返回 n_results 个最接近每个查询嵌入的结果,按相关性排序。
  • where 过滤字典可以基于 metadata 进行筛选。
  • where_document 过滤字典可以根据文档内容做过滤。

(4)查询相似文档

也可以直接通过 query_texts 来查询相似文本。Chroma 会先用集合的嵌入函数把每个查询文本转化为向量,再用生成的向量执行搜索。

# 查询相似文档
results = collection.query(
    query_texts=["什么是RAG技术?"],
    n_results=3)
print("查询的结果",results)

查询结果配置

  • 使用 get 或 query 时,可以通过 include 参数指定要返回的数据类型,包括 embeddings、documents、metadatas,include 可以传多个值。
  • 对于 query,默认会返回 distances(距离得分)。
  • 出于性能考虑,embeddings 默认不返回(显示为 None),如果想拿到,在 include 里加上 embeddings 即可。
  • ID 始终会返回。
  • 返回值中会有一个 included 参数,表明本次返回了哪些数据类型。
  • embeddings 以二维 NumPy 数组形式返回。
# Only get documents and ids
collection.get(
    include=["documents"])

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    include=["documents"])

查询结果示例:

{
'ids': [['doc1', 'doc3', 'doc2']], 
'embeddings': None, 
'documents': [['RAG是一种检索增强生成技术', '三英战吕布', '向量数据库存储文档的嵌入表示']], 
'uris': None,
'included': ['metadatas', 'documents', 'distances'], 
'data': None, 
'metadatas': [[{'source': 'tech_doc'}, {'source': 'tutorial1'}, {'source': 'tutorial'}]], 
'distances': [[0.2373753786087036, 0.7460092902183533, 0.7651787400245667]]
}

四、实战操作

下面实战一把:把一批数据插入到向量数据库,然后基于一个问题从中检索出最相似的文档。

1、安装包

pip install sentence_transformers
pip install modelscope

2、下载Embedding模型到本地

#模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('BAAI/bge-m3',
                              cache_dir=r"D:\Test\LLM\Train\testllm\llm")

3、核心逻辑:写入数据和查询相似度

import chromadb
from sentence_transformers import SentenceTransformer

class SentenceTransformerEmbeddingFunction:
    def __init__(self, model_path: str, device: str = "cuda"):
        self.model = SentenceTransformer(model_path, device=device)
    def __call__(self, input: list[str]) -> list[list[float]]:
        if isinstance(input, str):
            input = [input]
        return self.model.encode(input, convert_to_numpy=True).tolist()

# 创建/加载集合(含自定义嵌入函数)
embed_model = SentenceTransformerEmbeddingFunction(
    model_path=r"D:\Test\LLM\Train\testllm\llm\BAAI\bge-m3",
    device="cpu"  # 无 GPU 改为 "cpu",有则为cuda
)

# 创建客户端和集合
client = chromadb.PersistentClient(path=r"D:\Test\LLM\Train\chromadb_test\chroma_data")
collection = client.get_or_create_collection("my_knowledge_base",
                                      metadata={"hnsw:space": "cosine"},
                                      embedding_function=embed_model)

# 添加文档
collection.add(
    documents=[ "向量数据库存储文档的嵌入表示", "三英战吕布", "RAG是一种检索增强生成技术"],
    metadatas=[{"source": "tech_doc"}, {"source": "tutorial"}, {"source": "tutorial1"}],
    ids=["doc1", "doc2", "doc3"]
)

# 查询相似文档
results = collection.query(
    query_texts=["什么是RAG技术?"],
    n_results=3)
print("查询的结果",results)

执行返回结果:

查询的结果 
{
'ids': [['doc3', 'doc2', 'doc1']], 
'embeddings': None, 
'documents': [['RAG是一种检索增强生成技术', '三英战吕布', '向量数据库存储文档的嵌入表示']], 
'uris': None, 
'included': ['metadatas', 'documents', 'distances'], 
'data': None, 
'metadatas': [[{'source': 'tutorial1'}, {'source': 'tutorial'}, {'source': 'tech_doc'}]], 
'distances': [[0.2373753786087036, 0.7460092902183533, 0.7651787400245667]]
}

从返回结果来看,distances 是从小到大排列的,值越小表明文档与查询的相似度越高。所以第一条数据(doc3,关于RAG的解释)与问题“什么是RAG技术?”最为相似。

来源:https://www.53ai.com/news/RAG/2025042497604.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。