可嵌入的矢量数据库,用于具有色度样界面和零第三方依赖性。可选持久性内存。
由于chromem-go是可嵌入的,因此您可以在GO应用中添加检索增强生成(RAG)和类似的基于嵌入的功能,而无需运行单独的数据库。就像使用SQLITE代替PostgreSQL/MySQL/等时一样。
它不是连接到色度的库,也不是在GO中重新实现的。这是一个数据库。
重点不是比例(数百万个文档)或功能数量,而是最常见用例的简单性和性能。在2020 Intel笔记本电脑CPU中,您可以在0.3 ms中查询1,000个文档,并在40毫秒内查询100,000个文档,而记忆分配很少,并且很少。有关详细信息,请参见基准。
配x 该项目是在Beta的,在重大结构下,可能会在v1.0.0之前引入发行版的破坏变化。所有更改均在CHANGELOG中记录。
使用矢量数据库,您可以做各种事情:
让我们更详细地看一下抹布用例:
大型语言模型(LLMS)的知识 - 即使是300亿,700亿参数以及更多的知识。他们对训练结束后发生的事情一无所知,他们对未接受过培训的数据一无所知(例如您公司的Intranet,Jira / Bug Tracker,Wiki或其他类型的知识库),甚至他们知道他们经常无法完全重现的数据,而是开始幻觉。
微调LLM可以有所帮助,但它的意图是改善有关特定主题的推理的LLM,或重现书面文本或代码的样式。微调不会在模型中添加知识1:1 。详细信息丢失或混合。知识截止(关于微调后发生的任何事情)也没有解决。
=>矢量数据库可以充当LLM的最新,精确的知识:
text-embedding-3-small提供或可以创建它们。chromem-go可以为您做到这一点,并支持多个嵌入式提供商和模型。查看示例代码以查看它的操作!
我们最初的灵感是Chroma界面,其核心API是以下内容(取自他们的README):
import chromadb
# setup Chroma in-memory, for easy prototyping. Can add persistence easily!
client = chromadb . Client ()
# Create collection. get_collection, get_or_create_collection, delete_collection also available!
collection = client . create_collection ( "all-my-documents" )
# Add docs to the collection. Can also update and delete. Row-based API coming soon!
collection . add (
documents = [ "This is document1" , "This is document2" ], # we handle tokenization, embedding, and indexing automatically. You can skip that and add your own embeddings as well
metadatas = [{ "source" : "notion" }, { "source" : "google-docs" }], # filter on these!
ids = [ "doc1" , "doc2" ], # unique for each doc
)
# Query/search 2 most similar results. You can also .get by id
results = collection . query (
query_texts = [ "This is a query document" ],
n_results = 2 ,
# where={"metadata_field": "is_equal_to_this"}, # optional filter
# where_document={"$contains":"search_string"} # optional filter
)我们的GO库公开了相同的界面:
package main
import "github.com/philippgille/chromem-go"
func main () {
// Set up chromem-go in-memory, for easy prototyping. Can add persistence easily!
// We call it DB instead of client because there's no client-server separation. The DB is embedded.
db := chromem . NewDB ()
// Create collection. GetCollection, GetOrCreateCollection, DeleteCollection also available!
collection , _ := db . CreateCollection ( "all-my-documents" , nil , nil )
// Add docs to the collection. Update and delete will be added in the future.
// Can be multi-threaded with AddConcurrently()!
// We're showing the Chroma-like method here, but more Go-idiomatic methods are also available!
_ = collection . Add ( ctx ,
[] string { "doc1" , "doc2" }, // unique ID for each doc
nil , // We handle embedding automatically. You can skip that and add your own embeddings as well.
[] map [ string ] string {{ "source" : "notion" }, { "source" : "google-docs" }}, // Filter on these!
[] string { "This is document1" , "This is document2" },
)
// Query/search 2 most similar results. You can also get by ID.
results , _ := collection . Query ( ctx ,
"This is a query document" ,
2 ,
map [ string ] string { "metadata_field" : "is_equal_to_this" }, // optional filter
map [ string ] string { "$contains" : "search_string" }, // optional filter
)
}最初, chromem-go仅从四个核心方法开始,但随着时间的推移,我们添加了更多。不过,我们故意不想覆盖Chroma API表面的100%。
我们提供的一些替代方法更像是偶然的。
有关完整界面,请参见Godoc:https://pkg.go.dev/github.com/philippgille/chromem-go
chromem.EmbeddingFunc )chromem-go创建它们$contains , $not_contains io.Writer / io.Reader的方法EmbeddingFunc$and , $or等)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 : "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 n Similarity: %v n Content: %v n " , res [ 0 ]. ID , res [ 0 ]. Similarity , res [ 0 ]. Content )
}输出:
ID: 1
Similarity: 0.6833369
Content: The sky is blue because of Rayleigh scattering.
在2024-03-17的基准下进行:
$ 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 )benchstat : go install golang.org/x/perf/cmd/benchstat@latestbenchstat before.out after.out 在2023年12月,当我想在GO程序中进行检索增强发电(RAG)时,我寻找了一个可以嵌入GO程序中的矢量数据库,就像您嵌入SQLITE一样,以便不需要任何单独的DB设置和维护。考虑到GO生态系统中大量嵌入式钥匙值商店,我感到惊讶。
当时,大多数流行的矢量数据库,例如Pinecone,Qdrant,Milvus,Chroma,Weaviate等,或者根本不可嵌入Python或JavaScript/Typescript中。
然后,我找到了 @Eliben的博客文章和示例代码,该文章表明,几乎没有GO代码,您可以创建一个非常基本的矢量数据库POC。
那时,我决定构建自己的矢量数据库,该数据库可在Chromadb接口的启发下嵌入GO中。 Chromadb因可嵌入(在Python)而脱颖而出,并通过在其网站和网站的着陆页上显示其4个命令中的核心API。