No history yet

Agent Configuration

Configuring Your First Agent

The core of PydanticAI is the Agent class. It's the central point for configuring how you interact with a Large Language Model (LLM). Since you're familiar with Pydantic and Python's typing, you'll find the design intuitive. It's a generic class, which gives you powerful type safety right out of the box.

Let's start by creating a simple agent. The only required argument is model, which specifies the LLM provider and the model you want to use. This is done using a simple string format: 'provider:model_name'.

from pydantic_ai import Agent

# Instantiate an agent using OpenAI's GPT-4o model
agent = Agent(model="openai:gpt-4o")

# Or using Anthropic's Claude 3.5 Sonnet
# agent = Agent(model="anthropic:claude-3-5-sonnet")

Generic Types for Safety

The Agent class is defined as Agent[DepsT, ResultT]. This generic structure is a key feature, allowing you to specify the types for dependencies and results.

  • DepsT: Represents any dependencies your agent needs to run, like a database connection or user session information. For now, we'll use None as we don't have any dependencies.
  • ResultT: Defines the expected return type of the agent's execution. This leverages Pydantic's parsing and validation, ensuring the LLM's output conforms to your desired structure.

By specifying these types, you get better editor support and static analysis, catching potential errors before you even run your code.

from pydantic_ai import Agent
from pydantic import BaseModel

class UserProfile(BaseModel):
    name: str
    email: str

# An agent that takes no dependencies and is expected to return a string.
string_agent = Agent[None, str](model="openai:gpt-4o")

# An agent that is expected to return a structured UserProfile object.
structured_agent = Agent[None, UserProfile](model="openai:gpt-4o")

Crafting System Prompts

The system prompt sets the context and instructions for the LLM. It defines the agent's persona, its goals, and any constraints it must follow. PydanticAI offers two ways to define it: statically or dynamically.

A static system prompt is a simple string provided during the agent's instantiation. This is perfect for when the agent's core instruction never changes.

agent = Agent(
    model="openai:gpt-4o",
    system_prompt="You are a helpful assistant that always responds in JSON.",
)

For more complex scenarios, you might need a prompt that changes based on runtime information. A dynamic system prompt is a function decorated with @agent.system_prompt. This function receives a RunContext object, which contains information available only at the time of execution, like dependencies or other metadata.

from pydantic_ai import Agent, RunContext

# An agent without a pre-defined system prompt
agent = Agent[str, str](model="openai:gpt-4o")

# Define the system prompt dynamically using a decorator
@agent.system_prompt
def dynamic_prompt(context: RunContext[str, str]) -> str:
    # Access the dependency (a username string in this case)
    username = context.dependency
    return f"You are a helpful assistant for the user '{username}'. Always be polite."

This approach allows you to inject user-specific details, session data, or any other contextual information directly into the system prompt for each run.

Running the Agent

Once your agent is configured, you can execute it. PydanticAI provides three methods for this:

  1. .run(): The standard asynchronous method.
  2. .run_sync(): A synchronous version for use in non-async code.
  3. .run_stream(): An async generator for streaming the response token by token.

Each method returns an AgentRunResult object.

import asyncio
from pydantic_ai import Agent

async def main():
    agent = Agent[None, str](
        model="openai:gpt-4o",
        system_prompt="You are a concise assistant.",
    )

    # Execute the agent asynchronously
    result = await agent.run("Explain the theory of relativity in one sentence.")

    print(result.data)

# Run the async main function
asyncio.run(main())

The AgentRunResult object is a container for all information related to a single execution. It has three main properties:

  • .data: The main result of the run, parsed into the ResultT type you specified. For our example, this is a str.
  • .usage: An object containing token usage information (e.g., input tokens, output tokens).
  • .all_messages: A complete list of all messages exchanged with the LLM during the run, including system, user, and assistant messages. This is useful for debugging.
Quiz Questions 1/4

What is the only required argument when initializing a PydanticAI Agent?

Quiz Questions 2/4

In the PydanticAI class definition Agent[DepsT, ResultT], what is the primary role of ResultT?

Now you have the foundational knowledge to configure and run a basic agent, control its behavior with system prompts, and handle its output with type safety.