Project Icon

chromem-go

Go语言内嵌式向量数据库 支持RAG和语义搜索

chromem-go是一款Go语言内嵌式向量数据库,采用Chroma风格接口,无需第三方依赖。支持内存存储和可选持久化,聚焦常见用例的简单性和性能。适用于检索增强生成(RAG)和语义搜索等场景,可直接嵌入应用无需单独部署。具备多线程处理能力,支持多种嵌入创建方式,提供相似度搜索和过滤功能。

chromem-go

Go 参考 构建状态 Go 报告卡 GitHub 发布

适用于 Go 的可嵌入向量数据库,具有类 Chroma 接口,零第三方依赖。内存存储,可选持久化。

由于 chromem-go 是可嵌入的,它使您能够将检索增强生成(RAG)和类似的基于嵌入的功能添加到您的 Go 应用程序中,而无需运行单独的数据库。就像使用 SQLite 而不是 PostgreSQL/MySQL 等。

它不是连接 Chroma 的库,也不是用 Go 重新实现 Chroma。它是一个独立的数据库。

重点不是规模(数百万文档)或功能数量,而是最常见用例的简单性和性能。在 2020 年中端英特尔笔记本 CPU 上,您可以在 0.3 毫秒内查询 1,000 个文档,在 40 毫秒内查询 100,000 个文档,内存分配很少且很小。详情请参见基准测试

⚠️ 该项目处于测试阶段,正在大规模构建中,在 v1.0.0 发布之前的版本中可能会引入重大更改。所有更改都记录在 CHANGELOG 中。

目录

  1. 使用场景
  2. 接口
  3. 功能 + 路线图
  4. 安装
  5. 使用方法
  6. 基准测试
  7. 开发
  8. 动机
  9. 相关项目

使用场景

使用向量数据库,您可以做各种事情:

  • 检索增强生成(RAG),问答(Q&A)
  • 文本和代码搜索
  • 推荐系统
  • 分类
  • 聚类

让我们详细看看 RAG 使用场景:

RAG

大型语言模型(LLM)的知识是有限的 - 即使是那些拥有 300 亿、700 亿甚至更多参数的模型。它们不知道训练结束后发生的事情,不知道未经训练的数据(如您公司的内网、Jira / 错误跟踪器、维基或其他类型的知识库),即使是它们确实知道的数据,它们通常也无法准确重现,反而会开始产生"幻觉"。

微调 LLM 可以稍微有所帮助,但它更多是为了改善 LLM 对特定主题的推理,或重现文本或代码的风格。微调并不能将知识一对一地添加到模型中。细节会丢失或混淆。而且知识截止(关于微调后发生的任何事情)的问题也没有解决。

=> 向量数据库可以作为 LLM 的最新、精确知识来源:

  1. 您将想要 LLM 了解的相关文档存储在数据库中。
  2. 数据库将嵌入向量与文档一起存储,您可以提供这些嵌入向量,也可以由特定的"嵌入模型"(如 OpenAI 的 text-embedding-3-small)创建。
    • chromem-go 可以为您完成这项工作,并支持多个嵌入提供商和模型。
  3. 之后,当您想与 LLM 对话时,首先将问题发送到向量数据库以找到相似/相关的内容。这称为"最近邻搜索"。
  4. 在向 LLM 提问时,您将这些内容与您的问题一起提供。
  5. LLM 在回答时可以考虑这些最新的精确内容。

查看 示例代码 以了解其运行情况!

接口

我们最初的灵感来自 Chroma 接口,其核心 API 如下(摘自他们的 README):

Chroma 核心接口
import chromadb
# 在内存中设置 Chroma,便于原型设计。可以轻松添加持久性!
client = chromadb.Client()

# 创建集合。还可使用 get_collection、get_or_create_collection、delete_collection!
collection = client.create_collection("all-my-documents")
# 向集合添加文档。也可以更新和删除。基于行的 API 即将推出!
collection.add(
    documents=["这是文档1", "这是文档2"], # 我们自动处理分词、嵌入和索引。你也可以跳过这些步骤,添加自己的嵌入
    metadatas=[{"来源": "notion"}, {"来源": "google-docs"}], # 可以基于这些进行过滤!
    ids=["doc1", "doc2"], # 每个文档唯一
)

# 查询/搜索2个最相似的结果。你也可以通过 id 使用 .get 方法获取
results = collection.query(
    query_texts=["这是一个查询文档"],
    n_results=2,
    # where={"元数据字段": "等于这个值"}, # 可选过滤器
    # where_document={"$contains":"搜索字符串"}  # 可选过滤器
)

我们的 Go 库提供了相同的接口:

chromem-go 等效代码
package main

import "github.com/philippgille/chromem-go"

func main() {
    // 设置 chromem-go 内存模式,方便原型开发。可以轻松添加持久化!
    // 我们称之为 DB 而不是 client,因为没有客户端-服务器分离。DB 是嵌入式的。
    db := chromem.NewDB()

    // 创建集合。也可以使用 GetCollection、GetOrCreateCollection、DeleteCollection!
    collection, _ := db.CreateCollection("我的所有文档", nil, nil)

    // 向集合添加文档。未来将添加更新和删除功能。
    // 可以使用 AddConcurrently() 进行多线程处理!
    // 这里我们展示了类似 Chroma 的方法,但也提供了更符合 Go 习惯的方法!
    _ = collection.Add(ctx,
        []string{"doc1", "doc2"}, // 每个文档的唯一 ID
        nil, // 我们自动处理嵌入。你也可以跳过这步,添加自己的嵌入。
        []map[string]string{{"来源": "notion"}, {"来源": "google-docs"}}, // 可以基于这些进行过滤!
        []string{"这是文档1", "这是文档2"},
    )

    // 查询/搜索2个最相似的结果。未来将添加通过 ID 获取的功能。
    results, _ := collection.Query(ctx,
        "这是一个查询文档",
        2,
        map[string]string{"元数据字段": "等于这个值"}, // 可选过滤器
        map[string]string{"$contains": "搜索字符串"},         // 可选过滤器
    )
}

最初,chromem-go 只有四个核心方法,但随着时间推移我们添加了更多功能。不过我们有意不覆盖 Chroma 100% 的 API 表面。 我们提供了一些更符合 Go 习惯的替代方法。

完整接口请参见 Godoc:https://pkg.go.dev/github.com/philippgille/chromem-go

功能

  • 零依赖第三方库
  • 可嵌入(类似 SQLite,即无客户端-服务器模型,无需维护单独的数据库)
  • 多线程处理(添加和查询文档时),利用 Go 原生的并发特性
  • 实验性 WebAssembly 绑定
  • 嵌入创建器:
  • 相似性搜索:
    • 使用余弦相似度的穷尽最近邻搜索(有时也称为精确搜索、暴力搜索或 FLAT 索引)
  • 过滤器:
    • 文档过滤器:$contains$not_contains
    • 元数据过滤器:精确匹配
  • 存储:
    • 内存
    • 可选的即时持久化(为每个添加的集合和文档写入一个文件,以 gob 编码,可选 gzip 压缩)
    • 备份:将整个数据库导出到单个文件和从单个文件导入(以 gob 编码,可选 gzip 压缩和 AES-GCM 加密)
      • 包括用于通用 io.Writer/io.Reader 的方法,因此你可以插入 S3 存储桶和其他 blob 存储,示例代码见 examples/s3-export-import
  • 数据类型:
    • 文档(文本)

路线图

  • 性能:
    • 在支持的CPU上使用SIMD进行点积计算(草案PR:#48
    • 添加roaring bitmaps以加速全文过滤
  • 嵌入创建器:
    • 添加一个EmbeddingFunc,用于下载并调用llamafile
  • 相似度搜索:
    • 带索引的近似最近邻搜索(ANN)
      • 分层可导航小世界(HNSW)
      • 倒排文件平面(IVFFlat)
  • 过滤器:
    • 运算符($and$or等)
  • 存储:
    • JSON作为第二种编码格式
    • 预写日志(WAL)作为第二种文件格式
    • 可选的远程存储(S3、PostgreSQL等)
  • 数据类型:
    • 图片
    • 视频

安装

go get github.com/philippgille/chromem-go@latest

使用

参考Godoc文档:https://pkg.go.dev/github.com/philippgille/chromem-go

完整的工作示例,使用向量数据库进行检索增强生成(RAG)和语义搜索,并使用OpenAI或本地运行嵌入模型和LLM(在Ollama中),请参见示例代码

快速入门

以下内容摘自"最小"示例

package main

import (
 "context"
 "fmt"
 "runtime"

 "github.com/philippgille/chromem-go"
)

func main() {
  ctx := context.Background()

  db := chromem.NewDB()

  c, err := db.CreateCollection("knowledge-base", nil, nil)
  if err != nil {
    panic(err)
  }

  err = c.AddDocuments(ctx, []chromem.Document{
    {
      ID:      "1",
      Content: "天空呈蓝色是因为瑞利散射。",
    },
    {
      ID:      "2",
      Content: "树叶是绿色的因为叶绿素吸收红光和蓝光。",
    },
  }, runtime.NumCPU())
  if err != nil {
    panic(err)
  }

  res, err := c.Query(ctx, "为什么天空是蓝色的?", 1, nil, nil)
  if err != nil {
    panic(err)
  }

  fmt.Printf("ID: %v\n相似度: %v\n内容: %v\n", res[0].ID, res[0].Similarity, res[0].Content)
}

输出:

ID: 1
相似度: 0.6833369
内容: 天空呈蓝色是因为瑞利散射。

基准测试

2024-03-17进行的基准测试,配置如下:

  • 计算机:Framework Laptop 13(第一代,2021)
  • CPU:第11代英特尔酷睿i5-1135G7(2020)
  • 内存:32 GB
  • 操作系统:Fedora Linux 39
    • 内核:6.7
$ go test -benchmem -run=^$ -bench .
goos: linux
goarch: amd64
pkg: github.com/philippgille/chromem-go
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
BenchmarkCollection_Query_NoContent_100-8          13164      90276 ns/op     5176 B/op       95 allocs/op
BenchmarkCollection_Query_NoContent_1000-8          2142     520261 ns/op    13558 B/op      141 allocs/op
BenchmarkCollection_Query_NoContent_5000-8           561    2150354 ns/op    47096 B/op      173 allocs/op
BenchmarkCollection_Query_NoContent_25000-8          120    9890177 ns/op   211783 B/op      208 allocs/op
BenchmarkCollection_Query_NoContent_100000-8          30   39574238 ns/op   810370 B/op      232 allocs/op
BenchmarkCollection_Query_100-8                    13225      91058 ns/op     5177 B/op       95 allocs/op
BenchmarkCollection_Query_1000-8                    2226     519693 ns/op    13552 B/op      140 allocs/op
BenchmarkCollection_Query_5000-8                     550    2128121 ns/op    47108 B/op      173 allocs/op
BenchmarkCollection_Query_25000-8                    100   10063260 ns/op   211705 B/op      205 allocs/op
BenchmarkCollection_Query_100000-8                    30   39404005 ns/op   810295 B/op      229 allocs/op
PASS
ok   github.com/philippgille/chromem-go 28.402s

开发

  • 构建:go build ./...
  • 测试:go test -v -race -count 1 ./...
  • 基准测试:
    • go test -benchmem -run=^$ -bench .(添加 > bench.out 或类似命令将结果写入文件)
    • 带性能分析:go test -benchmem -run ^$ -cpuprofile cpu.out -bench .
      • (性能分析选项:-cpuprofile-memprofile-blockprofile-mutexprofile
  • 比较基准测试结果:
    1. 安装 benchstatgo install golang.org/x/perf/cmd/benchstat@latest
    2. 比较两次基准测试结果:benchstat before.out after.out

动机

2023年12月,当我想在Go程序中尝试检索增强生成(RAG)时,我寻找一个可以嵌入Go程序的向量数据库,就像嵌入SQLite那样,不需要单独的数据库设置和维护。令我惊讶的是,考虑到Go生态系统中嵌入式键值存储的丰富性,我竟然找不到这样的数据库。

当时,大多数流行的向量数据库,如Pinecone、Qdrant、Milvus、Chroma、Weaviate等,要么完全不可嵌入,要么只能在Python或JavaScript/TypeScript中嵌入。

后来我发现了@eliben博客文章示例代码,展示了如何用很少的Go代码创建一个非常基础的向量数据库概念验证。

那时我决定构建自己的向量数据库,可嵌入Go,灵感来自ChromaDB的接口。ChromaDB因可嵌入(在Python中)而脱颖而出,并在其README和网站首页上展示了其核心API的4个命令。

相关项目

  • 感谢 @eliben,他的博文示例代码激发了我开始这个项目的灵感!
  • Chroma:在比较Pinecone、Qdrant、Milvus、Weaviate等数据库时,Chroma脱颖而出,因为它在README和网站首页仅用4个命令就展示了其核心API。它还特别强调了自身在Python中的可嵌入性。
  • 大型、功能齐全的基于客户端-服务器的向量数据库,用于最大化规模和性能:
    • Pinecone:闭源
    • Qdrant:用Rust编写,无法嵌入Go
    • Milvus:用Go和C++编写,但截至2023年12月不可嵌入
    • Weaviate:用Go编写,但截至2024年3月不可嵌入Go(仅可在Python和JavaScript/TypeScript中嵌入,且仍处于实验阶段)
  • 一些非专门的SQL、NoSQL和键值数据库添加了存储向量和(部分)基于相似度查询的支持:
    • PostgreSQLpgvector扩展:客户端-服务器模型
    • Redis12):客户端-服务器模型
    • SQLitesqlite-vss扩展:嵌入式,但Go绑定需要CGO。有一个无CGO的Go库用于SQLite,但缺少向量搜索扩展。
    • DuckDB有计算余弦相似度的函数(1):嵌入式,但Go绑定使用CGO
    • MongoDB的云平台提供向量搜索产品(1):客户端-服务器模型
  • 一些向量相似度搜索库:
    • Faiss:用C++编写;第三方Go绑定使用CGO
    • Annoy:用C++编写;Go绑定使用CGO(1
    • USearch:用C++编写;Go绑定使用CGO
  • 一些受Python库LangChain启发的编排库,但没有或仅有简单的嵌入式向量数据库:
项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号