Skip to main content

Ariadne

Memory for AI agents. Local-first hybrid search + knowledge graph. Zero infrastructure.

PyPI Python 3.10+ Tests License: MIT


Quick Start

pip install "ariadne-memory[embeddings]"
from arriadne import AriadneMemory
from arriadne.embeddings import SentenceTransformerEmbedder

# An embedder turns text into vectors so semantic recall works automatically.
embedder = SentenceTransformerEmbedder("all-MiniLM-L6-v2")  # 384-dim

mem = AriadneMemory(db_path="memory.db", embedding_dim=embedder.dim, embedder=embedder)

mem.remember("VPS has 4 cores, 8GB RAM", importance=0.8)

# Semantic match — "server specs" finds the memory despite sharing no keywords.
results = mem.recall("server specs", k=5)

Without the [embeddings] extra (or without an embedder), Ariadne still works as a fast keyword store — pass your own vectors to remember/recall for semantic search, or omit them for FTS-only matching:

from arriadne import AriadneMemory

mem = AriadneMemory(db_path="memory.db")          # no embedder
mem.remember("deploy script lives in infra/deploy.sh")
mem.recall("deploy script", k=5)                  # keyword match

Why

Most "agent memory" options make you choose: a bare vector store (Chroma, sqlite-vec), or a hosted service (Mem0). Ariadne bundles vector + keyword + graph retrieval, deduplication, and a retention model into one local SQLite file — no daemon, no server, no API keys.

Capability Ariadne Chroma sqlite-vec Mem0
Vector search ✅ FAISS (auto Flat→IVF)
Keyword search (BM25/FTS5) ⚠️
Hybrid fusion (RRF) ⚠️ basic ⚠️
Knowledge graph (multi-hop) ⚠️
Near-duplicate dedup (MinHash) ⚠️
Retention / forgetting curve ⚠️
Runs fully local, no daemon
Single file, zero infra ⚠️

Capability comparison, not a benchmark — for latency, measure on your own hardware (see Performance). ✅ built-in · ⚠️ partial/varies · ❌ not available.


Features

Vector search (FAISS)

In-process FAISS index. Starts as exact IndexFlatIP and auto-upgrades to IndexIVFFlat once the dataset grows past ivf_threshold. Vectors are keyed by the memory's own id (IndexIDMap2) and rebuilt from the database on open, so the index can never drift out of sync after deletes or restarts.

Hybrid retrieval

Vector similarity + BM25 keywords (SQLite FTS5), fused with Reciprocal Rank Fusion. Keyword matching tries AND first (precise) and falls back to OR (recall). Stored confidence from memory provenance/feedback is applied after retrieval, so approved facts outrank rejected ones without hiding their history. Results include score_parts explaining the RRF/FTS and confidence contribution.

results = mem.recall("how to deploy to production", k=5)
# Runs keyword + vector search and fuses the rankings

context = mem.context_pack("how to deploy to production", token_budget=800)
# Compact, deterministic memory block ready for an agent prompt

Knowledge graph

Typed entities and relationships with multi-hop traversal via SQLite recursive CTEs. Edges are walked in both directions:

mem.add_edge("WebApp", "API", edge_type="depends_on")
mem.add_edge("API", "Database", edge_type="depends_on")
mem.graph("WebApp", hops=2)   # → API, Database

Cognitive retention

Ebbinghaus forgetting curve R = e^(-t/S). Stability S grows each time a memory is recalled (retention_growth_factor, capped) — memories strengthen with use and fade without it. Priority-weighted scoring from importance, recency, access count, and retention drives capacity-based eviction.

Your memories are never destroyed implicitly. Eviction only runs when the store exceeds an explicit max_memories capacity (default: off) — without one, evict() is a no-op and bounding the store is your call (curator.decay(), maintenance()).

Auto-deduplication

MinHash LSH catches near-duplicates before they enter the store; the index is rebuilt from the database on open so it survives restarts. Exact duplicates are caught by a SHA-256 content hash.

Smarter recall

Two optional knobs on recall() / context_pack() improve result quality:

# MMR diversifies the top-k so you get distinct facets, not k near-duplicates.
mem.recall("deploy", k=5, mmr=0.3)

# Recency weighting floats fresh facts (recorded in score_parts — still explainable).
mem.context_pack("what did we decide?", token_budget=800, recency_boost=0.5)

Superseded facts (e.g. an API key that was rotated) are hidden by checking the whole store for an active replacement — not just the current result window — and every ranking adjustment is visible in score_parts.

Config without code

export ARIADNE_DB_PATH=~/.ariadne/memory.db
export ARIADNE_MAX_MEMORIES=100000        # optional capacity bound
# or a TOML file: AriadneConfig.from_toml("ariadne.toml")

Health checks

ariadne doctor   # index sync, FTS coverage, orphans, dangling pointers — exit 1 on failure
ariadne feedback 42 --action reject   # confidence-weighted feedback loop

Built for agents

Thread-safe (a single AriadneMemory can be shared across threads), reads are side-effect-free, and housekeeping (evict / consolidate / prune_access_log / purge_deleted, or maintenance() for all four) keeps the store tidy.

Drop into Claude Code (and other MCP hosts)

One command prints ready-to-merge registration JSON for Claude Code, Claude Desktop, Cursor, VS Code, and Zed:

ariadne mcp --host claude-code

For Claude Code you can also wire memory hooks — every user prompt injects a packed block of relevant memories as context, and every finished turn is recorded (optionally distilled into facts/relations by an LLM):

// ~/.claude/settings.json — snippet printed by `ariadne mcp --host claude-code`
{
  "hooks": {
    "UserPromptSubmit": [
      { "hooks": [{ "type": "command", "command": "ariadne hook claude-code --db-path /abs/path.db" }] }
    ],
    "Stop": [
      { "hooks": [{ "type": "command", "command": "ariadne hook claude-code --db-path /abs/path.db" }] }
    ]
  }
}

Hooks are fail-open: if the memory store is unavailable, your session is not.

Dashboard auth + metrics

ariadne dashboard --token "$(openssl rand -hex 32)"   # or ARIADNE_DASHBOARD_TOKEN
curl -H "Authorization: Bearer $TOKEN" localhost:8765/api/stats
curl localhost:8765/metrics        # Prometheus text format, zero dependencies

Performance

Latency depends on your hardware, embedding dimension, and dataset size, so Ariadne ships no canned numbers — measure on your own box:

pip install "ariadne-memory[embeddings]"
import time, numpy as np
from arriadne import AriadneMemory, AriadneConfig

mem = AriadneMemory(config=AriadneConfig(db_path="bench.db", embedding_dim=384))
vecs = np.random.randn(10_000, 384).astype("float32")
for i, v in enumerate(vecs):
    mem.remember(f"memory {i}", embedding=v)

q = np.random.randn(384).astype("float32")
t = time.perf_counter()
for _ in range(1000):
    mem.recall("query", embedding=q, k=10)
print(f"recall avg: {(time.perf_counter() - t):.3f} ms/query")
mem.close()

Architecturally: FAISS does similarity as a single BLAS matrix multiply (and switches to an inverted-file index at scale), keyword search rides SQLite's FTS5 BM25 index, and graph traversal is a recursive CTE — all in-process, no network hops. See the benchmarks guide for a fuller harness.


Hermes Agent Integration

Ariadne works as a drop-in memory provider for Hermes Agent, giving your agent durable hybrid search memory with zero infrastructure.

Plugin Setup

git clone https://github.com/kyssta-exe/Ariadne.git /tmp/ariadne-repo
cp -r /tmp/ariadne-repo/plugin ~/.hermes/plugins/ariadne

Then configure Hermes to use Ariadne:

hermes config set memory.provider ariadne
hermes restart

Alternatively, set the provider in ~/.hermes/config.yaml:

memory:
  provider: ariadne

The plugin automatically creates its database at ~/.hermes/ariadne/memory.db (plus a shared surface at ~/.hermes/ariadne/shared/memory.db for cross-agent memory).

Available Tools

The plugin exposes these ariadne_* tools to Hermes:

Tool Description
ariadne_remember Store a durable memory (fact, preference, insight, etc.)
ariadne_recall Hybrid search — FTS5 text + FAISS vector ranking
ariadne_context_pack Pack relevant memories under a token budget
ariadne_stats Return memory system statistics
ariadne_forget Permanently delete a memory by ID
ariadne_update Update content or importance of an existing memory
ariadne_invalidate Soft-delete (mark as superseded) a memory
ariadne_export Export all memories to a JSON file
ariadne_import Import memories from a JSON file
ariadne_graph_query Traverse the knowledge graph from a seed entity
ariadne_graph_link Declare a relationship between two entities
ariadne_sleep Run memory consolidation (compress old working memories)
ariadne_diagnose Run diagnostics on the Ariadne installation
ariadne_scratchpad_write Write a temporary note to the scratchpad
ariadne_scratchpad_read Read scratchpad entries
ariadne_scratchpad_clear Clear all scratchpad entries
ariadne_shared_remember Store a memory in the shared surface DB (cross-agent)
ariadne_shared_recall Search the shared surface DB
ariadne_shared_forget Delete a shared surface memory
ariadne_shared_stats Return shared surface DB stats

Full guide: ariadne.mantes.net/guide/hermes


Configuration

from arriadne import AriadneConfig, AriadneMemory

config = AriadneConfig(
    db_path="memory.db",
    embedding_dim=384,
    faiss_type="auto",          # auto | flat_ip | ivf_flat
    dedup_threshold=0.8,
    retention_half_life=86400,  # 1 day
)

mem = AriadneMemory(config=config)

Documentation

ariadne.mantes.net


Backup & Restore

Ariadne supports full database backup and restore through the CLI, the web dashboard, and the Python API. Backups are consistent SQLite snapshots (WAL checkpoint + file copy) — no daemon restart required.

CLI Commands

# Create a timestamped backup (default: arriadne-backup-YYYYMMDDTHHMMSS.db)
ariadne backup

# Backup to a specific file
ariadne backup -o /backups/my-memory.db

# Restore from a backup (creates a safety backup of the current DB first)
ariadne restore /backups/my-memory.db

# Restore without safety backup
ariadne restore /backups/my-memory.db --no-safety-backup

# Export all memories as JSON (to stdout or a file)
ariadne export
ariadne export -o memories.json

# Import memories from a JSON file
ariadne import memories.json

Dashboard UI

Launch the dashboard and use the backup/restore controls:

ariadne dashboard

The dashboard exposes two endpoints:

Endpoint Method Description
/api/backup GET Download the current database as a .db file
/api/restore POST Upload a .db file to restore (creates a safety backup automatically)

Python API

from arriadne import AriadneMemory, AriadneConfig

mem = AriadneMemory(config=AriadneConfig(db_path="memory.db"))

# Export all memories to a dict
data = mem.export_json()
# data contains {"memories": [...], "stats": {...}}

# Import from a previously exported dict
imported_count = mem.import_json(data)
print(f"Imported {imported_count} memories")

mem.close()

Addons

Ariadne supports domain-specific addons that extend the core memory system with specialized extractors, entity types, CLI commands, and API endpoints. Addons are separate pip packages discovered automatically via Python entry points.

Available Addons

Addon Description Install
ariadne-finance Finance research — PDF/Excel extraction, ticker recognition, financial knowledge graph pip install ariadne-finance

Installing an Addon

# Install the finance addon (Excel + CSV only)
pip install ariadne-finance

# With PDF support
pip install "ariadne-finance[pdf]"

# Full (PDF + yfinance for market data)
pip install "ariadne-finance[full]"

Once installed, the addon is auto-discovered — no configuration needed:

from arriadne.addons import AddonRegistry

registry = AddonRegistry()
registry.discover()  # finds all installed addons
print(registry.addon_names)  # ['ariadne-finance']

# Use addon extractors
extractor = registry.get_extractor_for_file("report.pdf")
result = extractor.extract("report.pdf")

registry.shutdown()

Creating Your Own Addon

See docs/addons/index.md for the full addon authoring guide. Quick start:

from arriadne.addons import BaseAddon, ExtractorBase, EntityType

class MyAddon(BaseAddon):
    name = "my-addon"
    version = "0.1.0"
    description = "My custom addon"

    def get_extractors(self):
        return [MyExtractor()]

    def get_entity_types(self):
        return [EntityType(name="custom", display_name="Custom Entity")]

Register in your pyproject.toml:

[project.entry-points."ariadne.addons"]
my-addon = "my_addon:MyAddon"

License

MIT — see LICENSE.


Powered by Mantes

Download files

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

Source Distribution

arriadne-0.13.0.tar.gz (676.2 kB view details)

Uploaded Source

Built Distribution

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

arriadne-0.13.0-py3-none-any.whl (130.1 kB view details)

Uploaded Python 3

File details

Details for the file arriadne-0.13.0.tar.gz.

File metadata

  • Download URL: arriadne-0.13.0.tar.gz
  • Upload date:
  • Size: 676.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for arriadne-0.13.0.tar.gz
Algorithm Hash digest
SHA256 5d5b4a0cd71215be9c85131c92808729a9f7130ac787f30803f57119423c7e0d
MD5 6f2856e57393fd31d12d7217e4be4944
BLAKE2b-256 5c87622a551ad02c6ab131cf67ff6b52d550da46ea62c3191ffdc2eaed3d39fb

See more details on using hashes here.

File details

Details for the file arriadne-0.13.0-py3-none-any.whl.

File metadata

  • Download URL: arriadne-0.13.0-py3-none-any.whl
  • Upload date:
  • Size: 130.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for arriadne-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a826b1be1f7b513ca6a1ad209a560abcba32abac1b8e4d81fd7efa7c1240135
MD5 e595f3008f1a431915aaad69d6c5d201
BLAKE2b-256 a673b85053df3a6a0503273776954ce2f6ae2c9bbabbf00cfe2c058cf79eb3e2

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.13.0 This release

2 files

0.12.1

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.4

2 files

0.9.3

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.5

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.3.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

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