AI创想

标题: Chroma 向量数据库完全指南 [打印本页]

作者: xianshiyan    时间: 3 天前
标题: Chroma 向量数据库完全指南
作者:风送雨
一、什么是 Chroma?

Chroma 是一个开源的嵌入式向量数据库,专为 AI 应用设计,特别适合存储和检索向量嵌入(embeddings)。它简单易用,支持内存存储和持久化存储。
主要特性:

二、安装 Chroma
  1. # 基础安装
  2. pip install chromadb
  3. # 包含 CLI 工具
  4. pip install chromadb[cli]# 完整安装(包含所有依赖)
  5. pip install chromadb[all]
复制代码
三、核心概念

1. 集合(Collection)

类似于传统数据库的表,用于存储相关文档和向量。
2. 文档(Document)

要存储的文本内容,可以包含:
3. 查询(Query)

基于语义相似度的搜索。
四、基础使用示例

1. 创建客户端和集合
  1. import chromadb
  2. from chromadb.utils import embedding_functions
  3. # 创建客户端(内存模式)
  4. client = chromadb.Client()# 创建或获取集合
  5. collection = client.create_collection(
  6.     name="my_collection",
  7.     embedding_function=embedding_functions.SentenceTransformerEmbeddingFunction(
  8.         model_name="all-MiniLM-L6-v2"))
复制代码
2. 添加文档
  1. # 准备数据
  2. documents =["Chroma 是一个向量数据库","它专为 AI 应用设计","支持语义搜索和相似度匹配","可以用于构建问答系统","支持多种嵌入模型"]
  3. ids =["doc1","doc2","doc3","doc4","doc5"]
  4. metadatas =[{"source":"官方文档","type":"介绍"},{"source":"官方文档","type":"特性"},{"source":"官方文档","type":"功能"},{"source":"教程","type":"应用"},{"source":"教程","type":"特性"}]# 添加文档到集合
  5. collection.add(
  6.     documents=documents,
  7.     metadatas=metadatas,
  8.     ids=ids
  9. )
复制代码
3. 查询文档
  1. # 基本查询
  2. results = collection.query(
  3.     query_texts=["Chroma 有哪些功能?"],
  4.     n_results=3)print("查询结果:")for i, doc inenumerate(results['documents'][0]):print(f"{i+1}. {doc}")print(f"   元数据: {results['metadatas'][0][i]}")print(f"   距离: {results['distances'][0][i]}")print()
复制代码
4. 使用元数据过滤
  1. # 带过滤条件的查询
  2. results = collection.query(
  3.     query_texts=["向量数据库"],
  4.     n_results=5,
  5.     where={"source":"官方文档"},# 过滤条件
  6.     where_document={"$contains":"支持"}# 文档内容过滤)
复制代码
五、高级功能

1. 自定义嵌入函数
  1. import openai
  2. from chromadb.utils import embedding_functions
  3. # 使用 OpenAI格式 嵌入
  4. openai_ef = embedding_functions.OpenAIEmbeddingFunction(
  5.     api_key="sk-*********************************",
  6.     api_base="https://api.siliconflow.cn/v1/",
  7.     model_name="BAAI/bge-m3")# 创建使用 OpenAI 嵌入的集合
  8. collection = client.create_collection(
  9.     name="openai_collection",
  10.     embedding_function=openai_ef
  11. )
复制代码
2. 持久化存储
  1. # 持久化客户端
  2. persistent_client = chromadb.PersistentClient(path="./chroma_db")# 在指定路径创建集合
  3. collection = persistent_client.create_collection("persistent_collection")# 数据会自动保存到磁盘
复制代码
3. 更新和删除文档
  1. # 更新文档
  2. collection.update(
  3.     ids=["doc1"],
  4.     documents=["更新后的文档内容"],
  5.     metadatas=[{"source":"更新","version":"2.0"}])# 删除文档
  6. collection.delete(ids=["doc2"])# 按条件删除
  7. collection.delete(where={"source":"教程"})
复制代码
六、实际应用案例

1. 构建简单的问答系统
  1. import os
  2. import chromadb
  3. from chromadb.utils import embedding_functions
  4. openai_ef = embedding_functions.OpenAIEmbeddingFunction(
  5.     api_key="sk-******************************",
  6.     api_base="https://api.siliconflow.cn/v1/",
  7.     model_name="BAAI/bge-m3")classSimpleQASystem:def__init__(self, collection_name="qa_collection"):
  8.         self.client = chromadb.PersistentClient(path="./qa_db")
  9.         self.collection = self.client.get_or_create_collection(
  10.             name=collection_name,
  11.             embedding_function=openai_ef
  12.         )defadd_knowledge(self, documents, ids=None, metadatas=None):"""添加知识库文档"""if ids isNone:
  13.             ids =[f"doc_{i}"for i inrange(len(documents))]
  14.         
  15.         self.collection.add(
  16.             documents=documents,
  17.             ids=ids,
  18.             metadatas=metadatas
  19.         )defquery(self, question, n_results=2):"""查询相关问题"""
  20.         results = self.collection.query(
  21.             query_texts=[question],
  22.             n_results=n_results
  23.         )return{'answers': results['documents'][0],'sources': results['metadatas'][0],'scores': results['distances'][0]}defget_context(self, question, max_length=500):"""获取相关上下文"""
  24.         results = self.query(question)
  25.         context =""for answer in results['answers']:iflen(context)+len(answer)< max_length:
  26.                 context += answer +"\n\n"else:breakreturn context
  27. # 使用示例
  28. qa_system = SimpleQASystem()
  29. qa_system.add_knowledge(["Chroma 支持元数据过滤,可以按条件查询文档","向量数据库主要用于存储和检索高维向量数据","语义搜索基于文本的相似度匹配"])
  30. context = qa_system.get_context("Chroma 有什么功能?")print(f"相关上下文:\n{context}")
复制代码
2. 文档检索系统
  1. import os
  2. import chromadb
  3. from typing import List
  4. from chromadb.utils import embedding_functions
  5. openai_ef = embedding_functions.OpenAIEmbeddingFunction(
  6.     api_key="sk-***********************************",  
  7.     api_base="https://api.siliconflow.cn/v1/",
  8.     model_name="BAAI/bge-m3")classDocumentRetriever:def__init__(self, collection_name="documents"):
  9.         self.client = chromadb.PersistentClient("./qa_db")
  10.         self.collection = self.client.get_or_create_collection(
  11.             name=collection_name,
  12.             embedding_function=openai_ef
  13.         )defindex_documents(self, folder_path:str):"""索引文件夹中的所有文档"""
  14.         documents =[]
  15.         metadatas =[]
  16.         ids =[]for filename in os.listdir(folder_path):if filename.endswith('.txt'):
  17.                 filepath = os.path.join(folder_path, filename)withopen(filepath,'r', encoding='utf-8')as f:
  18.                     content = f.read()# 按段落分割
  19.                 paragraphs = self.split_into_paragraphs(content)for i, para inenumerate(paragraphs):if para.strip():# 跳过空段落
  20.                         documents.append(para)
  21.                         metadatas.append({"filename": filename,"paragraph": i,"source":"local_file","filepath": filepath
  22.                         })
  23.                         ids.append(f"{filename}_{i}")# 批量添加
  24.         batch_size =100
  25.         total_added =0for i inrange(0,len(documents), batch_size):
  26.             self.collection.add(
  27.                 documents=documents[i:i+batch_size],
  28.                 metadatas=metadatas[i:i+batch_size],
  29.                 ids=ids[i:i+batch_size])
  30.             total_added +=len(documents[i:i+batch_size])print(f"已添加 {i+batch_size if i+batch_size <len(documents)elselen(documents)}/{len(documents)} 个段落")return total_added
  31.    
  32.     defsplit_into_paragraphs(self, text:str, min_length:int=50)-> List[str]:"""将文本分割成段落"""
  33.         paragraphs = text.split('\n\n')return[p.strip()for p in paragraphs iflen(p.strip())>= min_length]defsearch(self, query:str, n_results:int=5,**filters):"""搜索文档"""return self.collection.query(
  34.             query_texts=[query],
  35.             n_results=n_results,
  36.             where=filters if filters elseNone)defsearch_with_scores(self, query:str, n_results:int=5,**filters):"""搜索文档并显示相似度分数"""
  37.         results = self.search(query, n_results,**filters)print(f"查询: '{query}'")print(f"找到 {len(results['documents'][0])} 个结果:")print("-"*50)for i,(doc, metadata, distance)inenumerate(zip(
  38.             results['documents'][0],
  39.             results['metadatas'][0],
  40.             results['distances'][0])):print(f"\n结果 {i+1}:")print(f"相似度: {1- distance:.4f}")# 转换为相似度分数print(f"来源文件: {metadata.get('filename','未知')}")print(f"段落: {metadata.get('paragraph','未知')}")print(f"内容预览: {doc[:150]}...")print("-"*30)return results
  41.    
  42.     defget_collection_info(self):"""获取集合信息"""
  43.         count = self.collection.count()return{"total_documents": count,"collection_name": self.collection.name
  44.         }defclear_collection(self):"""清空集合中的所有文档"""
  45.         self.collection.delete(where={})print("集合已清空")defdelete_by_filename(self, filename:str):"""根据文件名删除文档"""
  46.         self.collection.delete(where={"filename": filename})print(f"已删除文件 '{filename}' 的所有段落")# ================ 使用示例 ================defmain():print("=== 文档检索系统演示 ===\n")# 1. 初始化文档检索器
  47.     retriever = DocumentRetriever(collection_name="knowledge_base")# 2. 检查集合状态
  48.     info = retriever.get_collection_info()print(f"当前集合: {info['collection_name']}")print(f"现有文档数: {info['total_documents']}\n")# 3. 创建示例文档文件夹(如果不存在)
  49.     docs_folder ="sample_docs"ifnot os.path.exists(docs_folder):
  50.         os.makedirs(docs_folder)# 创建一些示例文档
  51.         sample_docs ={"python_tutorial.txt":"""
  52. Python 是一种高级编程语言,由 Guido van Rossum 于 1991 年创建。
  53. 它以简洁的语法和强大的功能而闻名,广泛应用于Web开发、数据科学、人工智能等领域。
  54. Python 的主要特性包括:
  55. 1. 简单易学:语法清晰,适合初学者
  56. 2. 解释型语言:无需编译,可直接运行
  57. 3. 动态类型:变量类型在运行时确定
  58. 4. 丰富的库生态系统:有大量的第三方库可以使用
  59. 在数据科学领域,Python 的 pandas、numpy、matplotlib 等库非常受欢迎。
  60. 在人工智能领域,TensorFlow、PyTorch 等框架都支持 Python。
  61. ""","machine_learning.txt":"""
  62. 机器学习是人工智能的一个分支,它使计算机能够从数据中学习而无需显式编程。
  63. 机器学习主要分为三类:监督学习、无监督学习和强化学习。
  64. 监督学习:使用标记数据训练模型,用于分类和回归任务。
  65. 无监督学习:使用未标记数据发现模式,用于聚类和降维。
  66. 强化学习:智能体通过与环境互动学习最优策略。
  67. 常见的机器学习算法包括线性回归、决策树、支持向量机、神经网络等。
  68. 深度学习是机器学习的一个子领域,使用多层神经网络解决复杂问题。
  69. ""","vector_databases.txt":"""
  70. 向量数据库是专门用于存储和检索向量嵌入的数据库系统。
  71. 它们在高维空间中执行相似性搜索,广泛应用于推荐系统、图像检索和自然语言处理。
  72. Chroma 是一个开源的向量数据库,具有以下特点:
  73. 1. 轻量级设计,易于部署
  74. 2. 支持多种嵌入模型
  75. 3. 提供元数据过滤功能
  76. 4. 支持语义搜索
  77. 向量数据库的工作原理是将文本、图像等数据转换为向量表示,然后通过计算向量之间的相似度来查找最相关的项目。
  78. 余弦相似度是常用的相似度度量方法。
  79. """}for filename, content in sample_docs.items():withopen(os.path.join(docs_folder, filename),'w', encoding='utf-8')as f:
  80.                 f.write(content)print(f"已创建示例文档到 '{docs_folder}' 文件夹\n")# 4. 索引文档(可选)if info['total_documents']==0:print("开始索引文档...")
  81.         total_added = retriever.index_documents(docs_folder)print(f"成功索引 {total_added} 个段落\n")# 5. 执行搜索查询print("=== 搜索演示 ===\n")# 示例查询 1print("查询 1: 'Python 有什么特点?'")
  82.     results1 = retriever.search_with_scores("Python 有什么特点?", n_results=3)# 示例查询 2print("\n\n查询 2: '机器学习有哪些类型?'")
  83.     results2 = retriever.search_with_scores("机器学习有哪些类型?", n_results=2)# 示例查询 3:带过滤条件的查询print("\n\n查询 3: '向量数据库'(只搜索特定文件)")
  84.     results3 = retriever.search_with_scores("向量数据库",
  85.         n_results=3,
  86.         filename="vector_databases.txt"# 过滤条件)# 示例查询 4:更具体的查询print("\n\n查询 4: 'Chroma 的特点是什么?'")
  87.     results4 = retriever.search_with_scores("Chroma 的特点是什么?", n_results=2)# 6. 高级功能演示print("\n=== 高级功能演示 ===\n")# 查看搜索结果详情print("查看查询 4 的完整结果:")
  88.     full_results = retriever.search("Chroma 的特点是什么?", n_results=2)for i, doc inenumerate(full_results['documents'][0]):print(f"\n结果 {i+1} 的完整内容:")print(doc)print("-"*50)# 7. 清理演示(可选)# print("\n=== 清理演示 ===\n")# 删除特定文件的所有段落# retriever.delete_by_filename("python_tutorial.txt")# print("已删除 python_tutorial.txt 的所有段落")# 清空整个集合(谨慎使用)# retriever.clear_collection()# print("集合已清空")if __name__ =="__main__":
  89.     main()
复制代码
七、最佳实践

1. 数据预处理

2. 批量操作
  1. # 使用批量添加提高性能
  2. batch_size =100for i inrange(0,len(documents), batch_size):
  3.     collection.add(
  4.         documents=documents[i:i+batch_size],
  5.         ids=ids[i:i+batch_size],
  6.         metadatas=metadatas[i:i+batch_size])
复制代码
3. 错误处理
  1. import chromadb
  2. try:
  3.     client = chromadb.HttpClient(host="localhost", port=8000)
  4.     collection = client.get_collection("my_collection")except chromadb.errors.ChromaError as e:print(f"Chroma 错误: {e}")# 创建新集合或使用回退方案
复制代码
4. 性能优化

八、部署选项

1. 本地部署(服务器模式)
  1. # 启动 Chroma 服务器
  2. chroma run --host localhost --port 8000# Python 客户端连接
  3. client = chromadb.HttpClient(host="localhost", port=8000)
复制代码
2. Docker 部署
  1. # Dockerfile
  2. FROM chromadb/chroma:latest
复制代码
  1. # 运行容器
  2. docker run -p 8000:8000 chromadb/chroma
复制代码
3. 云部署

Chroma 支持部署到各种云平台,也可以使用 Chroma Cloud 托管服务。
九、与其他工具集成

1. 与 LangChain 集成
  1. https://blog.csdn.net/u013172930/article/details/147719570
  2. 推荐参考这个博客学习
复制代码
2. 与 FastAPI 集成
  1. from fastapi import FastAPI
  2. import chromadb
  3. app = FastAPI()
  4. client = chromadb.PersistentClient()@app.post("/add_document")asyncdefadd_document(document:dict):
  5.     collection = client.get_collection("api_collection")
  6.     collection.add(**document)return{"status":"success"}@app.get("/search")asyncdefsearch(query:str, n_results:int=5):
  7.     collection = client.get_collection("api_collection")
  8.     results = collection.query(query_texts=[query], n_results=n_results)return results
复制代码
十、常见问题解决

1. 内存不足

2. 查询速度慢

十一、资源链接


原文地址:https://blog.csdn.net/mysterious_z/article/details/156196561




欢迎光临 AI创想 (https://llms-ai.com/) Powered by Discuz! X3.4