Help us shape the future of Go! Take the 2026 Go Developer Survey

embedding

package
v0.10.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package embedding provides text embedding infrastructure for VaultMind.

Index

Constants

View Source
const (
	BackendNameORT = "ort"
	BackendNameGo  = "go"
)

Backend names reported by BackendName(), which is defined per build tag in session_ort.go (ORT) and session_go.go (pure-Go). Declared here in a non-tagged file so callers in either build can compare against them without duplicating the literals (SSOT).

View Source
const (
	DefaultModelName    = "sentence-transformers/all-MiniLM-L6-v2"
	DefaultDims         = 384
	DefaultMaxTokens    = 510 // MiniLM max is 512 minus 2 for CLS/SEP tokens
	DefaultOnnxFilePath = "onnx/model.onnx"
)

Default model configuration for the all-MiniLM-L6-v2 embedder.

View Source
const (
	BGEM3ModelName    = "BAAI/bge-m3"
	BGEM3Dims         = 1024
	BGEM3MaxTokens    = 8190 // 8192 minus 2 for CLS/SEP
	BGEM3OnnxFilePath = "onnx/model.onnx"
	// BGEM3EmbedMaxTokens is the per-note token cap the embedder truncates to.
	// The model accepts BGEM3MaxTokens, but forward memory grows faster than
	// the token count. Peak memory of a full embed (ORT CPU, model included):
	// 12–16 GB at 8190, about 6 GB at 2048, about 3 GB at 1024. On labelled
	// sets, 1024 kept Hit@3 within one query of 8190. Search text (FTS) still
	// holds the whole note; only the vectors read the first 1024 tokens.
	BGEM3EmbedMaxTokens = 1024
)

BGE-M3 model configuration.

View Source
const (
	ModelMiniLM = "minilm"
	ModelBGEM3  = "bge-m3"
)

CLI model tokens — the values the --model flag and RunEmbed receive. Distinct from the HuggingFace IDs above (DefaultModelName / BGEM3ModelName); named here so the token→dimension mapping has a single source of truth.

View Source
const RepeatedNonAlnumCap = 16

RepeatedNonAlnumCap is the longest run of consecutive characters that are neither letters, digits, nor whitespace kept in text that will be tokenized. A longer run carries no ranking signal. The tokenizer's lattice on that run grows much faster than the length: one punctuation character at 2 KB already takes a third of a second, and an unspaced mix of punctuation stalls the same way. Exactly this many characters of the run are kept. Letters, digits, and whitespace are never shortened.

Variables

View Source
var ConstructBGEM3 = func(ctx context.Context, cfg HugotConfig) (Embedder, error) {
	if cfg == (HugotConfig{}) {
		cfg = BGEM3Config()
	}
	return NewBGEM3Embedder(ctx, cfg)
}

ConstructBGEM3 builds the BGE-M3 embedder. Ranking and embed-on-write both go through it, so a test can count how many times a process loads the model. The production value is NewBGEM3Embedder.

A zero config is the default, resolved inside the seam so a stub does not run DefaultCacheDir. Evaluating BGEM3Config at the call site renames ~/.vaultmind/models before the stub runs.

View Source
var ConstructMiniLM = func(ctx context.Context, cfg HugotConfig) (Embedder, error) {
	if cfg == (HugotConfig{}) {
		cfg = DefaultHugotConfig()
	}
	return NewHugotEmbedder(ctx, cfg)
}

ConstructMiniLM builds the MiniLM embedder. Same seam as ConstructBGEM3. A zero config is the default, resolved here for the same reason.

Functions

func Acceleration

func Acceleration() string

Acceleration mirrors the ORT-build's Acceleration() so callers don't need to special-case build tags. Pure-Go has no GPU path; "go-cpu" names the slow path explicitly.

func BGEM3TokenizerPath added in v0.10.13

func BGEM3TokenizerPath() string

BGEM3TokenizerPath is the legacy cache file ReadBGEM3Tokenizer reads. CI fetches tokenizer.json into ~/.vaultmind/models. Reading that file must not rename the directory into the XDG cache, so this does not call DefaultCacheDir.

func BGEM3TokenizerPin added in v0.10.13

func BGEM3TokenizerPin() (revision, sum, url string)

BGEM3TokenizerPin is the pinned tokenizer.json: revision, sha256, and the URL that serves only that file. Model weights are a different file.

func BackendName

func BackendName() string

BackendName identifies which hugot backend the binary was built against. Consumers (e.g. the index command) use this to warn when BGE-M3 indexing is about to run on the slow pure-Go path so operators don't mistake "hours-long indexing" for a hang or OOM. Reported by the build tag.

func CapSymbolRuns added in v0.10.13

func CapSymbolRuns(s string) string

CapSymbolRuns shortens every run of characters that are neither letters, digits, nor whitespace, when the run is longer than RepeatedNonAlnumCap, to its first RepeatedNonAlnumCap characters. A string with no such run is returned unchanged, so a short or ordinary query stays byte-identical. The ranking query and document embedding both use this function (Principle 7).

func CheckRuntime added in v0.9.0

func CheckRuntime(context.Context) error

CheckRuntime is a no-op on the pure-Go build: there is no native runtime to be the wrong version. See the ORT build's CheckRuntime.

func ColBERTHead

func ColBERTHead(hiddenStates [][]float32, weights [][]float32, bias []float32) [][]float32

ColBERTHead projects each non-CLS token through a linear layer and L2-normalizes. Input: hiddenStates[seq_len][dims], weights[out_dims][in_dims], bias[out_dims]. Output: [seq_len-1][out_dims] (CLS at index 0 is skipped).

func CosineSimilarity added in v0.4.0

func CosineSimilarity(a, b []float32) float64

CosineSimilarity is the cosine between two vectors, or 0 when they are unusable (mismatched length, empty, or zero-magnitude).

It lives in the embedding package because both the retrieval layer (internal/query, business) and the distillation layer (internal/distill, infrastructure) need it, and ADR-009 forbids distill importing query. Putting it in the shared infrastructure both may use is the only placement that gives them one definition. A second copy would drift — and this project has an arc about a similarity number that silently meant the wrong thing, so one definition is the point.

func DefaultCacheDir

func DefaultCacheDir() string

DefaultCacheDir returns the model cache directory — the XDG cache dir.

Weights are ~2.2 GB, so relocating must never mean re-downloading. On first use an existing legacy cache is renamed into place: instant when both live under $HOME, as they normally do. If the rename fails (separate filesystem, permissions), the legacy directory keeps being used rather than silently starting an empty cache beside a full one.

func DefaultModel

func DefaultModel() string

DefaultModel returns the embedding model to use when the operator hasn't picked one explicitly. Adapts to the backend the binary was built against:

  • ORT-tagged binaries → "bge-m3" (4-way hybrid retrieval — fast on this build path; what the README's retrieval description is built around).
  • Pure-Go binaries → "minilm" (BGE-M3 indexing on pure-Go takes hours per medium vault; minilm is the always-fast baseline).

The default is conservative: it never picks a model the binary can't run reasonably. Users who want minilm on an ORT binary (e.g. for fast re-indexing during development) can pass --model minilm explicitly. Users who want bge-m3 on a pure-Go binary can opt in via --model bge-m3 + --allow-slow-backend.

The 2026-05-05 dogfood surfaced this gap: the prior hardcoded "minilm" default contradicted the system's own framing. A user running `vaultmind index --embed` on an ORT-capable build silently got MiniLM-only embeddings, learning about it only from doctor's post-hoc warning. The runtime-aware default closes that gap by matching the model to what the binary can actually run well.

func DenseHead

func DenseHead(hiddenStates [][]float32) []float32

DenseHead extracts the CLS token embedding (index 0) and L2-normalizes it. Input: hiddenStates[seq_len][dims]. Output: [dims] unit vector.

func DownloadBGEM3

func DownloadBGEM3(cacheDir string) (string, error)

DownloadBGEM3 makes sure the pinned BGE-M3 files are in the cache and match their hashes, downloading what is missing or wrong. Returns the path to the model directory.

func ExpectedDenseDims added in v0.2.2

func ExpectedDenseDims(model string) (dims int, known bool)

ExpectedDenseDims returns the dense-embedding dimensionality a CLI model token produces, and whether the token is recognized. It is a pure lookup — it never loads a model — so callers can compare a vault's stored dimension against a requested model without paying the (multi-GB, multi-second) embedder load.

func L2Normalize

func L2Normalize(vec []float32) []float32

L2Normalize returns a unit vector. Returns zero vector if magnitude is zero.

func LoadLinearWeights

func LoadLinearWeights(path string) (weight [][]float32, bias []float32, err error)

LoadLinearWeights loads a PyTorch nn.Linear layer's weight and bias from a .pt file. Returns weight as [out_features][in_features] and bias as [out_features]. The .pt file must be a state_dict saved via torch.save(state_dict, path).

func MaxSimAll added in v0.10.1

func MaxSimAll(queryTokens [][]float32, docs [][][]float32, workers int) []float64

MaxSimAll scores every doc against the query with MaxSimScore, spread over up to workers goroutines, and returns the scores in doc order. Each doc's score is independent and computed exactly as MaxSimScore does, so the result is identical to scoring one at a time — only faster on several cores.

Why: ColBERT MaxSim over the candidate notes was 1.22 s of a 3.4 s three-vault ask, all on one core.

func MaxSimScore

func MaxSimScore(queryTokens, docTokens [][]float32) float64

MaxSimScore computes the ColBERT MaxSim score between query and document token matrices. For each query token, finds max similarity across all doc tokens, then sums. Assumes both query and doc tokens are L2-normalized (from ColBERTHead), so dot product = cosine.

func ModelForDenseDims added in v0.2.2

func ModelForDenseDims(dims int) (model string, known bool)

ModelForDenseDims is the reverse of ExpectedDenseDims: the CLI model token that produces embeddings of the given dense dimension, and whether it is recognized. Used to name the model behind a vault's stored embeddings in diagnostics.

func QuerySpanWindow added in v0.10.13

func QuerySpanWindow(text string, forwardTokens int) string

QuerySpanWindow returns the prefix a span read may see for forwardTokens. forwardTokens <= 0 leaves the text unchanged. The width is querySpanCharsPerToken bytes per token, broken on a word when one is near the cut. Callers compare a bounded embed against this prefix.

func ReadBGEM3Tokenizer added in v0.10.13

func ReadBGEM3Tokenizer() ([]byte, error)

ReadBGEM3Tokenizer reads the pinned tokenizer.json from the model cache. It does not load model weights.

func SparseDotProduct

func SparseDotProduct(a, b map[int32]float32) float64

SparseDotProduct computes the dot product between two sparse vectors. Only overlapping keys contribute.

func SparseHead

func SparseHead(hiddenStates [][]float32, tokenIDs, specialMask []uint32, weights []float32, bias float32) map[int32]float32

SparseHead pools SparsePositionWeights by vocabulary id. Duplicate token IDs keep the maximum weight. Positions the mask marks (CLS, SEP, PAD, UNK) are absent from the map.

func SparsePositionWeights added in v0.10.13

func SparsePositionWeights(hiddenStates [][]float32, specialMask []uint32, weights []float32, bias float32) []float32

SparsePositionWeights is the per-position ReLU(dot(hidden, w)+bias), before vocab-id max-pooling. Index i aligns with hiddenStates[i]. Positions the special mask marks are 0: the forward pass marks CLS, SEP, PAD, and UNK. Non-positive ReLU values are 0. Salient-term selection uses these weights, not the pooled map: pooling would give every occurrence of a token id the same weight.

func TokenizerFetchHint added in v0.10.13

func TokenizerFetchHint() string

TokenizerFetchHint names the cache path and how to fetch only tokenizer.json.

func TokenizerMissIsFatal added in v0.10.13

func TokenizerMissIsFatal(ci string) bool

TokenizerMissIsFatal reports that a missing tokenizer must fail a test. GitHub Actions sets CI=true. Any other value, including empty, skips.

func TruncateForEmbedding

func TruncateForEmbedding(text string, maxTokens int) string

TruncateForEmbedding truncates text to fit within the model's token limit. Uses a character-based approximation (2 chars/token, empirically derived). Breaks at word boundaries when possible.

Tail loss: content beyond maxTokens × 2 chars is dropped before tokenization — the head is embedded correctly but the tail is invisible to semantic retrieval (lexical FTS still sees the full body). For long-form notes where the tail carries information not in the head, this under-covers retrieval. Tracked as a quality improvement in vaultmind#30 (chunk-and-pool); not a silent failure or robustness bug, just a coverage limit. Build the chunking fix when retrieval visibly misses tail content; don't preempt.

func WhitespaceTokenSpans added in v0.10.13

func WhitespaceTokenSpans(text string) [][2]int

WhitespaceTokenSpans is the one whitespace split. A keyword-only ask has no BGE-M3 tokenizer, so each whitespace word is one token. alignTokenWords uses the same split, and the two cannot drift (Principle 7).

Types

type BGEM3Embedder

type BGEM3Embedder struct {
	// contains filtered or unexported fields
}

BGEM3Embedder produces dense, sparse, and ColBERT embeddings using BGE-M3.

func NewBGEM3Embedder

func NewBGEM3Embedder(ctx context.Context, cfg HugotConfig) (*BGEM3Embedder, error)

NewBGEM3Embedder creates a BGE-M3 embedder with all three heads.

func NewSpanEmbedder added in v0.10.13

func NewSpanEmbedder(tokenizerJSON []byte, modelMax int) (*BGEM3Embedder, error)

NewSpanEmbedder builds an embedder that can only read token spans. It does not load the ONNX model. modelMax is the model cap stored on the embedder. TokenSpans sizes its window from the forward bound it is given. A test passes BGEM3MaxTokens so a mutation back to that cap is the real model limit.

func (*BGEM3Embedder) AnalyzeQuery added in v0.10.13

func (e *BGEM3Embedder) AnalyzeQuery(ctx context.Context, text string) (QueryTokens, error)

AnalyzeQuery returns the per-token weights of the one forward pass for text. The caller embeds that same string afterwards, and the memo makes it one pass. Word spans come from the query-only tokenizer. A span-read failure leaves the forward-pass weights in place and does not fail the query. Those weights already have CLS, SEP, PAD, and UNK zeroed.

func (*BGEM3Embedder) Close

func (e *BGEM3Embedder) Close() error

Close releases the hugot session.

func (*BGEM3Embedder) Dims

func (e *BGEM3Embedder) Dims() int

Dims returns the embedding dimensionality (1024).

func (*BGEM3Embedder) Embed

func (e *BGEM3Embedder) Embed(ctx context.Context, text string) ([]float32, error)

Embed returns the dense embedding (Embedder interface compatibility).

func (*BGEM3Embedder) EmbedBatch

func (e *BGEM3Embedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

EmbedBatch returns dense embeddings (Embedder interface compatibility).

func (*BGEM3Embedder) EmbedColBERT

func (e *BGEM3Embedder) EmbedColBERT(ctx context.Context, text string) ([][]float32, error)

EmbedColBERT produces only the ColBERT per-token embeddings (used by ColBERTRetriever).

func (*BGEM3Embedder) EmbedFull

func (e *BGEM3Embedder) EmbedFull(ctx context.Context, text string) (*BGEM3Output, error)

EmbedFull produces all three embedding types for a single text. The same text is computed once while remembered: every retrieval lane calls this for the query, and each wants a different one of the three outputs.

func (*BGEM3Embedder) EmbedFullBatch

func (e *BGEM3Embedder) EmbedFullBatch(ctx context.Context, texts []string) ([]*BGEM3Output, error)

EmbedFullBatch produces all three embedding types for multiple texts. Bypasses hugot's Postprocess to access raw per-token hidden states.

func (*BGEM3Embedder) EmbedSparse

func (e *BGEM3Embedder) EmbedSparse(ctx context.Context, text string) (map[int32]float32, error)

EmbedSparse produces only the sparse embedding (used by SparseRetriever).

func (*BGEM3Embedder) TokenSpans added in v0.10.13

func (e *BGEM3Embedder) TokenSpans(text string, forwardTokens int) ([][2]int, error)

TokenSpans reports content-token byte spans for text without a forward pass. The read uses the query-only tokenizer, pre-cut to the span window for forwardTokens (the bound in use, not the model cap). forwardTokens <= 0 reads the whole string. The special mask only skips CLS and SEP. Spans are clamped to that window: the tokenizer can report an end a few bytes past the string it saw, and the cut must stay inside the prefix that was tokenized. An empty content list is a non-nil slice, so the caller can tell "tokenized, nothing" from a tokenizer error. The model clamp in preprocessWithinTokenLimit is what keeps an oversized note from hanging.

type BGEM3Output

type BGEM3Output struct {
	Dense        []float32         // [1024] CLS-pooled, unit length
	Sparse       map[int32]float32 // vocab_id -> weight (non-zero only)
	ColBERT      [][]float32       // [seq_len-1][1024] per-token, unit length
	TokenWeights []float32
	TokenWord    []int
	Words        []string
	TokenOffsets [][2]int
}

BGEM3Output contains all three embedding types from a BGE-M3 forward pass.

TokenWeights, TokenWord and Words are the query-token view used to choose salient terms. TokenWeights are per-position ReLU weights before vocab-id max-pooling, with the CLS position dropped so they line up with ColBERT. A sidecar pass does not fill them.

type Embedder

type Embedder interface {
	// Embed produces a single embedding vector for the given text.
	Embed(ctx context.Context, text string) ([]float32, error)

	// EmbedBatch produces embedding vectors for multiple texts.
	EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

	// Dims returns the dimensionality of the embedding vectors.
	Dims() int

	// Close releases resources (model session, etc.).
	Close() error
}

Embedder converts text into dense vector representations.

type FullEmbedder

type FullEmbedder interface {
	Embedder
	EmbedFullBatch(ctx context.Context, texts []string) ([]*BGEM3Output, error)
}

FullEmbedder extends Embedder with multi-output capability (BGE-M3).

type HugotConfig

type HugotConfig struct {
	// ModelPath is the local path to the ONNX model directory.
	// If empty, the model will be downloaded from HuggingFace.
	ModelPath string

	// ModelName is the HuggingFace model ID (e.g., "sentence-transformers/all-MiniLM-L6-v2").
	// Used for downloading if ModelPath is not set.
	ModelName string

	// CacheDir is where downloaded models are stored.
	CacheDir string

	// Dims is the embedding dimensionality (e.g., 384 for MiniLM, 1024 for BGE-M3).
	Dims int

	// OnnxFilePath specifies which ONNX file to use when a model has multiple variants.
	// E.g., "onnx/model.onnx" for the default, "onnx/model_O2.onnx" for optimized.
	OnnxFilePath string

	// MaxTokens is the model's context window size. Texts longer than this (in approximate
	// tokens) are truncated before embedding. 0 means no truncation.
	MaxTokens int
}

HugotConfig configures the HugotEmbedder.

func BGEM3Config

func BGEM3Config() HugotConfig

BGEM3Config returns the HugotConfig for BGE-M3.

func DefaultHugotConfig

func DefaultHugotConfig() HugotConfig

DefaultHugotConfig returns the standard HugotConfig for all-MiniLM-L6-v2.

type HugotEmbedder

type HugotEmbedder struct {
	// contains filtered or unexported fields
}

HugotEmbedder wraps the hugot library to produce embeddings using ONNX models.

func NewHugotEmbedder

func NewHugotEmbedder(ctx context.Context, cfg HugotConfig) (*HugotEmbedder, error)

NewHugotEmbedder creates an embedder using hugot with the Go backend. For ORT backend (faster, supports larger models), build with -tags ORT.

func (*HugotEmbedder) Close

func (e *HugotEmbedder) Close() error

Close releases the hugot session.

func (*HugotEmbedder) Dims

func (e *HugotEmbedder) Dims() int

Dims returns the dimensionality of the embedding vectors.

func (*HugotEmbedder) Embed

func (e *HugotEmbedder) Embed(ctx context.Context, text string) ([]float32, error)

Embed produces a single embedding vector.

func (*HugotEmbedder) EmbedBatch

func (e *HugotEmbedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

EmbedBatch produces embedding vectors for multiple texts. Texts exceeding the model's token limit are truncated automatically.

The limit is enforced on the ACTUAL token count, not only the char estimate. #69 relaxed that estimate to 4 chars/token believing an exact guard stood behind it — true for BGE-M3, false here. Citation-dense notes tokenize near 2 chars/token, so up to ~1100 tokens reached a 512-position model and failed their whole batch (stranger test, 2026-09-23: 28 of 60 notes unembedded). fitTextsWithinTokenLimit is the same measured loop BGE-M3 uses; it costs one extra tokenization and nothing when every text already fits.

type QueryTokens added in v0.10.13

type QueryTokens struct {
	Weights []float32
	Word    []int
	Words   []string
	// Offsets are byte ranges into the text the tokenizer saw, aligned with
	// Weights. A token with no span has end <= start.
	Offsets [][2]int
}

QueryTokens is one query's per-token view of the forward pass, aligned with ColBERT (the CLS position is already dropped).

Weights are the per-position ReLU sparse weights BEFORE vocab-id max-pooling. Word is -1 when a token has no word: a special token, an empty offset, or a pass that did not report offsets. Sidecar output has none of these fields, and salient word selection does not run for it.

type SidecarBGEM3Config

type SidecarBGEM3Config struct {
	// Python is the interpreter path. Must have torch + transformers
	// installed and be on a platform where torch.backends.mps.is_available()
	// returns true (Apple Silicon). When empty, falls back to "python3" on
	// PATH.
	Python string
	// ScriptPath is the absolute path to embed_server.py. When empty, the
	// embedder looks for the script alongside this Go file (resolved via
	// the project's $CLAUDE_PROJECT_DIR or the executable's directory).
	ScriptPath string
}

SidecarBGEM3Config controls how the sidecar process is launched.

type SidecarBGEM3Embedder

type SidecarBGEM3Embedder struct {
	// contains filtered or unexported fields
}

SidecarBGEM3Embedder runs BGE-M3 inference in an external Python process that uses PyTorch + MPS (Apple Silicon GPU). The Go side handles tokenization context (none — Python sidecar tokenizes with HF tokenizer loaded from cache) and the heads run inside the sidecar so the per-modality tensors flow through MPS without round-tripping to CPU mid-batch.

Why a sidecar instead of in-process: in-process ORT (via hugot) saturates CPU during indexing on Apple Silicon — there's no GPU acceleration path (vaultmind#34). The sidecar pattern moves heavy inference behind a JSON contract, isolating vaultmind core from the inference engine choice. Today the engine is PyTorch+MPS; tomorrow it could be CoreML or MLX without touching the Go side.

Lifecycle: the embedder spawns the Python subprocess in NewSidecarBGEM3. Close() tears it down. Per-batch round-trips happen via Send (write JSON line to stdin, read JSON line from stdout). Mutex serializes access since the protocol is synchronous request/response on a single FD pair.

func NewSidecarBGEM3

func NewSidecarBGEM3(cfg SidecarBGEM3Config) (*SidecarBGEM3Embedder, error)

NewSidecarBGEM3 spawns the Python sidecar and waits for its ready signal. Returns an error if the subprocess fails to start, the Python imports fail, or the model can't be loaded. The caller MUST defer Close() to reap the subprocess.

func (*SidecarBGEM3Embedder) Close

func (e *SidecarBGEM3Embedder) Close() error

Close terminates the sidecar process. Safe to call multiple times.

func (*SidecarBGEM3Embedder) Device

func (e *SidecarBGEM3Embedder) Device() string

Device reports the device the sidecar selected ("mps" or "cpu"). Useful for the doctor / index summary so the operator sees acceleration.

func (*SidecarBGEM3Embedder) Dims

func (e *SidecarBGEM3Embedder) Dims() int

Dims reports the dense embedding dimensionality.

func (*SidecarBGEM3Embedder) Embed

func (e *SidecarBGEM3Embedder) Embed(ctx context.Context, text string) ([]float32, error)

Embed produces a single dense embedding via the sidecar.

func (*SidecarBGEM3Embedder) EmbedBatch

func (e *SidecarBGEM3Embedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error)

EmbedBatch produces dense embeddings for a batch via the sidecar.

func (*SidecarBGEM3Embedder) EmbedFull

func (e *SidecarBGEM3Embedder) EmbedFull(ctx context.Context, text string) (*BGEM3Output, error)

EmbedFull is the singleton form of EmbedFullBatch.

func (*SidecarBGEM3Embedder) EmbedFullBatch

func (e *SidecarBGEM3Embedder) EmbedFullBatch(_ context.Context, texts []string) ([]*BGEM3Output, error)

EmbedFullBatch sends a batch of texts to the sidecar and parses the response. Tokens are sparse-key strings in the JSON; we parse to int32 here so the sidecar protocol stays portable across languages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL