随着大型语言模型(LLM) 及其应用的兴起,集成工具、LLMOps 框架和向量数据库的热度也随之上升。这是因为使用 LLM 的工作方式与传统机器学习模型不同,需要采用另一套方法。
支持 LLM 的核心技术之一是向量嵌入。计算机无法直接理解文本,但嵌入可以将文本表示为数值。所有用户提供的文本都会被转换为嵌入,然后用于生成回复。
将文本转换为嵌入是一个耗时的过程。为避免重复计算,我们使用专门为高效存储与检索向量嵌入而设计的向量数据库。
在本教程中,我将带您了解向量存储与 Chroma DB——一个用于存储和管理嵌入的开源数据库。您将学习如何添加和删除文档、执行相似度搜索,以及将文本转换为嵌入。
作者供图
要点速览
ChromaDB 是一个开源向量数据库,用于存储和检索嵌入——使用 pip install chromadb 安装
本地持久化使用 chromadb.PersistentClient(path="./chroma_db"),内存测试使用 chromadb.EphemeralClient()
先创建集合(collection) (类似表),再用 add() 添加文档,可选附带元数据和 ID
使用 collection.query(query_texts=["..."], n_results=5) 进行语义相似度搜索
可接入任意嵌入模型——OpenAI、HuggingFace、Google Gemini,或自定义函数
ChromaDB 广泛用作 RAG(检索增强生成) 流水线中的向量存储
什么是向量存储?
向量存储是为高效存储与检索向量嵌入而专门设计的数据库。它们之所以必要,是因为像 SQL 这样的传统数据库并未针对大规模向量数据的存储和查询进行优化。
嵌入会在高维空间中以数值向量的形式表示数据(通常是文本等非结构化数据)。传统关系型数据库并不适合存储和搜索这些向量表示。
向量存储可以对向量进行索引,并使用相似度算法快速搜索相似向量,使应用能够在给定目标向量查询时找到相关向量。
例如,在个性化聊天机器人的场景中,用户向生成式 AI 模型输入提示。模型使用相似度搜索算法,在文档集合中查找相似文本。得到的信息将用于生成高度个性化且准确的回复。通过向量存储中的嵌入与向量索引 ,这种信息检索成为可能。
什么是 Chroma DB?
Chroma DB 是一个开源向量存储,用于存储和检索向量嵌入。其主要用途是保存嵌入及其元数据,供大型语言模型后续使用。此外,它也可用于文本数据上的语义搜索引擎。
Chroma DB 的特性
简洁而强大:
一条命令安装:pip install chromadb。
Python SDK 快速上手,便于无缝集成与快速搭建。
功能完备:
全面的检索功能 :支持向量搜索、全文搜索、文档存储、元数据过滤和多模态检索。
高可扩展性 :本地持久化使用 SQLite,并支持客户端-服务器模式,便于多客户端与生产环境部署。
多语言支持:
提供多种主流语言 SDK,包括 Python 、JavaScript/TypeScript 、Ruby 、PHP 和 Java 。
集成完善:
与 HuggingFace、OpenAI、Google 等的嵌入模型原生集成。
兼容 Langchain 与 LlamaIndex,更多工具集成即将推出。
开源:
速度与易用:
专注简洁与高速,旨在在保证易用的同时,让分析与检索更高效。
Chroma DB 提供自托管服务器选项。如果您需要托管式或云原生的向量数据库,可参考我们的指南:Pinecone 向量数据库实战 或 Weaviate 作为替代方案。
图片来源:Chroma
Chroma DB 如何工作?
首先,创建一个集合(类似关系型数据库中的表)。默认情况下,Chroma 使用 all-MiniLM-L6-v2 将文本转换为嵌入,但您可以修改集合以使用其他嵌入模型。
将带有元数据和唯一 ID 的文本文档添加到新建集合中。当集合接收到文本时,会自动将其转换为嵌入。
通过文本或嵌入来查询集合,以获取相似文档。您也可以基于元数据过滤结果。
先决条件
要跟随本教程,您需要:
Python 3.8+ (为获得最佳 ChromaDB 兼容性,推荐使用 Python 3.11)
pip 包管理器
OpenAI API 密钥 (仅嵌入部分需要;ChromaDB 的核心部分无需密钥即可运行)
SQLite 3.35 或更高版本(内置于 Python 3.11;如果您使用更旧版本且遇到问题,请使用 pip install pysqlite3-binary)
具备 Python 列表和字典的基础知识
开始使用 Chroma DB
本节中,我将创建一个向量数据库,添加集合,向其中加载文本,并运行一次相似度搜索查询。
首先安装 chromadb 和 openai。只有在“嵌入”一节您才需要OpenAI API 密钥 ——以下 ChromaDB 的核心示例不需要。
注意: Chroma 需要 SQLite 3.35 或更高版本。如果出现问题,请升级到 Python 3.11,或安装较旧版本的 chromadb。
!pip install chromadb openai 技术支持
选择客户端模式
ChromaDB 根据您的使用场景提供三种客户端模式:
Client Use case Code EphemeralClient 内存测试;退出即丢失数据 chromadb.EphemeralClient()PersistentClient 本地文件存储;重启后数据仍在 chromadb.PersistentClient(path="./chroma_db")HttpClient 生产环境;连接到正在运行的 ChromaDB 服务器 chromadb.HttpClient(host="localhost", port=8000)
您可以使用 chromadb.EphemeralClient() 创建一个基于内存(临时)的测试数据库。它只在内存中存储数据,程序结束即重置——非常适合快速试验。
在本例中,我将创建一个持久化数据库,存储在 ./chroma_db 目录下。ChromaDB 在持久化模式下使用 SQLite 作为后端存储——DuckDB 后端已在 ChromaDB 0.4.0 中移除。
import chromadb
client = chromadb. PersistentClient( path= "./chroma_db" ) 技术支持
然后,我们将使用客户端创建一个 collection 对象。这类似于在传统数据库中创建表。
collection = client. create_collection( name= "Students" ) 技术支持
要向集合中添加文本,我们将生成关于学生、社团和大学的随机文本。您可以使用 ChatGPT 生成随机文本。
student_info = """
Alexandra Thompson, a 19-year-old computer science sophomore with a 3.7 GPA,
is a member of the programming and chess clubs who enjoys pizza, swimming, and hiking
in her free time in hopes of working at a tech company after graduating from the University of Washington.
"""
club_info = """
The university chess club provides an outlet for students to come together and enjoy playing
the classic strategy game of chess. Members of all skill levels are welcome, from beginners learning
the rules to experienced tournament players. The club typically meets a few times per week to play casual games,
participate in tournaments, analyze famous chess matches, and improve members' skills.
"""
university_info = """
The University of Washington, founded in 1861 in Seattle, is a public research university
with over 45,000 students across three campuses in Seattle, Tacoma, and Bothell.
As the flagship institution of the six public universities in Washington state,
UW encompasses over 500 buildings and 20 million square feet of space,
including one of the largest library systems in the world.
""" 技术支持
现在,我们将使用 add() 函数添加带有元数据和唯一 ID 的文本数据。随后,Chroma 会自动下载 all-MiniLM-L6-v2 模型,将文本转换为嵌入并存储到 "Students" 集合中。
collection. add(
documents = [ student_info, club_info, university_info] ,
metadatas = [ { "source" : "student info" } , { "source" : "club info" } , { 'source' : 'university info' } ] ,
ids = [ "id1" , "id2" , "id3" ]
) 技术支持
要运行相似度搜索,您可以使用 query() 函数并用自然语言提问。它会将查询转换为嵌入,并使用相似度算法生成相似结果。在我们的示例中,它返回了两个相似结果。
results = collection. query(
query_texts= [ "What is the student name?" ] ,
n_results= 2
)
results技术支持
嵌入(Embeddings)
您可以使用嵌入模型列表 中的任意高性能嵌入模型。您甚至可以创建自定义嵌入函数。若想深入了解 OpenAI 的现代引擎,请参阅我们的 text-embedding-3-large 指南。
本节中,我将使用 OpenAI 的 text-embedding-3-small 模型将文本转换为嵌入。这是 OpenAI 推荐用于替代旧版 text-embedding-ada-002 的模型——在基准上表现更好,成本降低 5 倍。
创建 OpenAI 嵌入函数后,您可以添加文本列表以生成嵌入。
了解如何使用 OpenAI 文本嵌入 API 创建文本分类器、信息检索系统和语义相似度检测器。
from chromadb. utils import embedding_functions
openai_ef = embedding_functions. OpenAIEmbeddingFunction(
api_key= "YOUR_OPENAI_API_KEY" ,
model_name= "text-embedding-3-small"
)
students_embeddings = openai_ef( [ student_info, club_info, university_info] )
print ( students_embeddings) 技术支持
[[-0.01015068031847477, 0.0070903063751757145, 0.010579396970570087, -0.04118313640356064, 0.0011583581799641252, 0.026857420802116394,....],]技术支持
与其使用默认嵌入模型,我将把已生成的嵌入直接加载到一个新集合中。
我们将使用 get_or_create_collection() 函数创建一个名为 "Students2" 的新集合。该函数不同于 create_collection(),如果集合已存在则获取,否则创建。
现在我们将把嵌入、文本文档、元数据和 ID 添加到新集合中。
collection2 = client. get_or_create_collection( name= "Students2" )
collection2. add(
embeddings = students_embeddings,
documents = [ student_info, club_info, university_info] ,
metadatas = [ { "source" : "student info" } , { "source" : "club info" } , { 'source' : 'university info' } ] ,
ids = [ "id1" , "id2" , "id3" ]
) 技术支持
还有一种更直接的方法。您可以在创建或访问集合时添加 OpenAI 嵌入函数。除了 OpenAI,您还可以使用 Cohere、Google Gemini、HuggingFace 和 Instructor 模型。
在我们的场景中,添加新文本文档时会调用 OpenAI 嵌入函数,而非默认模型,将文本转换为嵌入。
collection2 = client. get_or_create_collection( name= "Students2" , embedding_function= openai_ef)
collection2. add(
documents = [ student_info, club_info, university_info] ,
metadatas = [ { "source" : "student info" } , { "source" : "club info" } , { 'source' : 'university info' } ] ,
ids = [ "id1" , "id2" , "id3" ]
) 技术支持
让我们在新集合上运行相似查询,看看差异。
results = collection2. query(
query_texts= [ "What is the student name?" ] ,
n_results= 2
)
results技术支持
我们的结果有所改善。现在相似度搜索返回的是关于大学的信息,而不是社团。此外,向量之间的距离比默认嵌入模型更低,这是好事。
过滤查询结果
ChromaDB 支持通过元数据过滤来缩小相似度搜索结果范围。在 query() 中使用带操作符的 where 参数:
results = collection. query(
query_texts= [ "What is the student name?" ] ,
n_results= 2 ,
where= { "source" : "student info" }
)
results = collection. query(
query_texts= [ "university" ] ,
n_results= 5 ,
where= {
"$or" : [
{ "source" : "student info" } ,
{ "source" : "university info" }
]
}
) 技术支持
支持的操作符:$eq、$ne、$gt、$gte、$lt、$lte、$in、$nin、$and、$or。您也可以使用 where_document={"$contains": "chess"} 对文档内容进行过滤。
更新与删除数据
与关系型数据库类似,您可以更新或删除集合中的值。要更新文本与元数据,我们将提供记录的特定 ID 和新文本。
collection2. update(
ids= [ "id1" ] ,
documents= [ "Kristiane Carina, a 19-year-old computer science sophomore with a 3.7 GPA" ] ,
metadatas= [ { "source" : "student info" } ] ,
) 技术支持
运行一个简单查询,检查更改是否已生效。
results = collection2. query(
query_texts= [ "What is the student name?" ] ,
n_results= 2
)
results技术支持
可以看到,我们得到的是 Kristiane,而不是 Alexandra。
要从集合中删除记录,我们将使用 delete() 并指定唯一 ID。
collection2. delete( ids = [ 'id1' ] )
results = collection2. query(
query_texts= [ "What is the student name?" ] ,
n_results= 2
)
results技术支持
学生信息文本已被删除;取而代之的是返回下一个最优结果。
集合管理
本节我将介绍集合工具函数,用于统计、列出、重命名与删除集合。
我们将创建一个名为 "vectordb" 的新集合,并添加关于 Chroma DB 速查表、文档和 JS API 的信息及其元数据。
vector_collections = client. create_collection( "vectordb" )
vector_collections. add(
documents= [ "This is Chroma DB CheatSheet" ,
"This is Chroma DB Documentation" ,
"This document Chroma JS API Docs" ] ,
metadatas= [ { "source" : "Chroma Cheatsheet" } ,
{ "source" : "Chroma Doc" } ,
{ 'source' : 'JS API Doc' } ] ,
ids= [ "id1" , "id2" , "id3" ]
) 技术支持
我们将使用 count() 函数查看集合有多少条记录。
vector_collections. count( ) 技术支持
3 技术支持
要查看集合中的所有记录,使用 get() 函数。
vector_collections. get( ) 技术支持
{ 'ids' : [ 'id1' , 'id2' , 'id3' ] ,
'embeddings' : None ,
'documents' : [ 'This is Chroma DB CheatSheet' ,
'This is Chroma DB Documentation' ,
'This document Chroma JS API Docs' ] ,
'metadatas' : [ { 'source' : 'Chroma Cheatsheet' } ,
{ 'source' : 'Chroma Doc' } ,
{ 'source' : 'JS API Doc' } ] } 技术支持
要更改集合名称,使用 modify()。要查看所有集合名称,使用 list_collections()。
vector_collections. modify( name= "chroma_info" )
client. list_collections( ) 技术支持
看起来我们已将 "vectordb" 成功重命名为 "chroma_info"。
[ Collection( name= Students) ,
Collection( name= Students2) ,
Collection( name= chroma_info) ] 技术支持
要访问任意新集合,您可以使用集合名称调用 get_collection()。
vector_collections_new = client. get_collection( name= "chroma_info" ) 技术支持
我们可以使用客户端的 delete_collection() 并指定集合名称来删除集合。
client. delete_collection( name= "chroma_info" )
client. list_collections( ) 技术支持
[ Collection( name= Students) , Collection( name= Students2) ] 技术支持
我们可以使用 client.reset() 删除整个数据库中的集合。但并不推荐这样做,因为删除后无法恢复数据。
client. reset( )
client. list_collections( ) 技术支持
[ ] 技术支持
将 ChromaDB 与 LangChain 结合:一个 RAG 示例
ChromaDB 最常见的集成之一是与 LangChain 一起构建 RAG 应用。以下是一个将 ChromaDB 用作向量存储的最小示例:
from langchain_community. vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_core. documents import Document
embeddings = OpenAIEmbeddings( model= "text-embedding-3-small" )
vector_store = Chroma(
collection_name= "rag_docs" ,
embedding_function= embeddings,
persist_directory= "./chroma_db"
)
docs = [
Document( page_content= "ChromaDB stores vector embeddings" , metadata= { "source" : "doc1" } ) ,
Document( page_content= "LangChain simplifies LLM application development" , metadata= { "source" : "doc2" } ) ,
]
vector_store. add_documents( docs)
results = vector_store. similarity_search( "vector database" , k= 2 )
for doc in results:
print ( doc. page_content) 技术支持
如需一套可用于生产的 FastAPI RAG 流水线,请参阅我们的教程:使用 LangChain 和 FastAPI 构建 RAG 系统 。基于 DeepSeek 的示例请参阅:使用 Chroma 的 DeepSeek R1 RAG 聊天机器人 。
结语
像 Chroma DB 这样的向量存储正在成为大型语言模型系统的关键组件。通过提供针对向量嵌入的专用存储和高效检索,它们为 LLM 提供快速获取相关语义信息的能力。
在本篇 Chroma DB 教程中,我们介绍了创建集合、添加文档、将文本转换为嵌入、进行语义相似查询以及管理集合的基本用法。
下一步的自然方向是构建以 ChromaDB 为向量存储的检索增强生成(RAG)应用。您可以从我们的 使用 LangChain 和 FastAPI 构建 RAG 系统 教程开始,获得一套可用于生产的流水线;或探索更高级的代理驱动检索流程 Agentic RAG 。您还可以使用 LlamaIndex 将私有数据引入 LLM,或参考 LangChain LLM 教程 进行完整应用开发。
随着大型语言模型(LLM)及其应用的兴起,集成工具、LLMOps 框架和向量数据库的热度也随之上升。这是因为使用 LLM 的工作方式与传统机器学习模型不同,需要采用另一套方法。
支持 LLM 的核心技术之一是向量嵌入。计算机无法直接理解文本,但嵌入可以将文本表示为数值。所有用户提供的文本都会被转换为嵌入,然后用于生成回复。
将文本转换为嵌入是一个耗时的过程。为避免重复计算,我们使用专门为高效存储与检索向量嵌入而设计的向量数据库。
在本教程中,我将带您了解向量存储与 Chroma DB——一个用于存储和管理嵌入的开源数据库。您将学习如何添加和删除文档、执行相似度搜索,以及将文本转换为嵌入。
作者供图
要点速览
pip install chromadb安装chromadb.PersistentClient(path="./chroma_db"),内存测试使用chromadb.EphemeralClient()add()添加文档,可选附带元数据和 IDcollection.query(query_texts=["..."], n_results=5)进行语义相似度搜索什么是向量存储?
向量存储是为高效存储与检索向量嵌入而专门设计的数据库。它们之所以必要,是因为像 SQL 这样的传统数据库并未针对大规模向量数据的存储和查询进行优化。
嵌入会在高维空间中以数值向量的形式表示数据(通常是文本等非结构化数据)。传统关系型数据库并不适合存储和搜索这些向量表示。
向量存储可以对向量进行索引,并使用相似度算法快速搜索相似向量,使应用能够在给定目标向量查询时找到相关向量。
例如,在个性化聊天机器人的场景中,用户向生成式 AI 模型输入提示。模型使用相似度搜索算法,在文档集合中查找相似文本。得到的信息将用于生成高度个性化且准确的回复。通过向量存储中的嵌入与向量索引,这种信息检索成为可能。
什么是 Chroma DB?
Chroma DB 是一个开源向量存储,用于存储和检索向量嵌入。其主要用途是保存嵌入及其元数据,供大型语言模型后续使用。此外,它也可用于文本数据上的语义搜索引擎。
Chroma DB 的特性
pip install chromadb。Chroma DB 提供自托管服务器选项。如果您需要托管式或云原生的向量数据库,可参考我们的指南:Pinecone 向量数据库实战或 Weaviate 作为替代方案。
图片来源:Chroma
Chroma DB 如何工作?
all-MiniLM-L6-v2将文本转换为嵌入,但您可以修改集合以使用其他嵌入模型。先决条件
要跟随本教程,您需要:
pip install pysqlite3-binary)开始使用 Chroma DB
本节中,我将创建一个向量数据库,添加集合,向其中加载文本,并运行一次相似度搜索查询。
首先安装
chromadb和openai。只有在“嵌入”一节您才需要OpenAI API 密钥——以下 ChromaDB 的核心示例不需要。注意:Chroma 需要 SQLite 3.35 或更高版本。如果出现问题,请升级到 Python 3.11,或安装较旧版本的
chromadb。选择客户端模式
ChromaDB 根据您的使用场景提供三种客户端模式:
chromadb.EphemeralClient()chromadb.PersistentClient(path="./chroma_db")chromadb.HttpClient(host="localhost", port=8000)您可以使用
chromadb.EphemeralClient()创建一个基于内存(临时)的测试数据库。它只在内存中存储数据,程序结束即重置——非常适合快速试验。在本例中,我将创建一个持久化数据库,存储在
./chroma_db目录下。ChromaDB 在持久化模式下使用 SQLite 作为后端存储——DuckDB 后端已在 ChromaDB 0.4.0 中移除。然后,我们将使用客户端创建一个
collection对象。这类似于在传统数据库中创建表。要向集合中添加文本,我们将生成关于学生、社团和大学的随机文本。您可以使用 ChatGPT 生成随机文本。
现在,我们将使用
add()函数添加带有元数据和唯一 ID 的文本数据。随后,Chroma 会自动下载all-MiniLM-L6-v2模型,将文本转换为嵌入并存储到 "Students" 集合中。要运行相似度搜索,您可以使用
query()函数并用自然语言提问。它会将查询转换为嵌入,并使用相似度算法生成相似结果。在我们的示例中,它返回了两个相似结果。嵌入(Embeddings)
您可以使用嵌入模型列表中的任意高性能嵌入模型。您甚至可以创建自定义嵌入函数。若想深入了解 OpenAI 的现代引擎,请参阅我们的 text-embedding-3-large 指南。
本节中,我将使用 OpenAI 的
text-embedding-3-small模型将文本转换为嵌入。这是 OpenAI 推荐用于替代旧版text-embedding-ada-002的模型——在基准上表现更好,成本降低 5 倍。创建 OpenAI 嵌入函数后,您可以添加文本列表以生成嵌入。
了解如何使用 OpenAI 文本嵌入 API 创建文本分类器、信息检索系统和语义相似度检测器。
与其使用默认嵌入模型,我将把已生成的嵌入直接加载到一个新集合中。
get_or_create_collection()函数创建一个名为 "Students2" 的新集合。该函数不同于create_collection(),如果集合已存在则获取,否则创建。还有一种更直接的方法。您可以在创建或访问集合时添加 OpenAI 嵌入函数。除了 OpenAI,您还可以使用 Cohere、Google Gemini、HuggingFace 和 Instructor 模型。
在我们的场景中,添加新文本文档时会调用 OpenAI 嵌入函数,而非默认模型,将文本转换为嵌入。
让我们在新集合上运行相似查询,看看差异。
我们的结果有所改善。现在相似度搜索返回的是关于大学的信息,而不是社团。此外,向量之间的距离比默认嵌入模型更低,这是好事。
过滤查询结果
ChromaDB 支持通过元数据过滤来缩小相似度搜索结果范围。在
query()中使用带操作符的where参数:支持的操作符:
$eq、$ne、$gt、$gte、$lt、$lte、$in、$nin、$and、$or。您也可以使用where_document={"$contains": "chess"}对文档内容进行过滤。更新与删除数据
与关系型数据库类似,您可以更新或删除集合中的值。要更新文本与元数据,我们将提供记录的特定 ID 和新文本。
运行一个简单查询,检查更改是否已生效。
可以看到,我们得到的是 Kristiane,而不是 Alexandra。
要从集合中删除记录,我们将使用
delete()并指定唯一 ID。学生信息文本已被删除;取而代之的是返回下一个最优结果。
集合管理
本节我将介绍集合工具函数,用于统计、列出、重命名与删除集合。
我们将创建一个名为 "vectordb" 的新集合,并添加关于 Chroma DB 速查表、文档和 JS API 的信息及其元数据。
我们将使用
count()函数查看集合有多少条记录。要查看集合中的所有记录,使用
get()函数。要更改集合名称,使用
modify()。要查看所有集合名称,使用list_collections()。看起来我们已将 "vectordb" 成功重命名为 "chroma_info"。
要访问任意新集合,您可以使用集合名称调用
get_collection()。我们可以使用客户端的
delete_collection()并指定集合名称来删除集合。我们可以使用
client.reset()删除整个数据库中的集合。但并不推荐这样做,因为删除后无法恢复数据。将 ChromaDB 与 LangChain 结合:一个 RAG 示例
ChromaDB 最常见的集成之一是与 LangChain 一起构建 RAG 应用。以下是一个将 ChromaDB 用作向量存储的最小示例:
如需一套可用于生产的 FastAPI RAG 流水线,请参阅我们的教程:使用 LangChain 和 FastAPI 构建 RAG 系统。基于 DeepSeek 的示例请参阅:使用 Chroma 的 DeepSeek R1 RAG 聊天机器人。
结语
像 Chroma DB 这样的向量存储正在成为大型语言模型系统的关键组件。通过提供针对向量嵌入的专用存储和高效检索,它们为 LLM 提供快速获取相关语义信息的能力。
在本篇 Chroma DB 教程中,我们介绍了创建集合、添加文档、将文本转换为嵌入、进行语义相似查询以及管理集合的基本用法。
下一步的自然方向是构建以 ChromaDB 为向量存储的检索增强生成(RAG)应用。您可以从我们的 使用 LangChain 和 FastAPI 构建 RAG 系统 教程开始,获得一套可用于生产的流水线;或探索更高级的代理驱动检索流程 Agentic RAG。您还可以使用 LlamaIndex 将私有数据引入 LLM,或参考 LangChain LLM 教程进行完整应用开发。