Hoy, Sakana AI lanzó Sakana Fugu. Es un sistema de orquestación de múltiples agentes que se comporta como un solo modelo. Envía una solicitud a un único punto final. Fugu decide cómo manejarlo internamente. Resuelve una tarea directamente cuando eso es suficiente. También reúne y coordina un equipo de modelos expertos cuando es necesario. La complejidad de un sistema multiagente nunca llega a su código.
TL;DR
Fugu ofrece un sistema multiagente detrás de una API compatible con OpenAI. Fugu Ultra lidera la mayoría de los puntos de referencia de codificación y razonamiento publicados. El orquestador vence a los modelos individuales que coordina. La exclusión voluntaria y el enrutamiento de proveedores apuntan al cumplimiento y al riesgo de un solo proveedor. El enrutamiento es propietario, por lo que la selección del modelo por consulta permanece oculta.
¿Qué es Sakana Fugu?
Fugu es en sí mismo un modelo de lenguaje. Está capacitado para llamar a otros LLM en un grupo de agentes. Ese grupo incluye instancias de sí mismo, llamadas recursivamente. Fugu gestiona la selección, delegación, verificación y síntesis de modelos internamente.
En lugar de roles o flujos de trabajo codificados, Fugu aprende a coordinar. Decide cuándo delegar y cómo deben comunicarse los agentes. Luego combina su trabajo en una sola respuesta. Desde fuera se llama un modelo único. En el interior, un sistema coordinado de expertos hace el trabajo.
Sakana AI plantea esto como una protección contra la dependencia de un solo proveedor. Si un proveedor restringe el acceso, Fugu evita la interrupción. El equipo de investigación cita como motivación los recientes controles de exportación de los modelos Fable y Mythos de Anthropic. Con el tiempo, los modelos más nuevos se pueden incorporar a la piscina.
Fugu y Fugu Ultra: dos modelos, una API
Fugu se entrega en dos variantes, ambas detrás de una API compatible con OpenAI:
Fugu equilibra un rendimiento sólido con una baja latencia. Es un valor predeterminado para la codificación diaria, la revisión de códigos y los chatbots. También se adapta a herramientas como Codex. Puede excluir a agentes específicos de su grupo. Eso ayuda a los equipos a cumplir con los requisitos de datos, privacidad y cumplimiento. Fugu Ultra está optimizado para ofrecer la máxima calidad de respuesta en problemas difíciles de varios pasos. Coordina un grupo más profundo de agentes expertos. Su grupo es fijo, por lo que la exclusión voluntaria no está disponible. El ID del modelo actual es fugu-ultra-20260615.
La investigación detrás del orquestador
Fugu se basa en dos artículos de ICLR 2026, Trinity and the Conductor, sobre orquestación aprendida.
TRINITY utiliza un coordinador evolucionado liviano en varios turnos. Asigna roles de Pensador, Trabajador o Verificador para delegar el trabajo de forma adaptativa. El director está capacitado con aprendizaje por refuerzo. Descubre estrategias de coordinación del lenguaje natural e indicaciones enfocadas para diversos grupos de LLM.
Juntos, muestran que los sistemas pueden aprender a ensamblar y enrutar agentes por tarea. Esto reemplaza los flujos de trabajo diseñados a mano.
Explicador interactivo
Presione Ejecutar orquestación para observar los pasos de enrutamiento.
‘; Q(‘#agentes’).innerHTML = ”; Q(‘#respuesta’).innerHTML = ‘Esperando correr…‘; Q(‘#status’).textContent=”Listo.”; } Q(‘#resetBtn’).addEventListener(‘click’, function(){ if(!state.busy) reset(); }); función addStep(n, rol, html){ var d = document.createElement(‘div’); d.className=”paso”; var r = rol? ‘‘+rol+’‘ : ”; d.innerHTML = ‘
‘+n+’
‘+r+html+’
‘; Q(‘#log’).appendChild(d); Q(‘#log’).scrollTop = Q(‘#log’).scrollHeight; } función AgentBars(usado){ var box = Q(‘#agentes’); box.innerHTML=”; used.forEach(function(u){ var línea = document.createElement(‘div’); line.className=”agentline”; line.innerHTML = ‘‘+AGENTES[u.id].nombre+’‘+ ‘‘+ ‘‘+u.rol+’‘; box.appendChild(línea); var barra = line.querySelector(‘i’); setTimeout(function(){ bar.style.width = (40+Math.random()*55)+’%’; }, 120); }); } función ejecutar(){ si(estado.busy) retorno; estado.ocupado = verdadero; Q(‘#runBtn’).disabled = verdadero; Q(‘#resetBtn’).disabled = verdadero; Q(‘#log’).innerHTML=”; Q(‘#agentes’).innerHTML=”; Q(‘#respuesta’).innerHTML=’Orquestando_‘; Q(‘#status’).textContent=”En ejecución\u2026″; var tarea = Q(‘#tarea’).valor; var ultra = estado.modelo ===’ultra’; var piscina = activePool(); var trabajadores = pool.filter(function(a){return a!==’self’;}); si(trabajadores.longitud===0) trabajadores=[‘self’]; var T = TAREAS[task]; // elige modo: ultra o investigación/repro/razón => equipo multiagente var equipo = ultra || tarea===’investigación’ || tarea===’repro’ || tarea===’razón’; var pasos = []; pasos.push({d:300, rol:null, html:’Solicitud recibida en un único punto final. Sin código multiagente del lado del cliente.’}); pasos.push({d:600, role:null, html:’Decidir: ‘+(equipo?’esta tarea consta de varios pasos: formar un equipo.’:’un modelo sólido es suficiente: resolver directamente y luego verificar.’)}); var utilizada = []; if(equipo){ var pensador = trabajadores[0]; var trabajador = trabajadores[1] || trabajadores[0]; verificador var = trabajadores[2] || trabajadores[0]; pasos.push({d:700, rol:’Pensador’, html:”+AGENTES[thinker].name+’ redacta un plan y descompone la tarea.’}); pasos.push({d:700, rol:’Trabajador’, html:”+AGENTES[worker].name+’ ejecuta subtareas y produce resultados candidatos.’}); if(pool.indexOf(‘self’)>-1){ pasos.push({d:600, role:’Worker’, html:’Fugu emite una autollamada recursiva en un subproblema difícil.’}); } pasos.push({d:700, rol:’Verificador’, html:”+AGENTES[verifier].name+’ comprueba el resultado y marca los huecos para revisar.’}); usado = [{id:thinker,role:’Thinker’},{id:worker,role:’Worker’},{id:verifier,role:’Verifier’}]; if(pool.indexOf(‘self’)>-1) used.push({id:’self’,role:’Trabajador’}); } más { var solo = trabajadores[0]; pasos.push({d:700, rol:’Trabajador’, html:”+AGENTES[solo].name+’ maneja la tarea en una sola pasada.’}); pasos.push({d:700, rol:’Verificador’, html:”+AGENTES[(workers[1]||solo)].name+’ verifica la diferencia antes de regresar.’}); usado = [{id:solo,role:’Worker’},{id:(workers[1]||solo),rol:’Verificador’}]; } if(estado.restringido){ pasos.splice(2,0,{d:650, rol:null, html:”+AGENTES[state.restricted].nombre+’ está restringido. Ruta alrededor de él: sin cambios de integración.’}); } pasos.push({d:700, role:null, html:’Sintetizar el trabajo de los agentes en una respuesta confiable.’}); // deduplicación utilizada por id manteniendo el primer rol var visto={}; usado = usado.filtro(función(u){ si(visto[u.id])devuelve falso; visto[u.id]=1; devolver verdadero; }); var i=0, n=0; función siguiente(){ if(i>=steps.length){ finalizar(usado, T); devolver; } var s = pasos[i++]; n++; setTimeout(function(){ addStep(n, s.role, s.html); if(n===Math.min(4,steps.length-1)) agentBars(used); next(); }, sd); } próximo(); } función finalizar(usado, T){ setTimeout(función(){ QA(‘#agentes .bar i’).forEach(función(b){ b.style.width=”100%”; }); var mhtml = T.metrics.map(función(m){ retorno ‘
‘+m[0]+’‘+m[1]+’
‘; }).unirse(”); Q(‘#respuesta’).innerHTML = ‘
‘+T.respuesta+’
‘+mhtml; Q(‘#status’).textContent=”Listo. Los detalles de enrutamiento son propietarios y no se exponen en producción.”; estado.ocupado=falso; Q(‘#runBtn’).disabled=false; Q(‘#resetBtn’).disabled=false; sz(); }, 500); } Q(‘#runBtn’).addEventListener(‘hacer clic’, ejecutar); Q(‘#task’).addEventListener(‘cambiar’, función(){ if(!state.busy) reset(); }); renderModel(); // —- cambio de tamaño automático para la inserción de iframe de WordPress —- función sz(){ var h = root.offsetHeight + 40; if(window.parent && window.parent!==window){ window.parent.postMessage({tipo:’fugu-sim-height’, altura:h}, ‘*’); } } window.addEventListener(‘cargar’, sz); window.addEventListener(‘resize’, sz); setTimeout(tamaño, 300); // observar cambios DOM que afectan la altura if(window.MutationObserver){ new MutationObserver(sz).observe(root, {childList:true, subtree:true, atributos:true}); } })();