v1.10.0 · open sourceApache 2.0 · Python 3.11+

activegraph

A persistent world for long-running agents.

A shared graph of beliefs, tasks, evidence, decisions, and dependencies — derived from an append-only event log. Replay, fork, and diff any run.

watch the AI Engineer talkActive Graph Agent Runtime (BabyAGI 4)

From Yohei Nakajima, creator of BabyAGI (2023). activegraph is the architectural answer that years of agent infrastructure work kept pointing toward.

relation_behavior.py
from activegraph import Graph, Runtime, behavior, relation_behavior

graph = Graph()
runtime = Runtime(graph, budget={"max_events": 200, "max_seconds": 60})

# Behaviors react to events and write back to the graph.
@behavior(name="planner", on=["goal.created"])
def planner(event, graph, ctx):
    research = graph.add_object("task", {"title": "Research", "status": "open"})
    memo = graph.add_object("task", {"title": "Draft memo", "status": "blocked"})
    graph.add_relation(research.id, memo.id, "depends_on")

# Edges carry logic. This one knows how to unblock its target.
@relation_behavior(name="unblock", relation_type="depends_on", on=["task.completed"])
def unblock(relation, event, graph, ctx):
    if event.payload["task_id"] == relation.source:
        graph.patch_object(relation.target, {"status": "open"})

runtime.run_goal("Evaluate this idea")
runtime.print_trace()

# Fork the run at any historical event. The shared prefix
# replays from cache — no duplicate LLM calls.
fork = runtime.fork(at_event=4)
relation_behavior

The differentiated primitive. Coordination logic lives on the edge, where the meaning is — not duplicated across every node that might emit a relevant event.

runtime.fork(at_event=…)

Branches the run. The shared prefix replays from cache. Forks don't re-pay for LLM calls already made.

// Try it through your AI assistant

Paste this into Claude, ChatGPT, or your coding agent.

ActiveGraph is designed to be learned by agents as well as humans. The docs, quickstart, trace, and fork/diff primitives give an assistant enough structure to build something real in minutes — not just agent-legible infrastructure, but infrastructure that an agent can pick up and use.

prompt.txt
Read https://docs.activegraph.ai/llms.txt
(and llms-full.txt if you need depth).
For more context, also open:
- https://github.com/yoheinakajima/activegraph-packs
- https://github.com/yoheinakajima/activegraph-lab
- https://github.com/yoheinakajima/regimes
Install the activegraph Python package.
Build and run a small experiment that shows why an
event-sourced reactive graph is useful.
Use fork/diff or replay if possible.
Explain what happened and what the trace proves.

Point agents at llms.txt / llms-full.txt. Works with any agent that can read a webpage, install a pip package, and run Python.

// Agents need more than memory

The event log is the agent. The graph is its world.

Memory

Stores what an agent might want to recall.

Workflows

Define what should happen next.

Logs

Record what happened afterward.

ActiveGraph

Collapses these into one substrate: an append-only event log projected into a live graph. The graph is the agent's world — what exists, what depends on what, what was produced, what was approved, what changed, and why.

// Where it fits

Not another agent framework. The world beneath one.

Bring your model, tools, prompts, and workflows. ActiveGraph gives them durable state.

Workflows model computation. ActiveGraph models the world that computation acts on. Memory remembers conversations. ActiveGraph holds beliefs, evidence, contradictions, decisions, and their lineage.

ActiveGraph is where agent state becomes inspectable infrastructure.

  1. Models
    Reasoning and generation
  2. Tool frameworks
    Calling external systems
  3. Workflows
    Sequencing work
  4. Memory
    Retrieval and recall
  5. ActiveGraphthis layer
    The shared world: objects, relations, events, lineage, replay, forks, diffs

// What you can build

Primitives the loop doesn't give you.

Replay, fork, diff, lineage, edge logic — plus the post-v1.0 operator loop: sandboxed trials, promote gates, pluggable graph backends, and context-read traces. Concrete things that fall out once the event log is the substrate.

01

Auditable agents

Every object, claim, decision, and tool result traces back to the event that created it.

02

Fork → test → promote

Branch a run, try a change in isolation, and promote only what earns it — without destroying the parent lineage.

03

Edges with meaning

A depends_on, contradicts, supports, or blocks relation can carry behavior. Logic lives where the meaning is.

04

Pluggable graph backends

Swap the materialized graph store. In-memory by default; FalkorDB is the first external backend — native edges, Cypher push-down.

05

Sandboxed fork trials

Run candidate packs and patches in isolated trials before they touch the shared world. Cross-pack interactions become expressible experiments.

06

Context-read tracing

Record which objects a behavior actually looked at. The read set is an event — replayable, exportable, fork-stable.

// Research basis

The Log is the Agent.

Two papers. Same substrate: the event log as source of truth, the graph as its deterministic projection — then controlled self-improvement as a first-class, replayable workflow instead of external scaffolding.

arXiv:2605.21997

The Log is the Agent: Event-Sourced Reactive Graphs for Auditable, Forkable Agentic Systems

The design argument: invert the usual agent framework so the append-only log is the source of truth. Replay, fork, diff, and end-to-end lineage fall out of the architecture — not an audit layer bolted on top.

arXiv:2606.10241

Regimes: An Auditable, Held-Out-Gated Improvement Loop Demonstrated on LongMemEval with ActiveGraph

Controlled self-improvement as a first-class, replayable workflow instead of external scaffolding. Diagnose failing runs, route repairs, promote only through held-out gates — every step an event.

The site is its own proof. Research notes on this blog are drafted by the lab agent running on activegraph, then published through human editorial gates — each carrying an evidence-linked provenance trail.

// Example · BabyAGI, rewritten

BabyAGI, as an active graph.

The original BabyAGI (Nakajima, 2023) was a while-true loop with three steps: execute the current task, summarize against the objective, generate follow-ups. State lived in a global list.

This rewrite expresses the same loop as reactive behaviors over a shared graph. The loop IS event propagation. The graph IS the state. Every step is a subscription, not a function call; the trace records every mutation and is queryable after the run.

It's a download-and-run-it-yourself example in the OSS repo — not a bundled pack. Three behaviors: initializerexecutortask_creator, wired by events.

View on GitHub →examples/babyagi.py
Clone & run
git clone https://github.com/yoheinakajima/activegraph
cd activegraph && pip install -e .
export ANTHROPIC_API_KEY=...
python examples/babyagi.py "Plan a 3-day intro to Rust"
examples/babyagi.py
@behavior(name="initializer", on=["goal.created"])
def initializer(event, graph, ctx):
    goal = event.payload["goal"]
    graph.add_object("task", {"title": f"Plan first step toward: {goal}",
                              "status": "pending"})

@llm_behavior(name="executor", on=["object.created"],
              where={"object.type": "task"}, output_schema=TaskResult)
def executor(event, graph, ctx, llm_output: TaskResult):
    task = event.payload["object"]
    graph.patch_object(task["id"], {"status": "completed"})
    graph.emit("task.executed", {"task_id": task["id"],
                                 "result": llm_output.result})

@llm_behavior(name="task_creator", on=["task.executed"],
              output_schema=NewTasks)
def task_creator(event, graph, ctx, llm_output: NewTasks):
    for title in llm_output.tasks:
        graph.add_object("task", {"title": title, "status": "pending"})

Three behaviors. The graph queues itself; the event log is the order; an empty follow-up list terminates the loop.