En pocas palabras
Framework Python para construir agentes con dependencias explícitas, resultados tipados y evaluación.
Qué problema resuelve
Integraciones frágiles entre modelos, herramientas y lógica de aplicaciones.
Cuándo utilizarlo
Agentes Python. Ejemplo: un asistente que devuelve una propuesta validada de clasificación.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
En el Radar compartido: Trial (valoración de la edición aportada).
Cómo funciona
Utiliza Pydantic para expresar contratos de datos y ofrece integración de herramientas y observabilidad. Favorece composición en código con estado y dependencias delimitados.
Ejemplo de uso
Definir una salida con categoría, motivo y referencias; inyectar una consulta de catálogo de solo lectura. Comprobar campos y verificar que la categoría existe antes de usar el resultado.
Agente con dependencias y salida tipada
from dataclasses import dataclass
from typing import Literal
from pydantic import BaseModel, Field
from pydantic_ai import Agent, RunContext
@dataclass
class Deps:
catalogo: CatalogoProductos # servicio de solo lectura
cliente_id: str
class Clasificacion(BaseModel):
categoria: Literal["pagos", "solicitud", "reclamo", "otro"]
motivo: str = Field(description="Una frase que justifica la categoría")
producto_id: str | None = None
agente = Agent(
"anthropic:claude-sonnet-5-5",
deps_type=Deps,
output_type=Clasificacion,
instructions="Clasifica el mensaje del cliente. Usa la herramienta para identificar el producto.",
)
@agente.tool
async def buscar_producto(ctx: RunContext[Deps], nombre: str) -> list[dict]:
"""Busca productos del cliente por nombre aproximado."""
return await ctx.deps.catalogo.buscar(ctx.deps.cliente_id, nombre)
resultado = await agente.run("No me llegó el desembolso del crédito libre inversión",
deps=Deps(catalogo, "42"))
print(resultado.output) # Clasificacion(categoria='solicitud', …)
Si el modelo devuelve algo que no valida contra Clasificacion, Pydantic AI le reenvía el error para que lo corrija, con un límite de reintentos.
Probar sin llamar al modelo
from pydantic_ai.models.test import TestModel
def test_clasificacion_no_falla():
with agente.override(model=TestModel()):
r = agente.run_sync("hola", deps=Deps(catalogo_falso, "1"))
assert isinstance(r.output, Clasificacion)
TestModel genera respuestas válidas según el esquema y llama a las herramientas; FunctionModel permite definir respuestas concretas. Así se prueba la integración de forma determinista en CI.
Evaluaciones con pydantic-evals
from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import IsInstance
dataset = Dataset(
cases=[Case(name="desembolso", inputs="No me llegó el desembolso", expected_output="solicitud")],
evaluators=[IsInstance(type_name="Clasificacion")],
)
Los datasets combinan evaluadores deterministas y basados en LLM, y los informes comparan versiones del agente.
Ecosistema
| Capacidad | Descripción |
|---|---|
| Modelos | OpenAI, Anthropic, Gemini, Bedrock, Groq, Mistral, Ollama y otros con la misma interfaz |
| Observabilidad | Integración con Logfire y cualquier backend OpenTelemetry |
| MCP | Usar servidores MCP como herramientas |
| Grafos | pydantic-graph para flujos con estados explícitos |
| Ejecución duradera | Integración con Temporal para agentes de larga duración |
| Streaming | Salida estructurada parcial mientras se genera |
Comparado con LangGraph, Pydantic AI prioriza código Python idiomático y tipado; LangGraph, la orquestación explícita como grafo con estado persistente.
Criterios de implementación
Controlar reintentos, presupuesto y permisos de herramientas. Probar casos sin evidencia y registrar trazas sin datos sensibles; mantener interfaces que permitan sustituir proveedor.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.