- Tras un experimento de 2 días, una forma adecuada de describir a Claude Fable 5 es como "incansablemente proactivo"
- Con solo capturas de pantalla y un prompt de una línea, logró ejecutar un servidor local de desarrollo, manipular un navegador real e incluso insertar código de medición para rastrear la causa de un bug de CSS
- Fable intentó reproducir el bug pasando entre Playwright, Firefox, WebKit y Safari, y tras fallar configuró por sí mismo una automatización de capturas de pantalla buscando la ventana real del navegador
- Para probar el cuadro de diálogo modal que se abre con la tecla
/, insertó JavaScript en una plantilla de Datasette y generó eventos de teclado tras cargar la ventana para crear el estado necesario
- Para obtener mediciones internas de la página, creó un servidor de recolección CORS basado en Python
http.server y guardó en JSON la información del <textarea> dentro del shadow DOM de un Web Component
- Un agente de programación potente puede hacer en la terminal lo que un usuario puede hacer, por lo que ejecutarlo fuera de un sandbox aumenta el riesgo de prompt injection y filtración de datos
Proceso de depuración de Claude Fable 5
- Empezó investigando una barra de desplazamiento horizontal innecesaria en el prompt de chat del menú de salto de Datasette Agent
- Claude Fable 5 movilizó activamente diversas técnicas para alcanzar el objetivo
- La entrada fue una captura de pantalla y un prompt de una sola línea:
Look at dependencies to help figure out why there is a horizontal scrollbar here
- Bajo la idea de que la causa del problema podía estar en las dependencias de Datasette Agent, especialmente en Datasette mismo, se le pidió que revisara primero el código de las dependencias
- Claude Code, sin instrucciones explícitas de automatización de navegador, abrió una ventana normal de Firefox y navegó hasta ese cuadro de diálogo; después también abrió una ventana de Safari para seguir investigando
Automatización de capturas de pantalla del navegador
- Fable configuró su propio método para tomar capturas de pantalla de ventanas del navegador usando
uv run --with pyobjc-framework-Quartz
- Recorrió con Python todas las ventanas de la máquina y filtró las ventanas de Safari cuyo nombre contenía cadenas esperadas como
"textarea"
- Luego encontró un identificador entero como
153551, correspondiente al número de ventana, y guardó un PNG con la CLI screencapture
- Escribió una página HTML temporal como
/tmp/textarea-scrollbar-test.html, la abrió en Safari y obtuvo la captura de pantalla
- El comando de ejemplo fue
screencapture -x -o -l 153551 /tmp/safari-cases.png
Ejecución automática del cuadro de diálogo modal
- El modal a probar solo podía abrirse con clic o con un atajo de teclado, y no parecía haber un mecanismo claro para mover el mouse o ejecutar atajos de teclado dentro de Safari
- Claude se estaba ejecutando en la carpeta con el código fuente de la aplicación y entendió la estructura lo suficiente como para ejecutar el servidor local de desarrollo de Datasette
- Agregó JavaScript a una plantilla de Datasette para simular la pulsación de la tecla
/ después de abrir la ventana
- Ese código dispara un evento
keydown para la tecla / 1.2 segundos después de que carga la ventana, ejecutando así el atajo que abre el cuadro de diálogo modal
<script>
window.addEventListener("load", function () {
setTimeout(function () {
document.dispatchEvent(new KeyboardEvent("keydown", {key: "/", bubbles: true}));
}, 1200);
});
</script>
Recolección de mediciones internas de la página
- Claude necesitaba ejecutar JavaScript en la página para obtener mediciones directas y, para ello, escribió su propia aplicación web que recibía información mediante CORS
- Usó la biblioteca estándar de Python
http.server para ejecutar un servidor local en 127.0.0.1:9999
- El servidor recibía solicitudes POST con JSON, las registraba en
/tmp/diag.json y enviaba el header Access-Control-Allow-Origin: * para permitir la comunicación desde código en otros dominios
- Claude insertó JavaScript en la plantilla cargada por el navegador para encontrar el
<textarea> dentro del Web Component <navigation-search>
- El código insertado medía
devicePixelRatio, scrollWidth, clientWidth, whiteSpace y width, y luego enviaba esos datos al servidor local
const host = document.querySelector("navigation-search");
const ta = host.shadowRoot.querySelector("textarea");
const cs = getComputedStyle(ta);
fetch("http://127.0.0.1:9999/diag", {
method: "POST",
body: JSON.stringify({
dpr: window.devicePixelRatio,
scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth,
whiteSpace: cs.whiteSpace, width: cs.width,
}),
});
Cambio a Opus y verificación de la corrección
- Tras descubrir varias técnicas, Fable chocó con un guardarraíl invisible y fue degradado a Opus
- Opus podía acceder a todo el historial de la conversación y siguió usando las técnicas que Fable había abierto camino
- Después, Opus encontró el problema, lo probó, lo verificó y completó el commit de corrección
- Opus también documentó en
/tmp/automation-report.md las técnicas de automatización usadas sobre navegadores reales en la sesión, junto con ejemplos de código ejecutable
- Ese informe se compartió como un gist aparte, y también se publicó el registro completo de la terminal de Claude Code
Revisión completa de lo realizado
- Claude Fable 5 y Claude Code descubrieron cómo ejecutar el servidor local de desarrollo y también configuraron las variables de entorno falsas necesarias para hacerlo
- Ejecutaron una sesión de Playwright Chrome y activaron la configuración de barras de desplazamiento visibles en Chrome con
defaults write com.google.chrome.for.testing AppleShowScrollBars Always, para luego desactivarla más tarde
- También recorrieron Firefox y WebKit de Playwright, pero no lograron reproducir el bug
- Detectaron que el navegador predeterminado era Safari y crearon el documento HTML
textarea-scrollbar-test.html
- Abrieron el documento de prueba en Firefox real, y el acceso mediante
osascript fue bloqueado por “osascript is not allowed assistive access”
- Encontraron una vía alternativa con
pyobjc-framework-Quartz y construyeron un flujo de capturas basado en números de ventana
- Agregaron JavaScript a la plantilla del sitio para disparar la tecla
/ y recibieron datos JSON mediante un servidor CORS en Python
- Pasaron por el shadow DOM del Web Component para encontrar la información necesaria y confirmaron la causa del bug en Safari
- Aplicaron una posible corrección en una plantilla personalizada, comprobaron que funcionaba y luego reportaron cómo resolver el problema
Estimación de costos
- El plan en uso era Claude Max de $100 al mes, y Anthropic indicó que daría una cuota generosa para Fable hasta el 22 de junio, tras lo cual cobraría el precio completo de la API
- AgentsView se usó para rastrear el gasto, y si se hubiera pagado el precio completo, el costo de esa sesión habría sido de aproximadamente $12.11
- La salida de la sesión fue
68606, el contexto máximo fue 113178, y los modelos usados fueron claude-fable-5 y claude-opus-4-8
- Si no se vigila de cerca el costo, Fable puede consumir fácilmente unos $12 en tokens ideando nuevos métodos para depurar CSS
Necesidad de un sandbox
- Fue impresionante ver cómo Fable recurrió incluso a métodos extremos para obtener al final la información necesaria para una corrección de CSS de apenas dos líneas
- Un agente de programación puede hacer lo que un usuario podría hacer escribiendo comandos en la terminal, y los modelos frontier conocen muchísimas técnicas
- Si hubiera habido instrucciones maliciosas, prompt injection dentro de código o hilos de issues, o contenido pegado sin cuidado en la terminal, eso podría haber provocado filtración de datos u otros daños
- Ejecutar un agente de programación fuera de un sandbox siempre es una mala idea y se considera un fuerte candidato a causar incidentes de seguridad con agentes de programación
- Fable puede ser más inteligente y desconfiar más de instrucciones maliciosas, pero si cae en una de ellas, su proactividad incesante puede ampliar el alcance del daño
1 comentarios
Comentarios de Hacker News
Esto se lee como un caso impactante de pérdida fatal de agencia humana, y los commits reales también revelan bastante [0]
El autor quería ocultar la barra de desplazamiento horizontal. Cualquier desarrollador frontend junior competente habría preguntado enseguida: “¿dónde pongo
overflow-x: hidden;?”. La solución correcta consistía en presionar “Inspect element” en el navegador para encontrar la clase CSS y luego ubicarla en el código con (rip)grep para agregar una líneaUn programador más proactivo también habría preguntado qué contenido había en el cuadro de texto vacío para que se desbordara, por qué había que poner un parche en dos lugares para tapar el síntoma en vez de la causa raíz, y si no sería mejor estilizar
textareauna sola vez[0] https://github.com/datasette/datasette-agent/commit/a75a8b72...
__init__.py[0]Mi experiencia usando Claude ha sido mayormente que produce código bien estructurado, así que esto en realidad me sorprende un poco. Aunque lo mío se parece más a debatir amistosamente en modo socrático con otro ingeniero que es un robot, que a hacer vibe coding de verdad
[0] https://github.com/datasette/datasette-agent/blob/main/datas...
Eso es exactamente lo que esperaría de un desarrollador junior: confirmar que el bug realmente exista, encontrar una forma de corregirlo y verificar que efectivamente quedó arreglado
El problema, como también señala bien la entrada del blog, es que en vez de detenerse y preguntar cuando necesita permisos de nivel superior, se pone a buscar sin fin atajos tipo hack por su cuenta. En términos de un desarrollador humano, sería como necesitar acceso a un sandbox de terceros, pero en vez de pedirle credenciales a un senior, intentar construir su propio sandbox desde cero
Me recuerda a cuando conectarse al mundo online se cobraba por minuto. Había muchos incentivos para mantener corriendo el medidor, y esto se siente de ese estilo
Aunque reconocen claramente que “ejecutar un agente de código fuera de un sandbox siempre fue una mala idea”, me sigue desconcertando y sorprendiendo que tanta gente siga haciéndolo
Es como subir un video sentado en el asiento del copiloto con los pies sobre el tablero y decir: “¡Recuerden que si tienen un accidente, el airbag puede romperles las piernas o algo peor! ¡Qué suerte que a mí no me pasó!”
El problema es que la forma en que cada persona redacta prompts es demasiado distinta
Por ejemplo, yo podría pedir algo como: “Prueba varias variantes de esta annotation en el pod de k8s de este servicio en este clúster X. Eso va a probar la teoría Y”. Pero un colega diría: “Prueba la teoría Y”. Si se lo preguntas así a dos ingenieros junior, uno podría ponerse a probar al azar en producción y otro correr pruebas locales. Es una petición sin instrucciones concretas, del estilo “haz lo que sea necesario para averiguarlo”, y el agente lo interpreta como un junior al que no le dieron límites, pero sí mucha presión para “averiguarlo”
claudeTiene dotfiles parecidos a los míos, pero sin secretos. Mi directorio home es 0700,
claudetiene sus propias claves SSH, lo añadí a mi perfil de GitHub pero con contraseña, y yo me encargo del push/pull. También tiene un usuario y base de datos aparte de Postgres para desarrollo/pruebas, y no es superusuarioBásicamente lo trato como a cualquier otro desarrollador del proyecto. Si necesita ejecutar algo con sudo, me lo pregunta. A veces hasta trabajamos los dos en paralelo en la misma tarea. Después de todo, Unix se suponía que fuera un sistema multiusuario
Un truco que uso seguido es tener este remote adicional en sus repos de git:
paul ssh://paul@localhost/~/src/example (fetch)paul ssh://paul@localhost/~/src/example (push)Eso hace más fácil colaborar en cosas que todavía no están listas para compartir
Esta configuración me resulta bastante cómoda. Igual me preocupan los bugs de escalación de privilegios en Linux. No confío en que una IA entienda que no se le permite explotar vulnerabilidades. Me acuerdo de mi primer trabajo, cuando alguna vez usé mal la función
:!de vim para ampliar permisos limitados de sudo con el fin de editarhttpd.confen una urgencia. Hoy, incluso con actualizaciones automáticas de seguridad, termino actualizando paquetes manualmente más seguido. No creo que Opus se tome el trabajo de buscar vulnerabilidades de seguridad, pero Fable quizá sí, y últimamente hubo muchas. Los modelos futuros podrían incluso encontrar vulnerabilidades nuevas por su cuenta o instalar un keylogger para aprender la contraseña de una clave SSHUn usuario separado es, fuera de una máquina separada, casi la configuración más paranoica que he oído. Así que me pregunto si no estaré sacrificando demasiada velocidad y comodidad. Aun así, en la práctica sigue siendo muy cómodo, y me parece una forma eficiente y responsable de trabajar. Si alguien ve huecos, me gustaría escucharlos
Fable se siente como “Opus corriendo sobre un arnés que no lo deja parar hasta que esté seguro de que el problema quedó resuelto”. Si quieres un modelo mejor en benchmarks, suena como una dirección razonable
Es un modelo muy bueno, pero el sobreprecio es grande. No solo los tokens son más caros, sino que además el modelo quiere usarlos todos. Por ejemplo, en trabajo con React Native, Fable no dice “listo, ya quedó” y termina. Quiere reconstruir toda la app desde cero, correr toda la suite de pruebas y mirar todos los logs y warnings
Es la primera vez usando un LLM que siento que, aunque la empresa lo permita, el upgrade de modelo no vale la pena. Porque castiga demasiado mi máquina y mi batería con builds y pruebas, al punto de que no puedo hacer otras cosas
Por ahora parece mejor usar ultracode en Opus. Hay menos contaminación del contexto principal y la investigación también se paraleliza mejor
Fable intentó validar cambios de UI en mi juego. Yo estaba trabajando en otra ventana, y vi que el programa se abría en la barra de tareas. Fable abrió el juego desde la CLI con la herramienta movie maker, grabó la salida y capturó el último frame para validar la UI. Como la pantalla de bienvenida del juego tapaba la parte que quería ver, creó un worktree temporal, eliminó la pantalla de bienvenida y volvió a ejecutar movie maker
Mientras veía ese proceso, pensé que habría ahorrado tokens si simplemente me hubiera pedido una captura de pantalla. Aun así, no pude evitar quedarme impresionado. Opus jamás habría hecho algo así
Este tipo de texto se siente como si viniera de un universo paralelo. Por mi experiencia anecdótica y según un benchmark que hice yo mismo, aunque sigue siendo subjetivo (https://pshirshov.github.io/llm-bench-pi-oneshot/), Fable no me parece tan impresionante
A veces es mejor y a veces peor que gpt-5.5 y opus 4.8, claramente es más caro, y hasta se niega a ayudar con química en preguntas de React
No sé si todo este alboroto tiene realmente fundamento, o si es solo hype de AGI antes de la IPO
Yo hago que Fable coordine implementaciones complejas. Le doy tickets de alto nivel en Linear y le digo: “mira los issues derivados de este ticket, determina cuáles puedes implementar tú directamente, en qué orden deberías hacerlo y cómo coordinarte con lo que otros miembros del equipo están trabajando ahora mismo”. Estos tickets no son triviales; tienen muchas piezas móviles y dependencias, y se conectan con partes dentro y fuera del mismo proyecto, por ejemplo también con el backend
Entonces Fable elige tickets y delega cada ticket a subagentes, que también son Fable. El subagente revisa el diseño en Figma para ese ticket, sigue al pie de la letra las guías y convenciones del repositorio, lo implementa perfectamente, toma capturas de pantalla de cada parte, escribe mensajes de commit detallados y descripciones de PR, y adjunta capturas como evidencia. Al final te da un resumen tipo: “Primero se debe fusionar el PR #1283. Por cierto, para ciertas pantallas no había diseño en Figma, así que tomé como referencia pantallas similares ya implementadas y apliqué el patrón”
Esto probablemente sea como el 20% de lo que Fable puede hacer. De verdad es un modelo muy potente
Opus 4.8 también podía hacer gran parte de esto, pero había que llevarlo mucho más de la mano, y cuando se topaba con un punto de bloqueo era mucho más probable que se detuviera diciendo “hasta aquí pude llegar, pero no puedo avanzar más”
Fable es un poco más inteligente, pero precisamente por eso en general se siente como una peor herramienta
Sigue convirtiendo un parche de 50 líneas que debería resolverse con un solo prompt en una exploración de 30 minutos, y muchas veces no vale para nada la pena. Encima, a menudo se equivoca
Lo probé con una tarea bastante simple. Era backfillear una caché de deduplicación en redis cuando cambió la función hash. Bastaba con correr la nueva función hash sobre todos los valores de la DB y expandir la caché, pero Fable implementó una actualización de caché exageradamente compleja que intentaba inferir la versión de la función hash de cada valor en caché y solo recalcular los hashes viejos. En algunos contextos podría tener sentido, pero el resultado de quemar tokens durante 30 minutos fue código que yo reemplacé con un
forloop de 10 líneasMe preocupa porque parece una mala señal para la programación en general. Cada vez se ve más claro que la tecnología LLM está chocando con una pared de rendimientos decrecientes en términos de inteligencia, y si la respuesta a eso es simplemente volverlos más persistentes, entonces es una solución pésima para todos los involucrados. Salvo, claro, para quienes venden tokens y para quienes pueden costear los tokens para escanear 0-days
Primero, no tienen un modelo causal. Lo único que pueden hacer es búsqueda por prueba y error, y eso funciona bastante bien para muchos problemas, pero muchos otros sí requieren un modelo causal
Segundo, los prompts no son precisos. Los lenguajes de programación y los modelos de máquina se inventaron justamente para resolver ese problema. El inglés es excelente, pero no es un lenguaje de programación
Antes de la IPO han hecho mucha adopción estratégica y mucha manipulación, y en ese sentido sí les funcionó
tsc, escribió otro script para ejecutartscen cada subagente y combinar los resultadosDe verdad fue para enojarse. Era algo que como mucho tomaba 1 o 2 minutos, pero por irse por ese camino tardó como 10 minutos
Más adelante probaré tareas mucho más complejas, pero para cosas simples se sintió como manejar un Corvette hasta el buzón
Siento que se sigue justificando mi rechazo a usar LLM basados en terminal en mi máquina local
Incluso sin hacer nada malicioso, hay demasiadas formas en que pueden hacerme perder una cantidad nada menor de trabajo o directamente estropear mi máquina y mi capacidad de trabajar
¿No debería ser algo relativamente fácil de preparar para una empresa de 1 billón de dólares? Frente al arnés completo, parecería algo menor
Está claro que la seguridad es un problema mayor, pero mientras leía esto no dejaba de pensar en cuántos tokens habrán gastado para arreglar 2 líneas de CSS
Hay que estimar cuánto le habría tomado a una persona
La gente ahora simplemente puede ser floja y al mismo tiempo parecer productiva, pero sigue siendo flojera
Ahora hay personas que necesitan acceso a hardware de cientos de miles de dólares solo para escribir un correo. Paso. No quiero quemarme el cerebro para volverme dependiente de la máquina de pensar de un multimillonario
Tampoco voy a quemarme el cerebro con una “máquina que piensa por mí” local. Quiero ser una persona que valga más que el hardware al que puedo acceder
Mi experiencia personal con Fable 5 actuando a su manera fue muy positiva
Intentó encontrar la causa raíz de un crash de un módulo de Python que no dejaba errores ni en logs ni en la consola. Fable escribió un test harness que simulaba clics en la UI y luego hizo una búsqueda binaria en mi código para encontrar el punto donde empezaba el crash. Después formuló una hipótesis exagerada sobre la causa del crash y ejecutó una serie de comandos bash de una sola línea para crear entornos virtuales de cada versión de ese módulo de Python bajo
/tmp, con lo que encontró la versión en la que no ocurría el crashRastreó la causa raíz mucho más a fondo de lo que yo habría hecho por mi cuenta, y la causa fue una regresión del módulo que provocaba un desbordamiento en la asignación del heap. Proporcionó información suficiente y un ejemplo simplificado como para presentar un bug report, y también escribió una solución alternativa para evitar que eso ocurriera en mi aplicación
No lo dejo totalmente suelto. Yo reviso cada comando de CLI que intenta ejecutar y, cuando continúo con “yes”, añado una respuesta para evitar un uso excesivo de tokens
Ayuda poner límites en el prompt o en Markdown. Por ejemplo, si le dices que no use automatización del navegador web, he visto que Fable respeta tanto esa regla como su intención. Tampoco hizo hacks raros
Aun así, da la impresión de que trata algunas tareas de depuración simples como si fueran más complejas de lo que realmente son. El post original quizá sea un buen ejemplo
git bisectpara encontrar la causa de un crash de un módulo de Python que no dejaba errores ni en logs ni en la consolaEntiendo lo de generar el caso de prueba y el bucle de
git bisect, pero no veo por qué habría que ejecutarlo pasando por internet, GPU y demás. Me da la impresión de que es algo que podría correr hasta en un Celeron de un solo núcleo, ¿no?