Módulo 5: Handoff y delegación

Módulo 5: Handoff y delegación

Descripción

Los cuatro módulos anteriores construyeron patrones donde alguien de afuera decide primero. Un supervisor (M2) lee la petición completa y decide, antes de que nadie trabaje, a qué especialista delegarla. Un pipeline (M3) fija el orden de las etapas de antemano, sin ninguna decisión en el medio. Un fan-out (M4) reconoce, también de antemano, que dos sub-tareas son independientes y las reparte. En los tres casos, la decisión de "quién hace qué" está tomada antes de que el primer agente toque su primera tool.

Este módulo construye el patrón que rompe esa regla: handoff. Un agente que ya está trabajando —a mitad de una tarea que empezó a resolver de buena fe— descubre que una parte de lo que le están pidiendo no vive en su propia expertise. En vez de fabricar una respuesta sin fundamento, o de quedarse atascado, o de volver a preguntarle a un supervisor externo "¿a quién le mando esto?", el agente cede el turno directamente al especialista correcto — con un paquete mínimo de contexto, no con su historial completo. Vas a construir la pseudo-tool que representa esa decisión, el runner que la reconoce y detiene su propio loop, el paquete de transferencia que decide qué viaja y qué se queda atrás, y las guardas que evitan que dos agentes se pasen el turno indefinidamente entre ellos.

Regla dura de este módulo (léela antes de seguir)

Se mantiene la misma línea de los Módulos 1 a 4: la decisión de cada agente —incluida la decisión de ceder el turno— no se ejecuta. Sigue siendo un guion escrito a mano, rotulado como concepto (claude-sonnet-5). Lo que sí se ejecuta, de verdad, con Python 3.14 y su librería estándar, es la mecánica completa del handoff: el runner que detecta la pseudo-tool de handoff y detiene su propio loop sin despacharla como una tool de dominio, la construcción del paquete de transferencia, el despacho automático al receptor con SOLO ese paquete (nunca el historial del emisor), y las guardas contra cadenas de handoffs sin fin. Una regla nueva, específica de este módulo: el paquete de handoff nunca incluye el historial de mensajes del emisor — solo un task (la pregunta puntual a resolver) y un context (un diccionario chico, con exactamente los datos que el receptor necesita). Pasar el historial completo "por si acaso" es exactamente el anti-patrón que este módulo llama context bloat, y lo vas a medir, en bytes, con tu propia ejecución.


Dónde estamos en el ecosistema

agent-fundamentals-and-tool-calling-guide (ya completa)
  -> construyó UN agente: tools, protocolo, el bucle, multi-tool, memoria, robustez

multi-agent-orchestration-guide (esta guía)
├── Módulo 1: Por qué multi-agente (y cuándo no)  (completo)
│   → El criterio de decisión, medido con números reales
├── Módulo 2: El patrón supervisor/router  (completo)
│   → Ruteo determinista vs. ruteo por decisión del modelo
├── Módulo 3: Pipelines secuenciales  (completo)
│   → El segundo patrón: orden fijo, sin ninguna decisión de ruteo
├── Módulo 4: Fan-out paralelo y agregación  (completo)
│   → El tercer patrón: sub-tareas independientes, repartidas y agregadas
├── Módulo 5: Handoff y delegación  ← ESTÁS AQUÍ
│   → El cuarto patrón: un agente EN CURSO cede el turno a mitad de tarea
├── Módulo 6: Estado compartido y el patrón blackboard
├── Módulo 7: Orquestando el sistema completo de Reservo
└── Módulo 8: Proyecto — el sistema multi-agente de Reservo

Este módulo no re-explica el supervisor (M2), el pipeline (M3) ni el fan-out (M4) — los reusa como el contraste que le da sentido al handoff. Los tres patrones anteriores tienen algo en común que el handoff no tiene: en los tres, la decisión de reparto ocurre antes de que exista ningún trabajo en curso. El handoff es el primer patrón de la guía donde la necesidad de otro especialista aparece durante el trabajo, no antes.


Analogía: el mesero que llama al sommelier

Estás en un restaurante. El mesero que te atiende toma tu pedido, te recomienda un plato, anota los puntos de cocción — está genuinamente trabajando tu pedido, no solo repitiéndolo. En algún momento le preguntas: "¿qué vino marida bien con esto?". El mesero no tiene por qué saber de vinos a ese nivel de detalle, y tampoco tiene por qué fingir que sí. Un mesero con buen criterio hace una sola cosa: llama al sommelier directamente, le dice qué plato pediste, y deja que el sommelier responda tu pregunta. No va hasta la cocina a preguntarle al chef "¿quién debería atender esta pregunta de vino?" — él mismo, en el momento, reconoce el límite de su propia expertise y transfiere el turno a quien sí sabe.

Fíjate en lo que el mesero no hizo: no te hizo repetir todo tu pedido al sommelier desde cero, ni el sommelier necesita saber qué plato principal recomendó el mesero antes, ni a qué hora llegaste, ni si pediste agua con o sin gas. El sommelier solo necesita una cosa concreta: qué plato vas a comer, para poder recomendar un vino que maride bien. Eso es exactamente el paquete de handoff de este módulo: el mínimo dato real que el receptor necesita, ni una línea más.


El caso que acompaña el módulo: la pregunta que excede a mitad de tarea

Los Módulos 2, 3 y 4 dejaron tres especialistas terminados: booking_agent (cotizar, reservar, cancelar), policy_agent (search_docs, el stub de política), y pricing_agent (comparar precios). Este módulo tampoco agrega ningún especialista nuevo — reusa exactamente los mismos tres, con una situación distinta:

Petición: "Cotiza Focus pro 3h. Y otra cosa, ¿qué pasa si no llego a la reserva?"

booking_agent recibe la petición completa (la palabra "cotiza" la ubica ahí, sin ambigüedad).
Turno 1 (ejecutado): get_quote(Focus, pro, 3h) -> 6000 centavos. Esto SÍ vive en su expertise.
Turno 2 (concepto): booking_agent lee la segunda pregunta -- no-presentación -- y reconoce
que NO tiene ninguna tool para resolverla. En vez de inventar una respuesta o quedarse
atascado, cede el turno a policy_agent con un paquete mínimo: la pregunta puntual, más el
precio ya cotizado (6000), por si la respuesta necesita referenciarlo.

A diferencia de la petición compuesta del Módulo 4 ("cotiza Focus pro 3h y dime la política de cancelación") —donde las dos partes eran independientes desde el principio, y por eso se podían repartir con fan-out antes de que nadie trabajara—, acá la necesidad de policy_agent no era obvia de antemano: booking_agent ya había empezado a resolver la tarea, con una tool que sí tenía, cuando se topó con el límite. Esa diferencia de cuándo se descubre la necesidad del otro especialista es el eje completo de este módulo.


Frontera con lo que ya viste (y con lo que viene)

Con los tres patrones anteriores frescos, la distinción de fondo queda completa:

  • Un supervisor (M2) decide QUIÉN empieza, desde afuera, antes de que nadie trabaje. Lee la petición cruda, una sola vez, y rutea.
  • Un pipeline (M3) fija el ORDEN, sin decidir nada en cada paso. La secuencia de etapas está escrita antes de que exista ninguna petición concreta.
  • Un fan-out (M4) reparte sub-tareas que ya se sabe, de antemano, que son independientes. El reconocimiento de independencia ocurre antes del despacho, no durante.
  • Un handoff (este módulo) lo decide un agente EN CURSO, a mitad de camino. No hay ningún momento "antes" en el que alguien haya leído la petición completa y repartido el trabajo — el propio agente que ya está resolviendo una parte descubre, sobre la marcha, que otra parte excede su expertise, y cede el turno sin volver a consultarle a nadie externo.

Esta última distinción es la que sostiene todo el módulo: el supervisor decide desde afuera, antes de que nadie trabaje; el handoff lo decide el propio agente en curso, a mitad de camino. No son el mismo mecanismo en dos momentos distintos — son dos formas genuinamente distintas de resolver "quién sigue", con costos y garantías distintas, que la lección 02 compara con números.

Y hacia adelante, una distinción que este módulo deja pendiente a propósito: cuando booking_agent le pasa el paquete a policy_agent, esa transferencia es un mensaje directo, punto a punto — el emisor arma el paquete, el receptor lo recibe, y ahí termina la relación entre los dos. Existe una forma completamente distinta de compartir información entre agentes: un espacio de estado común que cualquiera puede leer y escribir, sin que nadie tenga que armarle un paquete a nadie en particular. Eso es el blackboard, y lo construye el Módulo 6.


Prerequisitos

Conocimiento requerido:

  • ✅ Módulo 1 completo de esta guía: el criterio de decisión y el costo de coordinar, medido.
  • ✅ Módulo 2 completo: SPECIALISTS, run_specialist, los tres especialistas de Reservo, y la anatomía de cuatro pasos de un supervisor (recibir, decidir, despachar, agregar) — el punto de contraste constante de este módulo.
  • ✅ Módulo 4 completo: la distinción entre repartir trabajo antes de que nadie empiece (fan-out) y lo que este módulo agrega — descubrir la necesidad durante.
  • agent-fundamentals-and-tool-calling-guide: el protocolo tool_use/tool_result, run_agent_parallel, dispatch_parallel — la base técnica que este módulo extiende con una pseudo-tool nueva.

Recomendado:

  • ✅ Haber corrido tú mismo el dispatcher completo del Módulo 2, lección 06 — este módulo contrasta su costo, número contra número, con el costo del handoff directo.

NO requerido:

  • ❌ No necesitas una API key ni conexión a internet: la decisión de ceder el turno sigue siendo concepto, escrita a mano.
  • ❌ No necesitas ningún framework de orquestación — la pseudo-tool de handoff, el runner que la reconoce y el paquete de transferencia se construyen a mano, con dataclasses de la librería estándar.

Entorno:

  • Python 3.14.0 con su librería estándar (dataclasses, concurrent.futures). Nada que instalar.

Roadmap del módulo

Lección 01 — Introducción al módulo (esta)

El patrón handoff, la analogía del mesero y el sommelier, y la frontera con supervisor (M2), fan-out (M4) y blackboard (M6).

Lección 02 — Reconociendo cuándo hace falta un handoff

Qué pasa SIN handoff: un agente que se topa con una pregunta fuera de su expertise, ejecutado en dos modos de falla reales — una respuesta sin fundamento y un intento de usar una tool que no tiene.

Lección 03 — El paquete de handoff: qué va, qué no va

HandoffPackage, y la medición ejecutada, en bytes, de cuánto más chico es el paquete mínimo frente al historial completo del emisor — el "context bloat" cuantificado.

Lección 04 — La tool de handoff y el loop interrumpido

handoff_to_specialist como pseudo-tool, y run_agent_with_handoff: la variante del runner que reconoce esa tool especial y detiene su propio loop en vez de despacharla como una tool de dominio.

Lección 05 — El handoff de Reservo, ejecutado de punta a punta

booking_agent cotiza, se topa con el límite, cede el turno; policy_agent responde, grounded en el contexto que recibió — la pieza central del módulo, de punta a punta.

Lección 06 — Guardando contra cadenas de handoffs sin fin

Qué pasa si el receptor también intenta ceder el turno (ping-pong), o si cede a un especialista que no existe — las dos guardas que un handoff real necesita.

Lección 07 — Midiendo el costo de un handoff directo

Cuánto cuesta, en llamadas al modelo y en hops, resolver la MISMA tarea con handoff directo frente a la alternativa de volver a un supervisor externo cada vez que un agente se topa con un límite.

Lección 08 — Mini-proyecto: handoffs en Reservo

Tres escenarios nuevos — un handoff real, un caso que NO necesita handoff, y un caso donde el handoff funciona pero fan-out (M4) hubiera sido el diseño correcto desde el principio.

Mapa de progresión

Lección 01 (esta)  → El patrón, la analogía, la frontera con M2/M4/M6
Lección 02         → Por qué hace falta: los modos de falla sin handoff, ejecutados
Lección 03         → El paquete mínimo, medido en bytes contra el historial completo
Lección 04         → El mecanismo: la pseudo-tool y el loop que se detiene
Lección 05         → El handoff completo de Reservo, de punta a punta
Lección 06         → Las guardas: ping-pong y receptor inexistente
Lección 07         → El costo medido: handoff directo vs. vuelta al supervisor
Lección 08         → Proyecto: tres escenarios, con el juicio de cuándo SÍ y cuándo NO

Dificultad: ⭐⭐ ──────────────────▶ ⭐⭐⭐

Qué lograrás en este módulo

Al completar las 8 lecciones, podrás:

  1. Distinguir con precisión un handoff (decidido por un agente EN CURSO, a mitad de tarea) de un supervisor (decide desde afuera, antes de empezar) y de un fan-out (reparte lo que ya se sabía independiente desde el principio).
  2. Reconocer los modos de falla de un agente que se topa con un límite de expertise sin tener un mecanismo de handoff — y por qué ambos son peores que ceder el turno.
  3. Diseñar un paquete de handoff mínimo — qué datos SÍ necesita el receptor, y por qué el historial completo del emisor casi nunca es uno de ellos.
  4. Construir handoff_to_specialist y run_agent_with_handoff, la pseudo-tool y el runner que la reconoce sin tratarla como una tool de dominio.
  5. Ejecutar un handoff completo de Reservo, de punta a punta, con la respuesta del receptor grounded en el contexto que recibió del emisor.
  6. Guardar un sistema de handoffs contra cadenas sin fin — ping-pong entre agentes, o un receptor que no existe.
  7. Medir el costo real de un handoff directo frente a la alternativa de volver a un coordinador externo cada vez que un agente se topa con un límite.

El antes y después

ANTES del módulo:
→ "Si un agente no puede resolver algo, la única opción es volver al supervisor"
→ Pasarle a otro agente "todo el contexto por si acaso" es lo más seguro
→ Un handoff y un re-ruteo del supervisor son, en la práctica, lo mismo
→ Cualquier momento es bueno para que un agente decida transferir el control

DESPUÉS del módulo:
→ Un agente EN CURSO puede ceder el turno directamente, sin volver a nadie externo -- MEDIDO,
  cuesta menos llamadas y menos hops que la vuelta obligada
→ El paquete mínimo (task + context chico) resuelve la tarea igual de bien que el historial
  completo, pesando una fracción -- MEDIDO en bytes
→ Un handoff decidido ANTES de que nadie trabaje no es un handoff -- es un supervisor o un
  fan-out mal etiquetados
→ Un sistema de handoffs sin guardas puede entrar en ping-pong -- necesita un límite explícito

Trampas a evitar al cursar este módulo

1. "El handoff y el ruteo del supervisor son el mismo mecanismo, solo que más tarde"

No. El supervisor (M2) lee la petición completa antes de que exista ningún trabajo en curso. El handoff lo decide un agente que ya está trabajando una parte real de la tarea. La lección 02 lo demuestra ejecutando: sin handoff, booking_agent no tiene forma de "devolver el control" a un supervisor que nunca estuvo mirando — tendría que fabricar una respuesta o quedarse atascado.

2. "Pasar el historial completo al receptor es más seguro que armar un paquete mínimo"

Al revés. La lección 03 mide, en bytes, cuánto más pesa el historial completo — y la lección 04 muestra, ejecutando, qué se rompe si intentas pasarlo donde se espera una tarea puntual. Más contexto no es más seguro: es más ruido que el receptor tiene que ignorar, y una fuente real de errores de formato.

3. "Cualquier petición con dos partes es candidata a handoff"

No — si las dos partes son independientes desde que llega la petición, el patrón correcto es fan-out (M4), no handoff. El handoff es específicamente para cuando la necesidad del segundo especialista se descubre durante el trabajo del primero, no antes. El mini-proyecto (lección 08) incluye un caso diseñado para poner a prueba exactamente esta distinción.

4. "Un sistema de handoffs no necesita límites — el modelo nunca se equivocaría"

Sí necesita. La lección 06 construye, y dispara de verdad, un caso de ping-pong (dos agentes cediéndose el turno entre ellos) y un caso de receptor inexistente — los dos fallan ruidoso, con un error claro, porque un sistema sin esas guardas podría reenviar el paquete indefinidamente.


Cómo trabajar este módulo

  1. Ejecuta la lección 02 tú mismo, con atención al número inventado. Ver, con tus propios ojos, que un agente sin handoff puede responder con un dato que no coincide con la política real — no solo "sin fundamento", sino directamente incorrecto — es lo que hace que el resto del módulo se sienta justificado, no un ejercicio académico.
  2. No te saltes la medición en bytes de la lección 03. Es la evidencia central de "qué va, qué no va" en un paquete de handoff — y se vuelve más contundente cuanto más larga sea la conversación del emisor antes del handoff, algo que la propia lección demuestra agregando un paso más.
  3. La lección 07 cierra el argumento económico del módulo. Practicar la comparación con distintos números de pasos internos antes del mini-proyecto hace que la lección 08 se sienta como aplicar un criterio, no memorizar un ejemplo.

Tiempo estimado:

Lección 01 (esta)  →  15 min lectura
Lección 02         →  20 min + correr la demo
Lección 03         →  25 min + correr la demo
Lección 04         →  25 min + correr la demo
Lección 05         →  30 min + correr la demo (la más densa del módulo)
Lección 06         →  25 min + correr la demo
Lección 07         →  25 min + correr la demo
Lección 08         →  30 min + aplicar el patrón completo

Total: ~3.2 horas

Evidencia de éxito

Antes de avanzar al Módulo 6 (Estado compartido y el patrón blackboard), deberías poder:

  • Explicar, con tus propias palabras, la diferencia entre un supervisor que decide desde afuera y un handoff que decide un agente en curso — sin confundir los dos momentos.
  • Construir HandoffPackage, handoff_to_specialist y run_agent_with_handoff, y ejecutar un handoff completo de booking_agent a policy_agent.
  • Citar de memoria el resultado en bytes de la lección 03: cuánto más chico es el paquete mínimo frente al historial completo, y por qué esa brecha crece con conversaciones más largas.
  • Citar de memoria el resultado de la lección 07: cuántas llamadas y hops ahorra un handoff directo frente a la vuelta obligada a un supervisor.
  • Reconocer, en un escenario nuevo, si corresponde handoff, o si en realidad corresponde supervisor (M2) o fan-out (M4) — la distinción que el mini-proyecto pone a prueba.

Resumen

  • Este módulo construye el cuarto patrón de los cinco que anticipó el Módulo 1: handoff — un agente que ya está trabajando descubre, a mitad de tarea, que necesita a otro especialista, y cede el turno directamente, sin volver a un coordinador externo.
  • Regla dura: la decisión de ceder el turno sigue siendo concepto (claude-sonnet-5); el mecanismo que la reconoce, el paquete de transferencia y las guardas contra cadenas sin fin se ejecutan de verdad con Python 3.14. El paquete de handoff NUNCA incluye el historial completo del emisor.
  • El caso reusa, sin cambios, los tres especialistas de Reservo — booking_agent cotiza y se topa con una pregunta de no-presentación que excede su expertise, y cede el turno a policy_agent con un paquete mínimo.
  • Frontera clara con lo que ya viste y con lo que sigue: el supervisor (M2) decide desde afuera, antes de empezar; el fan-out (M4) reparte lo que ya se sabía independiente; el handoff (este módulo) lo decide un agente en curso, a mitad de camino; el blackboard (M6) comparte estado sin pasarse paquetes punto a punto.

Siguiente lección: 02 — Reconociendo cuándo hace falta un handoff. Ejecutamos qué le pasa a un agente que se topa con un límite de expertise sin tener ningún mecanismo para cederlo.


Recursos adicionales

  1. Anthropic — Building effective agents — El principio de mantener a cada agente con un alcance acotado, y transferir el control cuando una tarea lo excede, en vez de forzar que un solo agente lo resuelva todo.
  2. Anthropic — Multi-agent research system — Un caso real de Anthropic donde un sub-agente reconoce el límite de su propio alcance y lo comunica explícitamente, en vez de responder más allá de lo que puede fundamentar.
  3. Anthropic — Tool use (function calling) overview — El protocolo tool_use/tool_result que la pseudo-tool de handoff de este módulo extiende, sin romperlo.
  4. Python 3.14 — What's New — La versión con la que se ejecuta toda la orquestación de esta guía.