Skip to content
ollamaembed

go · zero deps · ollama embeddings

Text embeddings for Go, via Ollama.

A zero-dependency client for text→vector embeddings through Ollama's local HTTP API — plus the vector math and a curated model catalog that go with it. The building blocks for semantic / RAG search, with no SDK, no cgo, and no bundled model.

MIT licensed · standard library only · Go 1.21+

embed.go
emb := ollamaembed.NewOllama(
    "http://localhost:11434", "nomic-embed-text")

vec, _ := emb.Embed(ctx, "the quick brown fox")
ollamaembed.Normalize(vec)  // unit vector → cosine == dot

what you get

The embedding layer for semantic search.

A small client, the vector helpers, and a curated catalog — everything you need to turn text into vectors and rank by meaning, nothing you don't.

Embedder interface

OllamaEmbedder.Embed(ctx, text) is context-aware and returns a []float32, with clear errors when Ollama is down or the model isn't pulled.

Vector math

Cosine, Dot, and Normalize operate directly on []float32 — normalize once and cosine becomes a dot product.

Curated catalog

Recommended embedding models with dimensions and size, plus CatalogLookup / BareName — pick a model without guessing.

Model management

ListLocal shows what's installed; Pull fetches a model with streaming progress — no shelling out to the CLI.

Zero dependencies

Standard library only — net/http, encoding/json, math. No SDK, no cgo, no bundled model to ship.

Semantic / RAG ready

The embedding + vector-math layer for RAG. Feed the vectors into any ANN index for sub-linear top-K at scale.

usage

Embed, then rank by similarity.

Set up Ollama once (ollama pull nomic-embed-text), then embed and compare.

// Embed a string to a unit vector
emb := ollamaembed.NewOllama(url, "nomic-embed-text")
vec, err := emb.Embed(ctx, "the quick brown fox")
if err != nil {
    log.Fatal(err) // Ollama down / model not pulled
}
ollamaembed.Normalize(vec)
// Rank documents by cosine similarity
query := mustEmbed(emb, ctx, "seafaring adventure")
for _, doc := range docs {
    v := mustEmbed(emb, ctx, doc.Text)
    ollamaembed.Normalize(v)
    doc.Score = ollamaembed.Cosine(query, v)
}
# Curated recommendations (no network)
for _, m := range ollamaembed.Catalog {
    fmt.Printf("%s — %dd\n", m.Name, m.Dimensions)
}
# Pull a model, streaming progress
emb.Pull(ctx, "nomic-embed-text",
    func(p ollamaembed.PullProgress) {
        fmt.Printf("\r%s %d/%d", p.Status, p.Completed, p.Total)
    })

install

Add it to your module.

One import, no transitive dependencies. Named ollamaembed so it never collides with the standard library's embed package.

go get go get github.com/richardwooding/ollamaembed
import import "github.com/richardwooding/ollamaembed"

Requires Go 1.21+ and a running Ollama. Pairs with bm25 (keyword) for hybrid search; extracted from file-search-on.