Встроенная векторная база данных для GO с хрома-подобным интерфейсом и нулевыми сторонними зависимостями. В памяти с необязательной настойчивостью.
Поскольку chromem-go встроен, он позволяет добавлять в поиска в поисках дополнительного генерации (RAG) и аналогичных функций на основе Entgeddings в ваше приложение GO без необходимости запуска отдельной базы данных . Как при использовании SQLite вместо PostgreSQL/MySQL/и т. Д.
Это не библиотека для подключения к Chroma, а также не переосмысление ее в Go. Это база данных самостоятельно.
Основное внимание уделяется не масштабным (миллионам документов) или количеству функций, а простота и производительность для наиболее распространенных вариантов использования. В среднем диапазоне 2020 года для ноутбука Intel вы можете запросить 1000 документов за 0,3 мс и 100 000 документов за 40 мс, с очень небольшим распределением памяти. Смотрите тесты для деталей.
️ Проект находится в бета -версии, под тяжелой конструкцией, и может внести нарушающие изменения в выпусках доv1.0.0. Все изменения задокументированы вCHANGELOG.
С помощью векторной базы данных вы можете делать различные вещи:
Давайте более подробно рассмотрим вариант использования тряпки:
Знание моделей крупных языков (LLMS) - даже те, которые имеют 30 миллиардов, 70 миллиардов параметров и многое другое - ограничены. Они ничего не знают о том, что произошло после окончания их обучения, они ничего не знают о данных, с которыми они не были обучены (например, интранет вашей компании, Jira / Bug Tracker, Wiki или другие виды баз знаний), и даже данные, которые они действительно знают, они часто не могут воспроизводить его точно , но начинают галлюцинировать .
Точная настройка LLM может немного помочь, но она больше предназначена для улучшения рассуждений LLMS по конкретным темам или воспроизведения стиля письменного текста или кода. Точная настройка не добавляет знаний 1: 1 в модель. Детали потеряны или смешаны. И обрезка знаний (о чем-либо, что произошло после точной настройки) также не решен.
=> Векторная база данных может действовать как актуальные, точные знания для LLMS:
text-embedding-3-small .chromem-go может сделать это для вас и поддерживает несколько поставщиков встраивания и моделей вне коробки.Проверьте пример кода, чтобы увидеть его в действии!
Нашим первоначальным вдохновением был интерфейс Chrama, основной 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 началась только с четырех основных методов, но мы добавили больше с течением времени. Мы намеренно не хотим покрывать 100% поверхности API Chroma.
Мы предоставляем некоторые альтернативные методы, которые более имиматические.
Для полного интерфейса см. Годок: https://pkg.go.dev/github.com/philippgille/chromem-go
chromem.EmbeddingFunc )chromem-go создавать их$contains , $not_contains io.Writer / io.Reader , чтобы вы могли подключить ковши S3 и другие штуки, см. Примеры / S3-Export-Import, например, кодEmbeddingFunc , который загружает и оболочки в ламафиле$and , $or и т. Д.) go get github.com/philippgille/chromem-go@latest
См. Годок для ссылки: https://pkg.go.dev/github.com/philippgille/chromem-go
Для полных рабочих примеров, используя векторную базу данных для поиска добыченного поколения (RAG) и семантического поиска и использования либо OpenAI, либо локально запускающего модель Enterdings и 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 года, когда я хотел поиграть с поисковой добычей поколением (RAG) в программе GO, я искал векторную базу данных, которая может быть встроена в программу GO, точно так же, как вы внедрили SQLite, чтобы не потребовать отдельной настройки и обслуживания DB. Я был удивлен, когда не нашел ничего, учитывая изобилие встроенных магазинов ключей в экосистеме Go.
В то время, когда большинство популярных векторных баз данных, таких как Pinecone, Qdrant, Milvus, Chroma, Weaviate и другие, вообще не были встроены или только в Python или Javascript/Typescript.
Затем я обнаружил, что пост в блоге @Eliben и пример кода, который показал, что с очень небольшим кодом GO вы могли бы создать очень базовый POC векторной базы данных.
Именно тогда я решил построить свою собственную векторную базу данных, внедренную в GO, вдохновленную интерфейсом ChromADB. Chromadb выделялся за то, что он был встроен (в Python), и, показывая свой основной API в 4 командах в их чтении и на целевой странице их веб -сайта.