Skip to main content

On This Page

Mastering PydanticAI: Add Functional Tools and Dependencies in 10 Minutes

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

How to Add Tools to a PydanticAI Agent in 10 Min

PydanticAI enables developers to register Python functions as LLM tools using a single decorator. This system allows agents to move beyond text generation to execute real-world tasks like querying APIs and databases with validated schemas.

Why This Matters

Traditional LLM agents often struggle with data reliability and “hallucinations” when interacting with external systems. PydanticAI solves this by using Pydantic models to force the LLM into returning structured, typed data, while its dependency injection system ensures that tools remain testable and decoupled from global application state.

Key Insights

  • The @agent.tool decorator uses Python docstrings as the primary mechanism for the LLM to understand when and how to invoke a specific tool (Nebula, 2026).
  • RunContext provides a type-safe mechanism for dependency injection, allowing tools to access shared resources like httpx.Client without relying on singletons.
  • PydanticAI agents can automatically chain multiple tool calls, such as using get_coordinates output as input for get_weather without manual orchestration logic.
  • Defining an output_type with a Pydantic BaseModel ensures the final agent response is a validated Python object, eliminating the need for manual JSON parsing.
  • Type hints in tool signatures drive the underlying JSON schema used by the LLM, providing automatic validation of arguments before function execution.

Working Examples

A complete PydanticAI agent with geocoding and weather tools using dependency injection.

import httpx
from dataclasses import dataclass
from pydantic import BaseModel
from pydantic_ai import Agent, RunContext

@dataclass
class Deps:
    http_client: httpx.Client

class CityWeather(BaseModel):
    city: str
    temperature_f: float
    summary: str
    recommendation: str

agent = Agent(
    "openai:gpt-4o-mini",
    deps_type=Deps,
    output_type=CityWeather,
    instructions="You help users check weather conditions. Use the tools provided to fetch real data before answering.",
)

@agent.tool
def get_coordinates(ctx: RunContext[Deps], city: str) -> str:
    """Get latitude and longitude for a city."""
    response = ctx.deps.http_client.get(
        "https://geocoding-api.open-meteo.com/v1/search",
        params={"name": city, "count": 1},
    )
    data = response.json()
    if not data.get("results"):
        return f"City '{city}' not found."
    result = data["results"][0]
    return f"{result['name']}: lat={result['latitude']}, lon={result['longitude']}"

@agent.tool
def get_weather(ctx: RunContext[Deps], latitude: float, longitude: float) -> str:
    """Get current weather for coordinates."""
    response = ctx.deps.http_client.get(
        "https://api.open-meteo.com/v1/forecast",
        params={
            "latitude": latitude,
            "longitude": longitude,
            "current": "temperature_2m,wind_speed_10m",
            "temperature_unit": "fahrenheit",
        },
    )
    data = response.json()["current"]
    return f"Temperature: {data['temperature_2m']}F, Wind: {data['wind_speed_10m']} km/h"

result = agent.run_sync(
    "What's the weather like in Tokyo?",
    deps=Deps(http_client=httpx.Client()),
)
print(result.output.city)
print(f"{result.output.temperature_f}F")

Practical Applications

  • Use case: Building a weather agent that sequences geocoding and forecast API calls automatically based on natural language input. Pitfall: Vague docstrings causing the LLM to skip necessary steps or provide incorrect parameters.
  • Use case: Implementing testable infrastructure by passing mock HTTP clients through Deps dataclasses. Pitfall: Hardcoding API clients inside tool functions, making unit testing and environment swapping impossible.
  • Use case: Forcing structured responses for downstream services using Pydantic models. Pitfall: Failing to provide clear instructions, leading to validation errors if the LLM cannot satisfy the schema.

References:

Continue reading

Next article

Build Production-Ready No-Code AI Pipelines with n8n and GPT-4o-mini

Related Content