Configure an embedding provider

Available on NAMS: No. The procedure on this page needs the Bolt backend. With the hosted NAMS backend its operations are unavailable: depending on the call, the client raises NotSupportedError, AttributeError or TypeError, or ignores a Bolt-only setting or argument (NAMS manages embedding and extraction server-side). See the backend capabilities reference for what NAMS provides instead.

Configure a client-side embedding provider through MemorySettings.embedding and verify that its output matches the graph indexes.

For the big-picture choice between providers see Bring your own model. Embedding adapters share the EmbeddingProvider Protocol; the same wiring patterns apply across cloud APIs and local models.

This page configures client-side embedding on the bolt backend. On NAMS, embedding runs server-side — the workspace’s embedding model and vector dimension are service/workspace configuration. Read those values from your service configuration instead of inferring them from this SDK. MemorySettings.embedding is therefore ignored on NAMS. See Bolt and NAMS backends.

Prerequisites

  • Install the extras for each selected provider and configure its credentials. Quote package extras in shell commands, for example pip install 'neo4j-agent-memory[openai]==0.7.0'.

  • Use a dedicated AuraDB instance and export NEO4J_URI, NEO4J_USERNAME, and NEO4J_PASSWORD as shown in the Aura connection setup. These examples use the bolt backend; NEO4J_DATABASE defaults to neo4j when omitted.

  • Model identifiers below illustrate adapter routing. Confirm the chosen model is available to your account before making a live request; successful provider construction does not verify model access.

  • Run snippets containing await in an async function. The provider, messages, and connected client in later fragments come from your application’s setup.

Procedure

  1. Choose a provider string or an explicit adapter from the options below.

  2. Configure both the LLM and embedding provider; changing one does not configure the other.

  3. Run the verification at the end before applying the configuration to an existing graph.

Set the embedding provider

MemorySettings.embedding accepts a provider string or an explicit Provider instance. Bring your own model — Three ways to wire a provider walks through both forms for llm=; framework pass-through (pattern C) applies to llm= only. The embedding field works the same way:

  • Provider string (recommended for most users) — embedding="openai/text-embedding-3-small" resolves via from_provider(model, kind="embedding"). The factory looks up the model in neo4j_agent_memory.llm.defaults.EMBEDDING_DIMENSIONS to populate dimensions automatically. For unknown models, pass an explicit instance with dimensions=N (see below).

  • Explicit Provider instance — construct the adapter directly for kwargs the string form can’t express. This example requests OpenAI’s dimension reduction and a larger embedding batch size:

import os
from neo4j_agent_memory import MemorySettings
from neo4j_agent_memory.llm.adapters.openai import OpenAIEmbeddingProvider

settings = MemorySettings(
    backend="bolt",
    neo4j={
        "uri": os.environ["NEO4J_URI"],
        "username": os.environ["NEO4J_USERNAME"],
        "password": os.environ["NEO4J_PASSWORD"],
        "database": os.getenv("NEO4J_DATABASE", "neo4j"),
    },
    embedding=OpenAIEmbeddingProvider(
        "openai/text-embedding-3-large",
        dimensions=1024,    # sent to OpenAI as the requested output size
        batch_size=200,
    ),
)

The Bedrock and Vertex AI sections below show the same pattern with their adapters.

Use local sentence-transformers

No API key needed; embeddings stay on your machine.

import os
from neo4j_agent_memory import MemorySettings

settings = MemorySettings(
    backend="bolt",
    neo4j={
        "uri": os.environ["NEO4J_URI"],
        "username": os.environ["NEO4J_USERNAME"],
        "password": os.environ["NEO4J_PASSWORD"],
        "database": os.getenv("NEO4J_DATABASE", "neo4j"),
    },
    embedding="BAAI/bge-small-en-v1.5",      # 384 dims
)

Install: pip install 'neo4j-agent-memory[sentence-transformers]==0.7.0'. First call downloads the model (~50-500 MB depending on choice). Subsequent calls hit the local cache.

Tune the device:

from neo4j_agent_memory.llm.adapters.sentence_transformers import (
    SentenceTransformersProvider,
)

embedder = SentenceTransformersProvider(
    "BAAI/bge-large-en-v1.5",
    device="cuda",   # or "mps" on Apple Silicon
)

Use a custom / unknown model

For embedding models not in the defaults table, you must pass dimensions= explicitly. Otherwise the adapter raises a clear error:

from neo4j_agent_memory.llm.adapters.openai import OpenAIEmbeddingProvider

# Will raise:
#   ValueError: Could not determine dimensions for embedding model
#   'openai/my-unreleased-model'. Pass dimensions=N explicitly or use a
#   model in the defaults table.
embedder = OpenAIEmbeddingProvider("openai/my-unreleased-model")

# Correct:
embedder = OpenAIEmbeddingProvider("openai/my-unreleased-model", dimensions=2048)

The current SentenceTransformersProvider also requires dimensions= for an unknown model and raises at construction if it is omitted. It does not infer unknown dimensions on the first embedding call. Verify the declared dimension against an actual vector.

Use AWS Bedrock embeddings

import os
from neo4j_agent_memory import MemorySettings
from neo4j_agent_memory.llm.adapters.bedrock import BedrockEmbeddingProvider

settings = MemorySettings(
    backend="bolt",
    neo4j={
        "uri": os.environ["NEO4J_URI"],
        "username": os.environ["NEO4J_USERNAME"],
        "password": os.environ["NEO4J_PASSWORD"],
        "database": os.getenv("NEO4J_DATABASE", "neo4j"),
    },
    embedding=BedrockEmbeddingProvider(
        "bedrock/amazon.titan-embed-text-v2:0",
        aws_region="us-east-1",
        aws_profile="my-aws-profile",    # optional
    ),
)

The adapter delegates to the existing BedrockEmbedder and reads the standard boto3 credential chain.

Use Vertex AI embeddings

import os
from neo4j_agent_memory import MemorySettings
from neo4j_agent_memory.llm.adapters.vertex_ai import VertexAIEmbeddingProvider

settings = MemorySettings(
    backend="bolt",
    neo4j={
        "uri": os.environ["NEO4J_URI"],
        "username": os.environ["NEO4J_USERNAME"],
        "password": os.environ["NEO4J_PASSWORD"],
        "database": os.getenv("NEO4J_DATABASE", "neo4j"),
    },
    embedding=VertexAIEmbeddingProvider(
        "vertex_ai/gemini-embedding-001",
        project_id="my-gcp-project",
        location="us-central1",
        dimensions=768,
    ),
)

The underlying VertexAIEmbedder supports gemini-embedding-001 and defaults to 768 output dimensions. The current VertexAIEmbeddingProvider does not forward its dimensions argument as output_dimensionality to that embedder. Keep this wrapper at 768 dimensions and verify the output length. Setting the wrapper to 1536 or 3072 can advertise a dimension different from what it returns. For other dimensions, use an application-owned EmbeddingProvider that actually produces the declared shape; this page does not supply a wrapper fix.

Vertex AI chat calls route through LiteLLM; this native adapter covers embeddings. See the Vertex AI model table for the supported and retired model IDs and the task_type values.

Configure via the MCP CLI

The neo4j-agent-memory command needs the cli extra, and mcp serve also needs the mcp extra. This example selects a local sentence-transformers model and keeps the default OpenAI LLM provider:

pip install 'neo4j-agent-memory[cli,mcp,sentence-transformers,openai]==0.7.0'
neo4j-agent-memory mcp serve \
  --backend bolt --uri "$NEO4J_URI" --user "$NEO4J_USERNAME" \
  --embedding BAAI/bge-small-en-v1.5 \
  --embedding-dimensions 384      # override for unknown models

Or env var:

export NAM_EMBEDDING=BAAI/bge-small-en-v1.5
neo4j-agent-memory mcp serve --backend bolt --uri "$NEO4J_URI" --user "$NEO4J_USERNAME"

Verify dimensions at runtime

from neo4j_agent_memory.llm import from_provider

embedder = from_provider("BAAI/bge-small-en-v1.5", kind="embedding")
assert embedder.dimensions == 384

# The vector should match
vector = await embedder.embed_one("test sentence")
assert len(vector) == embedder.dimensions
print("Verified vector dimensions:", len(vector))

Migrate between embedding models

MemoryClient.connect() raises EmbeddingDimensionMismatchError if existing managed vector indexes have a different size. It does not detect a same-dimension model change or verify every stored vector. The error lists every offending index and points at the migration runbook.

See Migrate to a new embedding model for the three remediation options (rebuild, revert, re-embed in place).

See also