1 puntos por GN⁺ 4 시간 전 | 1 comentarios | Compartir por WhatsApp
  • 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

 
GN⁺ 4 시간 전
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.

    • Antes pensaba que empujaban a la gente a workflows solo con prompts porque podían cobrar por tokens, pero no por el scaffolding que construyera el usuario. Ahora más bien parece que les da miedo que alguien tenga que diseñar e implementar ese scaffolding.
      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.
    • Esto también podría venir de la forma de hacer benchmarks con los modelos.
      ¿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?
    • De acuerdo. La única forma de hacer confiables estos sistemas es dividir el problema en pedazos pequeños. Incluso las comprobaciones internas de consistencia solo muestran que los LLM son mucho menos consistentes de lo que se esperaba.
    • Me mejoró muchísimo el rendimiento cuando combiné apply_patch con check_compilation y run_unit_tests. La herramienta todavía se llama apply_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.
    • El secreto es “compilar” ese prompt de orquestación. Si conviertes el prompt en código, ese código puede volver a ejecutar al agente, o ejecutar código, o ambas cosas, y así se resuelve el problema del determinismo.
      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 simple skill.py que contenga la tarea basta. También puedes tener un helper que invoque claude -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.

    • 100% de acuerdo. Hay que usar una herramienta no determinista que acierta el 90% para construir una herramienta determinista que acierte el 100%. Una de las frases clave que siempre incluyo en mis prompts es: “si te encuentras con un caso límite ambiguo, pregúntame”.
      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.
    • En la mayoría de las organizaciones, el flujo parece ir de llm -> prompt -> result, luego llm -> prompt + prompt encoded as skill -> result, y luego llm -> 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.
    • Nosotros tuvimos exactamente la misma experiencia. Al principio le dábamos al agente una lista de herramientas para manipular estructuras de datos de cierta forma, y ese enfoque era bastante frágil.
      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 problema es que los programas se topan con frecuencia con casos límite que necesitan interpretación, y en ese momento uno quiere dejar que el LLM se encargue de esos casos; y de ahí es muy fácil terminar queriendo dejarle también todo el loop y las llamadas a herramientas.
    • Hice exactamente eso en mi último proyecto, automatizando la generación de una librería de interfaz entre un servidor que controla hardware y una app móvil.
      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.

    • En la empresa tuvimos unas semanas libres y decidimos probar agentes en procesos de trabajo como tomar notas, seguimiento de tareas y gestión documental, y esto coincide exactamente con mi experiencia.
      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.
    • Si fuera un system prompt que diera la vuelta completa, sería algo como: “busca toda oportunidad de automatización que pueda dejarte sin trabajo. Si recibes una pregunta que el código puede responder, escribe y ejecuta código para obtener la respuesta”.
      Un LLM así quizá habría rendido mejor en la prueba de strawberry.
    • También ha habido en este foro la idea de que el futuro del software está en programas generados y adaptados en tiempo de ejecución usando IA generativa. No sé cuánto falta para llegar a eso.
    • He visto casos donde el modelo quedaba atrapado en una forma específica de resolver el problema y necesitaba un empujón para cambiar de enfoque. Por ejemplo, para manejar hotplug/unplug de un stream de audio, en vez de tocar un montón de configuración de servicios del sistema, lo que realmente hacía falta eran unas decenas de líneas de Python.
      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.

    • Yo creo que hace falta memoria real. La memoria actual, en un sentido amplio, se parece más a un sistema de post-its que la IA se deja a sí misma y revisa cada vez, no a un sistema integrado que permita aprender y activarse con más flexibilidad.
    • Hay un ejemplo interesante: https://www.youtube.com/watch?v=kYkIdXwW2AE&t=315s
  • 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.

    • Exacto, solo hay que agregar más agentes.
  • 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.

    • Entiendo a qué apuntas, pero en la práctica construir la arquitectura que propones es mucho más difícil. ¿Por qué no lo haces tú mismo y buscas trabajo en una gran empresa?
    • En codex CLI, /status sí funciona bien incluso en medio de un turno.
      En otros no, pero ahí sí.
    • Uso la app de escritorio de Codex. En la GUI puedo ver el indicador de contexto y las estadísticas de uso.
      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.

    • Me parece un nivel de abstracción todavía más alto que lo declarativo. ¿Tal vez podríamos llamarlo programación narrativa? Aunque también se puede debatir si la palabra “programación” sigue aplicando.
      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.
    • También pensé en lo declarativo, pero más que SQL me vino a la mente PROLOG. Del lado que sí tiene flujo de control real y capacidad de razonamiento.
      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.
    • De acuerdo. Pero también puedes hablarle de forma imperativa al agente. Incluso si le dices “aquí están los pasos concretos, síguelos”, todavía puede arruinarlo. Lo que se busca no es imperatividad sino determinismo.
      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.
    • La naturaleza declarativa de SQL está basada en la matemática del álgebra relacional, por eso devuelve siempre el mismo resultado. Que lo haga en el mismo tiempo depende de los índices y del tamaño de la base de datos.
      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 duckduckgo e import llm puedes 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.