Tu primer agente IA con PydanticAI
Creá tu primer agente IA con PydanticAI en Python. Tutorial paso a paso con structured outputs, tool calling y código funcional.

Si alguna vez quisiste crear un agente de inteligencia artificial en Python pero te pareció que las herramientas eran demasiado complicadas o estaban llenas de abstracciones innecesarias, PydanticAI va a ser tu nuevo framework favorito. Es simple, tipado, y construido por el mismo equipo detrás de Pydantic — la librería de validación que ya usa el 90% del ecosistema Python moderno.
En este tutorial vas a construir un agente IA con PydanticAI que analiza textos y devuelve respuestas estructuradas (structured outputs) usando herramientas personalizadas (tool calling). Todo en menos de 150 líneas de Python, sin magia negra, con tipos estrictos de punta a punta.
Este tutorial es para vos si sabés lo básico de Python y querés dar tu primer paso en el mundo de los agentes de IA. No necesitás experiencia previa con LLMs ni frameworks de agentes.
Requisitos previos:
- Python 3.12 o superior
- API key de OpenAI (obtené la tuya acá) — PydanticAI también soporta Anthropic y Gemini
- Conocimientos básicos de Python (funciones, clases, async/await)
uvinstalado como gestor de paquetes (instalación)
Instalación y configuración del proyecto
Primero, cloná el repositorio de tutoriales de khoal.ai y navegá hasta este tutorial:
git clone https://github.com/khoalai/khoal-ai-tutorials.git
cd khoal-ai-tutorials/tutorials/01-pydanticai-first-agentInstalá las dependencias con uv:
uv syncEsto instala pydantic-ai y python-dotenv automáticamente. Ahora configurá tu API key:
cp ../../.env.example .envAbrí el archivo .env y reemplazá el placeholder con tu clave real de OpenAI:
OPENAI_API_KEY=sk-tu-clave-real-aquiNunca commitees tu archivo .env. Ya está incluido en .gitignore, pero siempre verificá antes de hacer push. Las API keys expuestas pueden generar costos inesperados en tu cuenta.
PydanticAI es model-agnostic: si preferís usar Anthropic o Gemini, simplemente cambiá el modelo en el código y usá la API key correspondiente. Vamos a usar gpt-4o-mini porque es económico y rápido — ideal para experimentar sin gastar de más.
Definir la estructura de respuesta (Structured Output)
La gran ventaja de PydanticAI es que le podés decir al agente exactamente qué forma debe tener su respuesta. En lugar de recibir texto libre y rezar para que el formato sea correcto, definís un modelo Pydantic y el framework se encarga del resto.
from pydantic import BaseModel, Field
class AnalisisTexto(BaseModel):
"""Estructura para el análisis de un texto."""
resumen: str = Field(description="Resumen conciso del texto en 1-2 oraciones")
idioma: str = Field(description="Idioma detectado del texto")
sentimiento: str = Field(description="Sentimiento general: positivo, negativo o neutro")
temas: list[str] = Field(description="Lista de temas principales identificados")
cantidad_palabras: int = Field(description="Cantidad aproximada de palabras en el texto")Cada campo usa Field(description=...) para que el LLM entienda qué se espera. Esto funciona como documentación para la IA — cuanto más claro seas en las descripciones, mejores resultados vas a obtener.
Los structured outputs eliminan la necesidad de parsear texto libre con regex o hacks similares. PydanticAI valida automáticamente que la respuesta del LLM cumpla con tu esquema, y reintenta si no lo hace.
Crear el agente con dependencias
Ahora creamos el agente. En PydanticAI, un agente combina tres cosas: un modelo de IA, un prompt del sistema, y opcionalmente un tipo de resultado estructurado.
Primero, definimos las dependencias — datos de contexto que el agente y sus herramientas pueden compartir:
from dataclasses import dataclass
@dataclass
class DependenciasAgente:
"""Contexto compartido entre el agente y sus herramientas."""
nombre_usuario: str
modo_detallado: bool = FalseLuego creamos el agente propiamente dicho:
from pydantic_ai import Agent
agente_analista = Agent(
model="openai:gpt-4o-mini",
result_type=AnalisisTexto,
system_prompt=(
"Sos un analista de textos experto. Tu trabajo es analizar textos "
"y devolver un análisis estructurado con resumen, idioma, sentimiento, "
"temas principales y cantidad de palabras. "
"Respondé siempre en español."
),
deps_type=DependenciasAgente,
)Fijate que con result_type=AnalisisTexto le estamos diciendo al agente que su respuesta siempre debe ser un objeto AnalisisTexto válido. Si el LLM devuelve algo que no matchea el esquema, PydanticAI lo reintenta automáticamente.
Agregar herramientas (Tool Calling)
Las herramientas (tools) son funciones Python que el agente puede decidir usar durante su razonamiento. Vos las definís, y el LLM elige cuándo llamarlas.
from pydantic_ai import RunContext
@agente_analista.tool
async def contar_caracteres(ctx: RunContext[DependenciasAgente], texto: str) -> str:
"""Cuenta los caracteres de un texto (sin espacios y con espacios)."""
sin_espacios = len(texto.replace(" ", ""))
con_espacios = len(texto)
resultado = (
f"📊 Caracteres con espacios: {con_espacios}\n"
f"📊 Caracteres sin espacios: {sin_espacios}"
)
# Accedemos a las dependencias a través del contexto
if ctx.deps.modo_detallado:
resultado += f"\n📊 Espacios: {con_espacios - sin_espacios}"
return resultadoPuntos clave del tool calling en PydanticAI:
- El decorador
@agente_analista.toolregistra la función como herramienta disponible. - El docstring de la función es lo que el LLM lee para decidir si usarla — escribilo de forma clara y descriptiva.
- El primer argumento
ctx: RunContext[DependenciasAgente]te da acceso a las dependencias que configuraste. - El agente decide autónomamente si la herramienta le sirve para la tarea actual.
El tool calling es lo que diferencia a un agente de un simple chatbot. Un chatbot solo genera texto; un agente puede ejecutar acciones reales — consultar bases de datos, llamar APIs, hacer cálculos, lo que necesites.
Ejecutar el agente y ver los resultados
Finalmente, ejecutamos el agente con asyncio:
async def main() -> None:
texto = (
"La inteligencia artificial generativa sigue revolucionando "
"la industria del software. Empresas de todo el mundo están "
"adoptando modelos de lenguaje para automatizar tareas."
)
deps = DependenciasAgente(nombre_usuario="Developer", modo_detallado=True)
resultado = await agente_analista.run(
f"Analizá el siguiente texto:\n\n{texto}",
deps=deps,
)
# resultado.data es un AnalisisTexto tipado ✨
analisis = resultado.data
print(f"📋 Resumen: {analisis.resumen}")
print(f"🌐 Idioma: {analisis.idioma}")
print(f"💭 Sentimiento: {analisis.sentimiento}")
print(f"🏷️ Temas: {', '.join(analisis.temas)}")
print(f"📏 Palabras: ~{analisis.cantidad_palabras}")
asyncio.run(main())Ejecutá el programa:
uv run python main.pyDeberías ver algo como esto:
══════════════════════════════════════════════════════════
🐨 khoal.ai — Tu primer agente IA con PydanticAI
══════════════════════════════════════════════════════════
──────────────────────────────────────────────────────────
📝 Ejemplo 1: Noticia tecnológica
──────────────────────────────────────────────────────────
📋 Resumen: La IA generativa está transformando la industria del software...
🌐 Idioma: Español
💭 Sentimiento: Positivo
🏷️ Temas: IA generativa, software, Latinoamérica, open source
📏 Palabras: ~52
✅ ¡Análisis completado![IMAGEN: Captura de terminal mostrando la salida completa del programa con los dos análisis de texto, emoji y colores de terminal]
Los resultados exactos pueden variar entre ejecuciones porque los LLMs son probabilísticos. El resumen y los temas pueden cambiar ligeramente, pero la estructura siempre será la misma gracias al structured output.
💡 Por qué importa
PydanticAI resuelve un problema real que tenemos los desarrolladores Python: construir agentes de IA con seguridad de tipos y sin las capas de abstracción innecesarias que otros frameworks arrastran. Si ya usás Pydantic (y si trabajás con FastAPI, seguramente sí), PydanticAI se siente como una extensión natural de tu stack.
Los structured outputs cambian las reglas del juego. En lugar de recibir texto libre y rezar para que el modelo responda en el formato correcto, definís exactamente qué querés y PydanticAI se encarga de que el LLM cumpla. Esto es fundamental cuando estás construyendo aplicaciones reales donde necesitás datos consistentes para alimentar tu lógica de negocio.
Y el tool calling es la pieza que transforma a un LLM de un "generador de texto sofisticado" en un agente capaz de interactuar con el mundo real — consultar APIs, buscar en bases de datos, ejecutar código. El patrón que aprendiste en este tutorial es el mismo que vas a usar para construir agentes más complejos.
Próximos pasos
Ahora que tenés tu primer agente funcionando, podés:
- Cambiar de modelo: Probá con
anthropic:claude-sonnet-4-20250514ogoogle-gla:gemini-2.0-flash— solo cambiá una línea. - Agregar más herramientas: Conectá tu agente a APIs externas, bases de datos, o servicios de búsqueda.
- Encadenar agentes: Usá la salida de un agente como entrada de otro para crear flujos más complejos.
Encontrá el código completo de este y todos los tutoriales en el repositorio de GitHub.
Lo que nos encantó
- ●Type-safe de punta a punta con Pydantic
- ●Model-agnostic: OpenAI, Anthropic, Gemini con un solo cambio
- ●Tool calling integrado con decoradores simples
- ●Validación y reintentos automáticos de structured outputs
Lo que debe mejorar
- ●Framework relativamente nuevo — comunidad aún en crecimiento
- ●Documentación en inglés solamente por ahora