SurrealDB Vector Database

Use SurrealDB as a vector database for your Knowledge Base.

Setup

uv pip install -U surrealdb pypdf openai agno

The example uses OpenAI for embeddings and the agent model, so set your API key:

export OPENAI_API_KEY=xxx
docker run -d \
  --rm \
  --pull always \
  -p 8000:8000 \
  surrealdb/surrealdb:latest \
  start \
  --user root \
  --pass root

or

./cookbook/scripts/run_surrealdb.sh

Example

agent_with_knowledge.py
from agno.agent import Agent
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.knowledge.knowledge import Knowledge
from agno.vectordb.surrealdb import SurrealDb
from surrealdb import Surreal

# SurrealDB connection parameters
SURREALDB_URL = "ws://localhost:8000"
SURREALDB_USER = "root"
SURREALDB_PASSWORD = "root"
SURREALDB_NAMESPACE = "test"
SURREALDB_DATABASE = "test"

# Create a client
client = Surreal(url=SURREALDB_URL)
client.signin({"username": SURREALDB_USER, "password": SURREALDB_PASSWORD})
client.use(namespace=SURREALDB_NAMESPACE, database=SURREALDB_DATABASE)

surrealdb = SurrealDb(
    client=client,
    collection="recipes",  # Collection name for storing documents
    search_ef=40,  # HNSW search time/accuracy trade-off
    embedder=OpenAIEmbedder(),
)

def sync_demo():
    """Demonstrate synchronous usage of SurrealDb"""
    knowledge_base = Knowledge(
        vector_db=surrealdb,
    )

    # Load data synchronously
    knowledge_base.insert(
        url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"
    )

    # Create agent and query synchronously
    agent = Agent(knowledge=knowledge_base)
    agent.print_response(
        "What are the 3 categories of Thai SELECT is given to restaurants overseas?",
        markdown=True,
    )

if __name__ == "__main__":
    # Run synchronous demo
    print("Running synchronous demo...")
    sync_demo()

The async example supplies both authenticated clients to the same namespace and database: Knowledge currently checks the schema synchronously during construction. Context managers close both connections when the example finishes.

Async Support ⚡

SurrealDB awaits async client I/O. Knowledge initialization, PDF extraction, and query embeddings still use synchronous operations; async methods alone do not guarantee nonblocking execution.

async_surreal_db.py
import asyncio

from agno.agent import Agent
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.knowledge.knowledge import Knowledge
from agno.vectordb.surrealdb import SurrealDb
from surrealdb import AsyncSurreal, Surreal

SURREALDB_URL = "ws://localhost:8000"
SURREALDB_NAMESPACE = "test"
SURREALDB_DATABASE = "test"
CREDENTIALS = {"username": "root", "password": "root"}

async def main():
    # Knowledge checks/creates the schema through the synchronous client.
    with Surreal(SURREALDB_URL) as sync_client:
        sync_client.signin(CREDENTIALS)
        sync_client.use(namespace=SURREALDB_NAMESPACE, database=SURREALDB_DATABASE)
        async with AsyncSurreal(SURREALDB_URL) as async_client:
            await async_client.signin(CREDENTIALS)
            await async_client.use(namespace=SURREALDB_NAMESPACE, database=SURREALDB_DATABASE)
            vector_db = SurrealDb(
                client=sync_client,
                async_client=async_client,
                collection="recipes",
                search_ef=40,
                embedder=OpenAIEmbedder(),
            )
            knowledge = Knowledge(vector_db=vector_db)
            await knowledge.ainsert(
                url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf",
            )
            agent = Agent(knowledge=knowledge)
            await agent.aprint_response("How do I make pad thai?", markdown=True)

if __name__ == "__main__":
    asyncio.run(main())

Use ainsert() and aprint_response() with the async client for awaited database I/O. Measure or offload the remaining synchronous work when needed.

SurrealDB Params

ParameterTypeDefaultDescription
clientOptional[Union[BlockingWsSurrealConnection, BlockingHttpSurrealConnection]]NoneA blocking connection, either HTTP or WS
async_clientOptional[Union[AsyncWsSurrealConnection, AsyncHttpSurrealConnection]]NoneAn async connection, either HTTP or WS
collectionstr"documents"Collection name to store documents
distanceDistanceDistance.cosineDistance metric to use (cosine, l2, or max_inner_product)
efcint150Accepted but currently not applied to the generated index
mint12Accepted but currently not applied to the generated index
search_efint40HNSW search time/accuracy trade-off
embedderOptional[Embedder]OpenAIEmbedder()Embedder instance for creating embeddings