Skip to main content

Deterministic, self-hosted long-term memory for AI agents.

Project description

🪢 ai-knot

The deterministic memory layer for AI agents.

No LLM on the read path or the write path. ai-knot keeps a self-hosted, MCP-native knowledge store, recalls only the few facts each turn needs, and does it deterministically — cheap, fast, and testable. Multi-agent, temporal, and air-gappable by default.

CI PyPI npm License Python

Fastest proof · Basic memory commands · Integrations · Examples · Benchmarks · Comparison · Open in Codespaces

No LLM on read or write · shared memory for teams of agents · one-line integration · Python · TypeScript · MCP · HTTP

pip install ai-knot && ai-knot demo — 30 seconds, no signup, no API key

Works with: Claude · OpenClaw · CrewAI · LangGraph · LlamaIndex · AutoGen · OpenAI Agents SDK · PydanticAI · Vercel AI SDK

Backends: SQLite · PostgreSQL · YAML | Surfaces: Python · TypeScript · CLI · MCP · HTTP · Browser inspector

ai-knot demo: store facts once, recall only what matters, with deterministic memory persisted across restarts

Why another memory library? Most memory layers put an LLM in the loop — a model to extract on write, a model to rank on read — so every turn costs tokens and latency. ai-knot doesn't: recall is pure retrieval — $0 per call, milliseconds, fully offline, deterministic. It's built for teams of agents — shared memory with trust, provenance, and visibility, not one bag of vectors everyone writes to and poisons — and drops into your stack in one line: MCP, HTTP, or native adapters for Claude, LangGraph, CrewAI, LlamaIndex, AutoGen, OpenAI Agents, and PydanticAI. Quality holds up: 78% on LoCoMo with the optional embedding dial. See the benchmarks →

Self-hosted OSS — no cloud tier, no signup, no API key. New and pre-1.0 — a ⭐ helps others find it, and questions are welcome in Discussions.


At a glance

If you care about… ai-knot gives you…
recall that stays cheap and reproducible deterministic search / recall with no LLM on the read path
storage you can inspect and migrate SQLite for the default path, PostgreSQL for shared deployments, YAML for human-readable state
one memory product across stacks Python, TypeScript, CLI, MCP, HTTP sidecar, Browser inspector, and framework adapters
memory you can debug and correct list, get, delete, lineage, learn, add_resolved, and valid_until
more than one agent writing to memory shared memory with trust, provenance, visibility, and fan-in recall
conversation / tool output -> add or learn -> ai-knot -> SQLite | PostgreSQL | YAML
next question              -> search / recall -> 3-5 relevant facts -> next prompt

The 2026 memory problem

First-generation memory layers (2023–2024) fixed transcript replay by throwing more LLM at it — a model to extract facts on write, a model to pick what to retrieve, sometimes a model to build a graph. That trades one problem for three: cost on every call, non-determinism you can't test, and benchmark numbers nobody can reproduce.

❌ First-gen (2023–2024) ✅ ai-knot (2026)
LLM on extraction, retrieval, and ranking no LLM on the read path or the write path
token + latency cost on every turn recall is cheap and testable in CI
one shared bag of vectors, no governance shared memory with trust, provenance, and visibility
a black box you overwrite blindly lineage, supersession, and audit built in

ai-knot is the 2026 take: memory as a deterministic, self-hosted, MCP-native layer you can inspect, test, and run air-gapped — the same add / search / list / delete loop across Python, TypeScript, CLI, MCP, and HTTP, with direct paths for Claude, OpenClaw, CrewAI, LangGraph, LlamaIndex, AutoGen, OpenAI Agents SDK, and PydanticAI.

Fastest proof (30 seconds)

Shortest proof the product works:

pip install ai-knot
ai-knot demo

From Node / TypeScript:

npm install ai-knot
npx ai-knot-demo

The raw Python API is just as small:

from ai_knot import KnowledgeBase

kb = KnowledgeBase(agent_id="assistant")

fact = kb.add("User deploys APIs with Docker and Kubernetes")
kb.add("User prefers Go and avoids Java")
kb.add("Team standup is at 10am")

print(kb.search("what stack does the user use?"))  # alias: kb.recall(...)
# [1] User deploys APIs with Docker and Kubernetes
# [2] User prefers Go and avoids Java

print(kb.list())
print(kb.get(fact.id))
# kb.delete(fact.id)  # alias: kb.forget(...)

That is the core promise: persist facts to your own storage, then pull back only the 3-5 facts the next turn needs.

Basic memory commands

The core product loop:

ai-knot add    assistant "User deploys APIs with Docker and Kubernetes"
ai-knot search assistant "what does the user deploy with?"   # alias: ai-knot recall
ai-knot list   assistant                                      # alias: ai-knot show
ai-knot delete assistant <fact_id>                            # alias: ai-knot forget

The same loop exists across every major surface:

Surface Add Search List Delete
Core Python kb.add(...) kb.search(...) / kb.recall(...) kb.list() / kb.list_facts() kb.delete(id) / kb.forget(id)
TypeScript / npm await kb.add(...) await kb.search(...) / await kb.recall(...) await kb.list() / await kb.listFacts() await kb.delete(id) / await kb.forget(id)
CLI ai-knot add ... ai-knot search ... / ai-knot recall ... ai-knot list ... / ai-knot show ... ai-knot delete ... / ai-knot forget ...
MCP add search / recall list / list_facts delete / forget
HTTP sidecar POST /v1/facts POST /v1/search GET /v1/facts DELETE /v1/facts/{fact_id}

When you need a deeper correction or audit loop:

  • use get when you already have a fact_id
  • use lineage when the history of one fact matters
  • use learn when you want extract-on-write from raw text
  • use add_resolved when you want explicit update / delete semantics with valid_until

For the full command map, including include_inactive, lineage, structured correction, and cross-surface equivalents, use docs/memory-commands.md.

Wiring Claude or OpenClaw: keep setup separate from the memory verbs.

ai-knot setup openclaw --agent-id assistant --storage sqlite --write-default-config
ai-knot setup claude   --agent-id assistant --storage sqlite --write-default-config
ai-knot doctor --json

Once the MCP server is live, use the same add / search / list / delete loop inside the client.

Start here

Find your stack, install it, and run one command to see the full memory loop:

If you're starting from… Install Run this first What it proves
Core Python pip install ai-knot ai-knot demo the end-to-end add / search / list / get / delete loop against temporary local storage
Node / TypeScript npm install ai-knot npx ai-knot-demo the same built-in proof through the packaged Node bridge
Any function-calling Python agent pip install ai-knot python examples/function_calling_surface_demo.py plain Python memory callables for runtimes that register ordinary tools
CrewAI pip install "ai-knot[crewai]" python examples/crewai_surface_demo.py root memory plus scoped agent memory without a real model call
LangGraph tool-style memory pip install "ai-knot[langgraph]" python examples/langgraph_surface_demo.py explicit add / search / list / delete tools on a LangGraph-shaped path
LlamaIndex pip install "ai-knot[llamaindex]" "llama-index-llms-openai" python examples/llamaindex_surface_demo.py the memory=... seam on a zero-network path
PydanticAI pip install "ai-knot[pydanticai]" python examples/pydanticai_surface_demo.py per-run instruction injection with deterministic memory
Claude / OpenClaw / any MCP client pip install "ai-knot[mcp]" ai-knot setup openclaw --agent-id assistant --storage sqlite --write-default-config one-command config merge plus MCP sanity check
HTTP sidecar pip install "ai-knot[server]" python examples/http_sidecar_surface_demo.py /v1/facts, /v1/search, GET /v1/facts, and delete over the HTTP JSON surface
Vercel AI SDK npm install ai-knot ai @ai-sdk/openai cd npm && npm run example:vercel-ai-sdk memory injection into a mainstream TypeScript app path
No local install none follow docs/codespaces-quickstart.md install-free first run in Codespaces

Need the repo-native CLI transcript first? Run python examples/cli_memory_loop.py.

Need the visual debug surface first? Run python examples/browser_inspector_demo.py for the Browser inspector.

Need the real model-backed LlamaIndex path? Run OPENAI_API_KEY=... python examples/llamaindex_integration.py.

Need every runnable path in one place? Use examples/README.md.

TypeScript note: the npm package uses the Python engine underneath, so keep Python 3.11+ on PATH and use npx ai-knot-doctor --json if the bridge looks wrong.

To check the bridge or environment:

ai-knot doctor --json
npx ai-knot-doctor --json

What it looks like in your stack

Stack Integration seam
Core Python KnowledgeBase(...)
Plain function-calling Python runtimes create_basic_memory_functions(...)
LangChain / LangGraph tools create_basic_memory_tools(...)
CrewAI AiKnotCrewAIMemory
LlamaIndex AiKnotLlamaIndexMemory
AutoGen AiKnotAutoGenMemory
OpenAI Agents SDK AiKnotAgentsMemory
PydanticAI AiKnotPydanticAIMemory
TypeScript / Node KnowledgeBase
TypeScript over HTTP HttpKnowledgeBase
Claude / OpenClaw / any MCP host ai-knot-mcp via setup or serve-mcp

Any function-calling Python agent

from ai_knot.integrations import create_basic_memory_functions

functions = create_basic_memory_functions(kb, top_k=5, include_get=True)

CrewAI

from ai_knot.integrations.crewai import AiKnotCrewAIMemory

memory = AiKnotCrewAIMemory(kb, top_k=5)
crew = Crew(agents=[researcher, writer], tasks=[task], memory=memory)

LangGraph / LangChain

from langgraph.prebuilt import create_react_agent
from ai_knot.integrations.langchain import create_basic_memory_tools

tools = create_basic_memory_tools(kb, top_k=5)
agent = create_react_agent(model, tools=tools)

LlamaIndex

from ai_knot.integrations.llamaindex import AiKnotLlamaIndexMemory

memory = AiKnotLlamaIndexMemory.from_defaults(knowledge_base=kb, top_k=5)

TypeScript / Vercel AI SDK

import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { AiKnotAISDKMemory, KnowledgeBase } from "ai-knot";

const kb = new KnowledgeBase({ agentId: "assistant", storage: "sqlite" });
const memory = new AiKnotAISDKMemory(kb, { topK: 5 });
const system = await memory.buildSystem("Write a deployment checklist.", {
  baseSystem: "You are a concise staff engineer.",
});

const { text } = await generateText({
  model: openai("gpt-5"),
  system,
  prompt: "Write a deployment checklist.",
});

TypeScript / HTTP sidecar

import { HttpKnowledgeBase } from "ai-knot";

const kb = new HttpKnowledgeBase({
  baseUrl: "http://127.0.0.1:8000",
  token: process.env.AI_KNOT_SERVER_TOKEN,
});

Claude / OpenClaw / any MCP client

ai-knot setup claude --agent-id assistant --storage sqlite --write-default-config
ai-knot setup openclaw --agent-id assistant --storage sqlite --write-default-config
ai-knot serve-mcp assistant --port 8765
# MCP endpoint: http://127.0.0.1:8765/mcp

For the full surface map, use docs/integrations.md. If you want the assistant itself to know these surfaces before editing your repo, use skills/README.md. For a shareable landing page, use docs/site/index.html.

Why teams pick ai-knot

  • Deterministic recall. No LLM on the read path, so the hot path is cheaper, faster, and regression-testable.
  • Storage you control. SQLite for the default path, PostgreSQL for shared deployments, YAML when you want human-readable state.
  • Fact lifecycle, not blind overwrite. learn, add_resolved, valid_until, and lineage make memory correction explicit.
  • Framework breadth without lock-in. Python, TypeScript, MCP, HTTP, and adapters for the agent stacks people already use.
  • Multi-agent governance. Shared memory with provenance, trust, visibility, and fan-in recall instead of "everyone writes to one bag of vectors."
  • Benchmark credibility. Named-reader QA numbers plus deterministic retrieval metrics you can actually rerun.

Built for teams of agents

The single-agent path is the easy part. The harder problem is shared memory that does not turn into noise.

  • fan-in recall across multiple agents
  • evidence-before-belief gating
  • per-agent visibility control
  • deterministic conflict handling
  • trust penalties that survive flooding or laundering attempts

This is one of ai-knot's sharpest edges. See docs/multi-agent-governance.md for how it maps to the 2026 governed-shared-memory problem, and watch it defend itself under attack in examples/poisoned_pool.py (python examples/poisoned_pool.py). Full API: docs/usage.md.

What you can build

You are building… ai-knot gives you…
A chatbot that remembers users persistent per-user facts without replaying the full chat log
A coding agent project, tooling, and preference memory that comes back in milliseconds
A team of agents shared memory with trust and visibility rules, not just a shared database
A regulated or air-gapped system self-hosted storage and no LLM on recall
A product that must be testable deterministic retrieval you can lock into regression tests

How it compares

ai-knot is the newcomer in a crowded 2026 memory landscape, not the incumbent. Several projects are far more adopted — Mem0 (~60k★), Graphiti (~28k★), Cognee (~27k★), Letta (~24k★), Memori (~15.5k★). ai-knot's wedge is narrow on purpose.

If you want… Best fit
memory that needs no LLM on read or write (air-gapped, reproducible) ai-knot
the largest, most-adopted general memory layer Mem0
an LLM-built temporal knowledge graph Zep / Graphiti
the LLM to manage its own memory inside the agent loop Letta (ex-MemGPT)
an ontology + knowledge-graph memory pipeline Cognee
the most native memory for a LangGraph-only stack LangMem
SQL-native structured memory with no vector DB Memori

Several of these also keep the LLM off recall (Graphiti, LangMem, Memori). What's rarer: ai-knot needs no LLM on the write path either — direct fact insertion is the default and learn() extraction is optional — so the whole pipeline can run with zero model calls.

The honest wedge: self-hosted deterministic memory with no LLM required on read or write, one-line integration across your stack, and real multi-agent governance.

For the full, checked feature matrix versus each project, use docs/comparison.md.

Benchmarks you can rerun

Memory claims in this category swing hard depending on the reader model, judge model, prompts, and scoring rules. ai-knot publishes both named-reader QA numbers and deterministic retrieval metrics.

Deterministic retrieval: ai-knot vs naive baseline — ranking MRR 0.83 vs 0.18, precision@5 1.00 vs 0.40, LoCoMo recall@5 0.26 vs 0.15
Benchmark Metric ai-knot
Golden suite ranking MRR, deterministic, no LLM 0.83 vs 0.18 naive
LoCoMo evidence_recall@5, deterministic, no LLM 0.26 vs 0.15 naive
LoCoMo QA accuracy, cat1-4, gpt-4.1 reader / gpt-4o judge 78.0%
LongMemEval QA accuracy, Oracle, gpt-4.1 / gpt-4o 59.6%

The first two rows are the anchor: deterministic, no LLM, fixed seeds — re-run and you get the same numbers. The QA rows are LLM-judged (reader + judge named), so they move with the models; the deterministic rows don't.

LoCoMo by category — nothing cherry-picked. Reader gpt-4.1, judge gpt-4o; categories 1–4 scored (category 5 is adversarial and excluded per the dataset authors — the exact step the field's headline benchmark dispute got wrong):

cat1 single-hop cat2 multi-hop cat3 temporal cat4 open-ended overall
60.6% 67.6% 63.5% 89.4% 78.0%

Strong on open-ended synthesis, honestly mid on single-hop and temporal — and 74–84% on every one of the 10 conversations, not one lucky run.

AI_KNOT_EMBED_URL="" python -m tests.eval.benchmark.runner \
  --mock-judge --skip-multi-agent --backends baseline,ai_knot_no_llm

Full methodology, caveats, and per-conversation tables: docs/benchmarks.md.

Performance

In-process BM25 recall, measured with pytest-benchmark:

Facts in memory recall p50 p95
100 ~1 ms ~3 ms
1,000 ~8 ms ~25 ms
10,000 ~80 ms ~200 ms

MCP tool round-trip over stdio is roughly add ~15 ms / recall ~20 ms p50. For the fuller picture — methodology, per-conversation tables, and the deterministic suite you can re-run — use docs/benchmarks.md. Continuous pytest-benchmark history is published to GitHub Pages once Pages is enabled (see docs/RELEASE.md).

Documentation

Contributing

PRs are welcome, especially around storage backends, framework adapters, benchmark coverage, and docs. Start with CONTRIBUTING.md and DEVELOPMENT.md.

License

MIT. If a stack you use is missing, open an issue with the integration surface you want next.

Project details


Download files

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

Source Distribution

ai_knot-0.12.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

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

ai_knot-0.12.0-py3-none-any.whl (228.0 kB view details)

Uploaded Python 3

File details

Details for the file ai_knot-0.12.0.tar.gz.

File metadata

  • Download URL: ai_knot-0.12.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai_knot-0.12.0.tar.gz
Algorithm Hash digest
SHA256 0c83d3ad0e2795f7151e2534a461dab9cbf1059574d063d90d68478640f91df4
MD5 d958992c267e8d0e748d05dd328ffce9
BLAKE2b-256 e33e613f54f2518850cf08761e1034fc7fe8afc207504276dab0f85087c45110

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai_knot-0.12.0.tar.gz:

Publisher: publish.yml on alsoleg89/ai-knot

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

File details

Details for the file ai_knot-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: ai_knot-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 228.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai_knot-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e3ca643af34b85a998129b7048908eca69c40391d9ef4bea46c7c9b47eee778
MD5 347cd4139bdd23484c48089ee0c0ae84
BLAKE2b-256 d0d5d58ed7ea106b112d6621b4627f4e515a81eb3c1505123e60c1b3d7321e96

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai_knot-0.12.0-py3-none-any.whl:

Publisher: publish.yml on alsoleg89/ai-knot

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page