Los agents no necesitan más prompts, necesitan flujo de control
(bsuh.bearblog.dev)- Los agentes que manejan tareas complejas de forma confiable no necesitan cadenas de prompts más sofisticadas, sino flujo de control determinista codificado en software
- Si dependes de expresiones como MANDATORY o DO NOT SKIP en el prompt, ya llegaste al límite del prompting
- Si imaginas un lenguaje de programación donde las oraciones funcionan como sugerencias y las funciones alucinan mientras devuelven “Success”, a medida que crece la complejidad se vuelve imposible razonar sobre el sistema y la confiabilidad se derrumba
- El software escala mediante composicionalidad recursiva, formado por bibliotecas, módulos y funciones, y como ofrece un comportamiento predecible permite el razonamiento local
- Las cadenas de prompts son útiles para tareas acotadas, pero no comparten esas propiedades porque son no deterministas, están débilmente especificadas y son difíciles de verificar
Estructura necesaria para la confiabilidad de los agentes
- Para asegurar la confiabilidad, la lógica debe sacarse de la explicación en lenguaje natural y trasladarse al runtime
- La estructura necesaria es un andamiaje determinista que trate al LLM no como el sistema completo, sino como un componente
- Este andamiaje debe incluir transiciones de estado explícitas y checkpoints de validación
- La orquestación determinista por sí sola no basta; un sistema que puede fallar en silencio necesita detección agresiva de errores
- Sin validación programática, las opciones se reducen a tres
-
Cuidador (Babysitter)
- Una persona debe permanecer dentro del loop para detectar los errores antes de que se propaguen
-
Auditor (Auditor)
- Después de terminar la ejecución, debe verificarse a fondo todo el resultado
-
Oración (Prayer)
- Se termina dependiendo de aceptar el resultado por intuición o por sensación
-
1 comentarios
Comentarios de Hacker News
1000% de acuerdo. Cada vez me cuesta más creerle a Anthropic con ese redoble constante de “constrúyanlo pensando en el rendimiento de los modelos del futuro, pronto van a mejorar”.
Hice un agente de QA que recorría 200 archivos Markdown de requisitos en una sesión de navegador, y era un buen sistema que mejoró bastante la eficiencia del equipo. Pero cuando dejabas en manos del modelo el flujo de control de alto nivel, con algo como “revisa los archivos de requisitos de este directorio y, para cada archivo, crea tareas para verificar si la app cumple esos requisitos”, se desmoronaba a partir de unos 30 archivos.
Se saltaba archivos, o probaba algunos grupos de archivos tres veces, haciendo que algo de 3 minutos tomara 10, o volvía a probar sin motivo los 4 archivos anteriores por un error en uno solo. En Opus 4.6 y GPT 5.4, y también en una mirada rápida a Opus 4.7 y GPT 5.5, la capacidad de orquestar workflows era inconsistente.
Al final hice un arnés determinista muy simple alrededor del modelo: llamarlo para cada caso de prueba, guardar los resultados en un arreglo y luego escribirlos en un archivo, y la confiabilidad del sistema mejoró de forma abrumadora. Pero plataformas de agentes administrados como Cursor Cloud Agents o Anthropic parecen demasiado obsesionadas con que “el agente debe ejecutar todo”, y no ven el valor de meter un poco de determinismo en los puntos adecuados.
Porque eso enfría la narrativa de que esta tecnología va a reemplazar personas enteras, workflows completos o proyectos. Sí creo que puede aumentar mucho la productividad y tener efectos desastrosos en el mercado laboral y los salarios de desarrolladores, pero no parece que la versión actual de esta tecnología vaya a llegar al nivel que ellos dicen. Si la hubieran posicionado como “una herramienta muy útil que elimina buena parte del trabajo tedioso de los equipos humanos de desarrollo”, a los desarrolladores les habría encantado, pero menos a los ejecutivos, y los inversionistas probablemente no lo habrían permitido.
Además, las etapas finas y fuertemente controladas son mucho más amigables para conectar modelos más pequeños, más baratos y especializados que un modelo enorme capaz de automatizar pruebas o escribir al instante 5 tomos de fanfic de CSI.
¿No hay benchmarks donde dejan intentar varias veces el mismo problema y luego ignoran la tasa de fallos, quedándose con el resultado si una sola vez salió bien?
apply_patchconcheck_compilationyrun_unit_tests. La herramienta todavía se llamaapply_patch, pero ahora, si el parche tiene éxito, también devuelve información extra sobre build y pruebas.La tasa de éxito del agente pasó de alrededor de 80% a algo que, hasta ahora, parece casi determinista. Ya no necesito describir en el prompt el proceso de compilación y pruebas unitarias; basta con ejecutarlo bajo ciertas dependencias y devolver el resultado.
También siento que me estoy alejando de la moda actual. Llevo mucho tiempo usando tokens prepago y arneses personalizados, y simplemente funciona bien. Se puede ignorar la mayoría de las noticias. En problemas apuntados explícitamente, las herramientas tipo Copilot ya no sirven, y en algunos codebases, aun usando el mismo modelo basado en GPT 5.4, la diferencia de rendimiento está en otra dimensión.
Todo el mundo se está perdiendo este patrón con las skills. Si pones código junto a
SKILL.md, puedes garantizar ciertos comportamientos, pero por alguna razón todos están adictos a escribir prompts. Ni siquiera hace falta crear un CLI; con un simpleskill.pyque contenga la tarea basta. También puedes tener un helper que invoqueclaude -p.Sería gracioso que dentro de unos años la gente siguiera usando LLM, pero solo a través de un vocabulario y gramática controlados que al final habría que aprender. Como hace 15 años, cuando todo el mundo se pasó a NoSQL y enseguida volvió a crear esquemas dentro de JSON.
Parte del problema quizá sea que desde el principio se aplicó mal el LLM. Como se ha dicho en otros lados, tal vez el prompt del agente debería ser escribe código que ejecute la tarea de la forma más repetible, verificable y determinista posible.
También debería incluir validación de la salida del agente. El objetivo general es sacar al LLM de las tareas que un programa puede resolver de forma más eficiente y, muchas veces, más precisa.
Es mala idea conectar la IA a producción para que haga cosas directamente vía llamadas API. Creo que el único uso que debería tener la IA en una app es leer, clasificar y cosas así. Básicamente reemplazar la “R” de las viejas apps CRUD.
Está bien usar ese mismo endpoint “R” basado en IA para autocompletar formularios de “C”, “U” y “D” según el prompt, pero no debería modificar nada para un cliente antes de que un humano lo revise. Una app CRUD sigue siendo una app CRUD y lo seguirá siendo; lo único que apareció es un endpoint “R” muy inteligente que sugiere acciones o autocompleta formularios para clientes, herramientas internas, pipelines de Jenkins, etc. Puede sugerir acciones, pero no ejecutarlas directamente.
llm -> prompt -> result, luegollm -> prompt + prompt encoded as skill -> result, y luegollm -> prompt + deterministic code encoded as skill -> result.Al principio puedes acortar el camino hacia el código determinista haciendo que el código se genere con prompts, pero sigue siendo código determinista dentro de un wrapper no determinista. Para que las tareas largas tengan éxito, muchas veces hace falta esa capa de determinismo que suele faltar.
El código determinista tiene que estar fuera del límite no determinista, ya sea vía loops de agentes o frameworks. Entonces queda algo como
flujo de agente determinista -> toma de decisiones no determinista -> herramientas deterministas, donde el juicio no determinista queda entre capas de determinismo. En experimentos ha sido un patrón muy potente, y funciona aún mejor cuando el agente construye su propio determinismo con herramientas como auto-researcher.Ahora usamos un pequeño lenguaje específico de dominio y una sola herramienta, y el agente recibe como entrada un script escrito en ese lenguaje. Así podemos manejar casos de uso más dinámicos, y el parser detecta fácilmente la sintaxis incorrecta para devolvérsela al agente.
El equipo de control de hardware entregaba las especificaciones en documentos y hojas de cálculo, y el equipo móvil las usaba para programar la librería de interfaz y luego validarla contra el servidor. Yo convertí esos documentos a TSV y le pasé partes a Claude para que escribiera un parser TSV capaz de conservar los matices de una especificación escrita por humanos.
Hicieron falta más de 150 iteraciones para cubrir todos los casos límite y generar resultados intermedios en JSON. Después, Claude me ayudó a escribir un generador de código que montaba código glue personalizado sobre Apollo para producir el código que consumía la app móvil.
Todo este pipeline corre como parte de Github Actions, y solo llama a Claude cuando falla el validador de la librería. En ese caso, hay un archivo md incluido en la solicitud para pedirle que averigüe qué salió mal, proponga una solución y cree un PR. Luego un humano revisa, ajusta y hace merge. El costo total en créditos hasta ahora ha sido menor a 350 dólares.
Estoy de acuerdo con la idea general, pero creo que la conclusión debería cambiar. Cuando llegas al límite de los prompts, en vez de intentar que el LLM haga la tarea en tiempo de ejecución, deberías hacer que el LLM escriba el software que hará la tarea.
En tiempo de ejecución, el papel del LLM normalmente se reducirá a ayudar al usuario a elegir entradas adecuadas para un sistema de software que ya tiene reglas de negocio estrictas incorporadas.
La primera semana, los prompts no paraban de crecer y el rendimiento empeoraba. La segunda semana me concentré en definir con precisión objetos como notas, tareas, proyectos y personas, y en definir métodos que realizan operaciones bien delimitadas sobre esos objetos. Como dices, la superficie del agente se reduce a una capa de traducción que convierte lenguaje natural en comandos y argumentos que pasan por un validador de entradas.
Un LLM así quizá habría rendido mejor en la prueba de strawberry.
Hice que Claude escribiera por sí mismo unos cuantos scripts de shell para manejar casos comunes en mi workflow, como ejecutar pruebas. Ahora, en vez de dar vueltas durante 30 minutos, simplemente ejecuta esas herramientas y termina la configuración.
Cada vez que pide permiso para correr un one-liner raro de shell o Python para hacer algo puntual, termino pensando si no debería hacer que use una herramienta que pueda aprobarse automáticamente.
Por eso se usa tanto la expresión “IA de próxima generación”. No significa solo LLM. Los LLM son bastante impresionantes, y creo que seguirán generando valor al usarse y optimizarse de formas más interesantes, incluso si no hubiera más avances fundamentales.
Pero en ciertas áreas sí parece hacer falta algún tipo de mejora fundamental de próxima generación. El hecho de que un LLM vuelva borroso un “nunca hagas X” y, después de muchas tareas, termine interpretándolo como “por favor haz X” parece estar muy cerca de cómo funciona en lo esencial. Es fácil olvidarlo porque seguimos en la emoción inicial de descubrir qué podemos hacer, pero los LLM no son todo lo que buscamos en IA.
Tiene que existir una arquitectura que trate “nunca hagas X” más como lo haría un humano. También tiene que existir una arquitectura con una jerarquía de memoria parecida a la humana, en vez de una mera “ventana de contexto”. Que si dos personas hablan lo suficiente con la misma IA, al final terminen siendo dos entidades realmente distintas, no solo la misma IA con distinta ventana de contexto.
Claro, nadie sabe cómo sería eso. Pero tampoco hay motivo para pensar que los LLM sean la respuesta final de la IA.
No estoy de acuerdo; yo ya di la vuelta completa de enforcement por prompt → flujo determinista → enforcement por prompt otra vez.
La razón por la que “no te saltes nada” falla es que el agente está cargando demasiadas cosas, y otros elementos del contexto terminan desviando la atención de esa instrucción.
Pero nadie dijo que el agente que se encarga de hacer cumplir eso tenga que ser el mismo que construye. Se puede codificar cierta lógica inteligente de decisión dentro de un flujo de control determinista, pero si lo haces demasiado rígido no funciona bien, y si lo haces demasiado complejo, termina saliendo más barato configurar y mantener un agente.
Básicamente lo que hace falta son tres tipos de agentes: un supervisor que maneje el loop y active lo adecuado cuando haya problemas, un orquestador que delegue en el agente correspondiente y fuerce guardrails donde hagan falta, y un trabajador que ejecute unidades de trabajo.
En mi opinión, todos los arneses están mal en este aspecto, y algunos están muy mal.
Por ejemplo, los comandos slash son una mala funcionalidad. No deberías tener que esperar a que el chatbot termine un turno para poder revisar el estado de la ventana de contexto o cuánto dinero se ha gastado en esta sesión. El control debería ser ortogonal al loop de chat.
Hay cosas que terminan enredadas con el comportamiento del chat sin tener nada que ver con controlar la entrada y salida del generador de texto, solo porque “como es chat, hagámoslo como un bot de IRC”.
Hoy hay muchísimos agentes LLM, pero casi ninguno separa bien control, loop del agente y capa de presentación. Algunos al menos tienen modo headless, y eso ya ayuda.
/statussí funciona bien incluso en medio de un turno.En otros no, pero ahí sí.
También es más cómodo para moverse entre conversaciones y ver actualizaciones. A veces uso Claude Code u opencode en la terminal, pero la experiencia es bastante peor comparada con la app de escritorio de Codex.
La idea de “imagina un lenguaje de programación donde las oraciones son sugerencias y las funciones alucinan devolviendo ‘Success’. Ya no se puede razonar sobre nada, y mientras más crece la complejidad, más se derrumba la confiabilidad” en esencia se parece mucho a la programación declarativa.
La mayor parte de la programación tradicional es imperativa, que es a lo que los desarrolladores están acostumbrados. Das un conjunto exacto de instrucciones y esperas que se sigan tal como las escribiste. Los agentes se parecen mucho más a algo declarativo: les das el resultado y trabajan para conseguirlo.
Claro, en sistemas declarativos como SQL, el resultado suele ser bastante consistente y bien definido, pero aun así confías en el motor interno para decidir cómo procesarlo. Pensar en los agentes como algo declarativo me ayudó mucho más que intentar diseñar sistemas de “control” estilo Rube Goldberg. Si no encaja, lo validas, reportas que está mal y vuelves a intentar o pruebas otro enfoque.
Si de verdad necesitas algo imperativo, entonces escríbelo de forma imperativa. O haz que el agente lo escriba así. Esto se lee como intentar usar una herramienta que no corresponde a la tarea.
Puede parecer declarativo, pero eso solo dentro de la ilusión. En realidad no estamos describiéndole metas a una IA para que las interprete; lo que tenemos es un documento narrativo donde un personaje sustituto humano conversa con un personaje computadora, y en la realidad nosotros esperamos que el LLM pegue detrás una historia más coherente para extraer de ahí algo útil.
No es una distinción meramente académica. Si sabes que hay una historia, entiendes mejor la relación entre entrada y salida y puedes formular mejores estrategias. Por ejemplo, ayuda a entender riesgos como prompt injection y da pistas sobre qué datos de entrenamiento conviene incluir o excluir.
Ahí aparecen problemas parecidos a los LLM: si no tienes mucho cuidado, te topas con fallos silenciosos, repeticiones y contradicciones. En el fondo podría ser el mismo problema de la hipótesis de mundo cerrado. En los LLM eso aparece como alucinación en vez de admitir que no saben.
Y como dices, si le das una instrucción declarativa a un LLM no determinista del tipo “llévame a este estado final”, es todavía más probable que se desvíe.
Pero la consulta en sí no cambia como sí pasa con un LLM.
He pensado bastante en este problema. También puede conectarse con la idea de especialización. Mientras más especializado es un modelo, parece perder algo de capacidad general básica; quizá apuntar a un poco de abstracción permita capturar ventajas de ambos lados.
Es un ejemplo bastante específico, pero vale la pena pensarlo.
Resumen de podcast de 20 minutos: https://pub-6333550e348d4a5abe6f40ae47d2925c.r2.dev/EP008.ht...
Paper: https://arxiv.org/abs/2605.00225
Esto ya se veía en 2023 con Auto-GPT. La gente dejaba que GPT “condujera”, pero en la mayoría de los casos lo que realmente hacía falta eran diez líneas de Python y quizá unas cuantas llamadas a
llm().La alternativa era ejecutar esas diez líneas de Python de la forma más cara, lenta y menos confiable posible. Claro, era popular.
Por ejemplo, la mayoría usaba agentes para investigar en internet. Se quedaban corriendo durante horas, se distraían o se olvidaban de lo que estaban haciendo.
En cambio, con
import duckduckgoeimport llmpuedes escribir en 20 segundos un código de diez líneas que hace lo mismo, se ejecuta de forma determinista y cuesta 50 veces menos.Los modelos actuales son mucho mejores, y ahora sí son lo bastante buenos como para que Auto-GPT sea viable. Pero ejecutar un flujo de control mal especificado de la forma más cara posible sigue siendo una mala idea.