¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Agentes orquestador y trabajadores

Después de esta lección: Puedo repartir una tarea en encargos que se entienden solos, y comprobar cada resultado antes de unirlos.

Lección de 65 min6 comandosLaboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

Un trabajador solo conoce su encargo

El patrón orquestador-trabajadores es un programa donde un agente reparte una tarea en encargos, da cada uno a un trabajador y une los resultados. Importa porque un trabajador no sabe nada más que su encargo.

Un encargo vago recibe una respuesta segura a la pregunta equivocada. Un encargo que se entiende solo recibe una respuesta que puedes comprobar.

Al final de esta lección

Nota

Puedo repartir una tarea en encargos que se entienden solos, y comprobar cada resultado antes de unirlos.

Palabras clave

PalabraQué significa
Encargotodo lo que recibe un trabajador: pregunta, material y forma de la respuesta
Forma del resultadolos campos que un trabajador debe devolver
Materialel texto que un trabajador puede usar para responder
Validacióncomprobar un resultado antes de usarlo
Uniónjuntar los resultados aceptados
Fuente desconocidauna fuente que un trabajador cita pero nunca recibió

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Qué lleva un encargo

Un trabajador no ve la tarea, ni los otros encargos, ni la conversación. Lo que no está en el encargo no existe.

Así, un encargo lleva la pregunta, el material que se puede usar, la forma de la respuesta y un límite de tamaño. El material es el texto mismo, no la promesa de que el trabajador lo buscará.

Ejemplo resuelto: un encargo

CampoEjemploPor qué está
question¿Cuánto costaría un domingo en horas de personal?Una pregunta, no toda la tarea
materialLa hoja de costes de personal, como textoEl trabajador no puede usar nada más
sourcess2Para que la respuesta diga de dónde viene
replyUn objeto con answer y sourcesPara que el orquestador la compruebe

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Valida un resultado antes de unirlo

Un resultado es un dato que viene de una parte del sistema que no controlas. Comprueba primero la forma: ¿hay respuesta, hay una lista de fuentes? Luego comprueba que cada fuente es una que dio el encargo.

Une solo lo que pasa. El módulo sobre cómo construir agentes pasa un mensaje entre agentes. Aquí decidimos si creemos lo que vuelve.

Un error frecuente

Advertencia

Mucha gente une todos los resultados y arregla el desorden después. Un resultado malo pesa entonces lo mismo que uno bueno en la respuesta final. Rechaza en la puerta y guarda el motivo.

Escribir el ayudante del modelo, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el ayudante del modelo, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"estado \" + res.status);' '    const d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' 'module.exports = { ask };' >> model.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el orquestador, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const SOURCES = {' '  s1: \"Encuesta: 212 de 400 visitantes pidieron abrir los domingos.\",' '  s2: \"Personal: seis horas a 18 euros la hora son 108 euros cada domingo.\",' '  s3: \"Visitas: el sábado hubo 310 visitas el mes pasado, un día de semana 120.\",' '};' '// Un encargo lleva todo lo que su trabajador puede usar: la pregunta y el texto.' 'function brief(id, question, ids) {' '  const material = ids.map(function (i) { return SOURCES[i]; });' '  return { id: id, question: question, sources: ids, material: material, reply: \"un objeto con answer y sources\" };' '}' > team.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el orquestador, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Trabajadores con guion. Cada uno ve su encargo y nada más.' 'const WORKERS = {' '  b1: function (b) { return { answer: \"212 de 400 visitantes lo quieren\", sources: [\"s1\"] }; },' '  b2: function (b) { return { answer: \"108 euros cada domingo\", sources: [\"s2\"] }; },' '  b3: function (b) { return { answer: \"Los fines de semana hay mucha gente\", sources: [\"s9\"] }; },' '};' 'function problems(b, r) {' '  const out = [];' '  const full = typeof r.answer === \"string\" && r.answer.trim().length > 0;' '  if (full === false) out.push(\"falta la respuesta\");' '  if (Array.isArray(r.sources) === false || r.sources.length === 0) out.push(\"faltan las fuentes\");' '  else r.sources.forEach(function (s) { if (b.sources.includes(s) === false) out.push(\"fuente desconocida \" + s); });' '  return out;' '}' >> team.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el orquestador, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const own = \"¿Cuánta gente hay en la biblioteca un día de fin de semana?\";' '  const q = [{ role: \"user\", content: \"Escribe una pregunta de investigación corta sobre la afluencia a una biblioteca en fin de semana.\" }];' '  const text = (await ask(q, own, 30)).text.trim();' '  const briefs = [' '    brief(\"b1\", \"¿Cuántos visitantes quieren abrir los domingos?\", [\"s1\"]),' '    brief(\"b2\", \"¿Cuánto costaría un domingo en horas de personal?\", [\"s2\"]),' '    brief(\"b3\", text.endsWith(\"?\") ? text : own, [\"s3\"]),' '  ];' '  for (const b of briefs) {' '    const r = WORKERS[b.id](b);' '    const p = problems(b, r);' '    console.log(b.id + \" [\" + b.material.length + \" fuente] \" + b.question);' '    console.log(\"   \" + (p.length ? \"RECHAZADO: \" + p.join(\", \") : \"aceptado: \" + r.answer));' '  }' '}' 'main();' >> team.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecutar el orquestador

Comando
docker exec -w /home/node/project agent node team.js

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Los trabajadores tienen guion

El laboratorio solo tiene un modelo, así que un equipo real sería un modelo haciendo todos los papeles. Los tres trabajadores de aquí son funciones simples con respuestas grabadas. La única llamada en vivo redacta una pregunta de investigación.

Un sistema real envía cada encargo a un modelo, y la comprobación sigue igual.

Una salida posible

LíneaQué muestra
b1 [1 fuente] ¿Cuántos visitantes quieren abrir los domingos?Un encargo con su material
aceptado: 212 de 400 visitantes lo quierenLa forma y las fuentes pasan
aceptado: 108 euros cada domingoEl segundo trabajador también pasa
RECHAZADO: fuente desconocida s9El tercero cita una fuente que nunca recibió

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Sobre este laboratorio y su código: Laboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.