Wire reasoning steps to the entities they touched, then ask: "every reasoning trace that ever touched this client."
This example shows the reasoning-region polish in neo4j-agent-memory: explicit :TOUCHED edges from ReasoningStep → Entity, an automatic hook that infers them from tool-call results, and a structured TraceOutcome you can index on. The headline payoff is a one-hop audit query that is fast and explainable.
⚠️ Neo4j Labs ProjectThis example is part of
neo4j-agent-memory, a Neo4j Labs project. It is actively maintained but not officially supported. APIs may change. Community support is available via the Neo4j Community Forum.
Need a different LLM or embedding model? As of
neo4j-agent-memoryv0.3 you can swap providers via a single string —MemorySettings(llm="anthropic/claude-3-5-sonnet-latest", embedding="BAAI/bge-small-en-v1.5"). See Bring Your Own Model.
record_tool_call(touched_entities=[...])— explicit:TOUCHEDedge writes from a reasoning step to one or more entities.@client.reasoning.on_tool_call_recorded— register a per-app hook that infersEntityReflists from the tool name and arguments. Hook errors are logged, never raised.TraceOutcome— structured, indexable outcome oncomplete_trace(outcome=...): success flag, summary,error_kindfor failure-mode analytics, related entities, and metrics.- The headline audit query — a single one-hop
MATCH (e:Entity {name: 'Anthem'})<-[:TOUCHED]-(s:ReasoningStep)<-[:HAS_STEP]-(rt:ReasoningTrace). Fast and explainable.
| File | Purpose |
|---|---|
main.py |
Registers the observer hook, runs a trace, completes it with a structured outcome, prints the audit query results. |
tool_calls.py |
Domain-specific mapping from tool names to EntityRef lists. Hand-written per agent — not auto-derivable. |
queries.cypher |
The headline audit query plus error-kind and per-entity history queries you can run in cypher-shell. |
- Neo4j 5.x running at
bolt://localhost:7687(or setNEO4J_URI,NEO4J_USERNAME,NEO4J_PASSWORD). neo4j-agent-memoryinstalled in your environment (the demo runs without an LLM —llm=None, sentence-transformers embedder).
From the repo root:
uv run python -m examples.audit-trail.mainYou should see the audit query produce a row that links Anthem back through a :TOUCHED edge to a :ReasoningStep and its parent :ReasoningTrace:
Audit trail for Anthem:
- task: Recommend a team for Anthem
thought: Look up consultants who match Anthem's needs
outcome: {"success": true, "summary": "Recommended a 2-person team for Anthem", ...}
Then run the supplemental queries in cypher-shell:
cypher-shell -a $NEO4J_URI -u $NEO4J_USERNAME -p $NEO4J_PASSWORD < examples/audit-trail/queries.cypher- How-to guide:
docs/modules/ROOT/pages/how-to/audit-reasoning.adoc— design rationale, error-kind taxonomy, indexing tips. - Companion example:
examples/eval-harness/— runs a labelled audit-coverage test against:TOUCHEDpaths.
Verified against neo4j-agent-memory v0.2-dev (branch adopt-existing-graph) on 2026-05-03.