Skip to main content

Graph Memory

The graph memory tier stores entities and relationships that agents build up over many runs and share with each other: a customer and the orders it placed, a work item and the person who reviewed it, a company and the people who work there. Alongside the working, session, episodic and semantic tiers, it is the one tier whose contents are meant to be read by other agents, so it carries grants, provenance and visibility controls the other tiers do not need.

Graphs are named, and a workspace can have many​

A graph is identified by (workspace, graph_name). Any agent that declares a slot naming that graph reads and writes the same nodes; nothing is per-agent. Declare as many graphs as you have subjects:

agents:
- name: reviewer_claude
memory:
things: # graph "things" — this agent reads and writes it
tier: graph
graph_name: things
graph_access: read_write
team: # graph "team" — this agent may only read it
tier: graph
graph_name: team
graph_access: read

- name: team_seed
memory:
team: # the only writer of "team"
tier: graph
graph_name: team
graph_access: write

Two graphs, two grants, one agent. wax graph list shows the graphs that exist; wax graph show <name> prints one.

Grants​

graph_access is read, write or read_write (the default). It is enforced twice:

  • When the tools are built. A read slot gets graph__recall__<slot> and graph__find__<slot> only; a write slot gets graph__remember_entity, graph__remember_relationship, graph__remember_batch and the import/link tools only. The model never sees a tool it may not call.
  • At the backend, on every write, so a tool reached any other way is still refused. A refused write is a governance event on the run.

Grants are per agent, per slot. Change a reviewer's team slot to read_write, push, and its next run can write to team; nothing else moves.

What a node carries​

FieldMeaning
keyYour identifier. Use the same key everywhere (thing-001, u_42) so graphs join; keys are not namespaced per agent.
kindperson, thing, company, … — free text unless the graph has an ontology.
label, propertiesDisplay name and any JSON.
confidence0–1; re-observing a node reinforces it rather than duplicating it.
observation_countHow many writes have asserted this node.
provenanceThe agent that wrote it, the run, the person it acted for (from the end-user identity), the tool. Every node and edge.
visibility_groupOptional. Readers outside the group do not see the node (or edges touching it).

An edge is from_key → relationship → to_key with the same confidence and provenance. An edge whose endpoint has not been recorded as a node gets a low-confidence placeholder node (kind entity), so the edge is never invisible; the write result says endpoints_created when that happens.

The tools, from the agent's side​

ToolDoes
graph__recall__<slot>The subgraph around one or more keys (around, hops). The usual first call.
graph__find__<slot>Nodes whose key or label contains query, optionally by kind.
graph__remember_entity__<slot>One node.
graph__remember_relationship__<slot>One edge.
graph__remember_batch__<slot>Many nodes and edges in one call — use this after a piece of work.
graph__import__<slot>Pull a domain payload in and map it to entities.
graph__link__<slot> / graph__orphans__<slot>Housekeeping.

Every call emits a memory event on the run (graph.recall · 2 in team, graph.remember_batch · +2 entities, +1 relationships), so the run page shows what the agent remembered and recorded.

Reading a graph yourself​

wax graph list                         # graphs in the workspace
wax graph show things # nodes, edges, provenance per node
wax graph show things --group finance # what a reader in that visibility group sees
wax graph provenance things thing-001 # who wrote it, in which run, for whom; audit trail
wax graph show things --format json # the same data for your tooling

The Graph Memory page in the app (/graph-memory) renders the same graphs with a provenance panel and a live visibility-group toggle. GET /api/v1/graph-memory/?graph=<name> is the API behind both.

Ontology (optional)​

A graph may declare the kinds and relationships it accepts (/api/v1/graph-memory/ontology/?graph=<name>). In the default mode a write outside the ontology still lands and a proposal is recorded for a human to accept or map; in strict mode it is refused. Either way a shared graph does not drift into a hundred spellings of the same kind.

See it​

The public quickstart (github.com/waxell-ai/runtime-evaluation) has three reviewers sharing a things graph and reading a team graph that one seed agent writes; step 11 walks all four memory tiers in a few minutes. The evaluation tutorial explains each step.