From ab58b35bde7b364e4033ecd9bf7859c15f5e3392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Gill=C3=A9?= Date: Sat, 23 Mar 2024 12:36:09 +0100 Subject: [PATCH] Update README --- README.md | 109 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0cd17b8..bf2e13a 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,13 @@ The focus is not scale (millions of documents) or number of features, but simpli 1. [Use cases](#use-cases) 2. [Interface](#interface) -3. [Features](#features) -4. [Usage](#usage) -5. [Benchmarks](#benchmarks) -6. [Motivation](#motivation) -7. [Related projects](#related-projects) +3. [Features + Roadmap](#features) +4. [Intallation](#installation) +5. [Usage](#usage) +6. [Benchmarks](#benchmarks) +7. [Development](#development) +8. [Motivation](#motivation) +9. [Related projects](#related-projects) ## Use cases @@ -56,9 +58,9 @@ Check out the [example code](examples) to see it in action! ## Interface -For the full interface see . +Our original inspiration was the [Chroma](https://www.trychroma.com/) interface, whose core API is the following (taken from their [README](https://github.com/chroma-core/chroma/blob/0.4.21/README.md)): -Our inspiration was the [Chroma](https://www.trychroma.com/) interface, whose core API is the following (taken from their [README](https://github.com/chroma-core/chroma/blob/0.4.21/README.md)): +
Chroma core interface ```python import chromadb @@ -84,8 +86,12 @@ results = collection.query( ) ``` +
+ Our Go library exposes the same interface: +
chromem-go equivalent + ```go package main @@ -119,10 +125,12 @@ func main() { } ``` +
+ Initially `chromem-go` started with just the four core methods, but we added more over time. We intentionally don't want to cover 100% of Chroma's API surface though. We're providing some alternative methods that are more Go-idiomatic instead. -See the Godoc for details: +For the full interface see the Godoc: ## Features @@ -132,6 +140,7 @@ See the Godoc for details: For full, working examples, using the vector database for retrieval augmented generation (RAG) and semantic search and using either OpenAI or locally running the embeddings model and LLM (in Ollama), see the [example code](examples). +### Quickstart + +This is taken from the ["minimal" example](examples/minimal): + +```go +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\nSimilarity: %v\nContent: %v\n", res[0].ID, res[0].Similarity, res[0].Content) +} +``` + +Output: + +```text +ID: 1 +Similarity: 0.6833369 +Content: The sky is blue because of Rayleigh scattering. +``` + ## Benchmarks Benchmarked on 2024-03-17 with: @@ -211,6 +278,18 @@ PASS ok github.com/philippgille/chromem-go 28.402s ``` +## Development + +- Build: `go build ./...` +- Test: `go test -v -race -count 1 ./...` +- Benchmark: + - `go test -benchmem -run=^$ -bench .` (add `> bench.out` or similar to write to a file) + - With profiling: `go test -benchmem -run ^$ -cpuprofile cpu.out -bench .` + - (profiles: `-cpuprofile`, `-memprofile`, `-blockprofile`, `-mutexprofile`) +- Compare benchmarks: + 1. Install `benchstat`: `go install golang.org/x/perf/cmd/benchstat@latest` + 2. Compare two benchmark results: `benchstat before.out after.out` + ## Motivation In December 2023, when I wanted to play around with retrieval augmented generation (RAG) in a Go program, I looked for a vector database that could be embedded in the Go program, just like you would embed SQLite in order to not require any separate DB setup and maintenance. I was surprised when I didn't find any, given the abundance of embedded key-value stores in the Go ecosystem. @@ -240,7 +319,7 @@ That's when I decided to build my own vector database, embeddable in Go, inspire - [Faiss](https://github.com/facebookresearch/faiss): Written in C++; 3rd party Go bindings use CGO - [Annoy](https://github.com/spotify/annoy): Written in C++; Go bindings use CGO ([1](https://github.com/spotify/annoy/blob/2be37c9e015544be2cf60c431f0cccc076151a2d/README_GO.rst)) - [USearch](https://github.com/unum-cloud/usearch): Written in C++; Go bindings use CGO -- Some all-in-one libraries, inspired by the Python library [LangChain](https://github.com/langchain-ai/langchain): +- Some orchestration libraries, inspired by the Python library [LangChain](https://github.com/langchain-ai/langchain), but with no or only rudimentary embedded vector DB: - [LangChain Go](https://github.com/tmc/langchaingo) - [LinGoose](https://github.com/henomis/lingoose) - [GoLC](https://github.com/hupe1980/golc)