游乐游手机版
首页/AI热点日报/热点详情

如何在Rust中用一周时间编写一个矢量数据库

类型:热点整理2026-07-13
用Rust构建的版本化矢量数据库采用HNSW索引与页式存储,支持增量索引和提交版本管理。通过OpenAI嵌入与自定义模板实现语义搜索,测试表明即使查询词未出现在原文中也能准确匹配语义。

从零开始:用Rust构建一个版本化矢量数据库

矢量数据库正成为AI应用的核心组件,它通过向量嵌入实现语义搜索、相似性匹配等强大功能。然而,大多数开源方案缺乏版本控制能力,无法满足增量索引和CI工作流的需求。本文基于TerminusDB团队的实践,详细讲解如何用Rust编写一个支持版本化的矢量数据库,涵盖存储、索引、查询等关键环节。

为什么需要矢量数据库

矢量数据库用于存储和检索向量(即嵌入),利用向量之间的距离度量(如欧几里得距离、余弦相似度)实现语义相似性。例如,在Word2Vec中,king - man + woman ≈ queen。这种能力对以下任务至关重要:

  • 全文搜索
  • 实体解析(查找重复文档)
  • 相似性搜索(推荐系统)
  • 聚类

TerminusDB需要支持增量索引提交版本管理,以便在CI工作流中精确追溯索引对应的数据版本。但现有开源矢量数据库均不支持版本化,因此他们决定自行实现。

小提示: 版本化索引在需要回滚或审计数据的场景中非常有用,例如金融、医疗等合规性要求高的领域。

核心概念:HNSW索引

向量数据库需要快速比较向量,因此必须构建索引结构来减少比对次数。他们选用了HNSW(Hierarchical Navigable Small World)图算法(Malkov & Yashunin)。HNSW在低维和高维空间均表现良好,且实现简单。他们借鉴了Rust计算机视觉领域的开源HNSW实现。

HNSW的核心思想是构建多层图结构:顶层节点用于快速导航,底层节点包含所有向量。搜索时从顶层开始,逐层向下,快速定位候选向量。

常见问题:为什么选择HNSW而不是其他索引?

  • HNSW在数百万级向量上仍能保持亚秒级响应。
  • 相比Annoy(Spotify使用的近似最近邻算法),HNSW支持动态插入和删除。
  • 相比FAISS(Facebook开源的向量检索库),HNSW的内存占用更可控,适合嵌入式场景。

存储向量:页式存储与域管理

向量存储在域(Domain)中,每个域对应一组语义相关的向量。例如TerminusDB的不同数据提交属于同一域,因此共享相同的向量存储。

向量存储采用基于页面(Page-based)的缓冲区设计,每个页面大小与操作系统页面对齐,但对向量数据进行紧凑存储。每个向量分配唯一的索引号,通过索引号可映射到对应页面和偏移量。

在HNSW索引中,使用LoadedVec结构引用当前加载到内存的向量页面。当页面被逐出时,LoadedVec被回收,新页面可重新使用该缓冲区。

// 伪代码示意:向量索引到页面的映射
struct VecIndex {
    page_id: u32,
    offset: u32,
    length: u32,
}

小提示: 页式存储可以实现高效的磁盘I/O,避免内存碎片。推荐每页固定存储512或1024个向量,便于预计算。

创建版本化索引

每个(域 + 提交)对对应一个独立的HNSW结构。索引过程如下:

  • 如果是新索引,从空HNSW开始。
  • 如果是增量索引,加载上一次提交的HNSW,然后执行插入、删除、替换操作。
  • 变更由TerminusDB提供(通过差分算法找出提交间的变化),索引器只接收三种操作:InsertDeleteReplace

索引本身维护在LRU缓存池中,按需加载或复用。由于只有在提交时才会进行破坏性操作,缓存始终保持一致。

保存索引时,使用原始向量索引作为替身序列化HNSW结构,这能保持索引文件紧凑。未来计划引入层级层(Layer)技术,使增量索引无需复制整个结构,但目前索引规模相比向量本身已经足够小,暂不需要优化。

常见问题:删除和替换操作如何实现?

目前仅实现了插入操作(一周的开发时间有限)。团队设计了以下方案(尚未实现):

  • 在HNSW的高层中,直接忽略删除——因为高层节点仅用于导航,数量很少。
  • 在零层(底层)但不在高层的节点:从图中删除,并尝试用附近节点替代被删除节点的连接。
  • 在零层且也在高层的节点:标记为“已删除”,仍用于导航,但不加入候选池。

这个设计需要仔细验证,确保搜索精度不受影响。

查找嵌入:OpenAI + 自定义模板

TerminusDB使用OpenAI的嵌入API生成向量。在索引时,每个文档被发送给OpenAI,返回浮点向量列表。关键经验:嵌入的质量高度依赖上下文。直接提交原始JSON文档效果不佳。

他们发现,通过定义GraphQL查询 + Handlebars模板,可以生成高质量的嵌入。例如,对于《星球大战》中的People对象,模板将字段转换为自然语言描述:

{
    "embedding": {
        "query": "query($id: ID){ People(id : $id) { birth_year, created, desc, edited, eye_color, gender, hair_colors, height, homeworld { label }, label, mass, skin_colors, species { label }, url } }",
        "template": "The person's name is {{label}}.{{#if desc}} They are described with the following synopsis: {{#each desc}} *{{this}} {{/each}}.{{/if}}{{#if gender}} Their gender is {{gender}}.{{/if}}{{#if hair_colors}} They ha ve the following hair colours: {{hair_colors}}.{{/if}}{{#if mass}} They ha ve a mass of {{mass}}.{{/if}}{{#if skin_colors}} Their skin colours are {{skin_colors}}.{{/if}}{{#if species}} Their species is {{species.label}}.{{/if}}{{#if homeworld}} Their homeworld is {{homeworld.label}}.{{/if}}"
    }
}

未来计划:利用AI聊天模型从模式文档和数据结构中自动生成这样的模板,进一步降低使用门槛。

小提示: 模板中的字段描述越接近自然语言,嵌入效果越好。可以尝试加入关键属性(如颜色、特征、关系)来提升语义区分度。

实战:为星球大战数据索引

他们使用《星球大战》数据产品进行测试。首先发起索引请求:

curl 'localhost:8080/index?commit=o2uq7k1mrun1vp4urktmw55962vlpto&domain=admin/star_wars'

返回一个任务ID,可通过轮询确认完成。索引文件和向量文件分别命名为:admin%2Fstar_wars@o2uq7k1mrun1vp4urktmw55962vlpto.hnswadmin%2Fstar_wars.vecs

现在可以搜索:

curl 'localhost:8080/search?commit=o2uq7k1mrun1vp4urktmw55962vlpto&domain=admin/star_wars' -d "Who are the squid people"

返回结果:

[{"id":"terminusdb:///star-wars/Species/8","distance":0.09396297}, ...]

对应的嵌入文本为:

"The species name is Mon Calamari. They ha ve the following hair colours: none. Their skin colours are red, blue, brown, magenta. They speak the Mon Calamarian language."

注意:文本中从未出现“squid”(鱿鱼),但嵌入成功匹配了“squid people”的语义。

再试“Wise old man”:

curl 'localhost:8080/search?commit=o2uq7k1mrun1vp4urktmw55962vlpto&domain=admin/star_wars' -d "Wise old man"

返回结果是Yoda(尤达)的相关描述,尽管文本中只提到“最古老”,并未出现“聪明”或“人”等词。

常见问题:嵌入对上下文敏感,如何确保质量?

  • 使用结构化的模板将字段转化为完整语句,避免缺失属性。
  • 对于缺失字段(如desc),使用条件语法避免产生空字符串。
  • 如果数据中存在多种语言,建议统一使用英文模板(OpenAI嵌入对英文效果最佳)。

结论与展望

本教程详细介绍了如何使用Rust构建一个支持版本化的矢量数据库,涵盖HNSW索引、页式存储、增量索引、自定义嵌入模板等核心组件。实际测试表明,该数据库能够精准理解语义,即使查询词不出现在原始文本中也能返回正确结果。

未来计划包括:实现删除和替换操作的完整支持;引入层级层技术减少增量索引的冗余;以及利用AI自动生成模板,进一步简化用户工作。

虽然业界已有Pinecone等优秀产品,但作为一个与TerminusDB深度集成的sidecar组件,该数据库为技术栈较浅的用户提供了便捷、版本可控的语义搜索能力。如果你对项目源码感兴趣,欢迎访问TerminusDB仓库获取更多信息。

来源:https://m.elecfans.com/article/2103128.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。