Einbettbare Vektordatenbank für die Chroma-ähnliche Schnittstelle und keine Abhängigkeiten mit Drittanbietern. In Memory mit optionaler Persistenz.
Da chromem-go eingebettet ist, können Sie Ihre GO-App Abruf Augmented Generation (RAG) und ähnliche Einlagen-basiertes Funktionen hinzufügen , ohne eine separate Datenbank ausführen zu müssen . Wie bei der Verwendung von SQLite anstelle von PostgreSQL/Mysql/etc.
Es ist keine Bibliothek, um eine Verbindung zu Chroma herzustellen, und auch keine Neuauflagen in Go. Es ist eine Datenbank für sich.
Der Fokus liegt nicht im Maßstab (Millionen von Dokumenten) oder Anzahl der Merkmale, sondern Einfachheit und Leistung für die häufigsten Anwendungsfälle. Auf einer Mid-Range 2020 Intel-Laptop-CPU können Sie 1.000 Dokumente in 0,3 ms und 100.000 Dokumente in 40 ms abfragen, mit nur sehr wenigen und kleinen Speicherzuweisungen. Weitere Informationen finden Sie unter Benchmarks.
Euen Das Projekt befindet sich in der Beta -Konstruktion in Beta und kann vorv1.0.0Bruchänderungen in Veröffentlichungen einführen. Alle Änderungen sind imCHANGELOGdokumentiert.
Mit einer Vektordatenbank können Sie verschiedene Dinge tun:
Schauen wir uns den Lag -Gebrauchsfall ausführlicher an:
Das Wissen über Großsprachmodelle (LLMs) - auch diejenigen mit 30 Milliarden, 70 Milliarden Parametern und mehr - sind begrenzt. Sie wissen nichts über das, was nach dem Ende ihres Trainings passiert ist. Sie wissen nichts über Daten, mit denen sie nicht trainiert wurden (wie das Intranet, Jira / Bug -Tracker Ihres Unternehmens, und andere Arten von Wissensbasen) und selbst die Daten, die sie wissen , können sie oft nicht genau reproduzieren, sondern beginnen stattdessen zu halluzinieren .
Die Feinabstimmung eines LLM kann ein wenig helfen, aber es ist mehr dazu gedacht, die LLMs-Argumentation zu bestimmten Themen zu verbessern oder den Stil des geschriebenen Textes oder Code zu reproduzieren. Feinabstimmung fügt dem Modell kein Wissen 1: 1 hinzu. Details gehen verloren oder durcheinander. Und Wissens Cutoff (über alles, was nach der Feinabstimmung passiert ist) ist auch nicht gelöst.
=> Eine Vektor-Datenbank kann als aktuelles, genaues Wissen für LLMs dienen:
text-embedding-3-small erstellen können.chromem-go kann dies für Sie tun und unterstützt mehrere Einbettungsanbieter und Modelle außerhalb des Boxs.Schauen Sie sich den Beispielcode an, um ihn in Aktion zu sehen!
Unsere ursprüngliche Inspiration war die Chroma -Schnittstelle, deren Kern -API die folgende ist (aus ihrem 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
)Unsere Go -Bibliothek enthüllt dieselbe Schnittstelle:
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
)
} Anfangs begann chromem-go nur mit den vier Kernmethoden, aber wir haben im Laufe der Zeit mehr hinzugefügt. Wir wollen jedoch absichtlich nicht 100% der API -Oberfläche von Chroma abdecken.
Wir bieten einige alternative Methoden an, die stattdessen mehr Go-idiomatischer sind.
Für die vollständige Schnittstelle siehe Godoc: https://pkg.go.dev/github.com/philippgille/chromem-go
chromem.EmbeddingFunc )chromem-go erstellen zu lassen$contains , $not_contains io.Writer / io.Reader , damit Sie S3-Eimer und andere Blob-Speicher anschließen können. Siehe Beispiele / S3-Export-Import, z. B. CodeEmbeddingFunc hinzu, der Lamafile herunterlädt und beschleunigt$and , $or usw.) go get github.com/philippgille/chromem-go@latest
Siehe den Godoc als Referenz: https://pkg.go.dev/github.com/philippgille/chromem-go
Zum vollständigen, funktionierenden Beispiele, die die Vektor -Datenbank zum Abrufen von Augmented Generation (RAG) und semantische Suche sowie die Verwendung von OpenAI oder Lokal des Embodendings -Modells und LLM (in Ollama) verwenden, siehe Beispielcode.
Dies stammt aus dem "minimalen" Beispiel:
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 )
}Ausgabe:
ID: 1
Similarity: 0.6833369
Content: The sky is blue because of Rayleigh scattering.
Benchmarked am 2024-03-17 mit:
$ 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 . (Hinzufügen > bench.out oder ähnlich wie in eine Datei zu schreiben)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 Im Dezember 2023, als ich mit dem RAG -Programm Abruf Augmented Generation (RAG) herumspielen wollte, suchte ich nach einer Vektordatenbank, die in das GO -Programm eingebettet werden könnte, genau wie Sie SQLite einbetten würden, um keine separate DB -Setup und -wartung zu benötigen. Ich war überrascht, als ich angesichts der Fülle an eingebetteter Schlüsselwertgeschäfte im Go-Ökosystem keine fand.
Zu dieser Zeit wurden die meisten beliebten Vektordatenbanken wie Tinecone, Qdrant, Milvus, Chroma, Weaviate und andere überhaupt nicht in Python oder JavaScript/Typecript eingebettet.
Dann fand ich den Blog -Beitrag und den Beispielcode von @Elibens, der zeigte, dass Sie mit sehr wenig Go -Code einen sehr einfachen POC einer Vektor -Datenbank erstellen konnten.
Dann beschloss ich, meine eigene Vektor -Datenbank zu erstellen, die in Go, inspiriert von der Chromadb -Schnittstelle, inspiriert ist. Chromadb stach heraus, dass er (in Python) eingebettet war und seine Kern -API in 4 Befehlen auf ihrem Readme und auf der Zielseite ihrer Website zeigte.