Opens in a new tab

Procedural Graphs: Memory That Rewrites Itself

Last session I compared four memory engines for Whale, our agent harness, and ended on cognee. Then I read a paper and implemented something else entirely.

The paper is Procedural Graphs: Self-Evolving Execution Structures for LLM Agents by Yuxing Lu, Yicheng Chen, Shanchan Wu and Sercan Ö. Arık at Google, Georgia Tech and Peking University (arXiv:2609.09153, 8 September 2026). It does not propose a better database. It proposes a different answer to the question of what an agent’s memory is for — and once I had read the abstract twice, the comparison from the week before stopped being a shortlist and became a set of criteria that the paper simply scored better on.

Facts against procedures

Most memory for language models stores facts. The classic shape is a triple: entity, relation, entity. Zurich — is in — Switzerland. Ask it a question about the world and it answers. It is a what is structure.

A procedural graph stores the other kind of knowledge, in the same shape: procedure, relation, procedure. It is a what to do structure. The nodes are not things the agent knows, they are steps it has taken, and the edges are how those steps follow one another.

That distinction sounds academic until you watch an agent fail twice at the same task. The facts were never the problem. It knew what a cash-flow forecast was. What it didn’t have was the knowledge that this particular move tends to go wrong in this particular way — and that is exactly what a procedural graph keeps.

Guidance that biases without dictating

The mechanism I liked most is the one that sits in the loop. At each decision step the framework locates the agent’s active node in the graph, and a guidance model translates the surrounding subgraph into step-level situational guidance: a short piece of context about where the agent is and what tends to work from here.

The guidance is appended to the solver’s prompt. The solver still chooses. The paper’s own framing is that the guidance biases the next action without dictating it, and that phrase is doing real work — it is the difference between memory as advice and memory as a rail. An agent on a rail stops being able to handle the case you didn’t foresee, which was the whole reason you built an agent instead of a script.

The self-evolving part

Here is where it earns the name. A refiner — itself a language model — contrasts failed trajectories with successful ones and proposes edits to the graph: change the topology, change the attributes on a node, prune. Rejected variants are kept rather than deleted, so the graph remembers what not to try again. You start from a minimal skeleton and the loop grows it.

So the agent’s memory is not a log that gets longer. It is a structure that gets better, or at least gets different in a direction you can inspect.

Three decisions that took the session

Reading the paper took twenty minutes. The rest of the session went into decisions it doesn’t make for you.

What the graph is stored as. I weighed a few options — a JSON graph specification, the Graphviz JSON flavour, GraphML, plain YAML — and landed on NetworkX‘s own node-link JSON, written and read straight back through json_graph.node_link_data and node_link_graph. The reasoning was boring and I would make it again: it is human-readable, it diffs in git, it needs no dependency we don’t already have, and it gives us graph validation for free rather than hand-rolled.

What happens when the graph is invalid. The tempting answer is to fail hard — bad memory, stop everything. That is wrong. If memory validation can halt the agent, then memory is a new way for the run to die, and you have made the system worse by adding knowledge to it. So the validator warns, tied to the log level, and the agent keeps going with whatever guidance it could safely derive. Memory is an improvement, not a dependency.

When the refiner runs. Not after every step — that is a tax on every single turn, paid in tokens and latency. It runs at the session boundary, when the loop is done and there is a complete trajectory to compare against. The decision I noted as open on the recording is still open: we need numbers on what each iteration of the loop costs in tokens before we tune this any further.

Built test-first, by an agent

The implementation itself was done with Claude Code and the Superpowers plugin, test-driven, with me supervising rather than typing. It went well enough to be slightly unsettling: specs, tests, implementation, green.

The honest version of that sentence, though, is this. When an agent writes the code, the thing you have to review is no longer the code — it is the plan. Every mistake I would have caught by typing it myself now has to be caught by reading what it intends to do, before it does it. Which, as it happens, is exactly the subject of the next session: how do you put a critic and a human in front of a plan.

At the end of this one we had an agent loop that runs several iterations, a refine command, memory that records the trajectory and improves from it, and tests covering the lot.

Watch the session

Creating an AI Agent Harness: Iteration 4 — Memory Engine Implementation Creating an AI Agent Harness: Iteration 4 — Memory Engine Implementation — watch on YouTube →
Chapters: 00:00 Starting memory agent work · 02:27 Agent loop and memory structure · 06:46 Implementation and setup · 10:23 Choosing a graph data format · 17:06 Memory system components · 42:39 Planning next steps · 45:42 Test-driven progress · 49:54 Wrap up.
  • The series so far: https://www.youtube.com/playlist?list=PLPbgiIdJb7gE
  • The memory engine comparison that came first: https://nowtec.solutions/blog/choosing-a-memory-engine-for-an-agent/
  • Code: https://github.com/nowtec/whale

This article was written with the support of AI tools and reviewed by our team before publication (EU AI Act, Art. 50).

Let’s connect.

Fill out the form below and tell us what you are looking to solve. We will get back to you with tailored advice and solutions to match your needs.

Vladimir Stajilov

CTO @nowtec solutions | nowCRM | nowCDP | 🤖 Automation with AI and LLMs 🔌 Low-Code ☁️ Cloud
Browse Posts