chromem-go

repository·main·Indexed 21 days ago

https://github.com/philippgille/chromem-go

An embeddable, in-memory vector database for Go with a Chroma-like interface and zero third-party dependencies. Designed for high-performance vector search and Retrieval Augmented Generation (RAG), it supports multiple embedding providers including OpenAI, Azure OpenAI, GCP Vertex AI, Cohere, Mistral, Jina, mixedbread.ai, Ollama, and LocalAI. It features S3-compatible export/import for persistence and can be compiled to WebAssembly (WASM) for browser-based functionality.

Tokens
12.1K
Snippets
44
Records
50
Agent score
75%

What's inside chromem-go

  1. Explore chromem-go usage examples

    main

    The chromem-go repository provides several example implementations to demonstrate different use cases for the vector database:

    • Minimal Example: A bare-bones implementation using OpenAI for embeddings. Best for understanding the core API with minimal boilerplate.
    • RAG Wikipedia Ollama: A Retrieval Augmented Generation (RAG) application for question answering. It uses Wikipedia lead sections as a knowledge base and runs both the embedding model and the LLM via Ollama, demonstrating a fully offline RAG setup.
    • Semantic Search arXiv OpenAI: A semantic search application that indexes approximately 5,000 arXiv papers (Computer Science - Computation and Language category) using OpenAI embeddings.
    • WebAssembly (WASM): Demonstrates how to compile chromem-go to WebAssembly to enable vector database functionality directly in a web browser via JavaScript.
    • S3 Export/Import: Shows how to handle database persistence by exporting the database to and importing it from S3-compatible blob storage services.
  2. How chromem-go works: Embeddable Vector Database

    main
    Unlike traditional vector databases that require a separate client-server setup, chromem-go is an embeddable database. It functions similarly to SQLite: the database is part of your application process, meaning there is no separate service to maintain. It is designed for simplicity and performance in common use cases like Retrieval Augmented Generation (RAG), text/code search, and recommendation systems.
  3. Use chromem-go for Retrieval Augmented Generation (RAG)

    main

    You can use chromem-go to provide up-to-date, precise knowledge to Large Language Models (LLMs) to prevent hallucinations. The workflow is:

    1. Store Documents: Save relevant documents in a chromem-go collection.
    2. Generate Embeddings: chromem-go automatically handles embeddings using providers like OpenAI, Azure OpenAI, Cohere, or local providers like Ollama.
    3. Nearest Neighbor Search: When a user asks a question, query the database to find the most similar content.
    4. Augment Prompt: Provide the retrieved content to the LLM alongside the user's question to ensure an accurate answer.
  4. Quickstart with chromem-go

    main

    This example demonstrates how to initialize an in-memory database, create a collection, add documents using OpenAI embeddings (requires OPENAI_API_KEY), and perform a similarity query. Note that passing nil as the embedding function defaults to OpenAI.

    package main
    
    import (
     "context"
     "fmt"
     "runtime"
    
     "github.com/philippgille/chromem-go"
    )
    
    func main() {
      ctx := context.Background()
    
      db := chromem.NewDB()
    
      // Passing nil as embedding function leads to OpenAI being used and requires
      // "OPENAI_API_KEY" env var to be set. Other providers are supported as well.
      // For example pass `chromem.NewEmbeddingFuncOllama(...)` to use Ollama.
      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)
    }
  5. Adapt RAG example to use OpenAI for both embeddings and LLM

    main

    To replace both the local Ollama setup and the local embedding model with OpenAI services:

    1. Set the OPENAI_API_KEY environment variable.
    2. In your collection setup, pass nil as the embedding function to db.GetOrCreateCollection to use OpenAI embeddings.
    3. Update your LLM client to use openai.NewClient(os.Getenv("OPENAI_API_KEY")) instead of the Ollama-compatible client.
    4. Change the model name in your chat completion request to an OpenAI model (e.g., openai.GPT3Dot5Turbo).
    // 1. Use OpenAI for embeddings
    collection, err := db.GetOrCreateCollection("Wikipedia", nil, nil)
    
    // 2. Use OpenAI client for LLM
    openAIClient := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
    
    // 3. Request OpenAI model
    res, err := openAIClient.CreateChatCompletion(ctx, openai.ChatCompletionRequest{
        Model:    openai.GPT3Dot5Turbo,
        Messages: messages,
    })
  6. Run the minimal chromem-go example

    main

    To run the minimal demonstration of chromem-go, you must first configure your environment with an OpenAI API key, as the example relies on OpenAI for embeddings. Once the environment variable is set, you can execute the example directly using the Go CLI.

    Prerequisites

    • An OpenAI API key.

    Steps

    1. Set the OPENAI_API_KEY environment variable.
    2. Execute go run . from within the example directory.
    export OPENAI_API_KEY='your-api-key-here'
    go run .
  7. Export and Import Chroma DB using S3-compatible storage

    main

    This example demonstrates how to export a chromem-go database to and import it from any S3-compatible blob storage service. It utilizes gocloud.dev (Google's Cloud Development Kit) to provide a generic interface for interacting with storage providers via readers and writers.

    Prerequisites

    • An S3-compatible storage service (e.g., MinIO).
    • The OPENAI_API_KEY environment variable must be set.

    Setup with MinIO (Local Example)

    1. Start MinIO via Docker:
      docker run -d --rm --name minio -p 127.0.0.1:9000:9000 -p 127.0.0.1:9001:9001 quay.io/minio/minio:RELEASE.2024-05-01T01-11-10Z server /data --console-address ":9001"
    2. Configure Bucket:
      • Access the MinIO Console at http://localhost:9001.
      • Log in with user minioadmin and password minioadmin.
      • Create a bucket named mybucket.
    3. Run the Example:
      go run .

    Verifying Output

    After running, you can verify the exported database file (named chromem.gob.gz) in your bucket via the MinIO browser at http://localhost:9001/browser/mybucket.

    # 1. Start MinIO
    docker run -d --rm --name minio -p 127.0.0.1:9000:9000 -p 127.0.0.1:9001:9001 quay.io/minio/minio:RELEASE.2024-05-01T01-11-10Z server /data --console-address ":9001"
    
    # 2. Set API Key
    export OPENAI_API_KEY="your-key-here"
    
    # 3. Run the application
    go run .
  8. Compile chromem-go to WebAssembly (WASM)

    main

    To use chromem-go in a browser or JavaScript environment (Node, Deno, Bun, etc.), you must first compile the WASM binding. This requires setting the GOOS to js and GOARCH to wasm during the build process.

    Follow these steps to compile the binding:

    1. Navigate to the WASM directory: cd /path/to/chromem-go/wasm
    2. Run the build command: GOOS=js GOARCH=wasm go build -o ../examples/webassembly/chromem-go.wasm
    cd /path/to/chromem-go/wasm
    GOOS=js GOARCH=wasm go build -o ../examples/webassembly/chromem-go.wasm
  9. Adapt RAG example to use OpenAI embeddings

    main

    You can use OpenAI for generating embeddings while still using a local LLM (like Gemma 2B via Ollama) for the final answer generation.

    1. Set the OPENAI_API_KEY environment variable.
    2. When calling db.GetOrCreateCollection, pass nil for the embedding function instead of chromem.NewEmbeddingFuncOllama(embeddingModel). This tells chromem-go to use the default OpenAI embedding implementation.
    3. Ensure your document addition logic is prepared for the OpenAI API.
    // Use nil to trigger OpenAI embeddings instead of Ollama
    collection, err := db.GetOrCreateCollection("Wikipedia", nil, nil)
    
    // ... later when adding documents
    err = collection.AddDocuments(ctx, docs, runtime.NumCPU())
  10. Run the Semantic Search arXiv OpenAI example

    main

    This example demonstrates a semantic search application using chromem-go as a vector database. It loads approximately 5,000 arXiv papers from the 'Computer Science - Computation and Language' category and performs semantic searches using OpenAI embeddings.

    Prerequisites

    1. Dataset: Download arxiv-metadata-oai-snapshot.json from Kaggle.
    2. Filtering: Use ripgrep (or grep) to filter the dataset for the cs.CL category and updates from 2023.
      rg '"categories":"cs.CL"' ~/Downloads/arxiv-metadata-oai-snapshot.json | rg '"update_date":"2023' > /tmp/arxiv_cs-cl_2023.jsonl
    3. API Key: Set your OpenAI API key in your environment variables:
      export OPENAI_API_KEY='your-api-key-here'

    Execution

    Run the example using the Go CLI:

    go run .

    Note: The execution time is primarily dominated by the time taken to create embeddings via the OpenAI API.

    # 1. Filter data
    rg '"categories":"cs.CL"' ~/Downloads/arxiv-metadata-oai-snapshot.json | rg '"update_date":"2023' > /tmp/arxiv_cs-cl_2023.jsonl
    
    # 2. Set API Key
    export OPENAI_API_KEY='your-api-key-here'
    
    # 3. Run
    go run .
  11. Run the RAG Wikipedia Ollama example

    main

    This example demonstrates a Retrieval Augmented Generation (RAG) application for question answering. It uses chromem-go as a knowledge base to find relevant Wikipedia article snippets and provides them to an LLM to answer questions. The setup runs entirely offline using Ollama for both the embedding model and the LLM.

    Prerequisites

    1. Install Ollama.
    2. Download the required models via Ollama:
      • ollama pull gemma:2b (LLM)
      • ollama pull nomic-embed-text (Embeddings)

    Execution

    Navigate to the example directory and run:

    go run .
    go run .
  12. Develop and test chromem-go

    main

    To work with the chromem-go source code, use the following standard Go commands:

    • Build the project: go build ./...
    • Run tests: go test -v -race -count 1 ./... (includes race detection and runs tests multiple times to ensure stability).
    • Run benchmarks: go test -benchmem -run=^$ -bench .

    To perform profiling during benchmarks, you can use the following flags:

    • -cpuprofile <file>
    • -memprofile <file>
    • -blockprofile <file>
    • -mutexprofile <file>
    # Build
    go build ./...
    
    # Test
    go test -v -race -count 1 ./...
    
    # Benchmark
    go test -benchmem -run=^$ -bench .