Embedders

Convert text into vector representations for semantic search.

Embedders convert text into vectors (lists of numbers) that capture meaning. These vectors enable semantic search, so "How do I reset my passcode?" finds documents mentioning "change PIN" even without keyword matches.

The examples use a running PgVector database, a db_url connection string, and OPENAI_API_KEY. Follow the PgVector setup first; supply your own documents/ directory for ingestion.

from agno.knowledge.knowledge import Knowledge
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.vectordb.pgvector import PgVector

knowledge = Knowledge(
    vector_db=PgVector(
        table_name="docs",
        db_url=db_url,
        embedder=OpenAIEmbedder(),  # Default
    ),
)

How It Works

  1. Insert: When you add content, each chunk is converted to a vector
  2. Store: Vectors are saved in your vector database
  3. Search: Queries are embedded and matched against stored vectors by similarity

Agno uses OpenAIEmbedder by default, but you can swap in any supported embedder.

Configuration

from agno.knowledge.embedder.openai import OpenAIEmbedder

embedder = OpenAIEmbedder(
    id="text-embedding-3-small",
    dimensions=1536,
)

Using with Knowledge

from agno.knowledge.knowledge import Knowledge
from agno.vectordb.pgvector import PgVector

knowledge = Knowledge(
    vector_db=PgVector(
        table_name="docs",
        db_url=db_url,
        embedder=OpenAIEmbedder(id="text-embedding-3-small"),
    ),
)

# Content is embedded automatically on insert
knowledge.insert(path="documents/")

Batch Embeddings

Batch-capable embedders can send multiple texts per request. Whether ingestion uses that interface depends on the vector database and ingestion method. Setting enable_batch=True alone does not make synchronous insertion batch its requests.

For example, PgVector uses this interface during asynchronous insertion:

embedder = OpenAIEmbedder(
    id="text-embedding-3-small",
    dimensions=1536,
    enable_batch=True,
    batch_size=100,
)

knowledge = Knowledge(
    vector_db=PgVector(table_name="batched_docs", db_url=db_url, embedder=embedder),
)

async def main():
    await knowledge.ainsert(path="documents/")

# In a Python script:
import asyncio
asyncio.run(main())

Agno provides a batch interface for OpenAI, Azure OpenAI, Gemini, Cohere, Voyage AI, Mistral, Fireworks, Together, Jina, Nebius, LangDB, and vLLM. Provider and mode behavior differs: local vLLM currently loops over individual embedding calls. Confirm that your ingestion path consumes the batch interface, then measure its effect on request count and latency.

Error Handling

Embedders raise EmbeddingError from agno.exceptions when the provider call fails. They do not return an empty vector. This applies to direct calls such as embedder.get_embedding(text):

from agno.exceptions import EmbeddingError

try:
    vector = embedder.get_embedding("How do I reset my passcode?")
except EmbeddingError as e:
    print(e.provider, e.model_id, e.status_code)
    print(e.reason)         # authentication, rate_limit, content_too_large, or unknown
    print(e.recovery_hint)  # Suggested next step for this reason
    print(e.is_retryable)   # False for authentication and content_too_large
    print(e.safe_message)   # Provider message with credential-like strings redacted

reason comes from the provider's HTTP status when one is reported, and from the message text otherwise. status_code is 502 when the provider reported no status.

During ingestion, Knowledge catches the error and records it on the content row as a failed or partial content status. When a batch request fails, the embedder retries each text individually and keeps the ones that succeed. Set max_embedding_retries on Knowledge to retry transient failures. During search, a failed query embedding is logged and the search returns no results.

Best Practices

Re-embed when changing models: Vectors from different embedders aren't compatible. If you switch embedders, you must re-embed all content.

Test retrieval quality: Use sample queries to verify you're finding the right chunks. Adjust chunking strategy or embedder if results are poor.

Match dimensions: Ensure your embedder's output dimensions match what your vector database expects.

Supported Embedders

EmbedderExecutionNotes
OpenAIHostedDefault Agno embedder
GeminiHostedGoogle embedding API
CohereHostedDocument/query input types
Voyage AIHostedModel-dependent dimensions and input types
MistralHostedMistral embedding API
OllamaLocal/serverRequires a running Ollama server
FastEmbedLocalDownloads model weights
SentenceTransformersLocalModels via sentence-transformers
vLLMLocal/serverInjected local client or vLLM server
HuggingFaceHostedHugging Face Inference API
AWS BedrockHostedAWS model and region configuration
Azure OpenAIHostedAzure deployment configuration
FireworksHostedOpenAI-compatible embedding API
TogetherHostedVerify current endpoint/model availability
JinaHostedTask-specific request settings
NebiusHostedVerify available model and dimensions
LangDBGatewayOpenAI-compatible gateway

Choosing an Embedder

Compare candidates on your own content and queries:

  • Retrieval quality: Evaluate relevant-document recall across the languages and domains you need.
  • Deployment: Local models require suitable hardware and model downloads; hosted models require credentials and an available endpoint.
  • Latency and cost: Measure your workload and check current provider pricing. Local execution still has compute and operational costs.
  • Dimensions: Match the database's vector size and re-embed into a new compatible collection when changing models.

Next Steps