Skip to content

Agent memory with branching ​

ChronoVec's AgentMemory and branching API are designed for agentic workloads where the agent needs to:

  • Maintain memory across agent interactions
  • Speculate (explore a hypothesis without committing it)
  • Rewind (start a clean branch from what the agent knew at a previous step)
  • Erase records with a bounded cost (GDPR, multi-tenancy)

Running the example ​

bash
python examples/agent_memory.py

Core pattern: rewind, retry, and merge ​

python
from chronovec import AgentMemory
import numpy as np

memory = AgentMemory(dimensions=384)

# Establish base facts
memory.add(1, np.random.rand(384).astype("float32"), text="Paris is the capital of France")
memory.add(2, np.random.rand(384).astype("float32"), text="The Eiffel Tower is in Paris")

# Open a speculative branch
plan = memory.branch("plan-a")
plan.add(3, np.random.rand(384).astype("float32"), text="speculative: relocate capital")

# Branch sees base + speculation
print(len(plan.search(np.random.rand(384).astype("float32"), k=10)))  # 3

# Main never sees the speculation
print(len(memory.search(np.random.rand(384).astype("float32"), k=10)))  # 2

# Discard: abandon speculation; reclaim later at a safe horizon
plan.discard()

AgentMemory can be checkpointed explicitly with memory.save("agent") and restored with AgentMemory.load("agent"). Checkpoints include payloads and active branch metadata as well as vectors. A manifest atomically selects a complete native checkpoint and metadata generation; incomplete or mismatched generations are rejected on load.

Rewind and retry from an earlier interaction ​

Capture a snapshot before a risky tool call or reasoning step. If the future turns out to be wrong, fork from that snapshot and continue there. The later main-memory writes remain in the original timeline and do not contaminate the retry branch.

python
checkpoint = memory.snapshot()
memory.add("bad-plan", embedding, text="an unverified plan")

retry = memory.branch("retry", snapshot=checkpoint)
retry.add("good-plan", embedding, text="a corrected plan")
retry.search(query)  # sees the clean checkpoint plus the corrected plan
memory.search(query)  # remains on the original timeline

The complete runnable example is in examples/agent_memory.py. It shows a mistaken preference update, a retry from the clean checkpoint, and a merge of the corrected branch while the pre-interaction state remains queryable.

Many concurrent branches ​

Each branch gets its own private native delta index by default, so branch count isn't capped and idle branches cost only their own metadata; main pages, centroids, and routing are untouched until a branch merges:

python
branches = [memory.branch(f"plan-{i}") for i in range(200)]
for b in branches:
    b.discard()

(AgentMemory(..., branch_engine="labels") restores the previous shared-index implementation, which caps out at 63 concurrent branches.)

Merge: commit speculation to main ​

python
branch = memory.branch("research")
branch.add(4, embedding, text="discovered: important context")
branch.merge()  # promotes all branch writes to main
# now main sees record 4

Time travel: query past beliefs ​

python
t1 = memory.add(5, embedding, text="initial belief")
# ... time passes, belief is corrected ...
memory.delete(5)
memory.add(5, new_embedding, text="corrected belief")

# query as of t1: returns old belief
old_results = memory.search(query, k=10, as_of=t1)

LangChain: branching memory in a chain ​

python
from chronovec.integrations.langchain import ChronoVecVectorStore

store = ChronoVecVectorStore(embedding=embeddings, dimensions=1536)
store.add_texts(["user prefers dark mode"])

with store.branch("hypothesis") as scratch:
    scratch.add_texts(["user might prefer light mode"])
    retriever = scratch.as_retriever(search_kwargs={"k": 3})
    # run retrieval over speculative + confirmed memory
# hypothesis is discarded when the block exits

Garbage collection ​

python
# After merging or discarding branches, reclaim space
memory.purge(oldest_snapshot=memory.snapshot())

Released under the Apache-2.0 License.