DEV Community

Cover image for Building Continuum: Cross-Agent Graph Memory with Explainable Recall Using FalkorDB
Himanshu Jha
Himanshu Jha

Posted on

Building Continuum: Cross-Agent Graph Memory with Explainable Recall Using FalkorDB

If you have spent the last year building autonomous AI agents, you have almost certainly slammed into the agent amnesia barrier:

  1. Stateless context windows. When a session ends or the token limit is reached, your agent's memory vanishes.
  2. Vector search is probabilistic and blind to causality. RAG over text chunks gives you fuzzy cosine similarity. But embeddings cannot tell you when a fact was updated, why a decision changed, or how two entities relate across multiple degrees of separation.
  3. Multi-agent coordination is brittle. When multiple agents share state through flat key-value pairs or raw prompt dumps, they quickly poison each other's context with hallucinated or stale data.

To solve this, we built Continuum for the WeMakeDevs × FalkorDB Graph Hacks hackathon (Track 02: Agent Memory & Coordination).

Continuum is an open-source, cross-agent persistent memory engine powered by FalkorDB, designed around a single thesis: Agents are only as good as the context they reason over—and that context must be a graph.

Here is the complete architectural deep-dive into how we designed, benchmarked, and deployed it.


1. The Core Architecture: Three Cognitive Memory Tiers

In human cognitive science, memory is not a flat bucket of words. It is split into distinct functional systems. We mapped Continuum’s property graph schema directly to cognitive memory theory:

                  +-----------------------------------+
                  |         User (Tenant Root)        |
                  +-----------------+-----------------+
                                    |
          +-------------------------+-------------------------+
          |                         |                         |
    [:HAS_SESSION]              [:PREFERS]             [:HAS_PROCEDURE]
          |                         |                         |
          v                         v                         v
     (Session)                 (Preference)              (Procedure)
          |
     [:CONTAINS]
          |
          v
       (Turn) -----[:MENTIONS]-----> (Entity)
          |                             |
      [:DERIVED]                    [:RELATES]
          |                             |
          v                             v
       (Fact) <---[:SUPERSEDES*]--- (Fact)
Enter fullscreen mode Exit fullscreen mode
  1. Episodic Memory (Session, Turn): What happened, and in what exact sequence. Every message is a Turn node linked with nanosecond ordering tiebreakers (seq), making conversation replays deterministic.
  2. Semantic Memory (Entity, Fact): What is true about the world. Facts are extracted into structured triples (subject, predicate, value) linked to concrete Entity nodes with confidence scores and temporal validity bounds (valid_from, valid_to).
  3. Procedural Memory (Preference, Procedure): How the user likes things done. Stores explicit preferences ("prefers TypeScript") and multi-step procedures ("deploy preview: build → test → push → PR") with turn-level conversational step tracking.

2. Multigraph Topology: Real Multi-Tenant Isolation

In SaaS and multi-tenant architectures, you cannot risk leaking Alice's memory to Bob. Most vector databases force you to filter by metadata tags (where tenant_id == 'alice'), which wastes query execution cycles and risks catastrophic data leakage if an index is misconfigured.

FalkorDB supports native multigraph topology. In Continuum, every user is provisioned their own isolated graph brain inside a single FalkorDB instance:

def user_graph(self, user_id: str):
    graph = self.client.select_graph(f"user:{user_id}")
    if user_id not in self._indexed:
        ensure_schema(graph)
        self._indexed.add(user_id)
    return graph
Enter fullscreen mode Exit fullscreen mode
  • Absolute Isolation: Bob’s queries physically cannot traverse Alice’s graph nodes.
  • Query Planner Independence: Alice’s graph size does not degrade query optimization for Bob.
  • Instant Offboarding: Deleting a tenant's entire history is as simple as dropping a single graph.

3. Solving Temporal Amnesia with Variable-Length SUPERSEDES Walks

What happens when an engineer updates their project stack?

  • Yesterday: "I use Postgres for our persistence layer."
  • Today: "Update: We switched our persistence layer to CockroachDB."

In a vector database, both chunks exist simultaneously. The LLM gets confused, hallucinates, or flip-flops between them.

In Continuum, conflicting facts do not overwrite history. Instead, they create a directed SUPERSEDES relationship in FalkorDB:

MATCH (old:Fact {id: $old_id})
SET old.valid_to = timestamp()
MERGE (n:Fact {subject: $subject, predicate: $predicate, value: $value})
ON CREATE SET n.id = $new_id, n.valid_from = timestamp()
MERGE (n)-[:SUPERSEDES]->(old)
Enter fullscreen mode Exit fullscreen mode

When an agent needs to answer a historical rewind query ("What database were we using before?"), it executes an OpenCypher variable-length path traversal:

MATCH path = (root:Fact)-[:SUPERSEDES*1..5]->(old:Fact)
WHERE NOT (root)<-[:SUPERSEDES]-()
RETURN root, [n IN nodes(path) | n.value] AS evolution
ORDER BY root.last_seen DESC
LIMIT 6
Enter fullscreen mode Exit fullscreen mode

The agent doesn't guess—it walks the chain and explains:

"Previously Postgres, updated to CockroachDB on [timestamp]."


4. In-Graph Cross-Agent Coordination: Scribe & Scout

Track 02 challenged us to build coordination between multiple agents. We built two specialized agents:

  • Scribe: The conversational interface and summarizer.
  • Scout: The multi-hop graph researcher.

Instead of relying on human manual toggles, Scribe autonomously delegates to Scout when direct context is thin:

# Scribe autonomously summons Scout when keyword match finds 0 facts
if words and ctx.get("matched", 0) == 0 and QUESTION_RE.match(query):
    Scout(self.store, llm=self.llm).act(user_id, query, trace=trace)
    extra = self._pickup(user_id, query)
Enter fullscreen mode Exit fullscreen mode

When Scout is called, it expands entity relationships (Turn → Entity → Fact), writes a research synthesis to a SharedState node, and creates a directed HANDOFF_TO edge to Scribe:

MERGE (a:Agent {id: $from_id})
MERGE (b:Agent {id: $to_id})
CREATE (a)-[:HANDOFF_TO {
    id: $handoff_id,
    summary: $summary,
    status: 'pending',
    ts: timestamp()
}]->(b)
Enter fullscreen mode Exit fullscreen mode

The handoff protocol is not an ephemeral message—it is auditable graph data with full read/write provenance:

  1. Scribe inspects pending handoffs.
  2. A relevance gate verifies that the research matches the query tokens.
  3. Upon pickup, the handoff is marked status: 'consumed'.
  4. Stale handoffs older than 1 hour automatically expire via EXPIRE_STALE.

5. Explainable Recall: Opening the Black Box

When an AI agent makes a claim, how do you verify it?

Continuum ships with Explainable Recall. Every answer returns the exact Cypher queries executed, their parameters, and the node IDs touched. On the frontend, Cytoscape.js renders the live subgraph beside the chat:

  • Fact Nodes (Blue): Active knowledge triples.
  • Turn Nodes (Gray): Exact conversational provenance.
  • Entity Nodes (Orange): Real-world concepts connecting facts.
  • Preference Nodes (Green): Procedural user habits.
  • Superseded Facts (Dashed Red): Historical states.

Clicking any node slides open an Inspector Drawer displaying raw properties, timestamps, and confidence scores.


6. Performance: 4,300 Ops/Sec on FalkorDB

We benchmarked Continuum’s graph operations under heavy multi-tenant load using our automated benchmark runner (scripts/bench_concurrent.py):

  • 50 isolated tenant graphs
  • 32 concurrent worker threads
  • Local Docker container on standard hardware
Operation Samples p50 Latency p95 Latency Max Latency
read_facts 50 2.6 ms 6.4 ms 10.1 ms
read_turns 50 2.8 ms 6.8 ms 11.2 ms
read_prefs 50 3.1 ms 7.2 ms 11.8 ms
write_pref 50 5.4 ms 11.2 ms 18.5 ms
write_turn 50 6.1 ms 12.4 ms 21.0 ms

Overall Throughput: ~4,300 ops/second. Because FalkorDB executes graph algorithms via GraphBLAS matrix operations over the Redis protocol, traversals happen at memory bus speeds.


7. Try It Live & Run the Code

Continuum is deployed live on AWS EC2 (t3.small, ap-south-1) with FalkorDB, FastAPI, and Nginx serving the React frontend:

# Verify the graph engine and run tests
docker compose up --build -d
for t in episodic procedural semantic agent handoff scout_scribe api restart; do
  python scripts/test_$t.py
done
Enter fullscreen mode Exit fullscreen mode

Key Takeaway

Agents don't need larger prompt windows—they need structured, traceable, and temporal context. By replacing flat vector buckets with FalkorDB's property graphs, we can build agents that remember across sessions, coordinate with mathematical provenance, and explain every step of their reasoning.

Built with ❤️ for the WeMakeDevs × FalkorDB Graph Hacks Hackathon.

Top comments (0)