Equipo de Claudes crea compilador C que compila Linux | Keryc
Nicholas Carlini y su equipo en Anthropic empujaron a Claude a hacer algo que suena a ciencia ficción: coordinar muchas instancias en paralelo para escribir desde cero un compilador en Rust capaz de compilar el kernel Linux. ¿Suena loco? Lo es. ¿Funciona? En gran medida sí, y lo que importa no es solo el artefacto sino las lecciones sobre cómo diseñar un entorno para agentes LLM que trabajen autónomos durante días.
Qué hicieron y por qué importa
La idea fue simple en enunciado y brutal en ejecución: correr 16 agentes Claude en paralelo, cada uno en su contenedor, colaborando sobre un repositorio Git compartido para construir un compilador C en Rust que compile Linux 6.9 en x86, ARM y RISC-V. El proyecto consumió casi 2,000 sesiones de Claude Code, 2,000,000,000 de tokens de entrada y generó 140,000,000 de tokens de salida, con un costo aproximado de 20,000 USD.
El resultado: un compilador de 100,000 líneas que compila Linux y otros proyectos grandes (QEMU, FFmpeg, SQLite, Redis, Postgres) y pasa entre el 99% de varias suites de pruebas, incluida la tortura de GCC. También compila y ejecuta Doom, lo que siempre es un buen hito emocional para los ingenieros.
Pero no te imagines un reemplazo perfecto: hay limitaciones claras (falta de soporte 16-bit real mode para x86, dependencia en ensamblador y linker externos para algunas fases, y código generado menos eficiente que GCC). Lo interesante aquí es lo que aprendieron sobre la ingeniería del «harness» que permite a agentes LLM trabajar autónomamente y en paralelo.
Cómo habilitaron Claudes de larga duración
El problema con los agentes LLM tradicionales es que se detienen: esperan input humano, preguntas o confirmaciones. Para eliminar esa dependencia, construyeron un bucle infinito que relanza a Claude cada vez que termina una tarea, poniendo la instancia en modo de trabajo continuo. En esencia, cuando una sesión termina, otra vuelve a arrancar y continúa con el siguiente paso.
No te compliques: piensa en un pequeño supervisord que relanza procesos. En su caso el bucle era algo así como while true; do claude -p "AGENT_PROMPT.md" ...; done. Además, cada agente corre dentro de un contenedor aislado para evitar contaminación de entorno.
Un detalle gracioso y real: en una ocasión Claude ejecutó pkill -9 bash por accidente y se mató a sí mismo. Los agentes no son dioses; son herramientas con fallos curiosos.
Ejecutar Claude en paralelo: sincronización simple y efectiva
La arquitectura de colaboración fue deliberadamente mínima y basada en Git:
Un repo "upstream" vacío montado en cada contenedor.
Cada agente clona a /workspace, trabaja y luego hace push al upstream.
Para evitar que dos agentes trabajen exactamente la misma tarea hay un sistema de locks: un agente escribe un archivo en current_tasks/ (por ejemplo parse_if_statement.txt) para reclamar la tarea.
Si dos agentes intentan reclamar lo mismo, la sincronización de Git fuerza a uno a retroceder y elegir otra tarea.
Los conflictos de merge fueron frecuentes, pero Claude fue capaz de resolver muchos de ellos autónomamente. No hay un orquestador maestro: cada Claude decide su próximo paso, lo que simplifica el diseño pero deja algunas decisiones de alto nivel sin control central.
Diseño de pruebas: el alma del sistema
Si un agente hará trabajo autónomo, necesitas tests impecables. Claude tiende a optimizar para lo que le dices que pruebe; si el verificador es malo, el agente optimiza en la dirección equivocada.
Lecciones clave:
Escribe verificadores robustos y scripts de build que devuelvan salidas fáciles de parsear. Por ejemplo, cuando hay error, la salida debe contener la palabra ERROR en la misma línea con la causa, así grep y los agentes la encuentran sin filtrar megabytes de logs.
Evita "context window pollution". No imprimas miles de bytes al STDOUT; guarda logs y muestra resúmenes claros. Precalcula estadísticas agregadas para que el modelo no tenga que rehacer trabajo.
Mitiga la "time blindness": los agentes no saben cuánto tiempo toma una prueba. Implementaron opciones de muestreo (--fast) que ejecutan un 1% o 10% determinista de pruebas por agente, así cada instancia cubre porciones distintas sin repetir todo el corpus.
Integración continua estricta: cuando el compilador empezó a romper cosas con cada nueva feature, añadieron pipelines que bloqueaban commits que provocaran regresiones.
En resumen: los tests no son auxiliares, son la interfaz principal entre humanos y agentes.
Paralelismo efectivo y oráculos conocidos
Paralelizar tests independientes es fácil: cada agente caza un fallo distinto. El quebradero de cabeza llegó con el kernel, que es un único gran job. Muchos agentes caían en el mismo bug, se pisaban entre sí y no avanzaban.
La solución elegante fue usar GCC como "oráculo conocido bueno". La idea fue compilar la mayoría de archivos del kernel con GCC y solo compilar un subconjunto con el compilador de Claude. Si falla, reduces el conjunto atacado por Claude hasta localizar archivos problemáticos. Esa técnica, combinada con delta debugging para encontrar interacciones entre pares de archivos, permitió paralelizar el trabajo incluso dentro de una tarea aparentemente monolítica.
Roles de agentes y especialización
Una ventaja de tener muchos agentes es crear roles. Algunos ejemplos prácticos que aplicaron:
Agentes dedicados a coalescer código duplicado.
Agentes que optimizan el rendimiento del compilador.
Agentes centrados en generar código objetivo más eficiente.
Agentes que verifican la calidad del diseño desde la perspectiva de un desarrollador Rust.
Agentes que mantienen y actualizan la documentación y READMEs para que los nuevos contenedores se orienten rápido.
La especialización reduce la redundancia y acelera la convergencia, aunque requiere diseñar las tareas/locks para que los roles no entren en conflicto constantemente.
Evaluación: números que importan
Modelos: serie Opus 4 (4.5, 4.6 fue la que cruzó el umbral).
Sesiones: ~2,000 Claude Code sessions en dos semanas.
Tokens: 2B in, 140M out.
Coste: ~20,000 USD en API.
Resultado: compilador de ~100k líneas que compila Linux 6.9 en x86, ARM, RISC-V; compila QEMU, FFmpeg, SQLite, Postgres, Redis; 99% en muchas suites de pruebas; compila y ejecuta Doom.
Ese coste puede parecer alto, pero el autor señala que es fracción de lo que costaría montar un equipo humano que hiciera lo mismo desde cero en el mismo tiempo.
Límites técnicos y riesgos
A pesar del éxito, hay tech debt y límites claros:
Soporte 16-bit para x86: Claude no logró producir un codegen compacto dentro del límite de 32 KB que Linux exige para real mode, así que el flujo de arranque todavía depende de GCC para esa fase.
Ensamblador y linker: el proyecto aún usa herramientas externas en algunas fases porque los últimos esfuerzos de Claude en estas piezas fueron inestables.
Calidad del código Rust: suficiente para funcionar, pero no al nivel de un experto humano.
Eficiencia del código generado: incluso con optimizaciones, el output es menos eficiente que el de GCC sin optimizaciones. Hay espacio para muchas mejoras.
Fragilidad: nuevas features frecuentemente rompían funcionalidad existente; la necesidad de tests estrictos y CI es central.
Más allá de lo técnico están los riesgos de confianza: ¿desplegarías software crítico que nunca verificaste manualmente? El autor, con pasado en penetration testing, advierte que las pruebas que pasan no equivalen a una verificación humana exhaustiva.
Qué nos deja esto y hacia dónde va
Este experimento demuestra que las fronteras de lo posible con LLMs se mueven rápido: de autocompletar funciones en un IDE a coordinar equipos de agentes que entregan artefactos complejos. Pero también nos recuerda que "funcional" no equivale a "listo para producción".
Si trabajas en herramientas de desarrollo o en integrar LLMs en pipelines, ¿qué puedes llevarte? Diseña tests como si fueran contratos, haz logging pensado para modelos, divide el trabajo para permitir paralelismo real y usa oráculos conocidos cuando una tarea es inherentemente monolítica.
¿Y la ética y la seguridad? Necesitamos procesos para validar, auditar y limitar despliegues que hayan sido generados de forma mayoritariamente autónoma. El experimento es emocionante, pero también une la urgencia técnica con la responsabilidad.