.agents/skills/building-pydantic-ai-agents/references/AGENTS-CORE.md
Read this file when the user needs the core Agent workflow: creating agents, choosing output types, using dependencies, defining specs, selecting models, or choosing how to run/stream an agent.
from pydantic_ai import Agent
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Be concise, reply with one sentence.',
)
result = agent.run_sync('Where does "hello world" come from?')
print(result.output)
Use output_type=MyModel when the model should return validated structured data.
from pydantic import BaseModel
from pydantic_ai import Agent
class CityLocation(BaseModel):
city: str
country: str
agent = Agent('google-gla:gemini-3-flash-preview', output_type=CityLocation)
result = agent.run_sync('Where were the olympics held in 2012?')
print(result.output)
If the user is choosing between output modes:
output_type=str for plain textoutput_type=MyModel for structured outputTextOutput for custom text parsingNativeOutput or ToolOutput when they need explicit output-mode controlUse deps_type=... plus RunContext[...] when tools or instructions need app state.
from pydantic_ai import Agent, RunContext
agent = Agent('openai:gpt-5.2', deps_type=str)
@agent.instructions
def add_user_name(ctx: RunContext[str]) -> str:
return f"The user's name is {ctx.deps}."
Use @agent.tool when the tool needs RunContext. Use @agent.tool_plain when it does not.
Use YAML or JSON specs when configuration should live outside Python code.
model: anthropic:claude-opus-4-6
instructions: "You are helping {{user_name}} with research."
capabilities:
- WebSearch
- Thinking:
effort: high
from dataclasses import dataclass
from pydantic_ai import Agent
@dataclass
class UserContext:
user_name: str
agent = Agent.from_file('agent.yaml', deps_type=UserContext)
result = agent.run_sync('Find recent papers on AI safety', deps=UserContext(user_name='Alice'))
Template strings are part of the spec flow, so route template-string questions here too.
Model strings use the "provider:model-name" format.
Examples:
openai:gpt-5.2anthropic:claude-sonnet-4-6google-gla:gemini-3-pro-previewUse a model instance instead of a string when the user needs provider-specific constructor arguments.
Pick a run method based on the interaction pattern:
run() for async runs that complete normallyrun_sync() for synchronous scripts and notebooksrun_stream() for streaming final outputrun_stream_sync() for sync streamingrun_stream_events() when the caller needs the typed event stream directlyiter() when the caller needs step-by-step control over the agent loopUse event_stream_handler= with run() or run_stream() when the user wants progress updates without manually consuming the event stream:
from collections.abc import AsyncIterable
from pydantic_ai import Agent, AgentStreamEvent, FunctionToolCallEvent, RunContext
agent = Agent('openai:gpt-5.2')
async def stream_handler(ctx: RunContext[None], events: AsyncIterable[AgentStreamEvent]):
async for event in events:
if isinstance(event, FunctionToolCallEvent):
print(f'Calling {event.part.tool_name}...')
async def main():
await agent.run('Do the task', event_stream_handler=stream_handler)
Use FallbackModel when the user wants automatic provider or model failover.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.models.fallback import FallbackModel
from pydantic_ai.models.openai import OpenAIChatModel
fallback = FallbackModel(
OpenAIChatModel('gpt-5.2'),
AnthropicModel('claude-sonnet-4-6'),
)
agent = Agent(fallback)
Good defaults: