En algunas tareas, el código que acabo mergeando no lo ha escrito Opus. Lo ha escrito Qwen, un modelo de 27B que corre en mi servidor local. No pasa a menudo, pero pasa, y cada vez que ocurre me confirma que montar todo este tinglado tenía sentido.
Hace un tiempo escribí sobre los cinco niveles de trabajar con agentes de IA y por qué yo me había quedado en el tercero. Desde entonces el sistema ha cambiado bastante, así que toca actualizar.
Antes de nada: no hace falta montar todo esto
Esto es como trabajo yo a día de hoy. Sé que a mucha gente le va a parecer muy complejo, bastante más de lo necesario, y no digo que todo el mundo tenga que trabajar así. Hay quien con un Claude Code instalado en su máquina tiene más que suficiente, y me parece perfecto.
Es lo que me funciona a mí, para mi caso concreto: un freelance que está en varios proyectos a la vez. Prefiero tener cada proyecto separado, trabajar siempre con DDEV y que todo esté lo más aislado posible entre proyectos. Y lo he montado pensando en que escale, para que el día que me haga falta pueda repartirlo en máquinas distintas sin rehacerlo. Ahora mismo tengo dos servidores en casa y ya estoy pensando en un tercero, porque básicamente me he quedado corto de RAM. Aunque desde fuera parezca un lío, para mí no es tan complejo de mantener como parece.
Las tres piezas de debajo
Antes de entrar en los proyectos, conviene tener claro qué hay por debajo, porque son tres piezas distintas y es fácil mezclarlas.
Proxmox es la capa de infraestructura. Lo uso para virtualizar mis servidores: dentro de cada máquina física tengo varias máquinas virtuales y contenedores, y cada cosa vive en el suyo. No tiene nada que ver con la IA en sí, es simplemente lo que me permite repartir y aislar todo lo demás.
LiteLLM es un proxy de IA. Mi servidor de inferencia local se expone a través de él como una API más, y las APIs de terceros también pasan por ahí cuando me hacen falta. Así tengo un único punto al que se conectan mis aplicaciones, que en la práctica son sobre todo los contenedores de OpenCode, y que la mayoría de las veces acaban tirando de mi servidor local. Además me da control de costes y me permite dar de alta modelos nuevos o retirar los que ya no uso sin tocar la configuración de cada proyecto.
De estas dos ya hablé hace tiempo en otros artículos y en la charla que di el año pasado en la DrupalCamp Spain, así que no voy a entrar en cómo las tengo configuradas.
Atlas es la que más importa para entender el resto del artículo. Es un gestor de tareas que he hecho a medida para mí, y con el tiempo se ha convertido en mi interfaz para trabajar. Lleva el control de tiempo, de proyectos y de tareas, las estimaciones de tiempo de cada proyecto y el coste de IA de cada tarea. Y además tiene integrado el flujo de trabajo con los agentes: desde Atlas se generan los worktrees y se lanzan y gestionan los arneses. En el fondo es un meta-arnés, lo que algunos están empezando a llamar una factoría de código. No es público y lo sigo tocando casi cada semana, pero aparece en varias partes de lo que viene, así que mejor presentarlo ya.
Si estás en una agencia mediana o grande, estas tres cosas sí te las recomendaría. Un gestor de tareas propio, adaptado a cómo trabaja tu equipo, ayuda mucho a que la gente trabaje bien con agentes. Un LiteLLM o algo similar te permite decidir qué personas tienen acceso a qué modelos y con qué límite de gasto, en dinero o en tokens. Y si tienes servidores propios, Proxmox hace mucho más fácil gestionar toda la parte de infraestructura.
Creo que a más de una agencia le puede venir bien ver cómo está montando otro su orquestación de agentes, así que a partir de aquí voy de abajo arriba, desde la base que uso en cada proyecto hasta la parte más experimental.
La base: todo dentro de DDEV
Todos mis proyectos Drupal usan ddev-ai-workspace, un meta add-on público que mantengo y que instala en el proyecto todo lo que necesito para trabajar con IA. Claude Code y OpenCode corren cada uno en su propio contenedor, con acceso al proyecto pero separados del contenedor web.
Los agentes, las skills y las reglas no viven en cada proyecto. Vienen de drupal-ai-agents, mi repositorio público, y se sincronizan cada vez que levanto el proyecto con ddev start. Así tengo una configuración unificada en todos los proyectos sin copiar ficheros de un lado a otro.
Lo interesante es que puedo añadir más repositorios encima. Muchos de mis clientes son agencias, y algunas tienen ya sus propios agentes y skills. En esos casos añado su repositorio después del mío y el sistema combina los dos: lo que la agencia tiene y yo no se suma, y si tienen su propia versión de algo que yo también tengo, la suya manda. Me quedo con lo mejor de lo mío más lo que el cliente ya ha trabajado, sin tener que mantener una configuración distinta a mano para cada uno.
Hay una parte que no está en el repositorio público porque está hecha a medida para mí: la conexión con Atlas. En el fichero de configuración pongo a mano la API key de Atlas, y cada tarea le envía sus estadísticas de uso: qué modelos se han usado, cuántos tokens y cuánto dinero ha costado. Parece un detalle, pero es lo que me permite saber cuánto me cuesta de verdad cada tarea y si estoy gastando más de lo que debería.
Un worktree por tarea
Lo siguiente son los worktrees de Git. Tengo unos scripts que, para cada tarea, me crean un worktree nuevo del proyecto con los mismos add-ons de DDEV. Lo levantan, importan una base de datos sanitizada del proyecto, importan la configuración y hacen el deploy. Cuando termina, tengo un entorno completo listo para empezar a trabajar, sin haber tocado nada a mano. Y como este flujo está integrado en Atlas, lo lanzo directamente desde la tarea.
Esto me permite trabajar en varias ramas a la vez. Mientras un agente está con una funcionalidad en un worktree, otro puede estar con un bug en otro, y yo revisando un tercero. Cada uno con su base de datos y su DDEV, sin pisarse.
Antes de tener esto, el cuello de botella era el entorno. Cambiar de rama implicaba volver a importar base de datos, limpiar caché y rezar para que la configuración cuadrase. Ahora el coste de abrir una tarea nueva es prácticamente cero.
La arena: que se peleen entre ellos
Este es el nivel en el que estoy experimentando ahora. Lo llamo la arena, porque al final es un coliseo donde mis arneses de IA se pelean entre ellos y solo puede quedar uno: el que ha dejado la solución mejor implementada. Lo tengo publicado en ddev-ai-arena, aunque todavía está muy en beta y sigo haciendo pruebas.
La idea es para tareas complejas. La primera aproximación la hace la IA completamente de forma desatendida, y la hacen varias a la vez.
Funciona así. Primero hablo con el orquestador sobre la tarea. Discutimos cuál es la mejor forma de implementarla, me plantea alternativas, le corrijo lo que no me convence, y así hasta que tenemos claro cómo se va a hacer. Cuando llegamos a ese consenso, el orquestador lanza los scripts de worktrees que contaba antes y crea un worktree por candidato. A cada uno le pasa exactamente el mismo prompt. En uno se lanza Claude Code y en otro OpenCode. Más adelante quiero añadir Codex.
Cada candidato tarda lo que le haga falta. No hay prisa, porque mientras tanto yo estoy con otra cosa.
Cuando terminan todos, el orquestador revisa el código de cada rama y elige una ganadora. Pero no tira las demás a la basura. A menudo la rama perdedora, en conjunto, no es la mejor opción, pero tiene alguna función mejor pensada, algún caso límite que la ganadora no contempló o una parte mejor terminada. Esas piezas se traen a la rama ganadora. El resultado final es una rama con lo mejor del ganador más lo que los perdedores hicieron mejor.
Tiene un coste evidente. Si tienes dos o tres arneses haciendo la misma tarea, estás gastando el doble o el triple de tokens para llegar a un único resultado. No hay forma de maquillar eso.
A cambio, la calidad del código que me llega es bastante superior, y necesito mucha menos revisión humana. Para tareas pequeñas no compensa. Para las complejas, donde una mala decisión de diseño te cuesta días después, sí.
Cuando gana el modelo pequeño
En mi servidor local estoy usando ahora Qwen3.8-27B, el modelo denso de 27B que Alibaba publicó en agosto. Lo uso desde OpenCode, que se conecta a él a través de LiteLLM. Por el otro lado, Claude Code usa Opus como modelo principal y modelos más baratos para los subagentes.
En la mayoría de casos gana Claude Code, no voy a engañar a nadie. Pero en algunas tareas concretas, la rama de OpenCode con Qwen ha sido la ganadora, por delante de Opus.
Para mí eso dice mucho. Los modelos frontera no son siempre los mejores para todas las tareas, y la única forma de saberlo es ponerlos a competir con trabajo real, no con benchmarks. Si no tuviera la arena, nunca me habría enterado, porque simplemente habría usado Opus para todo. Y un modelo que corre en mi propio servidor ganando de vez en cuando también es una forma de no depender tanto de un único proveedor.
Los arneses tienen que soñar
Hay un concepto que vi en una charla y que me gustó mucho: que los agentes sueñen, dreaming en inglés. No he conseguido volver a encontrar esa presentación, pero sí esta otra de Anthropic, donde presentaban su función de dreaming, que va básicamente de lo mismo.
La idea parte de cómo funcionamos nosotros. Cuando dormimos es cuando el cerebro consolida lo que ha aprendido durante el día. Con un arnés de IA se puede hacer algo equivalente. Cuando termina una tarea, le pides que repase los problemas que ha tenido y cómo los ha resuelto, y que si ha aprendido algo nuevo lo consolide en una skill o en un agente. La próxima vez que tenga que hacer algo parecido, ese conocimiento ya está en su base y no tiene que redescubrirlo. Lo hace más rápido, gastando menos tokens, o con mejor calidad sin dar tantas vueltas.
En el artículo sobre la dependencia de proveedores ya hablaba de las skills que se automejoran, pero el nombre de "soñar" me parece que lo explica mucho mejor. Puedes hacerlo a mano, pidiéndole tú que consolide lo aprendido al terminar, o automatizarlo para que pase solo al final de cada tarea o una vez al día.
Lo que aprende tu IA se queda en tu ordenador
Hay una cosa de toda esta automejora que casi nadie comenta. Por defecto, todo lo que tu IA va aprendiendo en skills y agentes se queda en tu ordenador.
Si se te rompe, te lo roban o simplemente trabajas con más de un equipo, no tienes una forma fácil de recuperar ese conocimiento o de tenerlo igual en todas partes. Llevas meses afinando skills y agentes, y todo eso está en una carpeta local de la que probablemente ni tengas copia.
Justamente por eso mi sistema funciona con repositorios. Cuando se actualiza la base de conocimiento, se hace push al repositorio correspondiente. Y todos los contenedores de Claude Code y OpenCode se alimentan de esos repositorios cada vez que arrancan. Así todos mis arneses y todos mis proyectos tienen siempre lo último que se ha consolidado, ya sea del repositorio público o de alguno privado, porque hay proyectos con su propia base de conocimiento que no puede ser pública.
Audit para que la IA se corrija sola
En las skills le tengo especificado a la IA que tenga en cuenta rendimiento, seguridad, buenas prácticas de la comunidad, PHPCS, PHPStan, duplicación de código y complejidad. Y para que eso no se quede en una buena intención, uso el módulo Audit.
En todos los Drupal en los que estoy involucrado tengo Audit instalado, al menos en local. El arnés puede ejecutar los comandos de Drush para ver las puntuaciones y comprobar si algo ha empeorado con el código que acaba de generar. Si ve que algo no cumple las prácticas recomendadas, lo arregla antes de decir que ha terminado, y antes de que yo entre a revisar nada. Lo conté con más detalle en por qué los tests en verde no bastan.
Un navegador para los agentes
La otra pieza de retroalimentación es Playwright. Tengo un contenedor en DDEV con un navegador headless y su servidor MCP, con visibilidad sobre el worktree en el que se está trabajando.
Con eso los agentes pueden navegar por la web en local, hacer clic, rellenar formularios y comprobar cómo se comporta la interacción de usuario. También pueden hacer capturas en distintos tamaños de pantalla, que es especialmente útil cuando se está maquetando frontend. Hace una captura antes del cambio, modifica el código, hace otra después y compara. Si la página da error o algo se ha movido de sitio, se da cuenta y lo arregla.
Sin esto, un agente que toca frontend trabaja a ciegas. Escribe CSS y Twig y supone que queda bien. Con un navegador, se cierra el bucle.
No es nada nuevo. Hace más de un año que hay gente trabajando así. Pero me sigue sorprendiendo la cantidad de gente que ni siquiera sabe que se puede conectar un agente a un navegador para que vea lo que está haciendo.
Eso sí, toda la interacción con el navegador la hago con modelos más tontos y baratos. Hacer clic en un botón y sacar una captura no necesita a Opus ni a Fable, y usarlos para eso es tirar el dinero. Ya conté en cómo organizo los subagentes por modelo para que la suscripción o la API me dure lo máximo posible, y esta es una de las partes donde más se nota.
Esto caduca pronto
Todo esto es como trabajo ahora mismo, a principios de noviembre. Y con la velocidad a la que cambia todo, lo más probable es que a finales de año ya esté desactualizado. Cada pocas semanas sale un modelo nuevo, una función nueva en los arneses o una forma distinta de organizar los agentes, y yo intento estar en la cresta de la ola dentro de mis posibilidades.
La parte que más cambia es Atlas. Lo voy afinando cada semana, a veces cada día, y por eso todavía no he escrito nada en detalle sobre él. Pero creo que es hacia donde vamos todos: una factoría de código, con un orquestador por encima que gestiona todo lo que he contado en este artículo, desde los worktrees hasta la arena, y que te deja a ti decidir qué se hace y revisar lo que sale.
Cada paso que doy va en esa dirección. Hacer la base un poco más sólida para poder construir encima cosas que me ahorren tiempo y dinero. Y si a mí me cuesta menos implementar algo, también puedo entregarlo antes a mis clientes.