How Open Notebook Implements Vector Search for Knowledge-Base Data

Open Notebook implements vector search by generating query embeddings through the Esperanto AI layer and executing a SurrealDB stored procedure fn::vector_search that performs cosine similarity matching against pre-computed embeddings stored on Source and Note records.

Open Notebook is an open-source knowledge management system that stores notebook content in SurrealDB, a multi-model graph database. The platform provides semantic search capabilities through a vector search implementation that leverages SurrealDB's built-in vector storage and similarity functions. This article examines the exact mechanisms, file paths, and function calls that enable fast, scalable semantic retrieval across Source and Note records.

Architecture Overview

The vector search system integrates three core layers: the Esperanto AI provider for embedding generation, SurrealDB for vector storage and similarity computation, and a Python domain layer that orchestrates the workflow. When users submit a vector search query, the system embeds the text, invokes SurrealDB's fn::vector_search stored procedure, and returns ranked results based on cosine similarity scores.

The Vector Search Pipeline

Step 1: Generate Query Embeddings

The embedding process begins in open_notebook/utils/embedding.py via the generate_embedding function. This utility lazily loads the configured embedding model through the Esperanto AI-provider layer (open_notebook/ai/models/model_manager) by calling model_manager.get_embedding_model().

For text input, the system executes model.aembed([text]) to generate vector representations. If the query exceeds the model's payload limit, the helper automatically chunks the text, embeds each segment individually, and applies mean pooling through the mean_pool_embeddings function to produce a single representative vector.

The domain layer in open_notebook/domain/notebook.py contains the vector_search wrapper function that receives the query embedding and forwards it to SurrealDB. The system executes the following raw SurrealQL query through the repo_query helper in open_notebook/database/repository.py:

SELECT * FROM fn::vector_search($embed, $results, $source, $note, $minimum_score);

Parameters include:

  • $embed: The pre-computed query embedding vector
  • $results: Maximum number of matches to return
  • $source: Boolean flag to include Source records
  • $note: Boolean flag to include Note records
  • $minimum_score: Cosine similarity threshold for filtering

Step 3: Return Ranked Matches

SurrealDB computes the cosine similarity between the query embedding and pre-computed embeddings stored on each Source and Note record. The database returns the top-N matching records already ordered by similarity, which the API layer forwards directly to the client without additional sorting.

Fallback Behavior and Error Handling

When a standard text search fails due to highlighted position overflow, the system automatically falls back to the vector search path. This error-handling block in open_notebook/domain/notebook.py ensures users receive relevant semantic results even when exact text matching encounters boundary limitations.

Programmatic Usage and API Examples

Embedding a Query and Searching Programmatically

from open_notebook.domain.notebook import vector_search

async def find_similar(term: str):
    # Returns up to 10 most similar sources/notes

    results = await vector_search(
        keyword=term,
        results=10,
        source=True,
        note=True,
        minimum_score=0.2,
    )
    return results

Using the HTTP API Endpoint

Access the search functionality via the /search endpoint defined in api/routers/search.py:

curl -X POST http://localhost:5055/search \
  -H "Content-Type: application/json" \
  -d '{
        "type": "vector",
        "term": "machine learning pipelines",
        "results": 5,
        "minimum_score": 0.3
      }'

Generating Embeddings for Sources

While embeddings generate automatically upon source creation, you can manually trigger the process:

from open_notebook.commands.embedding_commands import embed_source_command

# Assume `source_id` is the UUID of the source

await embed_source_command(source_id=source_id)

Key Source Files and Components

Summary

  • Open Notebook stores all content in SurrealDB, which provides native vector search capabilities through the fn::vector_search stored procedure.
  • The Esperanto AI layer handles embedding generation with automatic chunking and mean-pooling for large text inputs.
  • The vector_search function in open_notebook/domain/notebook.py orchestrates the query embedding and database execution.
  • Cosine similarity matching occurs inside SurrealDB, returning pre-sorted results filtered by minimum score thresholds.
  • The system includes automatic fallback to vector search when text search operations fail due to position overflow.

Frequently Asked Questions

What database does Open Notebook use for vector storage?

Open Notebook uses SurrealDB as its primary data store. The database stores pre-computed embeddings directly on Source and Note records and provides the built-in stored procedure fn::vector_search for performing cosine similarity calculations.

How does Open Notebook handle text that exceeds the embedding model's token limit?

The generate_embedding function in open_notebook/utils/embedding.py automatically chunks large text inputs, generates embeddings for each chunk individually, and then applies mean pooling via mean_pool_embeddings to combine them into a single representative vector.

Can I use vector search through the REST API?

Yes. The /search endpoint in api/routers/search.py accepts a JSON payload with "type": "vector" to trigger semantic search. You can specify parameters including term, results, minimum_score, and boolean flags for including sources or notes.

What happens if a text search fails?

When a text search fails due to highlighted position overflow errors, the code automatically falls back to the vector_search path in open_notebook/domain/notebook.py, ensuring users still receive relevant results through semantic similarity matching.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →