跳到主要内容 向量数据库:核心原理、索引机制与 Chroma 实践 | 极客日志
目录
向量数据库概述 向量嵌入技术 向量搜索原理 向量索引技术 工作流程 Chroma 示例与实践 基本工作流程 测试数据准备 创建集合 添加到集合 [[-0.045326605439186096, 0.004748976789414883, 0.02001281827688217, 0.007265775464475155, -0.0672430619597435, ...]] 查询:相似性搜索 相似性搜索 输出两个相似的结果 { "ids": [["id1", "id2"]], "distances": [[1.6440917253494263, 1.6728706359863281]], "metadatas": [[{"source": "department info"}, {"source": "employee info"}]], "embeddings": None, "documents": [ [ "The development department at XYZ Corporation is responsible for designing, implementing....", "James Smith, a 32-year-old software engineer with 8 years of experience.......", ] ], "uris": None, "data": None } 查询过滤器 在匹配的元数据中查找 依据文档的内容进行过滤 results = collection.query( query_texts=["What is the employee's name?"], n_results=2, where_document={"$contains":"engineer"} ) 自定义嵌入模型 嵌入的向量 [[0.9733191728591919, -2.4074814319610596, -1.0328993794366455, ...]] 添加嵌入的向量 查询输出 { "ids": [["id1", "id3"]], "distances": [[27612.076171875, 29216.796875]], "metadatas": [[{"source": "employee info"}, {"source": "company info"}]], "embeddings": None, "documents": [ [ "James Smith, a 32-year-old software engineer with 8 years of experience, ....", "XYZ Corporation, established in 2005 in Silicon Valley, is a leading software development company specializing...." ] ], "uris": None, "data": None } 更新与删除数据 更新 相似性搜索 输出的员工信息变为了 Bob { "ids": [["id1", "id2"]], "distances": [[1.4391101598739624, 1.6440917253494263]], "metadatas": [[{"source": "employee info"}, {"source": "department info"}]], "embeddings": None, "documents": [ [ "Bob, a 28-year-old test engineer with 4 years of experience", "The development department at XYZ Corporation is responsible for designing, implementing..." ] ], "uris": None, "data": None } 最佳实践与总结
Python AI 算法
向量数据库:核心原理、索引机制与 Chroma 实践 向量数据库是处理高维嵌入数据的关键基础设施,支持对非结构化数据进行语义搜索。本文详细阐述了向量嵌入的概念、余弦相似度计算原理及向量索引技术(如 HNSW、IVF)。通过 Chroma 数据库的实战示例,展示了集合创建、数据添加、相似度查询、元数据过滤及模型切换等核心操作。文章还补充了更新、删除数据及最佳实践指南,帮助开发者理解如何在实际项目中利用向量数据库增强大模型应用的数据检索能力。
赛博朋克 发布于 2025/2/6 更新于 2026/4/20 1 浏览随着大型语言模型(LLM)的开源与普及,开发人员逐渐意识到向量数据库在增强模型能力方面的重要性。像 GPT 这类大模型通常使用大规模的嵌入向量来表示文本数据,而向量数据库提供了高效存储和检索这些向量数据的能力,使得在应用中存储和访问高维语义信息变得更加高效和快速。
向量数据库概述 向量数据库是一种专门用于索引、存储结构化或非结构化数据(例如文本、图像、音频等)及其向量嵌入(数据的数字表示)的数据库系统。它允许用户在生产环境中快速大规模地查找和检索相似的对象。由于其高效的搜索功能,向量数据库有时也被称为向量搜索引擎。与传统的关系型数据库不同,向量数据库不依赖于精确匹配,而是基于向量之间的相似度进行模糊匹配。
向量嵌入技术 现实生活中的数据主要分为结构化数据(如电子表格中的组织整齐的数据)和非结构化数据(如文档、图像、音视频等)。绝大多数业务数据属于非结构化数据,这类数据很难以传统方式存储以便轻松找到所需内容。如何对这些数据进行量化存储并实现快速查找是核心挑战。
向量嵌入是一种将非结构化数据转换为数学向量的方法,使得数据可以被量化存储并且可以进行快速查找。通过向量嵌入,非结构化数据被映射到一个多维的向量空间中,每个数据项都用一个向量来表示。这些向量通常被设计成能够捕捉数据的语义信息,使得相似的数据在向量空间中距离较近,不相似的数据在向量空间中距离较远。
现代机器学习模型可以经过训练将原始数据转换为嵌入,表示为固定维度的浮点数数组(或向量)。向量数据库便是用于存储这些嵌入向量的专用数据库。
向量搜索原理 使用向量嵌入,我们可以在向量空间中搜索彼此接近的对象,以找到并检索相似的对象。这种搜索方式被称为向量搜索、相似性搜索或语义搜索。
具体向量搜索是如何进行的?举个例子来讲:我们基于人格五因素测试对多人进行性格测试,在 5 个维度上收集了他们的评分,并将这些评分作为向量嵌入。为方便在平面坐标系中展示向量之间的关系,我们先只取 2 个维度的数据,将评分范围调到 -1 ~ 1,并将这些点表示为从坐标原点到它们的向量。
如果 Jay 需要寻找与其性格相似的人去代替,机器如何识别呢?这时向量的表示法就可以让我们通过数学方式计算向量的相似性来找到目标。
向量的相似性通常通过计算两个向量之间的距离来确定。计算相似度分数的常用方法是余弦相似度,其数学定义与公式如下:
给定两个 n 维属性向量 A 和 B,它们的余弦相似度 cos(θ) 通过使用向量点积和向量长度表示为:
$$ \cos(\theta) = \frac{A \cdot B}{||A|| ||B||} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$
其中,Ai 和 Bi 分别是向量 A 和 B 的第 i 个分量。按照数学公式我们可以计算出 Person #1 和 Jay 相似度最高,两个向量的夹角也最小,因此他们更相似。
实际上两个维度的特征不足以判断人格是否相似,因此我们需要用到 5 个维度的数据。虽然数据维度升高,但这种比较向量相似度的方法适用于任意维度的向量空间。
向量索引技术 向量索引是一种用于在大规模数据集中快速搜索相似向量的技术。通俗地说,就像我们在一堆杂乱的图片中找到与给定图片相似的图片一样。构建向量索引就像是给大量的照片贴上标签并整理成相册一样。
想象一下,你有一个非常大的图像库,每张图片都表示为一个向量。现在,你希望找到与给定图片相似的图片。这时,向量索引就派上了用场。可以根据给定图片的向量,在多维数据空间中快速定位相册,然后快速定位那些与给定图片在向量空间中距离较近的图片,而不必一个一个地比较每张图片。
基于聚类的索引 (如 IVF)
基于邻近图的索引 (如 HNSW)
基于树的索引 (如 KD-Tree)
基于哈希的索引 (如 LSH)
基于压缩的索引 (如 PQ)
向量索引在实际中有许多应用,比如图像搜索、语义搜索、推荐系统等。它能够帮助我们快速地处理和检索大规模的向量数据,从而在很多领域提高效率和性能。
工作流程
索引 :对嵌入的向量通过索引算法对其进行索引并将向量数据和构建好的索引结构存储到数据库中。
查询 :向量数据库会根据查询向量在向量索引中进行搜索,并返回与查询向量最相似的向量结果。
后期处理 :在某些情况下,向量数据库从数据集中检索出一组与查询向量最相似的向量,并对它们进行后期处理,以返回最终的结果。这个步骤可能包括使用不同的相似度度量重新对查询到的相似向量进行排序。换句话说,就像在购物网站上找到了一些可能的商品,然后根据不同的标准重新排序,以便更好地满足用户的需求。
Chroma 示例与实践 Chroma DB 是一个开源矢量存储,用于存储和检索矢量嵌入。它的主要用途是保存嵌入以及元数据,交由 LLM 模型使用。此外,它还可以用于文本数据的语义搜索引擎。
基本工作流程
创建 collection(类似关系型数据库中的表)。
使用元数据和唯一的 ID 将文本添加到集合中。
通过文本或嵌入查询集合。也可以通过元数据过滤结果。
测试数据准备 employee_info = """
James Smith, a 32-year-old software engineer with 8 years of experience,
is a member of the development and hiking clubs who enjoys cooking, photography, and playing guitar
in his free time. He aspires to lead a tech team after gaining more expertise in his field
at XYZ Corporation.
"""
department_info = """
The development department at XYZ Corporation is responsible for designing, implementing,
and maintaining the software products of the company. It consists of skilled professionals
ranging from software engineers to UX designers, working collaboratively to innovate
and deliver high-quality solutions to clients' needs.
"""
company_info = """
XYZ Corporation, established in 2005 in Silicon Valley, is a leading software development company
specializing in creating cutting-edge solutions for various industries. With over 1000 employees
and offices in multiple countries, XYZ Corp is known for its commitment to excellence and innovation
in the tech sector.
"""
默认情况下 Chroma 使用 all-MiniLM-L6-v2 模型将文字转换为向量。
import chromadb
chroma_client = chromadb.Client()
collection = chroma_client.create_collection(name="employee" )
collection.add(documents=[employee_info, department_info, company_info],
metadatas=[{"source" : "employee info" }, {"source" : "department info" }, {"source" : "company info" }],
ids=["id1" , "id2" , "id3" ]
)
添加数据到集合时便会自动下载 all-MiniLM-L6-v2 模型,并将文本转为嵌入到集合中。
from chromadb.utils import embedding_functions
def_efn = embedding_functions.DefaultEmbeddingFunction()
embedding_text = def_efn(['早上' ,'好' ])
查询:相似性搜索
results = collection.query(
query_texts=["What is the employee's name?" ],
n_results=2
)
查询过滤器
results = collection.query(
query_texts=["What is the employee's name?" ],
n_results=2 ,
where={"source" :{"$in" :["employee info" ,"company info" ]}}
)
自定义嵌入模型 也可以不使用默认的嵌入模型,例如使用 Ollama 提供的模型。
from chromadb.utils import embedding_functions
ollama_ef = embedding_functions.OllamaEmbeddingFunction(
url="http://localhost:11434/api/embeddings" ,
model_name="llama3" ,
)
employees_embeddings = ollama_ef([employee_info, department_info, company_info])
collection2 = chroma_client.get_or_create_collection(name="other_employee" ,
embedding_function=ollama_ef)
collection2.add(embeddings=employees_embeddings,
documents=[employee_info, department_info, company_info],
metadatas=[{"source" : "employee info" }, {"source" : "department info" }, {"source" : "company info" }],
ids=["id1" , "id2" , "id3" ]
)
result2 = collection2.query(query_texts=["What is the employee's name?" ],
n_results=2 )
和默认的词嵌入模型不同的是,相似度匹配到了 employee_info 和 company_info。不同的词嵌入模型执行查询时会有不一样的效果,选择适合场景的模型至关重要。
更新与删除数据
collection.update(ids=["id1" ],
documents=["Bob, a 28-year-old test engineer with 4 years of experience" ],
metadatas=[{"source" :"employee info" }],
)
results = collection.query(
query_texts=["What is the employee's name?" ],
n_results=2
)
print (f"删除前集合有 {collection.count()} 条记录" )
collection.delete(ids=["id1" ])
print (f"删除后集合有 {collection.count()} 条记录" )
最佳实践与总结
选择合适的嵌入模型 :不同的任务(如代码、医疗、法律)可能需要特定的预训练模型。确保模型能准确捕捉领域语义。
优化索引参数 :对于大规模数据,调整索引参数(如 HNSW 的 M 值和 efConstruction)可以平衡查询速度与召回率。
元数据管理 :充分利用元数据进行过滤,可以减少向量搜索的范围,提高查询效率。
持久化存储 :定期将内存中的集合持久化到磁盘,防止服务重启导致数据丢失。
向量数据库已成为 AI 应用开发的基础设施之一。随着多模态大模型的发展,其对向量检索的需求将进一步增长。掌握向量数据库的核心原理与工具使用,对于构建现代化的智能应用系统至关重要。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online