Construyendo Bencher en 2026: código abierto, autofinanciado y entregado a los agentes

Everett Pompeii

Everett Pompeii


Este ensayo se presentó originalmente al concurso The Pragmatic Engineer’s How Software Engineering is Changing Essay Challenge el 4 de octubre de 2026.

Este año ha supuesto un cambio radical en la forma en que construyo software. Soy staff software engineer. En los últimos seis años, he trabajado profesionalmente en Rust tanto para un unicornio respaldado por YC y a16z como para una empresa de la lista Fortune 500. Como desarrollador de C++ en rehabilitación, me sentí atraído por la profundidad y la destreza que exigía Rust. Me había convertido en un artesano experto en cincelar a mano software de sistemas en tiempo real. En los últimos diez meses, he tenido que enterrar esa identidad. Aunque mi cargo todavía dice “ingeniero de software”, mi trabajo ahora es el de un “ingeniero de contexto”.

Durante los últimos cuatro años, he pasado mis noches y fines de semana construyendo un negocio de código abierto y autofinanciado, Bencher. Bencher es una plataforma de benchmarking continuo que ayuda a los ingenieros de software de sistemas a detectar regresiones de rendimiento antes de que se fusionen. Para lograrlo hace falta todo un conjunto de herramientas: un CLI, un servidor API y una consola web como interfaz de frontend. Cada uno de estos componentes lo escribí yo, salvo un error de redondeo. He tenido algunos colaboradores de código abierto destacados a lo largo de los años, pero la gran mayoría de Bencher como proyecto de código abierto y el 100% de Bencher como negocio lo diseñé e implementé yo mismo.

En estos cuatro años, no me quedé encerrado en una cueva. Me comprometí, me casé y tuve a mi primer hijo. Me llevaba semanas, y a veces meses, sacar adelante la implementación de una funcionalidad grande y desplegarla. Tenía que hacer malabares entre el desarrollo y el soporte. Bencher ya tenía muchos usuarios, así que dedicaba bastante tiempo a responder preguntas y a corregir algún que otro bug.

Allá por 2022, mi uso de los LLM se limitaba a la versión freeware para Rust de TabNine, una herramienta de autocompletado con tabulador para desarrolladores creada por un estudiante que fue uno de los primeros becarios de OpenAI y que trabajaba en un curioso proyectito llamado Codex. En cuanto se lanzó GitHub Copilot y añadió soporte no oficial para Rust, solté los $10/mes de una licencia personal.

Era tosco. Pero aun así parecía un poco de magia. Recuerdo quedarme alucinado, poco después de que se añadiera el chat a la extensión de GitHub Copilot para VSCode, con lo bien que creaba macros procedurales de Rust. Normalmente tenía que retocar un poco el resultado, pero unas cuantas veces lo clavó a la primera. ¡Una locura! Esto estaba genial y probablemente me ahorró algo de tiempo, pero seguía trabajando mayoritariamente igual que antes.

A partir de entonces, tenía la mentalidad de que Microsoft iba en la vanguardia con GitHub Copilot. Aunque esos laboratorios novedosos estuvieran lanzando “agentes” por ahí, podía confiar en que GitHub Copilot se pondría al día si había algo que valiera la pena. Escuchaba a gente como Dan Shipper en Lenny’s Podcast, y lo que contaban sobre las capacidades de los modelos simplemente no cuadraba ni con mi experiencia ni con mi listón de calidad.

A principios del año pasado, escribí una publicación reflexionando sobre tres años de desarrollo de Bencher, Revisión de Ingeniería: Edición 2025. En esa publicación repasé todas mis decisiones de ingeniería importantes para construir Bencher, abarcando frontend, backend, entorno de desarrollo, CI, lo que quieras. Dediqué un párrafo entero a desahogarme sobre lo mucho que me costó entender CUE lang dos años antes. Y, sin embargo, no hay ni una sola mención a la IA, a los LLM, ni siquiera a Copilot en ninguna parte de ese texto de 3.500 palabras.

Avancemos rápido a menos de un año después, y me encuentro compartiendo el duelo de We mourn our craft.

Claude ayuda a salvar la Navidad

Como muchos otros, durante las vacaciones de invierno de 2025 tuve la oportunidad de usar Claude Opus 4.5 a fondo. Estaba en Londres visitando a la familia de mi hermana con mi esposa y mi hijo. Mi hermana acababa de dar a luz a gemelos, así que se suponía que yo estaba allí para echar una mano. En lugar de eso, estaba atrincherado en el piso de arriba intentando defenderme del spam por correo electrónico y de ataques DDoS contra Bencher. Claude fue de muchísima ayuda para diagnosticar lo que estaba pasando y para idear posibles soluciones.

Al final migré Bencher detrás de Cloudflare y configuré reCAPTCHA. Seguía siendo yo quien hacía la mayor parte del trabajo, pero Opus 4.5 supuso un salto notable en su capacidad para resolver problemas con muchas restricciones de diseño en conflicto. Eso sí, me sugirió un cambio que dejó inservible el script de conveniencia para instalar el CLI de Bencher durante medio día. Ups.

Año nuevo, arnés nuevo

Para enero de este año, llevaba meses oyendo lo impresionante que era Claude Code. Hasta entonces no lo había probado porque Opus 4 simplemente no alcanzaba mi listón de calidad como para fiarme de su trabajo. Ahora que Opus 4.5 sí lo alcanzaba, quise darle una oportunidad también a Claude Code. La mejora que noté al pasar de usar Copilot como arnés a Claude Code fue un salto tan grande como pasar de usar Opus 4/GPT-5.2/Gemini 2.5 Pro como modelo a Opus 4.5.

Mi primerísimo fin de semana con Claude Code hice una prueba no muy controlada contra Copilot. Quería que Copilot convirtiera un PDF en un audiolibro. Incluso en “Agent Mode”, Copilot avanzaba cinco o seis pasos y luego simplemente se detenía hasta que le daba otro empujón. Mientras tanto, Claude Code estaba a tope intentando construir un hipervisor a medida, después de pasar por un Plan mode exhaustivo. Me convencí por completo de que el nivel de abstracción había subido del modelo al arnés y de que Copilot nunca volvería a ponerse al día.

Soñando con Bencher Bare Metal

Desde los primeros días de Bencher, había soñado con construir una flota de benchmarking en bare metal. Los runners de CI tradicionales, por el hecho de ser máquinas virtuales, tienen demasiado ruido como para darte resultados de benchmark consistentes. Podrías detectar, digamos, un aumento del 200% en la latencia, pero nunca podrías detectar de forma fiable un aumento del 20%. El recuento de instrucciones es una posibilidad para hacer benchmarking en CI. Es mayormente determinista. Sin embargo, el recuento de instrucciones es un indicador indirecto de lo que de verdad te importa: el tiempo de reloj. Cualquier cosa que se ejecute en una “simulación de CPU” y escupa recuentos de instrucciones solo puede correlacionarse con la velocidad. El problema es que nunca sabes cuánto se desvía, ni si es por mucho o por poco, a menos que midas de verdad en bare metal.

Uno de los primeros usuarios de Bencher fue el proyecto Rustls. Ayudé a contribuir a su Rustls bench runner. Sin embargo, no era una buena base sobre la que construir una flota de benchmarking en bare metal. Vivía en un único host y trataba todas las cargas de trabajo de benchmark como de confianza. Eso significa nada de PRs desde forks y nada de multitenencia. Además, la mayoría de los equipos no quieren pagar más de $100 al mes por cada servidor de benchmarking en bare metal.

Había considerado usar GitHub Actions para la capa de orquestación, pero este enfoque tenía algunas carencias fundamentales. Para empezar, el GitHub Actions Runner está escrito en C#. Esto significa que su recolector de basura podría activarse en mitad de tu ejecución y sesgar los resultados de tus benchmarks. Ah, y asegúrate de desactivar el actualizador automático para que no se active a mitad de una ejecución, ¡pero no te olvides de él durante demasiado tiempo o tus jobs dejarán de ejecutarse!

Incluso si el GitHub Actions Runner fuera un binario de Rust bonito y silencioso, el problema más fundamental era que estaba atado a GitHub Actions. Bencher ha sido CLI first desde el principio. Para bien o para mal, no he querido atar Bencher demasiado a ningún proveedor de CI concreto. Existe una GitHub Action del CLI de Bencher, pero lo único que hace es instalarte el CLI. Quería que Bencher Bare Metal funcionara desde cualquier lugar donde funcione el CLI, no solo desde GitHub Actions.

La idea que se me ocurrió fue usar imágenes OCI para empaquetar la carga de trabajo de benchmarking y un sandbox opcional y muy pequeño para ejecutar siempre un único job a la vez en un host bare metal determinado. La perspectiva de construir todo esto yo solo, por las noches y los fines de semana, era abrumadora. Con un trabajo diurno y una familia, me habría llevado al menos un año irlo sacando adelante poco a poco por mi cuenta.

Construyendo Bencher Bare Metal

Con Opus 4.5 y Claude Code en la mano en enero de este año, sentí que por fin podía ver el camino práctico para construir Bencher Bare Metal. Una vez más solté la pasta, esta vez la friolera de $200/mes por el plan Claude Max 20x. Probablemente el mejor gasto empresarial de la historia.

Me puse a darle caña a tope e hice todo lo posible por exprimir al máximo el uso de mi plan de Claude cada semana. Dejé de escribir código a mano, tanto en Bencher como en mi trabajo diurno. En ese momento todavía iteraba en ciclos bastante cortos, usando Plan mode, leyendo todo el resultado y ejecutando en modo Accept edits. Todavía no me fiaba de que el agente tocara git/jj, así que me encargaba yo mismo de todo el control de versiones. Me veía a mí mismo como un Ralph Loop con un humano en el bucle. Con unos cinco agentes ejecutándose en paralelo, mi cerebro empezaba a derretirse.

Una sugerencia que había oído era que agentes distintos se encargaran de la implementación y de la revisión, así que empecé a hacer revisiones adversariales separadas. Estas revisiones adversariales realmente parecían ayudar a mejorar la calidad del resultado. Creé mi propio bot de revisión con GitHub Actions que usaba la clave API de mi suscripción de Claude Code. Luego hacía que mi agente local iterara con este revisor de CI para ahorrar ciclos en mi máquina local.

En algún momento de todo aquello, pensé que iba a hacer que Claude construyera su propio hipervisor para el sandbox de benchmarking. Luego le pedí a Claude que hiciera una revisión adversarial del plan en el papel de Linus Torvalds, y me dijo que era un estúpido y que era una idea muy, muy, muy tonta. ¡Nada de adulación cuando Linus está en tu contexto! Así que deseché ese plan y me fui con Firecracker.

El enemigo de un buen benchmarking es la varianza, no la velocidad en sí. Así que, aunque Firecracker añade sobrecarga como hipervisor, es una sobrecarga muy consistente, sobre todo con una sola microVM ejecutándose a la vez. Esto permite que los runners compartidos de Bencher Bare Metal tengan tanto multitenencia como resultados de benchmarking muy consistentes. También trabajé con Claude usando Plan mode para diseñarlo todo de forma que el sandbox fuera opcional. Si un usuario quiere ejecutar en su propio servidor dedicado, donde sí confía en todas las cargas de trabajo, puede ejecutar sin Firecracker con una sobrecarga casi nula.

Desarrollar el runner de Bare Metal fue una gran lección para mí sobre lo importante que es que los agentes tengan un ciclo de retroalimentación corto. Incluso después de que saliera Opus 4.6, Claude parecía tener dificultades para que todo funcionara de forma consistente. En cuanto le di acceso a un entorno de desarrollo con KVM habilitado (que es necesario para ejecutar Firecracker), todo empezó a encajar de verdad. Estos agentes no son omniscientes, simplemente son muy persistentes.

El nivel de escrutinio al que sometía el trabajo de Claude dependía de la parte del código en la que estuviera trabajando. El código que era exclusivamente para Bare Metal, como el registro OCI y el binario runner, solo lo revisé por encima. Mientras pasara la revisión adversarial, pasaran los tests end-to-end y la cosa no tuviera una pinta demasiado terrible, lo fusionaba. Con el código que tocaba el núcleo existente, la cola de jobs y el procesamiento de informes, fui igual de quisquilloso que siempre.

A finales de marzo de este año, lancé Bencher Bare Metal como parte de la v0.6.0. Para la flota pública de bare metal, estuve considerando usar AWS EC2 Bare Metal. Sin embargo, esas máquinas son enormes y solo ARM. Para reflejar la mayoría de las cargas de trabajo del mundo real, quería máquinas Intel x86 de clase trabajadora. Investigué con Claude para encontrar el mejor hogar para la flota que cumpliera las restricciones de diseño. Al final pudimos ofrecer la Spec intel-v1 en Bencher Cloud, que da a los usuarios 4 vCPU, 48 GB de memoria y 128 GB de disco, facturados por minuto. Con benchmarks bien estructurados, obtenía de forma consistente una varianza de <2% entre ejecuciones en toda la flota.

Autenticación de agentes

Hasta Bencher Bare Metal, toda la autenticación había sido con JWT. JWT grandes, preciosos e incomprensibles. La autenticación de los runners de Bare Metal era una clave API con un prefijo de nombre, por ejemplo bencher_runner_abc123....

En el lado del cliente, quería darles a los agentes algo con lo que trabajar que no fuera el propio JWT del token API de un usuario. El punto intermedio que encontré fue implementar por fin una funcionalidad muy solicitada desde hacía tiempo: la autenticación con alcance de proyecto. Claude me ayudó a crear claves API seguras, con prefijo y con alcance de proyecto. Estas claves API están limitadas a permisos equivalentes a lo que hace el comando bencher run del CLI: lecturas con alcance de proyecto y escrituras no destructivas. Esto también hace que estas claves API encajen de forma natural en los flujos de trabajo de CI de benchmarking continuo.

Más tarde, cuando añadí el Bencher MCP, estas claves API con alcance de proyecto también se usaron para la autenticación allí. El estándar MCP especifica OAuth 2.1, pero todavía es un borrador, así que no quise implementarlo aún. Sinceramente, soy un poco escéptico con MCP. Sigo pensando que un buen CLI + skills es una forma más eficaz y portable de exponer un servicio a un agente. Aunque el mayor problema de los CLI es que carecen de un mecanismo de autenticación estándar. Así que, aunque OAuth 2.1 todavía sea un borrador, al menos MCP tiene eso cubierto. Y una buena historia de autenticación importa de verdad en el mundo enterprise.

Claude, el políglota

Allá por 2023, decidí que quería que la documentación de Bencher estuviera disponible en 9 idiomas: inglés, chino, español, portugués de Brasil, ruso, japonés, francés, alemán y coreano. ¿Cómo elegí esos nueve idiomas? Son los idiomas en los que estaba la documentación de GitHub, así que pensé que era una aproximación suficientemente buena. El único problema es que solo hablo inglés con fluidez. Así que hice que GPT-4 me tradujera la documentación. En aquel momento GPT-4 solo tenía una ventana de contexto de 8k tokens. Esto significaba que tenía que dividir todas mis páginas de documentación en “fragmentos” de menos de 8k tokens. Luego tuve que crear una herramienta CLI para gestionar la traducción y, muy a menudo, la retraducción de los fragmentos después de actualizarlos.

Era un proceso muy tedioso y propenso a errores. Tenía que editar a mano los archivos traducidos porque, incluso con instrucciones muy explícitas en el system prompt, el modelo seguía estropeando las rutas de importación o metiéndolo todo dentro de otra capa de bloque de Markdown, sobre todo en japonés, por alguna razón.

En cuanto empecé a usar Claude Code con Opus 4.5, todo esto desapareció. Ahora el agente simplemente lo hace. La convención de lo que constituye un fragmento está ahí, en el código, y Claude simplemente la sigue. Cuando estaba escribiendo la documentación técnica de Bencher Bare Metal, Claude se encargó sin más de dividir en fragmentos y de orquestar las traducciones. Aunque el tamaño del contexto ahora es más que suficiente para abarcar una página entera, me gusta tener los fragmentos. Ayudan a mantener los cambios aislados, de modo que solo las secciones relevantes de una página se retraducen durante una revisión.

¿Quién no construyó un arnés en 2026?

Mientras construía Bencher Bare Metal, también hice que Claude creara herramientas para sí mismo con las que gestionar la flota. Esto constaba de dos partes: un CLI en el repo bencher para las tareas rutinarias y un nuevo meta-repositorio (meta-repo). Este meta-repo contiene toda la documentación y el contexto de Bencher como producto. Todos los demás repos de la organización bencherdev de GitHub son un submódulo dentro de este meta-repo. El meta-repo permite que el agente trabaje fácilmente en una tarea que puede abarcar varios repositorios y que escriba documentos que prefiero que no sean públicos (estrategia de producto, informes de incidentes, etc.).

Quería construir mi propio agente sobre el CLI de Claude Code que llevara este meta-repo de ser un artefacto a ser una parte proactiva del ciclo de desarrollo. En cuanto Fable 5 estuvo disponible, puse gran parte de mi atención en construir este agente. Quería poder confiar en que este agente se ejecutara de forma autónoma. Una gran parte de esto era la seguridad (es decir, mitigar las inyecciones de prompt). Lo diseñé para que los agentes trabajadores nunca tuvieran ningún secreto. Todos los secretos los inyecta un proxy de red y están restringidos a endpoints de una lista de permitidos. Los propios agentes se ejecutaban en otra microVM de Firecracker más, esta vez con paralelismo. La máquina de control de los agentes y el proxy de red + los sandboxes se ejecutaban en hosts completamente distintos.

Mi gran visión era que la interfaz fuera una cola ordenada por prioridad de tareas. Es decir, el objetivo de este agente sería mostrarme la tarea más importante en ese momento concreto. Mientras que los feeds de Facebook/Instagram/Twitter/X/TikTok están optimizados para el engagement, este feed estaría optimizado para lo que es importante para mí.

Quería crear la herramienta que me colocara a mí mismo por debajo de la API. Me había dado cuenta de que pasaba la mayor parte del tiempo cambiando de contexto y saltando de un hilo a otro. Mi esperanza era que el agente pudiera ayudar a aliviar estos malabares ordenando las cosas por mí. Con un sistema de votos positivos/negativos al estilo de Reddit, podría entrenar al agente para que supiera si ese nuevo mensaje de Slack era de verdad lo más importante a lo que debía prestar atención.

También me he dado cuenta de que gran parte de mi trabajo ahora consiste en ser el Rubeus Hagrid de mi agente, su “guardián de las llaves”. La inyección a nivel del proxy de red con una lista restringida de endpoints permitidos fue la mejor forma que Claude y yo encontramos para que el agente nunca tuviera acceso a un secreto y, aun así, pudiera usar herramientas como el CLI gh sin configuración adicional.

El otro gran objetivo era no salir nunca de la interfaz del agente. Alejarse del agente por cualquier motivo se considera un fallo del arnés. Creé un sistema de componentes de UI procedurales para que el agente que trabajaba en una tarea pudiera construir una interfaz nueva sobre la marcha o elegir uno de los componentes existentes de la biblioteca según la tarea en cuestión. Código, correo electrónico, Slack, calendario, datos de telemetría de producción, monitorización de errores, todo en una sola interfaz, todo en una sola cola priorizada.

Conseguí poner en marcha una versión mínima de todo esto. Sin embargo, todavía tiene muchas asperezas. Ahora mismo soy mucho más productivo si simplemente uso la app de escritorio de Claude. Y en este preciso momento, necesito toda la productividad inmediata que pueda conseguir para seguir el ritmo de la demanda.

¿Qué pasa cuando el número de desarrolladores se multiplica por 100?

Allá por 2022, estaba buscando un nuevo proyecto paralelo. Había cerrado mi anterior aventura de aspirante a emprendedor en 2020. Consejo pro: hazle caso a Jason Cohen, no intentes autofinanciar un marketplace.

En mi trabajo diurno estaba construyendo un parser y analizador estático de bash en Rust, y me di cuenta de que tenía que usar una hoja de cálculo para hacer el seguimiento de los resultados de mis benchmarks. El proyecto Rust tiene rustc-perf para hacer el seguimiento del rendimiento del propio compilador. Y, sin embargo, no había una buena herramienta para hacer esto con mi propio código.

Investigué muchísimo la técnica anterior en el campo. A lo largo de unos meses, tuve llamadas con varios desarrolladores que habían construido herramientas de benchmarking continuo o habían abogado por construirlas. Todo el mundo estaba reinventando la rueda. Pensé que había encontrado un remanso tranquilo en las aguas del mercado. Había una necesidad obvia y continua. Muchos equipos ya pagaban más de $100/mes por sus propios runners bare metal. Así que había disposición a pagar. Sin embargo, el caso de uso era de nicho. La mayor parte del software moderno se despliega como servicio, así que aplicar shift left a las pruebas de rendimiento no era una gran prioridad para la mayoría de los equipos. Simplemente configuraban alertas en Grafana después del despliegue y cazaban a posteriori cualquier cosa que se colara.

Sin embargo, con la llegada de agentes muy capaces, dos factores han aumentado enormemente el uso de Bencher:

  1. La necesidad de adoptar las buenas prácticas de ingeniería de software para probar de forma determinista el resultado de los agentes
  2. La facilidad de adoptar las buenas prácticas de ingeniería de software con la ayuda de los agentes

Los LLM y, por extensión, los agentes son sistemas no deterministas y estocásticos. Al igual que los desarrolladores humanos, necesitan barreras de protección para asegurarse de mantener la calidad del código. Las formas de hacerlo no son nuevas: un sistema de tipos robusto, un formateador estándar, un linter con el volumen a 11, tests, tests y más tests. Todo ejecutado en CI. Para cargas de trabajo sensibles al rendimiento, estos tests incluyen benchmarks de los que se hace seguimiento. Hacer el seguimiento del rendimiento del software a lo largo del tiempo te permite detectar regresiones de rendimiento en CI. Esto se llama benchmarking continuo. Implementar el benchmarking continuo siempre había sido un poco engorroso. Solo lo hacían los equipos a los que de verdad, de verdad les importaba el rendimiento, ¡y esos eran unos usuarios de Bencher estupendos!

Sin embargo, con la llegada de los agentes, el esfuerzo de añadir benchmarking continuo a tu flujo de trabajo usando Bencher pasó a estar a solo un prompt corto de distancia. Es difícil de medir del todo, pero apostaría a que la gran mayoría de los registros entrantes de Bencher vienen ahora de la recomendación de un agente o de un agente que lo hace por su cuenta. Esto no hará más que acentuarse con el tiempo, a medida que más desarrolladores adopten agentes y los empoderen con el comercio agéntico. Puede que sea o no el protocolo x402, pero creo que en el futuro gran parte del gasto en herramientas para desarrolladores estará mediado por agentes. Te recomiendo que reserves tu Cloudflare Wallet y tu Stripe Wallet, si no lo has hecho ya.

Casi todas las herramientas para desarrolladores tendrán que pasarse a precios basados en el uso en la era agéntica. Los precios por puesto no tienen sentido cuando son los agentes quienes usan tu servicio. Bencher siempre ha tenido precios basados en el uso. Sin embargo, con la ayuda de Claude, hace poco renové el modelo de precios para que fuera todavía más amigable con los agentes. Antes, Bencher cobraba por Métrica. Una Métrica es un único resultado de benchmark en un punto en el tiempo. Por ejemplo, si tienes 1 benchmark y lo ejecutas 5 veces, eso crea 5 Métricas. Claude me ayudó a analizar los comentarios de los usuarios y los patrones de uso. Llegué a la conclusión de que la unidad que usábamos en nuestro modelo de precios basado en el uso tenía que cambiar. Ahora Bencher cobra por Serie de Benchmark. Una Serie de Benchmark es un benchmark del que se hace seguimiento a lo largo del tiempo. Volviendo a nuestro ejemplo, si tienes 1 benchmark y lo ejecutas 5 veces, eso es 1 Serie de Benchmark. Este nuevo modelo de precios da a los usuarios mucha más previsibilidad. Puedes darle a un agente un problema de optimización y puede hacer hill climbing sobre tus benchmarks históricos sin incurrir en ningún coste adicional.

Una de las cosas que no he visto cambiar este último año son las contribuciones de código abierto. Bencher ha recibido un par de PRs de bazofia generada por IA. El principal problema de estos PRs era que corregían bugs aleatorios y sin relación que se habían ido encontrando por el camino. ¡Aunque seguían siendo bugs genuinos! Así que me encogí de hombros y fusioné los PRs, después de que mi propio agente los revisara, por supuesto. Es un poco triste, pero ya no veo mucho beneficio en cortejar a los colaboradores de código abierto. Ya sean sus tokens o los míos, sigo teniendo que poner el mismo esfuerzo en revisar el código. Ahora me cuesta mucha más energía revisar el PR de un colaborador que iterar yo mismo con Claude.

¿Cuál es el futuro del benchmarking continuo?

Cuando se intenta adivinar lo que depara el futuro, el patrón parece ser que deberíamos fijarnos en lo que hacen los propios laboratorios de vanguardia. Todos estaremos ahí en seis a doce meses, según parece. El artículo de The Pragmatic Engineer Inside OpenAI’s agentic software factory arroja una luz interesante sobre esto desde la perspectiva del benchmarking continuo:

Nuevo: un “perf harness”: el agente también usa un perf harness para enviar PRs problemáticos al framework A/B de Synthetics y evaluar sus implicaciones de rendimiento. Como se mencionó antes, la carga sobre los sistemas de CI ha aumentado enormemente en los últimos seis meses.

El “perf harness” de OpenAI parece muy similar a la práctica establecida del benchmarking continuo relativo. La parte novedosa de IA es el componente sintético del framework A/B. Los datos de prueba sintéticos no son nuevos. ¡Pero poder dar forma de manera autónoma a esos datos sintéticos para evaluar el rendimiento del conjunto de cambios en cuestión sí que es nuevo! Conseguir que un desarrollador escriba de verdad los benchmarks siempre ha sido la gran batalla. Ahora está automatizado. Del mismo modo que los agentes han aumentado drásticamente la cobertura de tests funcionales, también nos están permitiendo aumentar drásticamente la cobertura de tests de rendimiento.

OpenAI no está sola en esta búsqueda. Poco después, Anthropic publicó How we made claude.ai 3x faster in two weeks. En él también describen cómo construyen benchmarks sobre la marcha. Una diferencia clave fue que Anthropic encontró recuentos deterministas que se correlacionan con el rendimiento: instrucciones, commits por interacción, llamadas a funciones, recálculos de estilos y mutaciones del DOM. Luego Claude hizo hill climbing sobre estos recuentos para optimizar el rendimiento de su app. Al final de la pasada de optimización, comprobaron que sus optimizaciones basadas en recuentos se traducían de verdad en mejoras del tiempo de reloj en el mundo real.

Estas metodologías encajan con lo que yo mismo he estado viviendo al trabajar en Bencher. Eso sí, todas mis pruebas de rendimiento A/B se han ejecutado en local o en la máquina de trabajo de un agente, no en un bucle de CI. Siempre que estoy a punto de hacer un cambio grande en una consulta o una migración de esquema significativa, hago que Claude realice una evaluación de rendimiento exhaustiva del cambio. Esto siempre incluye el tiempo de reloj y, de vez en cuando, algunos recuentos deterministas complementarios (por ejemplo, instrucciones de la máquina virtual de SQLite).

Debido a los problemas de vecinos ruidosos, estas pasadas de optimización de rendimiento dirigidas por agentes han tenido unas barras de error bastante amplias. Quiero añadir fixtures (entradas de benchmark adicionales) y artefactos (salidas de benchmark adicionales) a Bencher Bare Metal para que mi agente pueda ejecutar mejor estas tareas de optimización de rendimiento con más confianza. El agente seguirá haciendo la mayor parte de su trabajo de optimización en local, haciendo hill climbing lo mejor que pueda sobre el tiempo de reloj o los recuentos deterministas. Luego usará Bencher Bare Metal para comprobar su trabajo, como una especie de calibre de tiempo de reloj.

Aunque creo que la mayoría de los “usuarios” de Bencher serán agentes dentro de un año o así, sigo pensando que la mayoría de los humanos querrán una interfaz visual para cuando se pasen a echar un vistazo. Ahora mismo estoy hasta el cuello con un rediseño total de la UI de Bencher con la ayuda de Claude. Como ingeniero de Rust que escribía Anyscript en los tiempos del autocompletado con tabulador de GitHub Copilot, la UI actual deja mucho que desear. Sin embargo, la reescritura de la UI está bloqueada por otra renovación aún más ambiciosa: una nueva versión del Bencher Metric Format (BMF).

BMF es el formato central al que se normalizan los resultados de benchmark dentro de Bencher. Lo atraviesa todo. Esta nueva versión de BMF permitirá parametrizar los benchmarks. Podrás decir my_benchmark con los parámetros size: 16 MB y size: 32 MB, en lugar de tener dos benchmarks separados, my_benchmark_16_mb y my_benchmark_32_mb. La nueva versión de BMF también permitirá nombres de métricas arbitrarios. Podrás proporcionar las métricas mean, p95 y p99 para tus mediciones de Latency, en lugar de tener solo mean o tener que crear Latency (mean), Latency (p95) y Latency (p99) como mediciones separadas.

Dar soporte a esta nueva versión de BMF es una renovación enorme del núcleo de Bencher. No me habría sentido cómodo haciendo este trabajo con nada anterior a Fable 5. Como comenté antes, la mayor parte del trabajo de Bare Metal era ortogonal al núcleo de Bencher: hacer el seguimiento del rendimiento a lo largo del tiempo y alertar sobre regresiones. BMF es central para esa propuesta de valor principal. Mi confianza en Fable 5, y más aún en Fable 5.1 y Opus 5.5, me ha permitido una vez más empezar un proyecto que me habría llevado años de noches y fines de semana completar. Antes tuve que dedicar bastante tiempo a optimizar SQLite para Bencher. Ahora, cada vez que evoluciono el modelo, simplemente le pido a Claude que levante un agente para hacer una investigación de rendimiento exhaustiva y asegurarse de que todo sigue siendo eficiente. En el futuro, creo que ni siquiera tendré que pedirlo.

Cómo programo hoy

Cuando usaba GitHub Copilot, era una extensión de VSCode. Cuando me pasé a Claude Code, al principio usaba el CLI. Tenía tres ventanas de terminal, cada una en su propio Space de macOS. Cada ventana de terminal tenía dos pestañas. Una pestaña era para Claude y la otra para Jujutsu (jj). Todavía gestionaba yo mismo el control de versiones y los workspaces de jj.

Hoy en día, simplemente uso la app de escritorio de Claude Code. Cada nueva sesión que inicio parte de mi meta-repo con la casilla worktree activada. Dejé de usar Plan mode hace unos meses. Nunca instalé la skill /grill-me de Matt Pocock. Simplemente le pido a Claude en el prompt que “me someta a un interrogatorio sobre todas las decisiones de diseño”, y a estas alturas el modelo sabe qué hacer. Mi CLAUDE.md AGENTS.md está bastante bien ajustado a cómo quiero que se comporte el modelo.

Prácticamente he desmantelado mi flujo de trabajo de CI de Claude Review. Ahora el agente se encarga de levantar un revisor adversarial en local sin que yo tenga siquiera que pedirlo. Luego iteran hasta converger, a veces hasta media docena de rondas. He empezado a experimentar con delegar el trabajo de desarrollo a máquinas de trabajo externas y dejar mi máquina local solo como orquestador.

Las únicas veces que toco el control de versiones yo mismo son cuando quiero hacer checkout de una build para probar cosas por mi cuenta o cuando creo una release etiquetada y versionada de Bencher. Esto ocurre más o menos una vez por semana y una vez al mes, respectivamente. Aparte de eso, ahora dejo que Claude se encargue. Uso muchísimo los PRs en borrador y, ahora que están disponibles en GitHub, los PRs apilados. No miro el código hasta que el PR está abierto. Todavía echo un vistazo rápido al código de Bencher, pero a estas alturas es más una comprobación de cordura que una revisión de código de verdad.


Cuando mire atrás dentro de un año y relea lo que he escrito aquí, ¿tendré otro momento de “¡Ni siquiera mencionaste la IA‽”? La mitad de mí piensa en lo increíble que sería. La otra mitad está absolutamente aterrorizada.


Bencher: Benchmarking continuo

Bencher es un conjunto de herramientas de benchmarking continuo. ¿Alguna vez has tenido un impacto de regresión de rendimiento en tus usuarios? Bencher podría haber evitado que eso sucediera. Bencher te permite detectar y prevenir las regresiones de rendimiento antes de que se fusionen.

  • Ejecutar: Ejecute sus benchmarks localmente o en CI usando exactamente los mismos runners bare metal y sus herramientas de benchmarking favoritas. La CLI bencher orquesta la ejecución de sus benchmarks en bare metal y almacena sus resultados.
  • Seguir: Sigue los resultados de tus benchmarks con el tiempo. Monitoriza, realiza consultas y representa gráficamente los resultados utilizando la consola web de Bencher basándose en la rama de origen, el banco de pruebas y la medida.
  • Capturar: Captura las regresiones de rendimiento localmente o en CI usando exactamente el mismo hardware bare metal. Bencher utiliza analíticas de vanguardia y personalizables para detectar regresiones de rendimiento antes de que se fusionen.

Por las mismas razones que las pruebas unitarias se ejecutan para prevenir regresiones funcionales, los benchmarks deberían ejecutarse con Bencher para prevenir regresiones de rendimiento. ¡Los errores de rendimiento son errores!

Empiece a capturar regresiones de rendimiento — prueba Bencher Cloud gratis.

🤖 Este documento fue traducido automáticamente por IA. Puede que no sea exacto y contenga errores. Si encuentra algún error, abra un problema en GitHub.