Using Pydantic AI to build a ReAct agent

til
llm
pydantic-ai
agents
Author
Affiliation
Published

July 4, 2025

Modified

July 4, 2025

I wanted to get more familiar with Pydantic AI, so I decided to build a ReAct agent with multiple tools.

After a first failed attempt, I realized that Pydantic AI uses asyncio under the hood, so you need to enable nest_asyncio to use it in a notebook.

Setup

import nest_asyncio

nest_asyncio.apply()

Then, I did the imports as usual. I hadn’t used logfire for monitoring LLM applications before, so I thought it’d be a good idea to try it out.

import os
from typing import Literal

import logfire
import requests
from dotenv import load_dotenv
from pydantic_ai import Agent

load_dotenv()

PydanticAI instrumentation uses OpenTelemetry (OTel). So it’s pretty straightforward to use it with Logfire or with any other OTel-compatible observability tool.

You just need to create a project in Logfire, generate a Write token and add it to the .env file. Then, you just need to run:

logfire.configure(
    token=os.getenv('LOGFIRE_TOKEN'),
)
logfire.instrument_pydantic_ai()

This will ask you to select a project the first time you run it. It will generate a logfire_credentials.json file in your working directory. In following runs, it will automatically use the credentials from the file.

ReAct Agent

I decided to make an agent that had access to a tool to get the weather and another one that checks if the response that’s going to be sent to the user follows the company guidelines.

Here’s thee code:

from pydantic import BaseModel

class Feedback(BaseModel):
    feedback: str
    status: Literal['OK', 'REQUIRES FIXING']

evaluator_agent = Agent(
    'openai:gpt-4.1-mini',
    system_prompt=(
        "You're a helpful assistant. Your task is to check if a given response follows the company guidelines. The company guidelines are that responses should be written in the style of a haiku. You should reply with 'OK' or 'REQUIRES FIXING' and a short explanation."
    ),
    output_type=Feedback,
)

react_agent = Agent(  
    'openai:gpt-4.1-mini',
    system_prompt=(
        "You're a helpful assistant. Use the tools provided when relevant. Then draft a response and check if it follows the company guidelines. Only respond to the user after you've validated and modified the response if needed."
    ),
)


@react_agent.tool_plain
def get_weather(latitude: float, longitude: float) -> str:
    """Get the weather of a given latitude and longitude"""
    response = requests.get(
        f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m"
    )
    data = response.json()
    return str(data["current"]["temperature_2m"])


@react_agent.tool_plain
def check_guidelines(drafted_response: str) -> str:
    """Check if a given response follows the company guidelines"""
    response = evaluator_agent.run_sync(drafted_response)
    return response.output


response = react_agent.run_sync("What is the temperature in Madrid?")
18:57:42.206 react_agent run
18:57:42.208   chat gpt-4.1-mini
18:57:43.191   running 1 tool
18:57:43.192     running tool: get_weather
18:57:43.408   chat gpt-4.1-mini
18:57:44.117   running 1 tool
18:57:44.118     running tool: check_guidelines
18:57:44.120       evaluator_agent run
18:57:44.120         chat gpt-4.1-mini
18:57:46.291   chat gpt-4.1-mini

And here’s the output:

print(response.output)
In Madrid sunshine,
Temperature climbs so high,
Thirty-four degrees.

The output in Logfire looks like typical observability tools:

Figure 1: Traces in Logfire

That’s all!

You can access this notebook here.

Citation

BibTeX citation:
@online{castillo2025,
  author = {Castillo, Dylan},
  title = {Using {Pydantic} {AI} to Build a {ReAct} Agent},
  date = {2025-07-04},
  url = {https://dylancastillo.co/til/react-agent-pydantic-ai.html},
  langid = {en}
}
For attribution, please cite this work as:
Castillo, Dylan. 2025. “Using Pydantic AI to Build a ReAct Agent.” July 4, 2025. https://dylancastillo.co/til/react-agent-pydantic-ai.html.