In the previous lesson, you learned the reasoning memory schema — how ReasoningTrace, ReasoningStep, and ToolCall nodes connect, and how cross-memory relationships tie all three layers together in a single graph. Now you will use the Pydantic AI integration to record those traces automatically.
In this lesson, you will learn how to use create_memory_tools() and record_agent_trace() to record a complete reasoning trace with minimal code.
Using the Pydantic AI integration
create_memory_tools() returns 19 pre-built agent tools that expose all three memory types to a Pydantic AI agent. The agent can call these tools to store and retrieve memory as part of its normal reasoning process.
import os
from neo4j_agent_memory import MemoryClient, MemorySettings
from neo4j_agent_memory.config import Neo4jConfig, EmbeddingConfig
from neo4j_agent_memory.integrations.pydantic_ai import create_memory_tools
from pydantic_ai import Agent
async with MemoryClient(settings) as memory:
# Returns 19 ready-to-use agent tools
tools = create_memory_tools(memory)
agent = Agent(
model="openai:gpt-4o-mini",
system_prompt="""You are a helpful assistant with persistent memory.
Use memory tools to recall past conversations and preferences.
Record your reasoning traces for auditability.""",
tools=tools
)This creates a Pydantic AI agent with all 19 memory tools registered. When the agent runs, it can call any of these tools to store and retrieve memory as part of its reasoning process.
Using the record_agent_trace context manager
For automatic trace recording, wrap your agent run with record_agent_trace():
from neo4j_agent_memory import record_agent_trace
async with MemoryClient(settings) as memory:
session = await memory.add_session("user_123")
async with record_agent_trace(memory, session_id=session.id, task="Answer user question"):
result = await agent.run("What can you tell me about Jessica Norris?")
print(result.data)When you use create_memory_tools(), the tools are closures that already hold a reference to memory. There is no need to pass deps to agent.run() — the tools handle memory access internally.
Every tool call the agent makes inside the record_agent_trace block is automatically captured as a ToolCall node in Neo4j, linked to the current ReasoningTrace.
Understanding what gets written to Neo4j
After one agent run, the following nodes will exist in your database:
-
One
Conversation+ one or moreMessagenodes (short-term) -
Any extracted entities as
EntityPerson,EntityOrganization, etc. (long-term) -
One
ReasoningTracelinked from the triggeringMessage -
One
ReasoningStepper reasoning iteration -
One
ToolCallper tool the agent invoked, with full parameters and results
Using the low-level reasoning API
record_agent_trace() is a convenience wrapper around the four low-level methods. Use the low-level API when you need manual control — for example, when integrating with a framework other than Pydantic AI, or when you want to record a trace for a non-agent workflow:
from neo4j_agent_memory import MemoryClient, MemorySettings, record_agent_trace
from neo4j_agent_memory.config import Neo4jConfig
async with MemoryClient(settings) as memory:
session = await memory.add_session("user_123")
# 1. Start a trace — creates the ReasoningTrace node
trace = await memory.reasoning.start_trace(
task="Evaluate credit limit for Jessica Norris",
session_id=session.id
)
# 2. Record a reasoning step
step = await memory.reasoning.add_step(
trace_id=trace.id,
thought="Retrieving customer entity from long-term memory",
action="search_entities"
)
# 3. Record a tool call within the step
await memory.reasoning.record_tool_call(
trace_id=trace.id,
step_id=step.id,
tool_name="search_entities",
parameters={"query": "Jessica Norris", "limit": 5},
result={"entities": ["Jessica Norris (EntityPerson)"]},
duration_ms=42
)
# 4. Complete the trace with an outcome
await memory.reasoning.complete_trace(
trace_id=trace.id,
outcome="success",
result={"decision": "Approved — risk score within threshold"}
)start_trace() returns a trace object whose id you pass to subsequent calls. record_agent_trace() calls all four of these automatically, wrapping your agent run so every tool call becomes a ToolCall node without any extra code.
Check your understanding
Starting a Reasoning Trace
Which neo4j-agent-memory method starts recording a new reasoning trace?
-
❏
memory.add_session() -
❏
memory.reasoning.record_step() -
✓
memory.reasoning.start_trace() -
❏
memory.long_term.add_entity()
Hint
Reasoning traces are recorded using the memory.reasoning.* namespace. A trace must be started before steps can be recorded inside it.
Solution
The correct answer is memory.reasoning.start_trace().
memory.reasoning.start_trace() creates the ReasoningTrace node in Neo4j and returns a trace object whose ID you pass to subsequent calls. memory.reasoning.record_step() records individual steps within an already-started trace — it cannot create a new trace. memory.add_session() creates short-term memory sessions. memory.long_term.add_entity() stores long-term memory entities.
Memory Tools Count
How many ready-to-use agent tools does create_memory_tools() return when integrating neo4j-agent-memory with Pydantic AI?
-
❏ 3
-
❏ 8
-
✓ 19
-
❏ 10
Hint
create_memory_tools() exposes the full Memory API surface — session management, entity operations, preference storage, trace recording, and similarity search.
Solution
create_memory_tools() returns 19 ready-to-use Pydantic AI agent tools, exposing all three memory types (short-term, long-term, and reasoning) as named tools the agent can call. This covers the complete Memory API surface across session management, entity operations, preference storage, trace recording, and similarity search.
Summary
In this lesson, you learned the key integration components:
-
create_memory_tools()— returns 19 Pydantic AI tools that expose all three memory types to the agent -
record_agent_trace()— a context manager that automatically captures every tool call as aToolCallnode in Neo4j -
Single agent run — after one run, all three memory layers are populated and cross-linked in Neo4j
In the next lesson, you will query the reasoning trace to understand what the agent did and why.