guides

Pydantic AI: La Guía de Producción (Más Allá del Hello World)

Escrito por Mert Batur
Apr 1, 2026
11 lectura
Pydantic AI: La Guía de Producción (Más Allá del Hello World)

Pydantic AI: La Guía de Producción (Más Allá del Hello World)

Las salidas brutas de los LLM rompen las aplicaciones. Pides JSON y obtienes Markdown. Pides un número entre 1 y 10 y obtienes "¡Claro! Aquí tienes un número: siete." Si has construido algo real con APIs de LLM, has escrito código de análisis defensivo que te hace cuestionar tus elecciones de carrera. Pydantic AI soluciona esto -- es el framework de agentes con seguridad de tipos construido por el mismo equipo detrás de Pydantic y FastAPI. Piénsalo como "FastAPI para agentes IA": defines lo que quieres con anotaciones de tipo Python, y el framework gestiona la validación, los reintentos y las llamadas a herramientas.

Esta guía de Pydantic AI es para desarrolladores que ya han hecho su primera llamada a un LLM y quieren patrones de producción: salidas estructuradas que no se rompan, inyección de dependencias para agentes testables, y herramientas del mundo real más allá de las APIs del tiempo. Al final, tendrás agentes funcionales con herramientas, DI, streaming y pruebas.

<!-- IMAGE: Arquitectura de agente Pydantic AI -- El agente recibe un prompt, llama a herramientas via RunContext, valida la salida a través del modelo Pydantic -->

Pydantic AI de un Vistazo

AtributoDetalles
Qué esFramework de agentes IA con seguridad de tipos para Python
Construido porEl equipo de Pydantic (Samuel Colvin et al.)
Filosofía"FastAPI para agentes IA" -- las anotaciones de tipo lo impulsan todo
LicenciaMIT (código abierto)
Versión actualv1.74.0 (marzo 2026)
Versión Python3.9+
Modelos soportadosOpenAI, Anthropic, Google Gemini, Groq, Mistral, Ollama y más
Características claveSalidas estructuradas, llamadas a herramientas, inyección de dependencias, streaming, TestModel
Estrellas GitHub16.000+
Listo para producciónSí -- v1.0 lanzada en septiembre de 2025
ObservabilidadIntegración nativa con Logfire (basado en OpenTelemetry)
Curva de aprendizajeBaja si conoces Pydantic/FastAPI; moderada de otro modo

Las características destacadas son las salidas estructuradas (validadas con modelos Pydantic), la inyección de dependencias (como Depends de FastAPI) y TestModel (LLM simulado para pruebas sin llamadas a la API). Si vienes de LangChain y te preguntas "¿hay algo más limpio?", probablemente sea esto.

Instalación y Primer Agente

bash
# Instalar con soporte para OpenAI (reemplaza openai por anthropic, google, etc.)
pip install "pydantic-ai[openai]"

# Establece tu clave API
export OPENAI_API_KEY="sk-..."

Tu primer agente en 5 líneas:

python
from pydantic_ai import Agent

agent = Agent("openai:gpt-4o", system_prompt="You are a helpful assistant.")

result = agent.run_sync("What's the capital of France?")
print(result.output)  # "Paris"

Eso es todo. Agent envuelve el modelo, run_sync envía un prompt y devuelve un resultado. El result.output es una simple cadena aquí, pero eso está a punto de cambiar.

Salidas Estructuradas -- Por Qué Existe Pydantic AI

Esta es la característica central. En lugar de obtener una cadena del LLM y esperar que sea JSON válido, defines un modelo Pydantic y el agente devuelve un objeto Python validado.

Antes: Salida Bruta del LLM

python
# La forma antigua -- esperar lo mejor
from openai import OpenAI

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Review the movie Inception. Return JSON with title, rating (1-10), summary."}]
)
# response.choices[0].message.content es una cadena
# Tal vez es JSON. Tal vez tiene comillas de bloque Markdown. Tal vez rating es "eight".
# Estás solo.

Después: Estructurado con Pydantic AI

python
from pydantic import BaseModel
from pydantic_ai import Agent

class MovieReview(BaseModel):
    title: str
    rating: int  # Garantizado que sea un int, no "eight"
    summary: str
    recommended: bool

agent = Agent("openai:gpt-4o", result_type=MovieReview)

result = agent.run_sync("Review the movie Inception")
review = result.output  # Esto es una instancia MovieReview, no una cadena

print(f"{review.title}: {review.rating}/10")
print(f"Recomendado: {review.recommended}")
print(review.summary)

La diferencia es como el día y la noche. result.output es un objeto MovieReview real. Si el LLM devuelve rating: "eight" en lugar de rating: 8, la validación de Pydantic lo detecta. Para una mirada más profunda a cómo funciona esto con diferentes proveedores, consulta nuestra guía sobre salidas estructuradas con proveedores LLM.

Qué Pasa Cuando Falla la Validación

Aquí está la parte que ningún otro tutorial muestra: ¿qué sucede cuando el LLM comete un error?

python
from pydantic import BaseModel, Field
from pydantic_ai import Agent

class StrictReview(BaseModel):
    title: str
    rating: int = Field(ge=1, le=10)  # Debe ser 1-10
    pros: list[str] = Field(min_length=2)  # Al menos 2 ventajas

agent = Agent("openai:gpt-4o", result_type=StrictReview)

# Si el LLM devuelve rating=15 o solo 1 ventaja:
# 1. La validación de Pydantic falla
# 2. El mensaje de error se envía DE VUELTA al LLM
# 3. El LLM lo intenta de nuevo con la salida corregida
# 4. Esto se repite hasta el límite de reintentos
result = agent.run_sync("Review the movie Inception")

Este bucle de reintento con retroalimentación es la característica asesina de Pydantic AI. El LLM aprende de sus propios errores de validación. No escribes lógica de reintentos -- el framework lo maneja.

Veredicto: Las salidas estructuradas son la mejor razón única para usar Pydantic AI en lugar de llamadas directas a la API. Si estás analizando JSON de LLM manualmente, detente.

Herramientas y Llamadas a Funciones

Las herramientas permiten a tu agente llamar a funciones Python para obtener datos reales. En lugar de que el LLM alucine hechos, puede consultar tu base de datos, buscar en tus documentos o llamar a una API.

Registrar una Herramienta

python
from pydantic_ai import Agent

agent = Agent("openai:gpt-4o")

@agent.tool
async def search_docs(query: str) -> str:
    """Search the documentation for relevant articles."""
    # Tu lógica de búsqueda real aquí
    results = await doc_search_engine.search(query, limit=5)
    return "\n".join(r.title + ": " + r.snippet for r in results)

El decorador @agent.tool registra la función. Pydantic AI lee las anotaciones de tipo y el docstring de la función para decirle al LLM qué hace la herramienta, qué argumentos acepta y qué devuelve. Sin escritura manual de esquemas -- tus anotaciones de tipo SON el esquema. Para contexto sobre cómo funcionan las llamadas a funciones de LLM bajo el capó, tenemos una guía dedicada.

RunContext: Pasar Datos a las Herramientas

Aquí es donde Pydantic AI diverge de otros frameworks. RunContext te permite pasar datos de tiempo de ejecución (conexiones de base de datos, información del usuario, clientes API) a tus herramientas sin estado global.

python
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext

@dataclass
class SupportDeps:
    customer_id: str
    db_connection: DatabaseConnection

agent = Agent("openai:gpt-4o", deps_type=SupportDeps)

@agent.tool
async def get_order_history(ctx: RunContext[SupportDeps], limit: int = 5) -> str:
    """Fetch recent orders for the current customer."""
    orders = await ctx.deps.db_connection.query(
        "SELECT * FROM orders WHERE customer_id = $1 ORDER BY date DESC LIMIT $2",
        ctx.deps.customer_id, limit
    )
    return format_orders(orders)

El ctx.deps da a la herramienta acceso a lo que pasaste en tiempo de ejecución. La herramienta no importa una conexión de base de datos global -- recibe una. Esto es inyección de dependencias, y es lo que hace que tus agentes sean testables.

Un Ejemplo de Herramienta del Mundo Real

python
@agent.tool
async def run_sql_query(ctx: RunContext[SupportDeps], sql: str) -> str:
    """Run a read-only SQL query against the analytics database.
    Only SELECT queries are allowed."""
    if not sql.strip().upper().startswith("SELECT"):
        return "Error: only SELECT queries are allowed"
    results = await ctx.deps.db_connection.fetch(sql)
    return json.dumps(results, default=str)

Veredicto: Las llamadas a herramientas en Pydantic AI son más limpias que en cualquier otro framework gracias a las anotaciones de tipo que hacen el trabajo pesado. Escribes funciones Python normales con anotaciones de tipo. El framework resuelve el resto.

Inyección de Dependencias -- La Característica que LangChain Quisiera Tener

Si has usado Depends de FastAPI, ya entiendes el sistema DI de Pydantic AI. Si no, aquí está la versión corta: en lugar de que tu agente salga a buscar lo que necesita (conexiones de base de datos globales, clientes API, configuración), le das todo en tiempo de ejecución.

Definir Dependencias

python
from dataclasses import dataclass
from pydantic_ai import Agent

@dataclass
class AppDeps:
    db: AsyncDatabasePool
    search_client: SearchAPIClient
    current_user: User

agent = Agent(
    "openai:gpt-4o",
    deps_type=AppDeps,
    system_prompt="You are a customer support agent."
)

Usar Dependencias en Herramientas

python
@agent.tool
async def lookup_account(ctx: RunContext[AppDeps]) -> str:
    """Look up the current user's account details."""
    account = await ctx.deps.db.fetchrow(
        "SELECT * FROM accounts WHERE user_id = $1",
        ctx.deps.current_user.id
    )
    return json.dumps(account, default=str)

# Ejecutar con dependencias reales
result = await agent.run(
    "What's my account status?",
    deps=AppDeps(db=real_db, search_client=real_search, current_user=user)
)

Por Qué DI Hace Tus Agentes Testables

Esta es la recompensa real. En LangChain, pasarías el contexto a través de kwargs de cadena o closures -- no hay un patrón estándar. En Pydantic AI, intercambiar dependencias reales por dobles de prueba es trivial:

python
# En tu archivo de prueba
from pydantic_ai import Agent
from your_app import agent, AppDeps

async def test_account_lookup():
    mock_deps = AppDeps(
        db=MockDatabase({"user_123": {"status": "active", "plan": "pro"}}),
        search_client=MockSearch(),
        current_user=User(id="user_123")
    )
    result = await agent.run("What's my account status?", deps=mock_deps)
    assert "active" in result.output
    assert "pro" in result.output

Sin monkey-patching. Sin mockear imports globales. Simplemente pasas deps diferentes.

Veredicto: La inyección de dependencias es por qué los desarrolladores Python con experiencia prefieren Pydantic AI. Es la influencia de FastAPI mostrándose.

Proveedores de Modelos -- OpenAI, Anthropic, Gemini, Ollama

Pydantic AI es agnóstico al modelo. Cambiar de proveedor es un cambio de una línea:

python
# OpenAI
agent = Agent("openai:gpt-4o")

# Anthropic
agent = Agent("anthropic:claude-sonnet-4-20250514")

# Google Gemini
agent = Agent("google-gla:gemini-2.0-flash")

# Ollama local
agent = Agent("ollama:llama3.1")

Todo lo demás -- herramientas, salidas estructuradas, DI -- permanece idéntico. Tu lógica de negocio no cambia cuando cambias de modelo.

ProveedorModelosNivel gratuitoComplejidad de configuración
OpenAIGPT-4o, GPT-4o mini, o1Crédito de $5 (cuentas nuevas)Baja -- solo clave API
AnthropicClaude Sonnet, Haiku, OpusSin nivel gratuitoBaja -- solo clave API
Google GeminiGemini 2.0 Flash, ProNivel gratuito generosoMedia -- configuración de proyecto
GroqLlama, MixtralNivel gratuito disponibleBaja -- solo clave API
Ollama (local)Llama, Mistral, Phi, etc.Completamente gratisMedia -- instalar Ollama

Veredicto: El diseño agnóstico al modelo significa que nunca estás atado a un proveedor. Empieza con OpenAI por conveniencia, benchmarkea con Anthropic y usa Ollama para el desarrollo local.

Respuestas en Streaming

Para interfaces de chat y aplicaciones en tiempo real, el streaming es esencial. Pydantic AI lo soporta manteniendo la seguridad de tipos:

python
from pydantic_ai import Agent
from pydantic import BaseModel

class AnalysisResult(BaseModel):
    summary: str
    sentiment: str
    confidence: float

agent = Agent("openai:gpt-4o", result_type=AnalysisResult)

async def stream_analysis(text: str):
    async with agent.run_stream(f"Analyze this text: {text}") as stream:
        async for partial in stream.stream_structured():
            # partial es un AnalysisResult parcialmente validado
            print(f"Streaming: {partial}")

        # El resultado final está completamente validado
        result = await stream.get_output()
        print(f"Final: {result.summary} ({result.confidence:.0%} de confianza)")

Esto funciona perfectamente con StreamingResponse de FastAPI -- mismo ecosistema, mismos patrones. La documentación de agentes Pydantic AI cubre opciones de streaming avanzadas incluyendo streaming solo de texto con stream_text().

Pydantic AI vs LangGraph vs OpenAI Agents SDK

Estás aquí, así que probablemente te preguntas: "¿debería usar Pydantic AI o LangGraph?" Respuesta honesta: resuelven problemas diferentes, y podrías usar ambos.

Tabla de Comparación de Características

CaracterísticaPydantic AILangGraphOpenAI Agents SDK
Seguridad de tiposCompleta (modelos Pydantic)Parcial (TypedDict)Mínima
Inyección de dependenciasIntegrada (estilo FastAPI)NingunaNinguna
Salidas estructuradasNativa con reintentoVia analizadores de salidaVia modo JSON
Llamadas a herramientasDecorador @agent.toolDecorador @toolDefiniciones de funciones
Multi-agenteTraspasos básicosAvanzado (máquinas de estado)Traspasos + guardrails
StreamingStreaming tipadoEventos de streamingStreaming
Soporte de modelos10+ proveedoresPrincipalmente modelos LangChainSolo OpenAI
PruebasTestModel integradoSin pruebas integradasSin pruebas integradas
Curva de aprendizajeBaja (si conoces Pydantic)Alta (conceptos de grafo)Baja (API simple)
Tamaño de comunidadCreciendo (16K estrellas)Grande (ecosistema LangChain)Creciendo (respaldo de OpenAI)
Mejor paraAgentes limpios y testablesFlujos de trabajo de estado complejosProyectos solo con OpenAI

Cuándo Usar Cada Uno

Elige Pydantic AI cuando quieras código de agente limpio y con seguridad de tipos. Es ideal para tareas de agente único con herramientas (bots de soporte al cliente, extracción de datos, agentes de revisión de código) y situaciones donde la testabilidad importa. Si tu equipo ya usa FastAPI y Pydantic, la curva de aprendizaje es casi plana.

Elige LangGraph cuando necesites flujos de trabajo de múltiples pasos complejos con ramificación condicional, aprobación humana en el bucle y gestión de estado sofisticada. LangGraph sobresale en la orquestación de múltiples pasos, no en la calidad de los agentes individuales. Para un análisis profundo, consulta nuestra comparación completa de LangGraph vs CrewAI vs OpenAI Agents SDK.

Elige OpenAI Agents SDK cuando estés al 100% con OpenAI, quieras la configuración más simple posible y no necesites soporte multi-proveedor ni DI.

El Patrón de Combinación

Lo que los equipos con experiencia realmente hacen: usar Pydantic AI para agentes individuales (código limpio, testable, salidas tipadas) y LangGraph para la orquestación entre agentes (enrutamiento, máquinas de estado, lógica condicional). No compiten -- son capas complementarias.

python
# Agente Pydantic AI -- limpio, testable, con seguridad de tipos
support_agent = Agent("openai:gpt-4o", result_type=SupportResponse, deps_type=SupportDeps)

# Grafo LangGraph -- orquesta cuándo llamar a qué agente
graph = StateGraph(SupportState)
graph.add_node("classify", classify_intent)
graph.add_node("support", lambda state: support_agent.run_sync(state["query"]))
graph.add_node("escalate", escalate_to_human)

Veredicto: Elige Pydantic AI para código de agente limpio y testable. Elige LangGraph para flujos de trabajo complejos de múltiples pasos. No son mutuamente excluyentes.

Probando Tus Agentes con TestModel

Esta es la sección que separa una guía para principiantes de una guía de producción. Todo codebase real necesita pruebas, y probar agentes es notoriamente difícil -- las llamadas a LLM son lentas, caras y no deterministas. Pydantic AI incluye una solución: TestModel.

python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel
from pydantic import BaseModel

class SupportResponse(BaseModel):
    answer: str
    confidence: float
    escalate: bool

agent = Agent("openai:gpt-4o", result_type=SupportResponse)

# En pruebas: reemplazar el modelo real con TestModel
def test_support_agent():
    with agent.override(model=TestModel()):
        result = agent.run_sync("I need help with billing")
        # TestModel devuelve datos estructurados válidos que coinciden con tu result_type
        assert isinstance(result.output, SupportResponse)
        assert isinstance(result.output.confidence, float)
        assert isinstance(result.output.escalate, bool)

TestModel genera datos válidos que coinciden con tu result_type sin hacer llamadas a la API. Cero costo, determinista, rápido. La documentación de pruebas de Pydantic AI cubre patrones avanzados como FunctionModel para respuestas personalizadas y capture_run_messages para inspeccionar las llamadas a herramientas.

Probando Herramientas y DI Juntos

python
def test_order_lookup_tool():
    # Dependencias simuladas
    mock_deps = SupportDeps(
        customer_id="test-123",
        db_connection=MockDB(orders=[{"id": "ord-1", "status": "shipped"}])
    )

    with agent.override(model=TestModel()):
        result = agent.run_sync(
            "Where is my order?",
            deps=mock_deps
        )
        assert isinstance(result.output, SupportResponse)

Sin llamadas a la API. Sin pruebas inestables. Sin costo. Ejecuta esto en CI/CD junto al resto de tu suite de pruebas.

Esta es la brecha de contenido n.° 1 en todo el SERP. Ninguna otra guía de Pydantic AI cubre las pruebas. Si estás construyendo agentes para producción, esto es lo que necesitas.

Observabilidad -- Integración con Logfire en 5 Minutos

Los agentes en producción necesitan observabilidad IA. Quieres ver cada llamada a LLM, invocación de herramienta, latencia, conteo de tokens y costo. Pydantic AI se integra de forma nativa con Logfire, la plataforma de observabilidad del equipo de Pydantic (construida sobre OpenTelemetry).

python
import logfire
from pydantic_ai import Agent

logfire.configure()  # Usa la variable de entorno LOGFIRE_TOKEN
logfire.instrument_pydantic_ai()

agent = Agent("openai:gpt-4o", result_type=MovieReview)
# Cada ejecución ahora se traza automáticamente
result = agent.run_sync("Review Inception")

Tres líneas. Obtienes trazas completas que muestran: prompt enviado, respuesta del modelo, llamadas a herramientas (si las hay), pases/fallos de validación, reintentos, latencia y costo estimado. Si Logfire no es lo tuyo, Langfuse es una sólida alternativa de código abierto con soporte de ingeniería de contexto para rastrear cómo evolucionan tus prompts.

FAQ

¿Qué es Pydantic AI y en qué se diferencia de LangChain?

Pydantic AI es un framework de agentes con seguridad de tipos donde las anotaciones de tipo Python impulsan la validación, los esquemas de herramientas y la inyección de dependencias. LangChain es un framework más grande enfocado en encadenar llamadas a LLM. La diferencia clave: Pydantic AI valida las salidas a nivel de framework y proporciona inyección de dependencias integrada para la testabilidad -- LangChain no hace ninguna de las dos cosas por defecto.

¿Cómo construyo un agente IA con seguridad de tipos con Pydantic AI?

Define un BaseModel de Pydantic para tu salida, pásalo como result_type a Agent y llama a run_sync() o run(). El agente devuelve una instancia validada de tu modelo, no una cadena bruta. Consulta la sección de Salidas Estructuradas para ejemplos completos.

¿Debería usar Pydantic AI o LangGraph para agentes en producción?

Usa Pydantic AI para agentes individuales donde la seguridad de tipos, la testabilidad y el código limpio importan. Usa LangGraph para orquestar flujos de trabajo de múltiples pasos complejos con enrutamiento condicional. Muchos equipos usan ambos -- agentes Pydantic AI dentro de una capa de orquestación LangGraph.

¿Cómo gestiona Pydantic AI las llamadas a herramientas y la inyección de dependencias?

Decora una función con @agent.tool y Pydantic AI lee sus anotaciones de tipo para generar el esquema de la herramienta. Para DI, establece deps_type en el Agent y acepta RunContext[TusDeps] en las herramientas. Las dependencias en tiempo de ejecución (conexiones DB, clientes API) fluyen sin estado global.

¿Cómo añado streaming a un agente Pydantic AI?

Usa agent.run_stream() en lugar de agent.run(). Devuelve un gestor de contexto asíncrono que produce resultados parciales via stream_structured() o stream_text(). El resultado final sigue estando completamente validado contra tu result_type.

¿Está Pydantic AI listo para producción en 2026?

Sí. La versión 1.0 se lanzó en septiembre de 2025 con un compromiso de estabilidad de API. Está respaldado por el equipo de Pydantic (la biblioteca Python más descargada para la validación de datos) y actualmente está en v1.74.0 con actualizaciones regulares.

¿Puedo usar Pydantic AI con Ollama y modelos locales?

Sí. Usa Agent("ollama:llama3.1") y asegúrate de que Ollama esté ejecutándose localmente. Instala el extra del proveedor ollama: pip install "pydantic-ai[ollama]". Las salidas estructuradas y las herramientas funcionan igual que con los proveedores en la nube.

¿Cómo pruebo los agentes Pydantic AI?

Usa TestModel -- un modelo simulado que genera datos estructurados válidos que coinciden con tu result_type sin llamadas a la API. Envuelve tu prueba con agent.override(model=TestModel()) y ejecuta assertions sobre la salida. Consulta la sección de Pruebas para ejemplos completos de pytest.

¿Funciona Pydantic AI con FastAPI?

Perfectamente. Comparten la misma filosofía de inyección de dependencias y están construidos por el mismo equipo. Puedes usar agentes Pydantic AI dentro de endpoints FastAPI, compartir tipos de dependencias entre ellos y hacer streaming de respuestas de agentes a través de StreamingResponse.

¿Cuál es la diferencia entre Pydantic AI y el OpenAI Agents SDK?

Pydantic AI es agnóstico al modelo (funciona con OpenAI, Anthropic, Gemini, Ollama, etc.), tiene inyección de dependencias, TestModel para pruebas y validación de Pydantic. El OpenAI Agents SDK es más simple pero está limitado a modelos OpenAI y carece de DI y pruebas integradas. Elige Pydantic AI para flexibilidad; elige OpenAI Agents SDK para la configuración más simple posible solo con OpenAI.

Conclusiones Principales y Próximos Pasos

ConceptoIdea ClavePróximo Paso
Salidas EstructuradasTu result_type se valida y reintenta automáticamenteDefinir modelos Pydantic para todas las salidas de agentes
HerramientasLas anotaciones de tipo SON el esquema -- sin definiciones manualesConstruir herramientas con @agent.tool y RunContext
Inyección de DependenciasPasar deps de tiempo de ejecución explícitamente para la testabilidadDefinir una dataclass deps_type para cada agente
PruebasTestModel elimina los costos de API en CI/CDAñadir agent.override(model=TestModel()) a tu suite de pruebas
Proveedores de ModelosCambio de modelo en una línea, sin cambios de códigoEmpieza con OpenAI, benchmarkea alternativas más tarde
ObservabilidadConfiguración de Logfire en 3 líneas para trazas completasAñadir logfire.instrument_pydantic_ai() a producción

Empieza con un agente pequeño que tenga salidas estructuradas. Añade una herramienta. Añade dependencias. Escribe una prueba con TestModel. Ese es el camino de producción -- y ahora tienes todo lo que necesitas para recorrerlo.

La documentación oficial de Pydantic AI y el repositorio GitHub son excelentes para profundizar más. El framework se mueve rápido, así que marca el changelog como favorito.

Fuentes

Etiquetas

pydantic aiagentes iasalidas estructuradasinyección de dependenciasagentes con tipos segurospythonframework llm

Compartir este artículo

Inicia Tu Proyecto

¿Listo para construir algo extraordinario?

Convirtamos tu visión en realidad. Nuestro equipo está listo para ayudarte a crear software que marque la diferencia.