Skip to main content

SynapticDB

A single-file memory store that gives AI agents hybrid search, learned associations, and confidence-aware recall.

PyPI · Benchmark · Report a bug


Why

AI agents need to retrieve useful context and recognize when no useful context exists. SynapticDB combines keyword search, vector search, and a graph of associations in one SQLite file. Each result includes an absolute confidence value, so an agent can reject weak matches instead of treating every ranked result as an answer.

SynapticDB v0.1 is alpha software. Hybrid search and confidence scoring are measured and working. The association graph is implemented, but current benchmark results do not show that the graph improves recall on its own.

Install

Install the built-in local embedding model:

pip install "synapticdb[embeddings]"

Install the smaller core package when you provide an embedding function:

pip install synapticdb

Requires Python 3.10 or newer. The embeddings extra downloads the 384-dimensional all-MiniLM-L6-v2 model on first use.

Quick start

from synapticdb import SynapticDB

with SynapticDB("synaptic.db") as memories:
    memories.store("Client X requires SOC2 for vendor deployments")
    result = memories.recall("deployment requirements for Client X")
    print(result.memories[0].content)
Client X requires SOC2 for vendor deployments

The database, full-text index, embeddings, associations, and recall history all live in synaptic.db. Use ":memory:" instead for a temporary in-process database.

Features

  • Run without a service — SQLite stores the complete memory system in one portable file.
  • Match words and meaning — BM25 keyword search and cosine vector search are fused into one ranking.
  • Reject weak answers — absolute confidence values support one threshold across different queries.
  • Learn relationships — temporal, co-retrieval, feedback, and manual links build an association graph.
  • Bring your own embeddings — a custom local or hosted embedding function can replace the built-in model.

Usage

Add memory to an OpenAI response

Install the OpenAI Python SDK and set OPENAI_API_KEY in your environment:

pip install "synapticdb[embeddings]" openai
export OPENAI_API_KEY="your-api-key"

The example retrieves memory for user_input, adds the memory to the OpenAI request, and stores the completed exchange:

from openai import OpenAI
from synapticdb import SynapticDB

client = OpenAI()
user_input = "What does Client X require for vendor deployments?"

with SynapticDB("agent-memory.db") as memories:
    memories.store("Client X requires SOC 2 for vendor deployments.")
    recalled = memories.recall(user_input, top_k=3)
    context = "\n".join(memory.content for memory in recalled.memories)

    response = client.responses.create(
        model="gpt-5.6",
        input=(
            "Use the memory below to answer the user.\n\n"
            f"Memory:\n{context}\n\n"
            f"User: {user_input}"
        ),
    )
    answer = response.output_text
    print(answer)

    memories.store(f"User: {user_input}\nAssistant: {answer}")

The OpenAI client reads OPENAI_API_KEY from the environment. See the OpenAI API quickstart for key setup.

Return nothing when evidence is weak

min_confidence filters results before SynapticDB records retrieval learning. A recall can return fewer than top_k memories, including none.

result = memories.recall(
    "deployment requirements for Client X",
    top_k=5,
    min_confidence=0.6,
)
relevant = result.memories

if not relevant:
    print("No reliable answer found")

score ranks memories within one recall. confidence measures query-to-memory similarity and can be compared across recalls.

Store metadata and filter results

memories.store(
    "Client X requires SOC 2 for vendor deployments",
    metadata={"client": "x", "topic": "compliance"},
)

result = memories.recall(
    "deployment requirements",
    where={"client": "x"},
)

Teach explicit relationships

requirement = memories.store("Client X requires SOC 2")
deployment = memories.store("Project Atlas deploys to Client X")

memories.connect(requirement.id, deployment.id)

result = memories.recall("What affects the Atlas deployment?")
memories.feedback(result.query_id, positive=True)

Positive feedback strengthens the relationships used by a recall. Negative feedback weakens them without creating new links.

Export results as JSON

payload = result.to_dict()
json_text = result.to_json()

Every public result model retains typed Python fields. JSON exports convert UUIDs and timestamps to strings. get(), connect(), forget(), and feedback() accept UUID objects or their string forms.

How it works

One recall() follows five bounded steps:

  1. FTS5 BM25 ranks keyword matches, and cosine similarity ranks embedding matches.
  2. Reciprocal rank fusion combines both result lists.
  3. The highest-ranked memories seed spreading activation across the association graph.
  4. Graph maturity controls how much activation contributes to the final ranking.
  5. SynapticDB returns each memory with its ranking score, confidence, and retrieval source.

A cold or empty graph falls back to hybrid search. Edge weights decay over time, and periodic maintenance prunes weak edges.

Benchmark

The committed chained benchmark compares SynapticDB with a locked BM25, FAISS, and cross-encoder baseline. SynapticDB answers 17 of 25 associative queries, compared with 10 of 25 for the baseline. Both answer all 25 direct queries.

A confidence floor of 0.6 keeps 41 of 42 correct answers and rejects all 12 unanswerable questions in the benchmark. Confidence AUC is 0.994.

Reproduce the results after the first model download:

uv sync --extra bench
uv run --extra bench python -m bench --profile chained --retriever synaptic

The run takes about 35 seconds on the development machine. See the benchmark documentation for profiles, measurements, and stored records.

What an associative answer looks like

For one associative holdout query, the locked baseline misses the answer. SynapticDB returns it at rank 6 with confidence 0.640.

Query: Why does the observatory dome trigger wind protection during calm weather?

Answer: Converting knots before publishing reduced false closure alerts while preserving every genuinely windy shutdown.

The query and answer share almost no words. The association graph connects them through two intermediate memories:

  1. Wind data reaches the controller through the Boreal weather adapter.
  2. Boreal labels readings as meters per second but forwards knot values unchanged.

The graph records a useful reasoning path, but it did not create this benchmark win. SynapticDB's hybrid search already returned the answer before the graph existed.

What does not work yet

  • Semantic seeding is disabled. A threshold sweep produced no unique wins. At 0.60, only 4 of 1,069 semantic edges landed on a real associative chain.
  • Co-retrieval and feedback are not measured end to end. Both update edges, but benchmark warm-up topics do not overlap the holdout paths. Adding overlap would leak training data into evaluation.
  • Decay and pruning are not measured end to end. Future-dated ingestion and write-only maintenance prevent the benchmark from aging edges. Unit tests cover both behaviors.
  • Confidence depends on embedding quality. Measure a threshold on your own data before using confidence as a production decision boundary.

Alternatives

If you only need vector search, start with a mature tool such as Chroma, LanceDB, or sqlite-vec. Choose SynapticDB when you want fused keyword and vector search in one SQLite file, plus a confidence value that can suppress weak answers. Treat the association graph as an experimental research feature.

Development

git clone https://github.com/xhillman/synapticdb.git
cd synapticdb
uv sync --extra dev
uv run --extra dev ruff format --check .
uv run --extra dev ruff check .
uv run --extra dev mypy
uv run --extra dev python -W error -m pytest
uv run --extra dev python -W error -m bench --profile smoke --retriever fixture --check --no-write
uv run --extra dev python -W error -m bench --profile smoke --retriever synaptic --check --no-write

Build the wheel and source distribution with uv run --extra dev python -m build.

Contributing

Contributions are welcome. Open an issue before starting a large change so the proposed scope can be reviewed first.

License

MIT © Xavier Hillman. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

synapticdb-0.1.1.tar.gz (171.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

synapticdb-0.1.1-py3-none-any.whl (42.1 kB view details)

Uploaded Python 3

File details

Details for the file synapticdb-0.1.1.tar.gz.

File metadata

  • Download URL: synapticdb-0.1.1.tar.gz
  • Upload date:
  • Size: 171.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for synapticdb-0.1.1.tar.gz
Algorithm Hash digest
SHA256 79723da5086f0f23b6d464ed9b0f94514732ceb3c7816a8d7f9dbc886098243b
MD5 15ccc2bf86c3be349c9c284f08167a61
BLAKE2b-256 60ef111c97773f9c3768aa43da881d1325365feb17f340822739eb5392498d2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapticdb-0.1.1.tar.gz:

Publisher: release.yml on xhillman/synapticdb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file synapticdb-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: synapticdb-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 42.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for synapticdb-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d1a7683dae10b95f65b1f28f72d24f4cd49138136ea52f5aaa7d039fff24753f
MD5 1493d43e25bb7e205b00f510d74131c6
BLAKE2b-256 d9a04fb016db9ea1eba99208f8df0d3d77b82d4cb0e4b01a27e3f9ff3145c69c

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapticdb-0.1.1-py3-none-any.whl:

Publisher: release.yml on xhillman/synapticdb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page