Type safety helps teams refactor AI applications and lets coding agents check more of their own work.
2
PydanticAI can return validation errors to a model, allowing it to correct structured output and try again.
3
Pydantic Logfire traces agent runs, tool calls, model calls, timings, and pricing so failures can be inspected.
Summary
Samuel Colvin explains how PydanticAI uses typed models, validation, and observability when building AI applications. He argues that type safety matters because AI applications change shape repeatedly, and static checking makes those refactors safer. A simple extraction task returns a typed Pydantic model, while a validation error can be sent back to the model so it corrects its answer. He then shows how generic types provide checked output values and typed dependencies for tools. The final example uses tools for recording and retrieving memories. It fails because the retrieval query does not match the stored text, and Logfire makes the cause visible by showing the tool arguments and results. The talk gives a practical view of agent loops, including how validation and final-result tools determine when a run ends. It also shows why tracing is useful when an apparently simple tool interaction goes wrong.
Reliable AI applications still need ordinary software discipline
Colvin says teams still want reliable, scalable applications, and GenAI can make that harder. He recommends techniques that let developers build quickly with more safety. Type safety matters during development because nobody knows the final shape of an AI application at the start. Applications will be refactored several times. A type-safe framework lets those changes happen with more confidence. Colvin also says a coding agent such as Cursor can run type checking to check its own work. He contrasts this with LangChain and LangGraph, which he says did not build around type safety.
An agent is a loop that updates state through tools
Colvin describes an agent as having an environment, tools that can access it, and a system prompt that describes the task. The model is called in a loop. It returns actions, the tools run, the environment state changes, and the model is called again. He points out that a short definition of this loop has a bug because it has no exit. An implementation needs a way to decide when the run is complete. Possible exits include plain text from the model, a final-result tool, or structured output from models such as those from OpenAI and Google.
Validation errors can give the model a useful second attempt
A basic PydanticAI example extracts a person from unstructured text into a typed model. Colvin then adds a validator requiring the date of birth to be before 1900. The input leads the model to produce 1987, which fails validation. PydanticAI sends the validation error back to the model with a request to try again. The model uses that information and returns the corrected date. Colvin says this is effective for simple cases where even capable models do not initially satisfy the application's validation rules. A docstring could also explain that the field must use a year from the 19th century.
Typed outputs are checked both by the type checker and at runtime
The agent's output type is generic, with Person used in the example. Accessing result.output therefore gives developers a value typed as Person, and Pydantic validation guarantees that the runtime value is actually a Person instance. Accessing a valid field such as first name works. Accessing an incorrect field produces an error from the typing system. Colvin presents this as an early example of the value of static typing in an AI application, where output shapes can otherwise be uncertain.
Tool dependencies can carry their own checked types
PydanticAI also makes the dependencies passed into tools generic. Colvin demonstrates an agent with tools for recording and retrieving long-term memories. The agent declares a dependency type, and each tool receives a run context parameterized with that type. The context's dependencies and their attributes therefore have known types. Changing a dependency field from one type to another produces a typing error where the old type is used. Running the agent also requires a dependency object of the declared type. Colvin says this takes work from both the framework authors and users, but makes refactoring easier.
In the memory example, one run records that the user's name is Samuel. A later retrieval call asks for "your name," which does not occur as a substring of the stored text, so the tool fails. Logfire shows the tool name, arguments, and returned results, making the mismatch visible. On another run, the query is "name," which is a substring of "user's name is Samuel," so retrieval succeeds. The example shows how examining the actual tool arguments can explain a failure that would otherwise look like an agent problem.
Colvin says Logfire provides tracing information for the calls in an agent run. Developers can see how long each call took, along with pricing for individual spans and for the whole trace. In the earlier extraction example, the trace showed two Gemini Flash calls, including the initial invalid result, the validation error, and the corrected final result. In the memory example, the trace exposed the difference between the failed and successful retrieval queries.
"If you build your application in a type safe way, if you use frameworks that allow it to be type safe, you can refactor it with confidence much more quickly."01:11
Who should watch
You are building an AI application whose output schema and tool interfaces keep changing, and you want refactors checked by the type system.
Your agent returns structured data that sometimes fails validation, and you want the model to receive the error and retry.
You are debugging tool calls or model runs and need to inspect arguments, timings, pricing, and trace history.