ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

5分钟极速入门ChromaDB:从文本向量化到语义搜索实战

5分钟极速入门ChromaDB:从文本向量化到语义搜索实战 1. 从“相似性搜索”到向量数据库为什么我们需要它如果你用过搜索引擎或者电商平台的“猜你喜欢”那你已经接触过相似性搜索的雏形了。传统数据库擅长处理“等于”或“大于小于”这类精确查询比如“找出所有姓张的用户”或“价格低于100元的商品”。但面对“找出和这张图片相似的图片”或“推荐几篇和这篇文章主题相近的文章”这类模糊需求时传统数据库就力不从心了。这背后的核心是文本、图片、音频这些非结构化数据计算机无法直接理解它们的“含义”。向量数据库的魔法就在于它先将这些数据转化为计算机能理解的“数学语言”——向量。你可以把向量想象成一个高维空间里的点。比如一篇关于“机器学习”的文章经过模型处理后会变成一个由几百甚至几千个数字组成的向量这个向量在空间中的位置就代表了它的“语义”。另一篇关于“深度学习”的文章其向量位置会和“机器学习”的非常接近因为它们语义相似。而一篇关于“烘焙蛋糕”的文章其向量就会离得很远。向量数据库的核心工作就是高效存储这些向量点并能快速找出与某个查询向量“距离最近”的邻居。这个“距离”通常用余弦相似度或欧氏距离来衡量值越小或相似度越高代表两者越相似。所以当你听到向量数据库时它本质上是一个为“相似性搜索”而优化的专用数据库。而 ChromaDB就是这样一个轻量级、易上手特别适合开发者快速原型和学习的开源向量数据库。它不像一些工业级向量数据库如 Milvus那样需要复杂的部署它可以直接嵌入你的 Python 脚本中让你在几分钟内就体验到从文本到向量再到智能搜索的完整流程。这正是我们接下来要做的。2. 环境准备不仅仅是安装 Python 和 ChromaDB在开始写代码之前确保你的环境是正确且隔离的这是一个好习惯能避免未来很多包冲突的麻烦。我们假设你已经在电脑上安装了 Python3.7 及以上版本。如果你还没有去 Python 官网下载安装器是最直接的方式安装时记得勾选“Add Python to PATH”。2.1 创建并激活虚拟环境虚拟环境是你的项目专属的“沙盒”。在这个沙盒里安装的包不会影响到系统全局或其他项目。打开你的终端Windows 上是 CMD 或 PowerShellmacOS/Linux 上是 Terminal执行以下命令来创建并激活一个虚拟环境。# 创建名为 chroma_demo 的虚拟环境 python -m venv chroma_demo # 激活虚拟环境 # 在 Windows 上 chroma_demo\Scripts\activate # 在 macOS/Linux 上 source chroma_demo/bin/activate激活后你的命令行提示符前面通常会显示环境名(chroma_demo)这表示你已经进入了这个沙盒。注意很多新手会忽略这一步直接在全系统环境安装。当项目多了不同项目依赖不同版本的包时就会陷入“依赖地狱”。养成使用虚拟环境的习惯是 Python 开发的基本素养。2.2 安装核心依赖包在我们的沙盒里安装本次体验所需的两个核心包chromadb和sentence-transformers。后者是一个强大的库里面封装了各种用于生成文本向量的预训练模型我们用它来把文本变成向量。pip install chromadb sentence-transformers这里有个小坑需要注意sentence-transformers依赖 PyTorch。pip install sentence-transformers会自动尝试安装一个兼容的 CPU 版本 PyTorch。如果你的网络环境导致下载慢或失败可以考虑先使用清华源安装 PyTorch再安装sentence-transformers或者耐心重试几次。安装过程可能会花费几分钟因为它需要下载模型文件。安装完成后你可以用pip list命令检查一下是否成功安装了chromadb和sentence-transformers。3. 第一步将文本转化为向量并存入 ChromaDB理论准备就绪环境也已搭建现在让我们开始写代码。创建一个新的 Python 文件比如叫做chroma_quickstart.py。3.1 初始化客户端与创建集合首先我们需要导入必要的库并初始化 ChromaDB 的客户端。ChromaDB 可以运行在内存中persist_directory参数为空也可以持久化到磁盘。为了简单起见我们先用内存模式。import chromadb from sentence_transformers import SentenceTransformer # 初始化 ChromaDB 客户端使用内存模式 chroma_client chromadb.Client() # 创建一个集合Collection。集合类似于传统数据库中的表用于存放一组相关的向量和元数据。 # 如果集合已存在get_or_create_collection 会获取它否则创建它。 collection chroma_client.get_or_create_collection(namemy_knowledge_base)collection是我们接下来操作的主要对象。3.2 准备数据并生成向量我们准备一些简单的文本数据作为我们的“知识库”。同时我们需要一个模型来把这些文本变成向量。sentence-transformers里的all-MiniLM-L6-v2模型是一个很好的起点它体积小、速度快并且在语义相似度任务上表现不错。# 准备一些文档文本数据 documents [ 机器学习是人工智能的一个分支它使计算机能够在没有明确编程的情况下学习。, 深度学习是机器学习的一个子领域它使用神经网络模拟人脑的工作方式。, Python 是一种流行的编程语言广泛用于数据科学和机器学习。, 向量数据库是一种专门用于存储和检索向量嵌入的数据库。, 今天天气很好适合去公园散步。 ] # 为每个文档提供一个唯一的 ID ids [doc1, doc2, doc3, doc4, doc5] # 初始化句子转换模型 model SentenceTransformer(all-MiniLM-L6-v2) # 将文档列表转换为向量嵌入 # encode 方法会返回一个 numpy 数组每一行对应一个文档的向量 embeddings model.encode(documents).tolist() # 转换为列表格式因为 ChromaDB 接收列表这里的关键是model.encode(documents)。这行代码调用了预训练模型将五段文本分别转换成了 384 维的向量all-MiniLM-L6-v2模型输出维度是 384。你可以把embeddings变量打印出来看看它是一个包含 5 个列表的列表每个子列表有 384 个浮点数。3.3 将向量和元数据存入集合有了向量、原始文本和 ID我们就可以将它们添加到 ChromaDB 的集合中了。# 将文档、对应的向量嵌入以及 ID 添加到集合中 collection.add( embeddingsembeddings, # 向量列表 documentsdocuments, # 原始文本列表 idsids # ID 列表 ) print(数据已成功添加到 ChromaDB 集合中)collection.add方法是核心操作。它接收三个主要列表参数且这三个列表必须一一对应。ChromaDB 会将这些向量存储起来并建立索引以便后续快速检索。至此我们已经完成了一个微型向量数据库的构建。4. 核心体验执行你的第一次语义搜索数据库建好了最激动人心的部分来了——搜索。我们不再使用关键词匹配而是用自然语言提出问题让数据库找到语义上最相关的答案。4.1 进行相似性查询我们尝试搜索与“什么是神经网络”相关的内容。注意我们的知识库里并没有完全相同的这句话。# 定义查询文本 query_text 什么是神经网络 # 将查询文本同样转换为向量 query_embedding model.encode([query_text]).tolist() # 注意这里传入的是列表 # 执行查询寻找最相似的 2 个结果 results collection.query( query_embeddingsquery_embedding, # 查询向量 n_results2 # 返回最相似的前 N 个结果 ) print(\n查询, query_text) print(最相关的文档) for i, doc in enumerate(results[documents][0]): # results[documents] 是一个嵌套列表 print(f{i1}. {doc})运行这段代码你会看到类似以下的输出查询 什么是神经网络 最相关的文档 1. 深度学习是机器学习的一个子领域它使用神经网络模拟人脑的工作方式。 2. 机器学习是人工智能的一个分支它使计算机能够在没有明确编程的情况下学习。太神奇了尽管我们没有存储“神经网络”这个词但模型理解到“神经网络”是“深度学习”的核心而“深度学习”又与“机器学习”强相关。它成功返回了语义上最接近的两条文档。这就是向量搜索的魅力它理解含义而不仅仅是字面匹配。4.2 理解查询结果的构成让我们更仔细地看看results这个对象。打印一下它的结构print(results)你会看到一个字典通常包含以下几个关键部分ids: 返回结果的文档 ID 列表。embeddings: 返回结果的向量列表如果你在查询时要求返回。documents: 返回结果的原始文本列表。distances: 查询向量与每个结果向量之间的距离列表。对于默认的l2欧氏距离来说这个值越小越好。例如你可能看到distances是[0.35, 0.78]这意味着第一个结果关于深度学习的与查询的语义距离是 0.35比第二个结果0.78要近得多因此相关性更高。5. 更进一步元数据过滤与混合搜索单纯的向量搜索已经很强大了但在实际应用中我们经常需要结合一些结构化条件进行过滤。比如在文档库中我们可能只想搜索某个特定作者或某个时间段内的文档。ChromaDB 支持为每个向量条目添加元数据metadata并基于元数据进行过滤。5.1 添加元数据并重新构建集合让我们重构一下数据为每篇文档添加类别和作者信息。# 删除旧的集合重新开始对于内存客户端 chroma_client.delete_collection(namemy_knowledge_base) collection chroma_client.get_or_create_collection(namemy_knowledge_base_with_meta) # 新的文档、ID 和元数据 documents [ 机器学习是人工智能的一个分支它使计算机能够在没有明确编程的情况下学习。, 深度学习是机器学习的一个子领域它使用神经网络模拟人脑的工作方式。, Python 是一种流行的编程语言广泛用于数据科学和机器学习。, 向量数据库是一种专门用于存储和检索向量嵌入的数据库。, 今天天气很好适合去公园散步。 ] ids [doc1, doc2, doc3, doc4, doc5] # 为每个文档定义元数据 metadatas [ {category: AI, author: Alice}, {category: AI, author: Bob}, {category: Programming, author: Charlie}, {category: Database, author: Alice}, {category: Life, author: David} ] embeddings model.encode(documents).tolist() # 添加数据这次包含元数据 collection.add( embeddingsembeddings, documentsdocuments, metadatasmetadatas, # 新增元数据参数 idsids )5.2 执行带过滤条件的查询现在我们可以在搜索时加入过滤条件。例如我们想搜索与“机器学习”相关但仅限于“AI”类别的文档。query_text 机器学习 query_embedding model.encode([query_text]).tolist() results collection.query( query_embeddingsquery_embedding, n_results3, where{category: AI} # 元数据过滤条件 ) print(f\n查询 ‘{query_text}’ (过滤条件: categoryAI)) for doc, meta in zip(results[documents][0], results[metadatas][0]): print(f- {doc} [作者: {meta[author]}])这次结果将只包含doc1和doc2因为doc3关于 Python 编程虽然语义上也相关但其类别是 “Programming”被过滤掉了。这种“向量相似度搜索 元数据过滤”的模式被称为混合搜索它结合了语义理解和精准过滤是构建高级 AI 应用如个性化推荐、知识库问答的基石。6. 实测中的关键细节与常见“坑点”通过上面的步骤你已经跑通了一个完整的流程。但在实际独立开发时你可能会遇到下面这些问题。了解它们能让你走得更稳。6.1 嵌入模型的选择与性能权衡我们使用了all-MiniLM-L6-v2它是一个权衡了速度和质量的模型。但在实际项目中模型选择至关重要更大更强的模型如all-mpnet-base-v2能生成 768 维、质量更高的向量搜索结果更精准但计算更慢、占用内存更多。更小更快的模型如all-MiniLM-L6-v2我们用的或paraphrase-albert-small-v2速度极快适合对延迟要求高的场景但精度略有牺牲。领域特定模型如果你处理的是医学、法律等专业文本使用在该领域语料上微调过的模型如bge系列、gte系列效果会远好于通用模型。实操心得不要一开始就追求最大最强的模型。先用一个像all-MiniLM-L6-v2这样的轻量级模型快速验证想法、搭建管道。当整个应用流程跑通并且语义搜索成为性能瓶颈或质量瓶颈时再考虑升级模型。升级模型通常意味着要重新生成所有向量的嵌入这是一个成本不低的操作。6.2 ChromaDB 持久化与生产部署我们的示例使用了内存客户端程序关闭数据就丢失了。对于真实项目你需要持久化。初始化客户端时指定一个目录即可# 持久化到磁盘 persistent_client chromadb.PersistentClient(path./my_chroma_db) collection persistent_client.get_or_create_collection(namepersistent_collection) # ... 后续的 add, query 操作不变这样数据会保存在./my_chroma_db目录下。下次运行程序连接到同一个路径和集合名数据依然存在。关于生产部署ChromaDB 也提供了 HTTP 服务器模式可以作为一个独立服务运行允许多个客户端通过网络连接。这对于微服务架构是必要的。你可以参考官方文档使用chroma run --path /db_path来启动服务端然后在客户端代码中连接http://localhost:8000。6.3 查询时为什么是results[documents][0]这是一个容易困惑的细节。collection.query的query_embeddings参数接受一个列表这意味着你可以一次性提交多个查询向量进行批量搜索。因此返回的results[‘documents’]也是一个列表其第一维对应查询的数量。我们只提交了一个查询所以需要取[0]来获得这个查询的结果列表。同理results[‘distances’][0]对应第一个查询与各个结果的距离列表。6.4 距离函数与分数解释ChromaDB 默认使用l2欧氏距离。距离越小越相似。你也可以在创建集合时指定cosine余弦相似度或ip内积。余弦相似度的值在 -1 到 1 之间1 表示完全相同通常更常用在文本相似度中。需要注意的是ChromaDB 的query接口返回的distances对于余弦相似度实际是1 - cosine_similarity所以它仍然是一个“距离”概念越小越好。理解你使用的距离度量方式对于设置相似度阈值例如只返回距离小于 0.3 的结果非常重要。7. 从体验到实践接下来可以尝试什么恭喜你现在你已经掌握了 ChromaDB 最基本也是最核心的操作。但这只是一个起点。你可以用这个工具做很多有趣的事情构建个人知识库问答系统将你的笔记、博客、PDF 文档切片并向量化存入 ChromaDB。然后你可以用自然语言提问让它帮你找到所有相关的笔记片段。再结合像 ChatGPT 这样的 LLM让它基于检索到的片段生成一个连贯的答案这就是一个最简单的 RAG检索增强生成应用原型。实现推荐系统将商品描述、电影简介、音乐标签向量化。根据用户的历史交互点击、购买向量在向量数据库中寻找相似的商品进行推荐。文本去重与聚类将大量文本向量化后通过计算向量之间的距离可以很容易地发现内容重复或主题相似的文档进行去重或自动归类。探索多模态ChromaDB 不仅能存文本向量也能存图像、音频的向量。你可以使用 CLIP 等多模态模型将图片和文本映射到同一个向量空间实现“用文字搜图片”或“用图片搜相似图片”。我个人的体会是向量数据库降低了AI应用中“记忆”和“联想”能力的实现门槛。它把复杂的相似性计算封装成了简单的add和query接口。真正的挑战和乐趣在于如何设计你的数据分块、清洗、添加元数据如何选择合适的嵌入模型以及如何将检索结果巧妙地与下游任务如LLM生成结合。这5分钟的极速入门希望为你打开了一扇门门后是一个正在被向量技术重塑的、更智能的数据处理世界。
返回列表