Memory is not just storage. It is judgement about what deserves to become memory.
Neural Ledger is a lightweight memory engine for software and agents. It helps systems remember useful things, recall what matters, and learn from feedback.
from neural_ledger import Memory
mem = Memory()
mem.remember("GitHub API 401 — the access token expired", kind="observation")
mem.remember("Fix: regenerate the expired GitHub personal access token", kind="procedure")
mem.remember("Check rate limit headers before retrying requests", kind="note")
hits = mem.recall("How do I fix a GitHub API 401 error?", with_why=True, limit=3)
for hit in hits:
print(f"[{hit.kind}] {hit.content}")
print(f" score={hit.score:.4f} why: {hit.why}")
# Tell the engine which memory actually helped
mem.feedback([hits[0]], helped=True)
mem.feedback(hits[1:], helped=False)
# Repeated feedback accumulates. Over time, useful records rise;
# misleading ones score lower. See docs/examples/failure-memory.md
# for a controlled benchmark demonstrating the learning effect.Three verbs. Everything else stays behind the curtain.
Most memory systems stop at retrieval. They find candidates by similarity and return them. They do not get better.
Neural Ledger is built around a different idea: feedback is a first-class signal, not a logging call. Every feedback() call updates a per-record usefulness prior and a graph of co-retrieval links. Those signals directly shape future rankings.
The result is a memory engine that improves with use — one that can learn, over repeated interactions, which memories are worth surfacing and which are noise.
Three verbs cover everything:
remember(...)— store experiencerecall(...)— retrieve the most relevant contextfeedback(...)— teach the system what actually helped
Everything else stays behind the curtain.
pip install neural-ledgerfrom neural_ledger import Memory
mem = Memory()By default, Neural Ledger runs fully in memory. No database, API key, or graph backend is required.
mem.remember("User prefers terse weekly updates")
mem.remember(
"GitHub API failed because the token expired",
kind="observation",
metadata={"tool": "github", "severity": "high"},
)hits = mem.recall("How should I write the update?", with_why=True)mem.feedback(hits, helped=True)Over time, Neural Ledger can use feedback to improve ranking and retrieval quality.
Memory(
persist_path: str | None = None, # None = in-memory; path = SQLite
namespace: str = "default",
agent_id: str | None = None, # identity for governed shared memory
config: MemoryConfig | None = None,
)Store a new memory.
record = mem.remember(
content: str,
*,
kind: str = "note",
metadata: dict | None = None,
source: str | None = None,
timestamp: datetime | None = None,
visibility: str = "local", # 'local' or 'shared'
provenance: str | None = None, # run ID, tool name, etc.
)Store multiple memories at once.
records = mem.remember_many(
[
"User prefers terse weekly updates",
{"content": "Token expiry caused the API failure", "visibility": "shared"},
],
default_visibility="local",
)Retrieve the most relevant memories for a query.
hits = mem.recall(
query: str,
*,
limit: int = 5,
kind: str | list[str] | None = None,
metadata_filter: dict | None = None,
min_score: float | None = None,
with_why: bool = False,
scope: str = "local", # 'local', 'shared', or 'merged'
)Tell Neural Ledger whether retrieved memories helped.
mem.feedback(
hits_or_ids,
*,
helped: bool | float,
reason: str | None = None,
metadata: dict | None = None,
)helped accepts either:
True/Falsefor simple usage- a float in
[0, 1]for finer control
@dataclass(slots=True)
class MemoryRecord:
id: str
content: str
kind: str
metadata: dict
source: str | None
timestamp: datetime
agent_id: str | None = None
provenance: str | None = None
visibility: str = "local"@dataclass(slots=True)
class MemoryHit:
id: str
content: str
score: float
kind: str
metadata: dict
source: str | None
timestamp: datetime
why: str | None = None
agent_id: str | None = None
provenance: str | None = NoneThe first successful use should take under five minutes. Advanced machinery can come later.
Similarity finds candidates. Feedback teaches the system what actually helps.
Neural Ledger should return the smallest useful set, not a heap of vaguely related notes.
The public API should stay simple even if the engine becomes sophisticated.
The public API is three verbs. Behind them is a layered retrieval and learning engine.
┌──────────────────────────────────────────────────────┐
│ Memory (public API) │
│ remember() · recall() · feedback() │
└──────────────────────┬───────────────────────────────┘
│
┌──────────▼──────────┐
│ Runtime │
│ namespace · policy │
└────┬──────────┬─────┘
│ │
┌────────────▼──┐ ┌────▼──────────────────────┐
│ RecordStore │ │ Retrieval pipeline │
│ (dict/SQLite)│ │ Semantic (optional) │
└───────────────┘ │ → Keyword fallback │
│ → Path expansion (BFS) │
┌───────────────┐ │ → Rank by seed · link · │
│ LinkStore │ │ freshness · usefulness │
│ (nx/SQLite) │ └────────────────────────────┘
└───────────────┘
┌────────────────────────────┐
│ Learning engine │
│ usefulness prior │
│ link weight + evidence │
│ uncertainty · decay │
└────────────────────────────┘
Key properties:
- Semantic retrieval with automatic keyword fallback when embeddings are unavailable
- Graph path expansion: retrieval follows co-retrieval links, not just nearest neighbours
- Per-record usefulness prior: feedback directly scales future retrieval scores
- Evidence history on links: conflicting signals raise uncertainty rather than overwriting
- Time-based decay: recent interactions are fresher; activation fades without reinforcement
- Full SQLite persistence: records, link weights, usefulness, and metrics survive restarts
- Governed shared memory: multiple agents share a ledger with explicit visibility and provenance
These are engine-room concerns. The public API stays at three verbs.
Neural Ledger is not:
- a thin vector-store wrapper,
- a graph database pitch deck,
- an ontology-first framework,
- an LLM-everywhere abstraction layer.
The point is not to make memory more complicated. The point is to make memory more useful.
Memory survives process restarts when you pass a persist_path:
# First run — store something.
with Memory(persist_path="memory.db") as mem:
mem.remember("GitHub 401 caused by expired token", kind="observation")
# Later run — it is still there.
with Memory(persist_path="memory.db") as mem:
hits = mem.recall("GitHub 401")
print(hits[0].content) # "GitHub 401 caused by expired token"Records, learned usefulness, link weights, and engine metrics all survive the restart.
Multiple agents can share a governed memory ledger. Records default to local; sharing is always explicit.
# Agent A stores a shared finding.
with Memory(persist_path="team.db", agent_id="agent-a") as agent_a:
agent_a.remember(
"GitHub API 401 caused by expired token — refresh resolves it",
visibility="shared",
provenance="run-042",
)
# Agent B recalls it — with full provenance.
with Memory(persist_path="team.db", agent_id="agent-b") as agent_b:
hits = agent_b.recall("GitHub 401 fix", scope="merged")
print(hits[0].content) # agent-a's finding
print(hits[0].agent_id) # "agent-a"
print(hits[0].provenance) # "run-042"
agent_b.feedback(hits, helped=True) # reinforces the shared recordSee docs/examples/shared-memory.md and examples/shared_memory_two_agents.py for the full scenario.
Neural Ledger is intentionally small.
Included:
- in-memory and SQLite-persistent usage
- records, retrieval, and feedback
- feedback-learned usefulness and link weights
- governed shared memory with
agent_id,visibility, andprovenance - lightweight configuration
Not yet included:
- per-agent evidence attribution (Phase 4)
- explicit forgetting API
- heavy backend integrations
- full proof-chain objects
- broad framework adapters
- Phase 1 — Tiny public API, in-memory backend, feedback-aware retrieval
- Phase 2 — Canonical proof: feedback improves recall over keyword and semantic baselines
- Phase 3 — SQLite persistence: records, usefulness, link weights, and metrics survive restarts
- Phase 3B — Governed shared memory: multiple agents on one ledger with explicit visibility, provenance-preserving recall, and accumulated feedback
- Phase 4 — Evidence and confidence strengthening: per-agent attribution, explainable conflict handling, trust-weighted ranking
- Phase 5 — Public proof pack and release: polished README, benchmark summary, terminal demo
from neural_ledger import Memory
mem = Memory()
mem.remember("The user prefers concise answers on work topics", kind="preference")
mem.remember("The user likes deep examples when learning maths", kind="preference")
hits = mem.recall("How should I answer this question about a status update?", with_why=True)
for hit in hits:
print(f"{hit.content} ({hit.score:.2f})")
print(hit.why)
mem.feedback(hits, helped=True, reason="The preference was relevant")- Proof: feedback improves recall — controlled benchmark showing the learning effect
- Shared memory across agents — two-agent scenario with provenance-preserving recall
examples/— runnable scripts for quickstart and shared memory
Internal design docs (architecture, decision log, phase history) live in docs/internal/ for those who want them.
Neural Ledger is being built in the open.
The current focus is:
- a beautiful beginner experience,
- honest internals,
- strong evaluation,
- and a clear theory of memory as judgement.
Issues, ideas, benchmarks, and well-argued criticism are welcome.
MIT
Build the memory layer that decides what deserves to become memory.