Install
pydantic-ai-slim 2.0 to 3.0. 2.0 removed Agent(instrument=...) and introduced the capability protocol this adapter is built on, so 1.x cannot be instrumented this way.
Instrument
root_capability, so there is
no agent.capabilities attribute to read.
Agents built while instrumented keep the capability, so you can uninstrument() and re-instrument without rebuilding them.
What gets recorded
There is no hook pair and no human-in-the-loop pair here. Pydantic AI has no node or step boundary to bracket and no built-in human pause, so there is nothing to map. If you build either, emit the events yourself — see Custom agents.
output_type makes no difference to the trace. A typed run and a string run produce the same events.
Example
restock_eta appears as a tool_result carrying an error, followed by another model call where the agent works around it, and the run still ends success. Both facts are kept.
Errors, retries, and control flow
Pydantic AI raises exceptions for three different things, and the adapter separates them:ModelRetry is in the first group deliberately. It means an attempt genuinely failed and the model was asked to try again, which is what a tool span’s error field is for. Classifying it as control flow would hide real tool failures behind a green run.
Name your spans
Pydantic AI’s own run span is namedagent. Wrap the call to give it a label you chose:
inventory, and that is where the model and tool events hang.
Keep agent_id low cardinality. It is the primary facet on every dashboard surface, so use a role name, never a UUID or per-run string.
Control the session
Resolved in this order, first match winning:instrument("pydantic_ai", session_id=...)- The enclosing
failproofai_sdk.session()scope - The run’s
conversation_id, then itsrun_id - A generated
uuid4().hex
Options
Common problems
The run works but no events appear
The run works but no events appear
The
Agent was constructed before instrument() ran. See the warning above, and check agent.root_capability.capabilities.A plain exception in a tool kills the run
A plain exception in a tool kills the run
A bare
raise propagates; that is Pydantic AI’s design. To let the model work around it, raise ModelRetry with a message it can act on. The failure is recorded either way.There is a nested agent span I did not create
There is a nested agent span I did not create
That child is Pydantic AI’s own run span, and it is where the model and tool events hang. Drop your own scope if you want a single span, at the cost of the custom name.
Tracebacks start with a truncation marker
Tracebacks start with a truncation marker
Pydantic AI’s async graph stack is longer than the payload field limit, and a traceback’s last line is the exception itself. This field is trimmed from the front rather than the back, so the line you need survives.
Next
How it works
Pairs, ids, session lifecycle, and delivery.
Read a trace
Follow causality through the session you just captured.
Other frameworks
LangGraph, CrewAI, LlamaIndex, and custom agents.

