Skip to content
tnsaijava agent framework

Embedding prefixes

EmbeddingFunctions.matryoshka derives a shorter, L2-normalized prefix from any EmbeddingFunction. The helper and EmbeddingDimensionMismatchException are @since 0.14.0 in TnsAI 0.14.0 (TnsAI@c2bb5306). They ship in Maven Central 0.14.1.

TnsAI 0.15.0 also makes the declarative hash-embedding fallback visible. That warning ships in 0.15.0 and later. See Hash-embedding fallback.

Use this only when the delegate model is Matryoshka-trained (or otherwise prefix-compatible). Truncating a non-Matryoshka vector changes the geometry; the helper does not invent a second model.

What it does

EmbeddingFunction full = /* application provider, e.g. 1024-d */;
EmbeddingFunction reduced = EmbeddingFunctions.matryoshka(full, 256);
VectorMemoryStore store = new VectorMemoryStore(reduced);

Each embed call:

  1. asks the delegate for the full vector
  2. copies the first dimensions values (the delegate array is never mutated or returned)
  3. L2-normalizes that prefix; an all-zero prefix stays a zero vector

dimensions must be positive. A non-finite prefix value fails with IllegalArgumentException. A delegate vector shorter than dimensions throws EmbeddingDimensionMismatchException (expectedDimension / actualDimension).

Store pin

VectorMemoryStore pins the first admitted vector's length for the store's lifetime. Later add and non-empty search vectors must match that length or the same mismatch exception is thrown. clear() removes entries but does not reset the pin.

Build the store with the reduced function from the first add. Mixing a 1024-d query against a 256-d index is a typed failure, not a silent reshape.

Hash-embedding fallback (0.15.0)

Declarative Role bindings discover one process-wide EmbeddingFunction through Java ServiceLoader. When none is installed, the runtime uses the bundled 128-dimensional hash embedding — a normalised bag-of-words that ranks by token overlap, not meaning. Cosine is near zero for two documents that say the same thing in different words. @Retrieval(strategy = SEMANTIC) then behaves lexically.

On Maven Central 0.14.1 that fallback is silent: no warning, no diagnostic. The annotation says SEMANTIC; the results are token overlap.

TnsAI 0.15.0 (TnsAI@89d41d1b, PR #195 / TAN-5885) emits one WARN per Role class for the process lifetime when both of these hold:

  1. the resolved function is the bundled hash embedding
  2. the requested strategy is vector-backed: SEMANTIC, HYBRID, HIERARCHICAL, or TEMPORAL

KEYWORD, GRAPH, REASONING, and MULTI_QUERY do not warn on this path. An installed provider logs nothing. The runtime does not throw — the hash embedding stays a deliberate zero-setup default so offline tests and examples keep running.

What you see

A single warning that names the Role, states that retrieval is ranking by token overlap rather than meaning, and names remedies. Repeat dispatches do not repeat the line.

What it means

SEMANTIC (and the other vector-backed modes above) is not semantic until a real provider is installed. Hybrid fusion is only partly degraded — BM25 still runs — but the vector half is lexical. Treat the warning as "this annotation is advertising a capability you do not have."

What to do

  1. Install one EmbeddingFunction provider — see Strategies.
  2. Or set strategy = KEYWORD if lexical matching is what you want.
  3. Or acknowledge the fallback deliberately with -Dtnsai.rag.acknowledgeHashEmbedding=true so the warning is not suppressed globally by a log-level workaround.

To ask what resolved, including whether the snapshot is the bundled fallback, use RagDiagnostics (@since 0.15.0).

Not this page

  • Process-wide declarative EmbeddingFunction discovery — see Strategies
  • Inspecting the resolved RAG binding — RAG diagnostics (@since 0.15.0)
  • The Matryoshka helper ships in Maven Central 0.14.1. The hash-fallback warning does not.