Build With Abdallah logo Build With Abdallah Software · AI · Automation
Tutorial 6 min read Jun 05, 2026

Building AI Agents in Python with Pydantic AI

A
Abdallah Mohamed
Senior Full-Stack Engineer
Building AI Agents in Python with Pydantic AI

Building AI Agents in Python with Pydantic AI

In the rapidly evolving landscape of artificial intelligence, creating AI agents that are both efficient and reliable is crucial. Pydantic AI, a library that extends the capabilities of Pydantic, offers a structured approach to building AI agents by providing data validation and settings management. This tutorial guides you through building AI agents using Pydantic AI, focusing on creating robust, maintainable, and scalable Python projects.

Prerequisites

Before diving into the project, ensure you have the following software installed on your system:

  • Python 3.8 or higher
  • pip (Python package installer)

You can install Python and pip using the following commands:

For Ubuntu/Debian-based systems:

sudo apt update
sudo apt install python3 python3-pip

For macOS:

brew update
brew install python

For Windows:

Download and install Python from python.org.

Once Python is installed, you can install the required Python packages using pip:

pip install pydantic pydantic-ai

Project Structure

Before we start coding, let's set up our project structure. This will help keep the project organized and maintainable.

pydantic_ai_agent/
│
├── agent/
│   ├── __init__.py
│   ├── base.py
│   └── simple_agent.py
│
├── tests/
│   ├── __init__.py
│   └── test_simple_agent.py
│
└── main.py

Step 1: Setting Up the Base Agent Class

We'll start by creating a base class for our AI agents. This class will define the basic structure and common functionalities for all agents.

Create a file named base.py inside the agent directory:

# agent/base.py

from pydantic import BaseModel

class BaseAgent(BaseModel):
    name: str
    version: str

    def perform_task(self):
        raise NotImplementedError("Subclasses should implement this method.")

Explanation:

The BaseAgent class extends BaseModel from Pydantic, allowing us to define data models with type validation. The perform_task method is a placeholder that we expect all subclasses to implement.

Step 2: Implementing a Simple AI Agent

Next, we'll implement a simple AI agent that inherits from BaseAgent. This agent will perform a basic task, such as greeting a user.

Create a file named simple_agent.py inside the agent directory:

# agent/simple_agent.py

from .base import BaseAgent

class SimpleAgent(BaseAgent):
    def perform_task(self):
        return f"Hello, I am {self.name}, version {self.version}."

Explanation:

The SimpleAgent class inherits from BaseAgent and implements the perform_task method. This method returns a simple greeting message that includes the agent's name and version.

Step 3: Running the Simple AI Agent

Now that we have our simple AI agent, let's run it. We'll create a main.py file to serve as the entry point for our application.

Create the main.py file at the root level of the project:

# main.py

from agent.simple_agent import SimpleAgent

def main():
    agent = SimpleAgent(name="SimpleAI", version="1.0")
    print(agent.perform_task())

if __name__ == "__main__":
    main()

Explanation:

In main.py, we import the SimpleAgent class and create an instance of it. We then call the perform_task method and print its result. This setup allows us to easily run and test our agent.

To execute the program, run the following command in your terminal:

python main.py

You should see the output:

Hello, I am SimpleAI, version 1.0.

This demonstrates a basic AI agent using Pydantic AI for structured data validation and management. In the next steps, we'll expand on this foundation to build more complex agents.


```markdown
## Step 4: Adding Configuration Management

To enhance our AI agent, we'll introduce configuration management. This allows our agent to be more flexible and customizable without changing the code. We'll use Pydantic's settings management capabilities.

Create a `config.py` file in the root directory:

```python
# config.py

from pydantic import BaseSettings

class AgentConfig(BaseSettings):
    name: str = "ConfigurableAI"
    version: str = "2.0"
    greeting: str = "Hello"

    class Config:
        env_prefix = 'AGENT_'

Explanation:

The AgentConfig class extends BaseSettings, which allows configuration via environment variables. The env_prefix option means that any environment variable prefixed with AGENT_ will be used to override the default values.

Step 5: Integrating Configuration with the Agent

Now, let's modify our SimpleAgent to use the configuration settings.

Update the simple_agent.py file:

# agent/simple_agent.py

from .base import BaseAgent
from config import AgentConfig

class SimpleAgent(BaseAgent):
    def __init__(self, config: AgentConfig):
        super().__init__(name=config.name, version=config.version)
        self.greeting = config.greeting

    def perform_task(self):
        return f"{self.greeting}, I am {self.name}, version {self.version}."

Explanation:

The SimpleAgent now takes an AgentConfig instance as a parameter, allowing it to use configurable settings for its name, version, and greeting.

Step 6: Updating the Main Entry Point

Finally, update main.py to use the new configuration system.

Update the main.py file:

# main.py

from agent.simple_agent import SimpleAgent
from config import AgentConfig

def main():
    config = AgentConfig()
    agent = SimpleAgent(config=config)
    print(agent.perform_task())

if __name__ == "__main__":
    main()

Explanation:

In main.py, we instantiate AgentConfig and pass it to SimpleAgent. This allows the agent to be configured via environment variables if needed.

Complete Working Example

Here's the complete code for the project:

agent/base.py

from pydantic import BaseModel

class BaseAgent(BaseModel):
    name: str
    version: str

    def perform_task(self):
        raise NotImplementedError("Subclasses should implement this method.")

agent/simple_agent.py

from .base import BaseAgent
from config import AgentConfig

class SimpleAgent(BaseAgent):
    def __init__(self, config: AgentConfig):
        super().__init__(name=config.name, version=config.version)
        self.greeting = config.greeting

    def perform_task(self):
        return f"{self.greeting}, I am {self.name}, version {self.version}."

config.py

from pydantic import BaseSettings

class AgentConfig(BaseSettings):
    name: str = "ConfigurableAI"
    version: str = "2.0"
    greeting: str = "Hello"

    class Config:
        env_prefix = 'AGENT_'

main.py

from agent.simple_agent import SimpleAgent
from config import AgentConfig

def main():
    config = AgentConfig()
    agent = SimpleAgent(config=config)
    print(agent.perform_task())

if __name__ == "__main__":
    main()

Common Errors and Fixes

  1. ModuleNotFoundError: No module named 'agent'

    • Fix: Ensure that the PYTHONPATH includes the root directory of your project. You can set it temporarily in your terminal with export PYTHONPATH=$(pwd).
  2. ValidationError: field required

    • Fix: Ensure all required environment variables are set if you are using them to override defaults. Check your .env file or environment settings.
  3. TypeError: init() missing 1 required positional argument: 'config'

    • Fix: Ensure you pass an AgentConfig instance when initializing SimpleAgent.

Conclusion

In this tutorial, we developed a basic AI agent using Pydantic AI, focusing on data validation and configuration management. This structured approach makes our AI agents more maintainable and adaptable to different environments.

Sources