Conceptos Fundamentales de Pydantic AI 2.0: Aplicaciones de IA con Type-Safety
Pydantic AI 2.0 es un framework para desarrollar aplicaciones de IA con type-safety y validación. Permite obtener salidas estructuradas de Large Language Models (LLMs) e se integra perfectamente con modelos de Pydantic.
¿Qué es Pydantic AI?
Pydantic AI es una librería Python construida sobre Pydantic y diseñada específicamente para trabajar con LLMs. Ofrece:
- Salidas de IA type-safe: Las respuestas de IA se convierten automáticamente en modelos de Pydantic
- Validación: Las entradas y salidas se validan contra esquemas
- Soporte multi-proveedor: OpenAI, Anthropic, Groq, modelos locales (Ollama, vLLM)
- Streaming: Transmisión en tiempo real de datos estructurados
- Tool-Calling: Soporte integrado para Function Calling
¿Por qué usar Pydantic AI?
Usuario típico
Pydantic AI es ideal para estos grupos:
- Desarrolladores Python que ya usan Pydantic y valoran el type-safety
- Desarrolladores backend que quieren integrar salidas de IA estructuradas en APIs
- Data engineers que necesitan extracción y validación de datos con IA
- Desarrolladores de aplicaciones de IA que necesitan salidas confiables y validadas
Beneficiarios típicos
¿Quién se beneficia de Pydantic AI en un proyecto?
- Usuarios finales: Reciben datos consistentes y validados en lugar de respuestas de texto no estructurado
- Desarrolladores: Ahorran tiempo en validación y manejo de errores
- Sistemas: La integración es más sencilla porque las salidas ya tienen tipo
- Equipos QA: Se necesitan menos pruebas porque la validación ocurre automáticamente
Consideraciones del proyecto: ¿Cuándo usar Pydantic AI?
Antes de integrar Pydantic AI en tu proyecto, plantéate estas preguntas:
1. ¿Necesitas salidas estructuradas?
- ✅ Sí: Pydantic AI es perfecto si necesitas respuestas de IA en formatos específicos (JSON, objetos, enums)
- ❌ No: Si solo necesitas texto libre, Pydantic AI podría ser excesivo
2. ¿Ya usas Python y Pydantic?
- ✅ Sí: Pydantic AI se integra perfectamente en tu ecosistema existente
- ❌ No: Si no usas Python, Pydantic AI no es adecuado (es específico de Python)
3. ¿Qué importancia tiene el type-safety para tu proyecto?
- ✅ Muy importante: Pydantic AI ofrece validación en tiempo de compilación y ejecución
- ⚠️ Moderada: Pydantic AI puede ayudar, pero alternativas como LangChain podrían ser suficientes
- ❌ No es importante: Si no necesitas tipado estricto, alternativas más simples son mejores
4. ¿Planeas soportar múltiples proveedores?
- ✅ Sí: Pydantic AI facilita cambiar entre OpenAI, Anthropic, Groq y modelos locales
- ❌ No: Si solo usas un proveedor, esto no es un criterio de decisión
5. ¿Cuán compleja es tu integración de IA?
- ✅ Simple a moderada: Pydantic AI es ideal para salidas estructuradas y tool-calling
- ⚠️ Muy compleja: Para sistemas multi-agent complejos, LangChain o LangGraph podrían ser mejores
Matriz de decisión
| Requisito | Pydantic AI | LangChain | API directa |
|---|---|---|---|
| Salidas estructuradas | ✅ Óptimo | ⚠️ Posible | ❌ Manual |
| Type-safety | ✅ Nativo | ⚠️ Limitado | ❌ Ninguno |
| Simplicidad | ✅ Alta | ⚠️ Media | ⚠️ Media |
| Multi-agent | ⚠️ Limitado | ✅ Fuerte | ❌ No |
| Agnóstico a proveedores | ✅ Sí | ✅ Sí | ❌ No |
| Curva de aprendizaje | 🟢 Baja | 🟡 Media | 🟡 Media |
Cuándo NO deberías usar Pydantic AI
- No usas Python
- Solo necesitas texto libre sin estructura
- Requieres orquestación compleja de multi-agent (usa LangGraph)
- Quieres dependencias mínimas
- Tu proyecto es muy pequeño y simple (la API directa es suficiente)
Cuándo deberías usar Pydantic AI
- Ya usas Python y Pydantic
- Necesitas salidas de IA confiables y validadas
- El type-safety es importante para ti
- Quieres cambiar entre proveedores de LLM
- Desarrollas APIs con integración de IA
- Quieres tool-calling con parámetros validados
Caso práctico: Empresa con API en FastAPI usando Langdock
Dentro de una empresa, uso FastAPI con Langdock para crear un entorno compatible con RGPD. El chat funciona, los chatbots también. ¿Por qué debería considerar Pydantic AI?
Respuesta: Probablemente no en el escenario actual.
Si el chatbot solo proporciona texto libre y no devuelve datos estructurados, Pydantic AI es innecesario. Langdock y FastAPI ya manejan la conformidad con RGPD y la funcionalidad de chat.
Sin embargo, Pydantic AI podría ser necesario si:
Supón que expandimos el escenario un poco:
# Actualmente: Solo texto libre
response = "¡Hola! Puedo ayudarte."
# Con Pydantic AI: Salidas estructuradas
from pydantic import BaseModel
from pydantic_ai import Agent
class SupportTicket(BaseModel):
kategorie: str # p.ej. "technisch", "billing", "hr"
prioritaet: str # p.ej. "hoch", "mittel", "niedrig"
beschreibung: str
assigned_to: str | None = None
# La IA analiza la solicitud y devuelve datos estructurados
ticket = agent.run_sync(
"Mi computadora no arranca más, ¡necesito ayuda urgentemente!",
result_type=SupportTicket
)
# SupportTicket(kategorie='technisch', prioritaet='hoch', beschreibung='Mi computadora no arranca más...', assigned_to=None)
Ejemplo concreto para la empresa:
- Sin Pydantic AI: El chatbot devuelve texto → Debes parsear el texto para reconocer categorías
- Con Pydantic AI: El chatbot devuelve directamente un objeto
SupportTicket→ Puedes guardarlo en tu base de datos sin parsear
Conclusión para este escenario:
- Si solo necesitas chats: No necesitas Pydantic AI
- Si quieres extraer datos estructurados de chats (tickets, formularios, reportes): Pydantic AI es muy útil
Punto clave:
Un chatbot no necesita Pydantic AI. Un agente de IA usualmente sí. Los casos de uso típicos son asistentes de código, agentes de investigación, automatizaciones, flujos de trabajo con múltiples herramientas o aplicaciones que requieren salidas tipadas y validadas.
Instalación
pip install pydantic-ai
Para proveedores específicos:
pip install pydantic-ai[openai] # OpenAI
pip install pydantic-ai[anthropic] # Anthropic
pip install pydantic-ai[openai,anthropic] # Ambos
Fundamentos: Salidas estructuradas
Ejemplo simple
from pydantic import BaseModel
from pydantic_ai import Agent
class UserResponse(BaseModel):
name: str
age: int
email: str
agent = Agent('openai:gpt-4o')
result = agent.run_sync(
'Crea un perfil de usuario para un desarrollador',
result_type=UserResponse
)
print(result.data)
# UserResponse(name='Max Mustermann', age=28, email='max@example.com')
Con system prompt
from pydantic_ai import Agent, SystemPrompt
agent = Agent(
'openai:gpt-4o',
system_prompt=SystemPrompt('Eres un asistente útil para desarrolladores.')
)
result = agent.run_sync(
'Crea un perfil para un desarrollador Python',
result_type=UserResponse
)
Modelos más complejos
Estructuras anidadas
from typing import List
from pydantic import BaseModel
class Skill(BaseModel):
name: str
years_experience: int
level: str # beginner, intermediate, advanced
class DeveloperProfile(BaseModel):
name: str
role: str
skills: List[Skill]
github_url: str | None = None
available_for_hire: bool
agent = Agent('openai:gpt-4o')
result = agent.run_sync(
'Erstelle ein detailliertes Profil für einen Senior Python-Entwickler',
result_type=DeveloperProfile
)
Validación con Enum
from enum import Enum
from pydantic import BaseModel
class SkillLevel(str, Enum):
BEGINNER = 'beginner'
INTERMEDIATE = 'intermediate'
ADVANCED = 'advanced'
EXPERT = 'expert'
class Skill(BaseModel):
name: str
level: SkillLevel
Soporte multi-proveedor
OpenAI
from pydantic_ai import Agent
agent = Agent('openai:gpt-4o')
result = agent.run_sync('Hallo Welt!')
Anthropic
agent = Agent('anthropic:claude-3-5-sonnet-20241022')
result = agent.run_sync('Hallo Welt!')
Modelos locales (Ollama)
agent = Agent('ollama:llama3.2')
result = agent.run_sync('Hallo Welt!')
Groq
agent = Agent('groq:llama-3.1-70b-versatile')
result = agent.run_sync('Hallo Welt!')
Llamadas a herramientas
Herramienta simple
from pydantic_ai import Agent, Tool
def get_weather(location: str) -> str:
"""Holt das Wetter für einen Ort."""
# In der Realität: API-Aufruf
return f'In {location} sind es 22°C.'
agent = Agent('openai:gpt-4o', tools=[Tool(get_weather)])
result = agent.run_sync('Wie ist das Wetter in Berlin?')
Con modelos Pydantic
from pydantic import BaseModel
class WeatherQuery(BaseModel):
location: str
unit: str = 'celsius'
def get_weather(query: WeatherQuery) -> str:
return f'In {query.location} sind es 22°{query.unit}.'
agent = Agent('openai:gpt-4o', tools=[Tool(get_weather)])
Streaming
Streaming de texto
agent = Agent('openai:gpt-4o')
async for chunk in agent.run_stream('Erzähle mir eine Geschichte'):
print(chunk.content, end='')
Streaming estructurado
async for chunk in agent.run_stream(
'Erstelle ein Benutzerprofil',
result_type=UserResponse
):
if chunk.content:
print(chunk.content, end='')
Manejo de errores
Errores de validación
from pydantic import ValidationError
try:
result = agent.run_sync(
'Erstelle ein Profil',
result_type=UserResponse
)
except ValidationError as e:
print(f'Validierungsfehler: {e}')
Lógica de reintentos
from pydantic_ai import Agent, RetryPolicy
agent = Agent(
'openai:gpt-4o',
retry_policy=RetryPolicy(max_retries=3)
)
Buenas prácticas
1. Definir modelos claros
# ✅ Bien
class UserProfile(BaseModel):
name: str
email: str
age: int
# ❌ Mal
class Response(BaseModel):
data: dict # Keine Type-Safety
2. Usar prompts del sistema
agent = Agent(
'openai:gpt-4o',
system_prompt=SystemPrompt(
'Du bist ein technischer Dokumentations-Assistent. '
'Antworte präzise und strukturiert.'
)
)
3. Aprovechar la validación
from pydantic import field_validator
class UserProfile(BaseModel):
email: str
@field_validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Ungültige E-Mail')
return v
4. Optimizar costos
# Modelos más pequeños para tareas simples
agent_simple = Agent('openai:gpt-4o-mini')
# Modelos más grandes para tareas complejas
agent_complex = Agent('openai:gpt-4o')
Integración con proyectos existentes
Integración con FastAPI
from fastapi import FastAPI
from pydantic_ai import Agent
app = FastAPI()
agent = Agent('openai:gpt-4o')
@app.post('/generate')
async def generate(prompt: str):
result = await agent.run(prompt)
return {'response': result.content}
Async/Await
import asyncio
async def main():
agent = Agent('openai:gpt-4o')
result = await agent.run('Hallo Welt!')
print(result.content)
asyncio.run(main())
Errores comunes
1. Claves API faltantes
import os
from pydantic_ai import Agent
# Establecer la clave API
os.environ['OPENAI_API_KEY'] = 'sk-...'
agent = Agent('openai:gpt-4o')
2. Modelos inválidos
# ✅ Correcto
agent = Agent('openai:gpt-4o')
# ❌ Incorrecto
agent = Agent('openai:gpt-5') # Modell existiert nicht
3. Falta de anotaciones de tipo
# ✅ Con anotaciones de tipo
def get_weather(location: str) -> str:
return f'Wetter in {location}'
# ❌ Sin anotaciones de tipo
def get_weather(location):
return f'Wetter in {location}'
Pydantic AI frente a alternativas
| Característica | Pydantic AI | LangChain | LlamaIndex |
|---|---|---|---|
| Type-Safety | ✅ Nativo | ⚠️ Limitado | ⚠️ Limitado |
| Integración Pydantic | ✅ Completa | ⚠️ Parcial | ⚠️ Parcial |
| Multi-proveedor | ✅ Simple | ✅ Sí | ✅ Sí |
| Streaming | ✅ Sí | ✅ Sí | ✅ Sí |
| Llamadas a herramientas | ✅ Nativo | ✅ Sí | ✅ Sí |
| Curva de aprendizaje | 🟢 Baja | 🟡 Media | 🟡 Media |


