Cómo construir un sistema multi-agente con OpenAI Agents SDK: tutorial en Python
Tutorial paso a paso para construir un sistema multi-agente con OpenAI Agents SDK: un orquestador que redirige consultas a agentes especializados mediante handoffs, con guardrails de validación y un endpoint FastAPI listo para producción.
El OpenAI Agents SDK convierte una conversación lineal con la API de OpenAI en un sistema de agentes especializados que se pasan el control entre sí. En Cognitiva, agencia chilena de IA, lo usamos como punto de entrada para equipos que ya consumen la API de OpenAI y quieren pasar del chatbot simple al agente estructurado sin migrar de plataforma. Este tutorial es ejecutable: al final tendrás un orquestador que analiza cada consulta y la redirige al agente de ventas, soporte o técnico según corresponda, con guardrails que bloquean contenido fuera de alcance y todo expuesto como endpoint FastAPI. El tiempo estimado es 45 minutos si ya tienes una API key de OpenAI y Python 3.10 o superior instalado. No necesitas frameworks adicionales ni infraestructura propia: el SDK gestiona el loop de razonamiento, los handoffs entre agentes y el historial de conversación por ti.
Qué resuelve el OpenAI Agents SDK y cuándo usarlo
El OpenAI Agents SDK es un framework de Python (y TypeScript) mantenido por OpenAI que abstrae el loop de agente: en lugar de manejar manualmente el ciclo llamada-herramienta-respuesta, declaras agentes con instrucciones, herramientas y handoffs, y el SDK ejecuta el loop hasta obtener una respuesta final. La versión 0.17.7, publicada el 24 de junio de 2026, es la más reciente y la que usaremos en este tutorial.
SDK de agentes vs. loop propio: cuándo usar cada uno
| Criterio | Agents SDK | Loop manual | LangGraph |
|---|---|---|---|
| Curva de aprendizaje | Baja (3 primitivas principales) | Media (implementas todo) | Alta (grafos de estado) |
| Control del flujo | Declarativo con handoffs | Total (imperativo) | Total (grafos tipados) |
| Estado persistente | RunResult por ejecución | Debes implementarlo | Estado de grafo nativo |
| Guardrails integrados | Sí (input/output) | Debes construirlos | Debes construirlos |
| Ideal para | Sistemas multi-agente simples/medios | Flujos muy específicos | Flujos complejos con estado |
Elige el Agents SDK cuando tu equipo ya usa la API de OpenAI, quieres handoffs declarativos sin implementar grafos de estado, y necesitas guardrails sin un framework adicional. Para flujos con ramificaciones complejas y estado persistente entre sesiones, LangGraph ofrece más control a costa de mayor complejidad.
Prerrequisitos e instalación
- Python 3.10 o superior (el SDK lo requiere explícitamente).
- Una API key de OpenAI con acceso al modelo gpt-4o-mini o superior.
- Conocimiento básico de Python asíncrono (async/await): el Runner usa asyncio.
- FastAPI y uvicorn para exponer el endpoint al final del tutorial.
Instala las dependencias
# Crea y activa el entorno virtual
python -m venv .venv
source .venv/bin/activate # en Windows: .venv\Scripts\activate
# Instala el SDK y FastAPI
pip install openai-agents fastapi uvicorn python-dotenv
# Verifica la version instalada
pip show openai-agentsConfigura la API key
# En tu archivo .env (no lo subas a git)
OPENAI_API_KEY=sk-proj-tu-api-key-aquiDefine los agentes especializados
Cada agente especializado recibe instrucciones precisas sobre su dominio. Mientras más específicas sean las instrucciones, mejor decide el orquestador a cuál derivar una consulta. En el parámetro model puedes usar gpt-4o-mini para los agentes especializados (menor costo) y gpt-4o para el orquestador (mayor capacidad de razonamiento).
# agents_definition.py
from agents import Agent
# Agente especializado en ventas
agente_ventas = Agent(
name='Agente de Ventas',
instructions=(
'Eres el especialista en ventas de Cognitiva. '
'Responde preguntas sobre planes, precios, demos y propuestas comerciales. '
'Siempre ofrece una llamada de 30 minutos si el cliente muestra interes real. '
'No respondas preguntas tecnicas ni de soporte.'
),
model='gpt-4o-mini',
)
# Agente especializado en soporte al cliente
agente_soporte = Agent(
name='Agente de Soporte',
instructions=(
'Eres el especialista en soporte de Cognitiva. '
'Ayuda con problemas de acceso, configuracion y uso de los sistemas implementados. '
'Para problemas tecnicos de codigo o infraestructura, transfiere al agente tecnico.'
),
model='gpt-4o-mini',
)
# Agente especializado en consultas tecnicas
agente_tecnico = Agent(
name='Agente Tecnico',
instructions=(
'Eres el especialista tecnico de Cognitiva. '
'Responde preguntas sobre APIs, integraciones, arquitectura y codigo. '
'Proporciona ejemplos concretos y verifica que el usuario entienda antes de cerrar.'
),
model='gpt-4o-mini',
)Por qué usar modelos distintos por agente
Asignar gpt-4o-mini a los agentes especializados y gpt-4o al orquestador reduce el costo total sin sacrificar calidad: el orquestador toma la decisión de enrutamiento más difícil, mientras que los agentes especializados responden en un dominio acotado donde un modelo más pequeño es suficiente.
Crea el orquestador con handoffs y guardrail
El orquestador es el agente de entrada. Recibe cada consulta, decide a cuál agente especializado derivarla mediante un handoff, y el SDK transfiere automáticamente el historial completo de la conversación al agente receptor.
Define el guardrail de entrada
El guardrail analiza cada consulta antes de que el orquestador consuma tokens. Si la consulta está fuera del dominio (por ejemplo, contenido inapropiado o preguntas completamente ajenas al negocio), el guardrail activa el tripwire y la ejecución se detiene sin llegar al modelo principal.
# guardrail.py
from pydantic import BaseModel
from agents import Agent, Runner, input_guardrail, GuardrailFunctionOutput, RunContextWrapper, TResponseInputItem
from typing import Union
# Esquema de salida del agente de clasificacion
class ClasificacionConsulta(BaseModel):
es_relevante: bool
razon: str
# Agente ligero que clasifica si la consulta es relevante al negocio
agente_clasificador = Agent(
name='Clasificador',
instructions=(
'Clasifica si la consulta es relevante para una empresa de IA y automatizacion. '
'Una consulta es relevante si trata sobre: ventas, precios, soporte, APIs, integraciones, '
'automatizacion o IA en general. No es relevante si es ofensiva, irrelevante o spam.'
),
output_type=ClasificacionConsulta,
model='gpt-4o-mini',
)
@input_guardrail
async def guardrail_relevancia(
ctx: RunContextWrapper[None],
agent: Agent,
input: Union[str, list[TResponseInputItem]]
) -> GuardrailFunctionOutput:
resultado = await Runner.run(agente_clasificador, input, context=ctx.context)
clasificacion = resultado.final_output
return GuardrailFunctionOutput(
output_info=clasificacion,
tripwire_triggered=not clasificacion.es_relevante,
)Define el orquestador
# orchestrator.py
from agents import Agent
from agents_definition import agente_ventas, agente_soporte, agente_tecnico
from guardrail import guardrail_relevancia
orquestador = Agent(
name='Orquestador',
instructions=(
'Eres el primer punto de contacto de Cognitiva. '
'Analiza la consulta del usuario y delega al agente correcto: '
'- Si es sobre precios, planes o ventas: transfiere al Agente de Ventas. '
'- Si es sobre soporte, acceso o uso del sistema: transfiere al Agente de Soporte. '
'- Si es sobre codigo, APIs o arquitectura tecnica: transfiere al Agente Tecnico. '
'Si no puedes determinar el destino, responde de forma general y pide mas contexto.'
),
handoffs=[agente_ventas, agente_soporte, agente_tecnico],
input_guardrails=[guardrail_relevancia],
model='gpt-4o',
)Expón el sistema como endpoint FastAPI
Con el orquestador definido, exponer el sistema como API REST requiere menos de 20 líneas. El endpoint recibe la consulta del usuario, ejecuta el orquestador y retorna la respuesta del agente especializado que atendió la consulta.
# main.py
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from agents import Runner
from agents.exceptions import InputGuardrailTripwireTriggered
from orchestrator import orquestador
from dotenv import load_dotenv
load_dotenv()
app = FastAPI(title='Sistema Multi-Agente Cognitiva')
class ConsultaRequest(BaseModel):
query: str
class ConsultaResponse(BaseModel):
respuesta: str
agente_que_respondio: str
@app.post('/chat', response_model=ConsultaResponse)
async def chat(request: ConsultaRequest):
if not request.query.strip():
raise HTTPException(status_code=400, detail='La consulta no puede estar vacia')
try:
resultado = await Runner.run(orquestador, request.query)
return ConsultaResponse(
respuesta=resultado.final_output,
agente_que_respondio=resultado.last_agent.name,
)
except InputGuardrailTripwireTriggered:
raise HTTPException(
status_code=422,
detail='Consulta fuera del alcance del sistema. Por favor reformula tu pregunta.'
)
@app.get('/health')
def health():
return {'status': 'ok'}Ejecuta y prueba el endpoint
# Levanta el servidor
uvicorn main:app --reload
# Prueba con una consulta de ventas
curl -X POST http://localhost:8000/chat \
-H 'Content-Type: application/json' \
-d '{"query": "Cual es el precio del plan de automatizacion?"}'
# Resultado esperado:
# {"respuesta": "...", "agente_que_respondio": "Agente de Ventas"}
# Prueba con una consulta tecnica
curl -X POST http://localhost:8000/chat \
-H 'Content-Type: application/json' \
-d '{"query": "Como integro la API con mi sistema Node.js?"}' Verifica el sistema y próximos pasos
Checklist de validación (ownData de Cognitiva)
- El endpoint /health responde con status 200 y {status: 'ok'}.
- Una consulta de ventas retorna agente_que_respondio: 'Agente de Ventas'.
- Una consulta de soporte retorna agente_que_respondio: 'Agente de Soporte'.
- Una consulta técnica retorna agente_que_respondio: 'Agente Tecnico'.
- Una consulta irrelevante (spam, contenido inapropiado) retorna HTTP 422.
- El campo respuesta nunca viene vacío cuando el guardrail no se activa.
- El servidor no lanza excepciones no controladas para consultas de texto plano.
Extensiones inmediatas para producción
Este sistema es el punto de partida. Para llevarlo a producción en una empresa chilena, considera estas extensiones ordenadas por impacto:
- Historial de conversación: pasa una lista de mensajes en lugar de un string para mantener contexto entre turnos.
- Herramientas de negocio: agrega @function_tool al agente de ventas para consultar tu CRM o base de precios en tiempo real.
- Guardrail de salida: agrega output_guardrails al orquestador para revisar que la respuesta no incluya información confidencial.
- Límite de turnos: fija max_turns al ejecutar, con Runner.run(orquestador, query, max_turns=10), para evitar bucles infinitos en producción.
- Observabilidad: el SDK trae su propio sistema de tracing basado en trace processors; agrega un processor o una integración de terceros para exportar cada ejecución a Langfuse o LangSmith.
El patrón orquestador-agentes especializados con handoffs declarativos reduce el código de enrutamiento a cero: describes las reglas en lenguaje natural y el modelo decide.
Cómo construir un sistema multi-agente con OpenAI Agents SDK en Python
Tutorial paso a paso para crear un orquestador con handoffs a agentes especializados, guardrails de validación y endpoint FastAPI usando OpenAI Agents SDK 0.17.7.
Configuración del entorno
Definir los agentes especializados
Configurar el orquestador con handoffs
Exponer como endpoint FastAPI
Preguntas frecuentes
Da el siguiente paso
Hablemos
Cuéntanos sobre tu negocio. Respondemos en 24 horas.
Otros canales
Escríbenos por WhatsApp o agenda una llamada de 30 minutos.