chromem-go向量数据库介绍

项目地址:
https://github.com/philippgille/chromem-go

一个可嵌入的 Go 向量数据库,具有类似 Chroma 的接口和零第三方依赖。支持内存存储,并可选持久化。

因为 chromem-go
 是可嵌入的,所以它允许你在 Go 应用程序中添加检索增强型生成(RAG)和类似的基于嵌入的特性,而无需运行单独的数据库。这就好比使用 SQLite 而不是 PostgreSQL/MySQL 等。

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

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

⚠️ 该项目处于测试阶段,正在积极开发中,在发布 v1.0.0
 之前可能会引入破坏性变更。所有变更都会记录在 CHANGELOG
 中。

使用场景

有了向量数据库,你可以做很多事情:

  • 检索增强型生成(RAG)、问答(Q&A)

  • 文本和代码搜索

  • 推荐系统

  • 分类

  • 聚类

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

RAG

大型语言模型(LLMs)的知识是有限的——即使是拥有 300 亿、700 亿参数甚至更多的模型也是如此。它们不知道训练结束后的任何事情,也不知道它们未被训练的数据(比如你公司的内网、Jira/缺陷跟踪器、维基或其他知识库)。即使是它们“知道”的数据,它们也往往无法精确复现,而是开始“幻觉”。

对 LLM 进行微调可以有所帮助,但它更多是为了改进 LLM 对特定主题的推理能力,或者复现特定的写作风格或代码风格。微调并不能将知识 1:1 地添加到模型中。细节会丢失或混淆,而且知识截止日期(关于微调后发生的事情)的问题仍未解决。

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

  1. 你将希望 LLM 了解的相关文档存储在数据库中。

  2. 数据库会存储文档的 嵌入
    ,你可以提供这些嵌入,也可以由特定的“嵌入模型”(如 OpenAI 的 text-embedding-3-small
    )生成。

  3. chromem-go
     可以为你完成这项工作,并且支持多种嵌入提供者和模型。

  4. 当你想与 LLM 对话时,首先将问题发送到向量数据库中以找到 相似的/相关的
     内容。这被称为“最近邻搜索”。

  5. 在向 LLM 提问时,将这些内容与问题一起提供。

  6. LLM 可以在回答时考虑这些最新的精确内容。

查看示例代码以了解实际操作!

接口

这个库最初灵感来源于 Chroma 的接口,其核心 API 如下:

Chroma 核心接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{% raw %}
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=[{"source":"notion"},{"source":"google-docs"}],# 可以根据这些进行过滤   
ids=["doc1","doc2"],# 每个文档的唯一标识)

# 查询/搜索 2 个最相似的结果。你也可以通过 ID 获取。
results = collection.query(   
query_texts=["这是一个查询文档"],   
n_results=2,    
# where={"metadata_field": "is_equal_to_this"}, # 可选过滤    
# where_document={"$contains":"search_string"}  # 可选过滤)

{% endraw %}
```

该 Go 库提供了相同的接口:

chromem-go 等效代码

package main
import “github.com/philippgille/chromem-go

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

// 创建集合。还提供 GetCollection、GetOrCreateCollection、DeleteCollection 等方法!    
collection,_:= db.CreateCollection("all-my-documents",nil,nil)    
// 向集合中添加文档。更新和删除功能将在未来添加。    
// 可以使用 AddConcurrently() 实现多线程!    
// 我们在这里展示了类似 Chroma 的方法,但也提供了一些更符合 Go 风格的方法!    

_= collection.Add(ctx,
        []string{"doc1","doc2"},// 每个文档的唯一标识
        nil,// 我们会自动处理嵌入。你也可以跳过这些步骤并添加自己的嵌入。
        []map[string]string
{{"source":"notion"},
    {"source":"google-docs"}},
// 可以根据这些进行过滤
        []string{"这是文档1","这是文档2"},
    )
    // 查询/搜索 2 个最相似的结果。你也可以通过 ID 获取。
    results,_:= collection.Query(ctx,
        "这是一个查询文档",
        2,
        map[string]string
{"metadata_field":"is_equal_to_this"},// 可选过滤
        map[string]string{"$contains":"search_string"},
         // 可选过滤
    )}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  
完整的接口请查看 Godoc:
https://pkg.go.dev/github.com/philippgille/chromem-go
## 功能
- 零第三方库依赖

- 可嵌入(类似 SQLite,即没有客户端-服务器模型,无需维护单独的数据库)

- 多线程处理(在添加和查询文档时),充分利用 Go 的原生并发特性

- 实验性 WebAssembly 绑定

- embedding创建器:

- Ollama

- LocalAI

- OpenAI(默认)

- Azure OpenAI

- GCP Vertex AI

- Cohere

- Mistral

- Jina

- mixedbread.ai

- 托管:

- 本地:

- 自定义(实现 chromem.EmbeddingFunc


- 你也可以在添加文档到集合时传递现有的嵌入,而不是让 chromem-go
 创建它们

- 相似性搜索:

- 使用余弦相似度进行穷尽最近邻搜索(有时也称为精确搜索、暴力搜索或 FLAT 索引)

- 过滤器:

- 文档过滤器:$contains
、$not_contains

- 元数据过滤器:精确匹配

- 存储:

- 包括通用的 io.Writer
/io.Reader
 方法,因此你可以接入 S3 存储桶和其他对象存储,查看示例代码 examples/s3-export-import

- 内存

- 可选即时持久化(为每个添加的集合和文档写入一个文件,以 gob 格式编码,可选 gzip 压缩)

- 备份:将整个数据库导出和导入到一个文件(以 gob 格式编码,可选 gzip 压缩和 AES-GCM 加密)

- 数据类型:

- 文档(文本)

## 安装

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

1
2
3
4
5
6
7
8
9
## 使用  

查看 Godoc 获取参考:
https://pkg.go.dev/github.com/philippgille/chromem-go

查看完整的示例代码,了解如何使用向量数据库进行检索增强型生成(RAG)和语义搜索,以及如何使用 OpenAI 或本地运行的嵌入模型和 LLM(在 Ollama 中)。
### 快速入门

以下是“最小”示例中的代码:

package mainimport(“context”“fmt”“runtime”“github.com/philippgille/chromem-go”)funcmain(){  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:“The sky is blue because of Rayleigh scattering.”,    },    {      ID:      “2”,      Content:“Leaves are green because chlorophyll absorbs red and blue light.”,    },}, runtime.NumCPU())if err !=nil{    panic(err)}  res, err := c.Query(ctx,“Why is the sky blue?”,1,nil,nil)if err !=nil{    panic(err)}  fmt.Printf(“ID: %v\nSimilarity: %v\nContent: %v\n”, res[0].ID, res[0].Similarity, res[0].Content)}

1
2
  
输出:

ID: 1Similarity: 0.6833369Content: The sky is blue because of Rayleigh scattering.

  
  

![江达小记](/images/wechatmpscan.png)