Más agentes no es más inteligencia
Un sistema multiagente es un programa donde una llamada al modelo reparte trabajo a otras llamadas, cada una con su propio contexto. Importa porque cada agente que añades se paga en tokens, en tiempo y en nuevas formas de fallar.
Los equipos de agentes se venden como el siguiente paso. A veces lo son. Muchas veces un solo agente con buenas herramientas hace el mismo trabajo por mucho menos.
Al final de esta lección
Nota
Puedo decir cuándo compensa usar más de un agente, y demostrarlo con estimaciones de tokens.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Ventana de contexto | el máximo de texto que un agente puede tener a la vez |
| Orquestador | el agente que reparte el trabajo y reúne las respuestas |
| Trabajador | un agente que hace una parte y informa |
| Texto común | las instrucciones que cada agente debe volver a leer |
| Trabajo acoplado | pasos en que cada uno necesita el resultado del anterior |
| Paralelo | partes que se pueden hacer a la vez |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Cada agente vuelve a leer el texto común
Un agente solo lee sus instrucciones una vez. Un equipo, no. El orquestador las lee, y cada trabajador también, porque tiene su propio contexto y no ve el de los demás.
Así, un equipo cuesta el texto común una vez por agente, más un encargo y un resultado por parte. La parte en sí la lee una sola vez el trabajador que la tiene.
Ejemplo resuelto: tres informes
| Quién | Lee | Tokens |
|---|---|---|
| Un solo agente | Común 1500 + tres informes 5500 + respuesta 400 | 7400 |
| Orquestador | Común 1500 + tres encargos 600 + final 300 | 2400 |
| Tres trabajadores | Común 1500 cada uno + un informe + un resultado | 10600 |
| El equipo en total | Orquestador y trabajadores juntos | 13000 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Cuándo compensa dividir
Divide cuando un solo agente no puede con el trabajo. Divide cuando las partes son independientes y la velocidad importa. Divide cuando una parte necesita un contexto limpio, para que el texto anterior no la confunda.
No dividas el trabajo acoplado. Si el paso dos necesita el resultado exacto del paso uno, un segundo agente solo añade un resumen que pierde información.
Un error frecuente
Advertencia
Mucha gente divide una tarea porque tiene varios sustantivos. Cuenta las dependencias, no los sustantivos. Un trabajo que comparte un solo registro y lo edita en orden es cosa de un solo agente.
Escribir el ayudante del modelo, parte 1
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
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 script de costes, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const WINDOW = 8000; // tokens que un agente puede contener' 'const NOTE = 200; // un encargo o un resultado' 'const CASES = [' ' { name: \"tres informes\", shared: 1500, parts: [1800, 2000, 1700], coupled: false },' ' { name: \"un informe largo\", shared: 1500, parts: [900], coupled: false },' ' { name: \"editar un archivo\", shared: 1500, parts: [1200, 1000], coupled: true },' ' { name: \"diez documentos\", shared: 1500, parts: Array(10).fill(900), coupled: false },' '];' > split.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 script de costes, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function sum(list) { return list.reduce(function (a, b) { return a + b; }, 0); }' '// Un solo agente lee el texto común una vez, luego todas las partes y responde.' 'function single(c) { return c.shared + sum(c.parts) + 400; }' '// Un equipo: el jefe vuelve a leer el texto común, y cada trabajador también.' 'function team(c) {' ' const boss = c.shared + NOTE * c.parts.length + 300;' ' const workers = c.parts.map(function (p) { return c.shared + p + NOTE; });' ' return boss + sum(workers);' '}' >> split.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 script de costes, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function choose(c) {' ' if (c.coupled || c.parts.length < 2) return \"uno\";' ' if (single(c) > WINDOW) return \"varios\";' ' return team(c) <= 2 * single(c) ? \"varios\" : \"uno\";' '}' 'async function main() {' ' for (const c of CASES) {' ' const x = Math.round((team(c) * 10) / single(c)) / 10;' ' console.log(c.name + \": uno \" + single(c) + \", equipo \" + team(c) + \" (x\" + x + \"), elegir \" + choose(c));' ' }' ' const q = [{ role: \"user\", content: \"En una frase: nombra un trabajo que no debe repartirse entre agentes.\" }];' ' const r = await ask(q, \"Editar un archivo por pasos, porque cada paso necesita el anterior.\", 40);' ' console.log(\"Modelo: \" + r.text.trim());' '}' 'main();' >> split.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 script de costes
docker exec -w /home/node/project agent node split.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Son estimaciones
El Run no llama a un equipo. Hace las cuentas sobre cuatro casos grabados, porque un equipo real gastaría de golpe la asignación del laboratorio. Los tamaños en tokens son inventados, y un sistema real mide los suyos.
La única llamada en vivo solo pide una frase.
Una salida posible
| Línea | Qué muestra |
|---|---|
| tres informes: uno 7400, equipo 13000 (x1.8), elegir varios | Cabe en una ventana, pero el equipo cuesta menos del doble |
| un informe largo: … elegir uno | Una sola parte no se puede repartir |
| editar un archivo: … elegir uno | El trabajo acoplado se queda con un agente |
| diez documentos: uno 10900, equipo 29800 (x2.7), elegir varios | Un solo agente no cabe, así que compensa pagar más |
| Modelo: … | Una frase que cambia en cada ejecución |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.