DEV Community

Vincent Tran
Vincent Tran

Posted on • Originally published at 0xgosu.dev on

The Log Is the Agent: ActiveGraph and Replayable AI Systems

Most AI agent frameworks start with the model.

That sounds natural. The model is the part users talk to, the part that chooses tools, the part that appears to reason. So the usual architecture grows around a conversation loop: messages go in, model output comes out, tool calls happen in between, and some memory layer tries to preserve enough context for the next turn.

The log usually arrives late. It is there for observability, debugging, billing, or incident review. It records what the real system did, but it is not the system’s source of truth.

Yohei Nakajima’s ActiveGraph paper makes the opposite bet. The agent is not the chat loop. The agent is the append-only event log. Everything else - current graph state, memory, tool history, model responses, artifacts, rules, and even behavior changes - is a projection from that log.

That inversion is the whole idea. It does not claim that agents become smarter by using an event log. It claims that long-running agents become inspectable in ways conventional loops struggle to be: replayable, forkable, and explainable from goal to output.

Why the Usual Agent Shape Breaks Down

A normal agent run is a moving pile of state.

There is a system prompt. There are user messages. There are retrieved memories. There is a model’s hidden sampling behavior. There are tool schemas, tool calls, tool results, intermediate summaries, external database writes, approvals, retries, and final artifacts. In a small demo, all of this can feel like one transcript.

In production, it is not one transcript. It is scattered across prompts, framework internals, logs, vector stores, queues, databases, file systems, and monitoring tools. When the agent produces a wrong answer, the hard question is not only “what did it say?” The harder questions are:

  • Why was this fact in context?
  • Which event caused this tool call?
  • What did the agent know before this rule changed?
  • Can I replay the run without paying for every model call again?
  • Can I branch from step 150, change one behavior, and compare the result honestly?

Most agent stacks can answer some of those questions with enough logging discipline. ActiveGraph is designed so those questions are native operations.

The Core Model

ActiveGraph has three central pieces.

First, there is an append-only event log. Every meaningful change is recorded as an event: a goal was created, a pack was loaded, an object was added, a relation was created, a behavior started, a model was requested, a model responded, a tool was called, a patch was applied, an approval was granted, or a failure occurred.

Second, there is a graph. The graph is not the primary database. It is the current working view produced by replaying the log. Objects and typed relations form the world the agent sees: companies, questions, documents, claims, evidence, risks, memos, tasks, dependencies, or whatever ontology a domain pack defines.

Third, there are behaviors. A behavior is reactive code. It subscribes to event types and graph patterns, then fires when a matching change appears. A behavior can be a plain function, a class, an LLM-backed routine, or logic attached to a typed relation. It reads the graph, maybe calls a model or a tool, and emits more events.

No component directly mutates the graph as its own private state. The runtime records events, and the graph is reconstructed from those events.

This matters because the graph and the log do different jobs. The log makes state reproducible. The graph makes reactivity expressive. A flat log alone would force every behavior to rebuild shape-aware context for itself. A graph alone would show current state while losing the causal chain that created it. Together, they let a behavior fire on patterns such as “a claim that addresses an unanswered question” while still preserving the ordered history behind that pattern.

Coordination Without a Workflow Script

ActiveGraph is not saying coordination disappears. It says coordination moves from explicit control flow into shared state.

In a traditional workflow, a top-level script says: plan the work, generate questions, research documents, extract claims, detect contradictions, identify risks, then synthesize a memo. The orchestration is the program counter.

In ActiveGraph, a planner behavior can react to a new goal by creating a company object. A question generator can react to that company object by creating research questions. A researcher can react to open questions. A claim extractor can react to documents. A contradiction detector can react to claims and evidence. A memo writer can react when the graph has enough material.

The chain still exists, but it is visible as events and graph transitions rather than hidden inside a controller. That is why the architecture fits long-running agent systems: the flow emerges from recorded state changes, so the flow can be replayed, inspected, forked, and diffed.

There is a tradeoff. You have not eliminated complexity. You have made it data-driven. That can be a win when auditability matters, but it also means behavior authors need to understand the event vocabulary, graph ontology, subscriptions, budgets, and failure modes.

Replay Has to Admit That Models Are Not Deterministic

The paper is careful about the most important problem: language model calls are not deterministic in the way pure functions are deterministic.

Even if a request uses temperature zero, real model services can change across time. Tool outputs can change too. Search results move. APIs return different data. A live agent run is not something you can naively execute twice and expect byte-identical behavior.

ActiveGraph handles this by separating live execution from replay.

On the first run, a behavior may call a model or tool. The request and response are both recorded. The model request is normalized and hashed over the full request shape: messages, model identifier, tool definitions, output schema, and related parameters. A tool response is likewise tied to a deterministic hash of the tool name and arguments.

During replay, the runtime does not ask the model to produce the same answer again. It serves the recorded response from the log-backed cache. Replaying the run means reconstructing what happened, not pretending the outside world is pure.

That distinction is the strongest part of the design. Determinism is a property of re-projecting an already captured log. It is not a claim that agent execution itself has become deterministic.

ActiveGraph has strict and permissive replay modes. Permissive replay reconstructs state and can continue from a changed behavior or prompt by making fresh calls where needed. Strict replay re-fires behavior and compares the event stream against the recorded one. If something diverges, the runtime can point to the first event that failed to reproduce.

This is also how the determinism contract is enforced. Behavior code is supposed to avoid direct reads from random sources, wall-clock time, fresh UUIDs, arbitrary I/O, or mutable global state. The framework does not prove that statically. It catches violations when replay diverges.

Forking Is the Payoff

Once a run is a log, branching becomes cheap.

A fork copies the parent’s events through a chosen cutoff event, replays that shared prefix from the cache, and then continues independently. If the first 149 steps of a 200-step run are unchanged, the fork does not need to re-pay for those model and tool calls. Live execution resumes only after the fork point.

That enables a useful style of agent evaluation. Instead of asking “would a different prompt have helped?” in the abstract, you can fork at the point where the prompt matters, change the behavior, run forward, and structurally diff the resulting graph against the parent.

This is more honest than comparing two unrelated runs. The shared history is identical. The divergence point is explicit. The diff is over objects, relations, and patches rather than over vague transcripts.

For agent development, that is a serious tool. It turns prompt changes, policy changes, model swaps, tool additions, and self-modifications into branchable experiments.

Lineage Becomes the Product

The paper’s worked example is an investment diligence pack. It starts from companies, generates research questions, searches documents, extracts claims, links evidence, detects contradictions, identifies risks, and writes memos.

The important output is not just the memo. It is the lineage behind the memo.

In the reported quickstart run, the bundled fixtures produce 671 events, 93 objects, 76 relations, 103 model calls, and 48 tool calls. Because the run uses recorded fixtures, it can execute offline and replay byte-deterministically. Every claim in the memo can point back to the behavior that created it, the event that caused it, the model request that produced it, the question it addresses, the document it came from, and the evidence relation supporting it.

That is the difference between an answer and an inspectable answer.

For casual chat, this may be overkill. For diligence, compliance, research, security review, legal analysis, scientific workflows, and production automation, lineage is not decoration. It is often the reason an agent output can be trusted, challenged, corrected, or approved.

The BabyAGI Lineage Matters

ActiveGraph is explicitly connected to BabyAGI, Nakajima’s earlier task-driven autonomous agent loop. BabyAGI was simple: keep a global task list, execute the current task, summarize the result against the objective, generate follow-up tasks, and continue.

The simplicity made it memorable, but the architecture was transient. The state lived in a loop and a mutable task list.

ActiveGraph keeps the self-extending character but changes the substrate. Tasks, rules, tool calls, outputs, and behavior changes become events. The task list becomes a projection of the log. Follow-up work emerges from behaviors reacting to graph state.

That change is not cosmetic. It is the difference between an autonomous loop that does things and an autonomous loop whose history is durable enough to inspect.

What ActiveGraph Is Not

The project documentation is refreshingly direct about boundaries.

ActiveGraph is not a chat framework. If the task fits in one conversation, a chat framework is simpler.

It is not a workflow engine. Workflow engines model control flow. ActiveGraph models world state and lets behavior react to that state.

It is not a production graph database. The default event store is SQLite, Postgres is available behind an event-store protocol, and the materialized graph can be in memory or backed by a graph store such as FalkorDB. The graph is the runtime’s working projection, not a promise that the framework replaces a dedicated graph database.

It is not magic. Bad behaviors still produce bad graph state. The runtime makes badness traceable, not impossible.

Those limits are important. Event sourcing gives you history, but it also gives you migration work. Replay costs grow with log length. Long-lived agents will eventually need checkpointing and compaction. Reactive systems can loop or cascade, so ActiveGraph uses budgets for events, calls, time, recursion depth, and cost. External tools with side effects are replay-safe only after the first execution records what happened; the external world still changed during that first execution.

Distributed writers and concurrent multi-agent contention are also hard. A single append-only log gives a clean order. Many writers over shared graph state introduce ordering and conflict questions that the paper names as future work rather than pretending they are solved.

Why This Architecture Feels Timely

AI agent development is moving from toy demos toward systems that run for longer, call more tools, modify more state, and produce artifacts people actually depend on. In that world, “we have logs” is not enough.

You need to know whether the log is authoritative or merely observational.

If the log is observational, it can help after an incident, but the real state may still live elsewhere. It may be incomplete, lossy, out of order, or disconnected from the memory layer the agent used.

If the log is authoritative, then current state, memory views, audit trails, forks, diffs, and replay all come from the same history. That makes the system heavier upfront, but it reduces a class of ambiguity that becomes painful once agents do meaningful work.

ActiveGraph is best understood as a serious systems argument, not as a benchmark claim. The paper does not show that agents solve tasks more accurately with this runtime. It shows a way to make agent runs reconstructable, branchable, and accountable.

That may be the more urgent problem. Model capability keeps improving. The harder production question is how to operate agents whose work must be explained, reproduced, revised, and trusted after the fact.

For that class of system, treating the log as the agent is not a metaphor. It is an engineering stance: the durable history is the thing you can reason about. Everything else is a projection.

Sources: The Log is the Agent paper, ActiveGraph repository, ActiveGraph documentation, BabyAGI repository, and the discussion thread.

Top comments (0)