Skip to content

Embedder

The query-embedding port behind embed().

Port: embed(request: EmbedRequest) -> EmbedResult, reached as indx.embed(). A stage rather than an extension point, so no Embedder protocol is declared: QueryEmbedder is the one implementation, and what a deployment substitutes is an embedding space, not the stage that selects one.

Embedder is the boundary for encoding a text or image query into a selected embedding space. It chooses the query-role embedder compatible with the input modality and returns vectors together with the exact public space and embedder configuration used.

An embedding space defines the vector dimension, distance metric, normalization, and compatible embedders. Each embedder declares its roles, modalities, model revision, preprocessing configuration, and reproducible fingerprint.

Document vectors are useful only when callers can produce compatible query vectors. Selecting by embedding-space ID lets document and query encoders use different implementations while preserving a shared vector contract where compatibility has been established.

Returning the exact public configuration makes query results reproducible and lets downstream indexes validate dimensions and similarity semantics without exposing provider credentials or private endpoints.

The input is EmbedRequest, which carries a request ID, a text or image input, and the required embedding space ID.

The output is EmbedResult, which carries:

  • The caller’s request ID.
  • The complete selected EmbeddingSpace descriptor.
  • The exact query-role EmbedderConfig used.
  • One or more vectors identifying that embedder.
  • Resolve the requested embedding space from the capability inventory.
  • Select exactly one query-role embedder compatible with the input modality.
  • Apply the declared model revision and preprocessing configuration.
  • Return at least one vector with the embedding space’s declared dimension.
  • Identify every vector with the selected embedder ID.
  • Preserve the space’s distance metric and normalization semantics.
  • Keep credentials and private provider endpoints out of public descriptors.

The protocol covers query encoding. Document embeddings are produced as part of the execution workflow and identify the same versioned spaces on returned blocks.

What that side may be handed is one statement: DOCUMENT_EMBEDDING_MODALITIES in indx-interfaces, read by the router’s fault and by the executor’s selection alike. It is (text, image) and the order is load-bearing. A chunk is usually text; a page nothing could read as text becomes the rendered page instead, which is what indx-chunker-pdf produces and what makes the image half reachable at all. A page never carries both: a chunker hands over text for a page that was read and a render only for one that was not, so a read page never also pays for a rasterization. The order decides which lane a space is reported by, not what execution embeds.

A space is refused when a plan names it only if it declares no document lane this list covers; a space whose only document lane is an image is routable, and was not before. Execution embeds each modality in its own call against the embedder that space declares for it, so a document whose scanned pages were rendered can carry text vectors and image vectors in one space. A modality the space has no document embedder for is skipped rather than failed – the space still answers for everything else the document produced.

Query encoding is unrestricted by the list: a space may read images for queries whatever it does for documents, which is what clip-vit-b32 did before it took the document role too.

The public indx.embed() facade and POST /v1/embed operation delegate to an embedder. Capability snapshots advertise the embedding spaces from which the request selects, and encoded document blocks reference those same space IDs.