RAG进阶:Chroma开源的AI原生向量数据库

一、Chroma 核心概念与优势

1. 什么是 Chroma?

Chroma 是一款开源的向量数据库,专为高效存储和检索高维向量数据设计。其核心能力在于语义相似性搜索,支持文本、图像等嵌入向量的快速匹配,广泛应用于大模型上下文增强(RAG)、推荐系统、多模态检索等场景。与传统数据库不同,Chroma 基于向量距离(如余弦相似度、欧氏距离)衡量数据关联性,而非关键词匹配。

GitHub地址:

https://github.com/chroma-core/chroma

官方文档:

https://docs.trychroma.com/

2. 核心优势

  • 轻量易用:以 Python/JS 包形式嵌入代码,无需独立部署,适合快速原型开发。
  • 灵活集成:支持自定义嵌入模型(如 OpenAI、HuggingFace),兼容 LangChain 等框架。
  • 高性能检索:采用 HNSW 算法优化索引,支持百万级向量毫秒级响应。
  • 多模式存储:内存模式用于开发调试,持久化模式支持生产环境数据落地。

 

二、安装和基础配置

 1、安装Chroma

支持windows、ubuntu等操作系统,Python>=3.9  。

创建虚拟环境以及安装

#创建虚拟环境
conda create -n chromadb python==3.10#激活
conda activate chromadb#安装chromadb
pip install chromadb

注意:Chroma 默认是本地嵌入式数据库,并不原生支持远程访问像传统数据库那样(比如 PostgreSQL 那种 client-server 模式)。

当然官方也提供了客户端-服务器端模式(Client-Server Mode),服务器端的启动方式如下:

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

2、初始化客户端

 内存模式调试,实验的场景):

import chromadb
client = chromadb.Client()

持久化模式(生产环境):

在创建的时候,可以配置本地的存储路径

client = chromadb.PersistentClient(path="/path/to/save") # 数据保存至本地目录

Client-Server模式的客户端:

前两种,都是本地模式,chroma的服务端和客户端需要位于同一台机器。CS模式可以独立部署,通过httpclient进行访问。

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

三、增删改查操作

1. 创建集合(Collection

集合是 Chroma 中管理数据的基本单元,类似传统数据库的表。 集合的name名称有以下约束:
  • 名称的长度必须介于 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")

如果不提供嵌入函数,则使用默认的嵌入函数 sentence transformer  使用的的是一个小型的模型all-MiniLM-L6-v2,该模型主要是针对英语场景。一般我们都需要自定义一个嵌入函数:

import chromadb
from sentence_transformers import SentenceTransformerclass 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\LLMTrain\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)

创建collect时,可以配置如下参数。

  • name标识collect的名称,是必填项;
  • embedding_function,指定嵌入函数,不填为默认的嵌入模型。
  • metadata,元数据,比如索引方式等,非必填。
from datetime import datetimecollection = 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、写入数据

写入数据时,配置以下参数:

  • document,原始的文本块。
  • metadatas,描述文本块的元数据,kv键值对。
  • 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"],  # 使用已存在的IDdocuments=["RAG是一种检索增强生成技术222"]
)

4、更新插入方法

Chroma 还支持更新插入操作,更新现有项目,如果项目尚不存在则添加它们。

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使用delete。与每个项目相关的嵌入、文档和元数据将被删除。

还支持where过滤器。如果没有ID提供,它将删除集合中与where筛选。

# 提供ids
collection.delete(ids=["doc1"])
collection.delete(ids=["id1", "id2", "id3",...],where={"chapter": "20"}
)

6、查询数据

(1)查询所有数据

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

(2)根据ids查询

可以通过以下方式从集合中检索项目ID使用get

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

(3)查询嵌入

可以通过多种方式查询 Chroma 集合,使用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_result每个最接近的匹配查询嵌入,按顺序排列。 可选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_transformerspip install modelscope

2、下载Embedding模型到本地

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

3、写入数据和查询相似文本

import chromadb
from sentence_transformers import SentenceTransformerclass 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\LLMTrain\testllm\llm\BAAI\bge-m3",device="cuda"  # 无 GPU 改为 "cpu"
)# 创建客户端和集合
client = chromadb.PersistentClient(path=r"D:\Test\LLMTrain\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,值是从小到大排序的,所以3条数据与问题“什么是RAG技术?”的相似度情况:distances值越小越相似。因此,第1条数据与问题越相似。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/78077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

店匠科技摘得 36 氪“2025 AI Partner 创新大奖”

全场景 AI 方案驱动跨境电商数智化跃迁 4 月 18 日,36 氪 2025 AI Partner 大会于上海盛大开幕。大会紧扣“Super App 来了”主题,全力探寻 AI 时代的全新变量,探索 AI 领域下一个超级应用的无限可能性。在此次大会上,跨境电商独立站 SaaS 平台店匠科技(Shoplazza)凭借“店匠跨…

SQL技术终极指南:从内核原理到超大规模应用

一、DDL核心应用场景与最佳实践 1.1 表结构设计场景矩阵 业务场景核心语法要素典型实现案例电商用户画像JSON字段虚拟列索引CREATE TABLE users (id INT, profile JSON, AS (profile->>$.age) VIRTUAL, INDEX idx_age((profile->>$.age)))物联网时序数据分区表压…

吴恩达深度学习作业CNN之ResNet实现(Pytorch)

课程中认识许多CNN架构。首先是经典网络: LeNet-5AlexNetVGG 之后是近年来的一些网络: ResNetInceptionMobileNet 经典网络 LeNet-5 LeNet-5是用于手写数字识别(识别0~9的阿拉伯数字)的网络。它的结构如下: 网络…

FPGA入门学习Day1——设计一个DDS信号发生器

目录 一、DDS简介 (一)基本原理 (二)主要优势 (三)与传统技术的对比 二、FPGA存储器 (一)ROM波形存储器 (二)RAM随机存取存储器 (三&…

SqlSugar与Entity Framework (EF)的SWOT分析

以下是基于 SWOT 分析法 对 SqlSugar 和 Entity Framework (EF) 的特性对比: SqlSugar 优势 (Strengths) 高性能: SqlSugar 以轻量化设计著称,执行速度更快,适合对性能要求较高的场景。在大数据量操作和复杂查询中表现优异。 易…

学习记录:DAY16

Maven 进阶与前端实战 前言 二轮考核的内容下来了,由整体项目构建转为实现特定模块的功能。对细节的要求更高了,而且有手搓线程池、手搓依赖注入等进阶要求,又有得学力。嘻嘻,太简单了,只要我手搓 Spring Boot 框架……

深度学习--卷积神经网络调整学习率

文章目录 前言一、学习率1、什么学习率2、什么是调整学习率3、目的 二、调整方法1、有序调整1)有序调整StepLR(等间隔调整学习率)2)有序调整MultiStepLR(多间隔调整学习率)3)有序调整ExponentialLR (指数衰减调整学习率)4)有序调整…

【消息队列RocketMQ】四、RocketMQ 存储机制与性能优化

一、RocketMQ 存储机制详解 1.1 存储文件结构​ RocketMQ 的存储文件主要分布在store目录下,该目录是在broker.conf配置文件中通过storePathRootDir参数指定的,默认路径为${user.home}/store 。主要包含以下几种关键文件类型:​ 1.1.1 Comm…

C++入门小馆: 探寻vector类

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的pa…

CSS-跟随图片变化的背景色

CSS-跟随图片变化的背景色 获取图片的主要颜色并用于背景渐变需要安装依赖 colorthief获取图片的主要颜色. 并丢给背景注意 getPalette并不是个异步方法 import styles from ./styles.less; import React, { useState } from react; import Colortheif from colorthief;cons…

RAGFlow:构建高效检索增强生成流程的技术解析

引言 在当今信息爆炸的时代,如何从海量数据中快速准确地获取所需信息并生成高质量内容已成为人工智能领域的重要挑战。检索增强生成(Retrieval-Augmented Generation, RAG)技术应运而生,它将信息检索与大型语言模型(L…

SpringBoot应用:MyBatis的select语句如何返回数组类型

在SpringBoot应用中&#xff0c;比如想返回一个表的主键id构成的Long型数组Long[]&#xff0c;需要在XxxMapper.xml文件中这样定义select语句&#xff1a; <select id"selectIds" parameterType"int" resultType"Long">select id from sy…

【HFP】蓝牙HFP协议来电处理机制解析

目录 一、协议概述与技术背景 1.1 HFP协议演进 1.2 核心角色定义 1.3 关键技术指标 二、来电接入的核心交互流程 2.1 基础流程概述&#xff1a;AG 的 RING 通知机制 2.2 HF 的响应&#xff1a;本地提醒与信令交互 三、带内铃声&#xff08;In-Band Ring Tone&#xff0…

【每天一个知识点】如何解决大模型幻觉(hallucination)问题?

解决大模型幻觉&#xff08;hallucination&#xff09;问题&#xff0c;需要从模型架构、训练方式、推理机制和后处理策略多方面协同优化。 &#x1f9e0; 1. 引入 RAG 框架&#xff08;Retrieval-Augmented Generation&#xff09; 思路&#xff1a; 模型生成前先检索知识库中…

基于STC89C52RC和8X8点阵屏、独立按键的小游戏《打砖块》

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 用的是普中A2开发板&#xff0c;外设有&#xff1a;8X8LED点阵屏、独立按键。 【单片机】STC89C52RC 【频率】12T11.0592MHz 效…

C++学习:六个月从基础到就业——C++学习之旅:STL迭代器系统

C学习&#xff1a;六个月从基础到就业——C学习之旅&#xff1a;STL迭代器系统 本文是我C学习之旅系列的第二十四篇技术文章&#xff0c;也是第二阶段"C进阶特性"的第二篇&#xff0c;主要介绍C STL迭代器系统。查看完整系列目录了解更多内容。 引言 在上一篇文章中…

leetcode刷题——判断对称二叉树(C语言版)

题目描述&#xff1a; 示例 1&#xff1a; 输入&#xff1a;root [6,7,7,8,9,9,8] 输出&#xff1a;true 解释&#xff1a;从图中可看出树是轴对称的。 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 解释&#xff1a;从图中可看出最…

无法右键下载文档?网页PDF下载方法大全

适用场景&#xff1a;绕过付费限制/无法右键下载/动态加载PDF 方法1&#xff1a;浏览器原生下载&#xff08;成功率60%&#xff09; Chrome/Edge&#xff1a; 在PDF预览页点击工具栏 ⬇️下载图标&#xff08;右上角&#xff09; 快捷键&#xff1a;CtrlS → 保存类型选PDF …

基于缺失数据的2024年山东省专项债发行报告

一、数据情况 本次报告选取了山东省财政局公开的2024年专项债数据,共计2723条,发行期数是从第1期到第58期,由于网络原因,其中25期到32期,54到57期的数据有缺失,如下图所示。 从上图看出,一年52周,平均每周都有一期发布,因此持续做专项债的谋划很重要,一定要持续谋划…

Ubuntu数据连接访问崩溃问题

目录 一、分析问题 1、崩溃问题本地调试gdb调试&#xff1a; 二、解决问题 1. 停止 MySQL 服务 2. 卸载 MySQL 相关包 3. 删除 MySQL 数据目录 4. 清理依赖和缓存 5.重新安装mysql数据库 6.创建程序需要的数据库 三、验证 1、动态库更新了 2、头文件更新了 3、重新…