Branching Memory: Persistent Conversational Context in GraphRAG
Barnyard stores conversation turns as a persistent graph in Neo4j, enabling durable context, branching threads, and provenance tracking that survives session restarts.
Overview
Traditional chatbots maintain conversation history in a flat list of messages that disappears when the session ends. Barnyard's branching memory system stores conversation turns as a persistent graph structure in Neo4j, enabling:
- Durable context that survives session restarts and server reboots
- Branching conversations where a single turn can spawn independent continuations without overwriting the original path
- Provenance tracking — each memory node is anchored to the entities and documents it referenced during retrieval
Architecture
MemoryNode
Each conversational turn is stored as a MemoryNode in Neo4j with:
| Field | Type | Description |
|---|---|---|
id | UUID | Globally unique identifier returned to the caller |
query | str | The user's original question |
answer | str | The model's generated response |
grounding_context | str | Text snapshot of the retrieved KG context at answer time |
timestamp | datetime | When this turn occurred |
user_id | str | Which user owns this memory node |
Graph Structure
Turns are chained together with NEXT_TURN edges — turn A to turn B to turn C — and each turn also carries provenance links: an ABOUT edge to the entities it discussed (such as Apple Inc.) and a SOURCED_FROM edge to the documents it drew on (such as a Q3 report).
Relationship types:
NEXT_TURN— links consecutive turns in the same conversation threadABOUT— links a memory to the Entity nodes it discussed (survives entity merges)SOURCED_FROM— links a memory to the TextNode(s) used as retrieval context (survives re-ingestion)
Branching Conversations
The key innovation is the spawn_child flag. Without it, each new turn extends the current chain linearly:
Without it, each new turn simply extends the current chain in a straight line — root, then turn one, turn two, turn three.
With spawn_child=True, a new branch is created from the current node without mutating it:
With branching enabled, a new turn forks off the current node without changing it: the original branch (root → turn one → turn two) stays intact, while an alternate follow-up grows alongside it as a separate path.
This is useful for:
- Exploring alternative hypotheses without losing the original reasoning path
- Parallel investigation threads on the same document set
- A/B comparing different follow-up questions against the same context
Retrieval Enrichment
When answering a question, generate_answer_node injects the last N turns from the memory chain as conversation history. This means:
- The user doesn't need to resend prior turns — they're fetched directly from Neo4j
- Multi-turn coherence is maintained even across separate API sessions
- The grounding context from prior turns can be referenced if the current retrieval returns sparse results
Provenance and Robustness
ABOUT and SOURCED_FROM edges use stable identifiers:
ABOUT→ Entityid(deterministic MD5 of name+type — survives entity re-extraction)SOURCED_FROM→ TextNodeid(UUID4 — survives re-ingestion of the same document)
When a TextNode is deleted, SOURCED_FROM edges are removed but the MemoryNode itself is preserved with its grounding_context snapshot — the conversation history remains coherent even after source documents are removed.
Keep Reading
Source Traceability: From Answer Back to Passage
Every answer Anatypical generates is anchored to specific document passages and entities via persistent Neo4j graph edges — surviving re-ingestion, entity merges, and session restarts.
Vadalog Semantic Grouping: Structured Predicate Taxonomy for Knowledge Graphs
How Barnyard normalizes inconsistent LLM-extracted predicates into a 30+ canonical predicate ontology across 13 semantic groups, preventing knowledge graph fragmentation.
Tribrid RAG: Three-Signal Retrieval with MMR Fusion
Barnyard combines entity search (BM25 + vector), topic cluster retrieval, and knowledge graph expansion into a single ranked passage pool using Maximum Marginal Relevance fusion.