1 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Al refactorizar por etapas una capa de acceso a datos en Rust de 17,155 líneas escrita por un agente, los tokens de entrada necesarios para el mismo cambio funcional bajaron de 159,564 a 27,360, una reducción del 83%
  • Aunque el volumen total de código casi no cambió, al separar el código relacionado en archivos con alta cohesión, el agente pudo leer solo el conjunto mínimo de archivos necesario para el cambio
  • Los tokens de entrada no se redujeron de forma significativa hasta que el archivo más grande se volvió lo suficientemente pequeño; al final, la capa de datos quedó dividida en 19 archivos Rust y el tamaño máximo de archivo bajó de 17,155 a 3,695 líneas
  • Los tokens de salida y la cantidad de funcionalidad implementada casi no cambiaron, y Claude tampoco pudo elegir por sí mismo una refactorización adecuada ni ejecutarla de manera confiable, por lo que se necesitaron indicaciones humanas activas para planificar y ejecutar
  • Con el precio de entrada de Sonnet 5 de $3/MTok, el ahorro por cada cambio fue de apenas unos $0.397, pero se confirmó la posibilidad de reducir costos de forma recurrente cada vez que se modifique la capa de acceso a datos en el futuro

Un archivo de 17,155 líneas creado por un agente

  • La aplicación de soporte operativo cuenta con una UI web con actualización y consulta dinámicas, modales y guardado automático, integración con sistemas externos, machine learning y análisis de texto, trabajos en segundo plano y un entorno de despliegue automático
  • De unas 150 mil líneas en total, alrededor de 120 mil son Rust y el resto es TypeScript y Terraform; la mayor parte fue escrita por agentes usando Claude Code y algo de Cursor
  • Salvo revisiones ocasionales por curiosidad, el desarrollador no leyó ni revisó el código
  • La capa de acceso a datos creció a más de 6,000 líneas al repetir la misma configuración de solicitudes HTTP y la codificación/decodificación JSON en todas las consultas de lectura y escritura, hasta que finalmente un único archivo Rust llegó a 17,155 líneas
  • Este módulo no tenía eliminación de duplicación ni un lenguaje interno, tenía una extracción de funciones limitada y casi ninguna extracción de clases, pero sí interfaces que preservar y límites claros, por lo que era adecuado para un experimento de refactorización

Método de medición repitiendo el mismo cambio

  • El objetivo era comprobar si invertir tokens en la refactorización actual podía reducir el consumo de tokens de futuros cambios funcionales
  • Como el agente no aprende de tareas anteriores, en cada etapa se pidió exactamente el mismo cambio a un nuevo subagente para evitar que se mezclara el efecto de aprendizaje
  • El experimento siguió este orden
    • Escribir un plan completo siguiendo principios estrictos de refactorización
    • Definir un cambio representativo con un solo prompt
    • Hacer que un subagente realizara el cambio e informara el consumo de tokens para medir el valor base
    • Descartar el resultado del cambio y aplicar una etapa de refactorización
    • Repetir el mismo cambio y volver a descartar el resultado
    • Registrar por etapa el costo en tokens, el tiempo de ejecución y las líneas de código
  • Como Claude no podía entregar de forma confiable el recuento de tokens en tiempo real, se le pidió reportar la cantidad de caracteres enviados y recibidos, y se aproximaron los tokens dividiendo los caracteres entre 4 con tiktoken

Resultados de medición por etapa

  • En el estado base, tanto la capa de acceso a datos como el archivo más grande tenían 17,155 líneas, el código Rust total tenía 50,359 líneas, y el cambio representativo requirió 159,564 tokens de entrada, 1,705 tokens de salida y 342 segundos
  • Después de 15 etapas, la capa de acceso a datos tenía 16,608 líneas, el archivo más grande 3,695 líneas, el código Rust total 49,812 líneas, y se necesitaron 27,360 tokens de entrada, 2,113 tokens de salida y 454 segundos de ejecución
  • En las etapas intermedias, a medida que se reducía el archivo más grande, también disminuían los tokens de entrada
    • Tras extraer queries.rs en la etapa 7, el archivo más grande bajó a 15,670 líneas y la entrada a 151,850 tokens
    • Tras extraer traits.rs en la etapa 8, el archivo más grande quedó en 13,845 líneas y la entrada en 132,558 tokens
    • Tras separar store/ en la etapa 12, el archivo más grande quedó en 9,269 líneas y la entrada bajó a 104,080 tokens
    • Tras la última separación de store/, el archivo más grande quedó en 3,695 líneas y la entrada cayó bruscamente a 27,360 tokens
  • La capa final de acceso a datos quedó compuesta por 19 archivos Rust, y el archivo más grande pasó a ser una librería de pruebas
  • En una refactorización adicional se podría aplicar el mismo método a ese archivo de pruebas

Por qué los tokens de entrada bajaron 83%

  • Los tokens de entrada para la misma tarea bajaron de 159,564 a 27,360, lo que ahorró 132,204 tokens
  • Como el volumen total de código de la capa de acceso a datos casi no cambió, no fue resultado de tener menos código que leer
  • El agente identificó el conjunto mínimo de archivos necesario para la tarea y fue leyendo regiones de código cada vez más pequeñas; esto también se confirmó en la salida de razonamiento de Claude Code y en los resúmenes de lectura de archivos
  • Si solo se dividen archivos arbitrariamente en partes pequeñas, el agente tendría que leer varios archivos para encontrar el código relacionado, por lo que es difícil obtener el mismo efecto
  • La mayor reducción ocurrió en la última separación, pero fue posible gracias a que en etapas anteriores se extrajo duplicación y se creó una estructura central repetida
  • Esta secuencia no se diseñó de antemano con el objetivo de reducir costos, sino que surgió de un proceso normal de refactorización: primero eliminar duplicación local, luego revelar el núcleo común y finalmente descomponer en archivos pequeños

Tokens de salida e impacto económico

  • Los tokens de salida generados al escribir el cambio representativo casi no cambiaron, por lo que la refactorización no redujo el tamaño real del cambio
  • Aunque el precio de los tokens de salida era 5 veces mayor que el de los tokens de entrada, su cantidad absoluta era mucho menor
  • Calculado con el precio de entrada de Sonnet 5 de $3/MTok, el ahorro por cambio es de unos 39.7 centavos
  • No se confirmó si el ahorro se acumula también en depuración, funcionalidades más complejas o refactorizaciones de todo el codebase, ni cuánto cuesta la refactorización en sí
  • Tampoco está claro si es posible una refactorización que reduzca los tokens de salida; en el cambio representativo simple, el ruido de la generación de código no determinista ocultó las diferencias atribuibles a cambios estructurales

Refactorización realizada con Claude

  • Claude no pudo observar el código y elegir por sí mismo qué refactorización aplicar; los resultados reales correspondieron a las tareas indicadas directamente en el prompt
  • Aunque el arnés de desarrollo tenía una etapa explícita de refactorización, Claude no la usó para mejorar el archivo de 17,155 líneas
  • Durante la planificación, Claude Code identificó la extracción de funciones como primer paso, mientras que Claude.ai llegó a identificar la extracción de toda una clase cliente
  • Para cambios mecánicos se usaron scripts de Python con grep y sed, pero los scripts se confundían con frecuencia por la indentación
  • La separación de archivos de store, que fue la más valiosa, se omitió en el primer intento y se aplicó de nuevo en una etapa posterior; por eso el número de etapas en las mediciones no coincide con las etapas del plan del apéndice
  • Todo el experimento tomó unas 8 horas y se realizó en su mayor parte sin supervisión
    • Después de 6 horas y 40 minutos se detectó una etapa omitida y hubo una intervención
    • La causa principal de la lentitud en la ejecución de pruebas no fue el Wi-Fi lento del hotel, sino una caché temporal de compilación de Cargo que había crecido demasiado

Prompt del cambio representativo

  • Cada subagente recibió solo el codebase y la documentación de arquitectura, e implementó el mismo trait público asíncrono ItemWatchStore
  • El trait incluye los siguientes tres métodos
    • watch_item(&self, item_id: &str, user_id: &str) -> Result<()>
    • unwatch_item(&self, item_id: &str, user_id: &str) -> Result<()>
    • watched_items_for_user(&self, user_id: &str) -> Result<Vec<String>>
  • La información de watch se guarda en la colección item_watches de Firestore con los campos itemId, userId y createdAt
  • Devuelve un Vec<String> de ID de ítems sin una estructura Rust de registro separada
  • En FakeStore se agrega un campo en memoria Vec<(String, String)>, y en FirestoreStore se implementa usando el patrón HTTP existente tal como está
  • Al final de la respuesta se le pidió que imprimiera en JSON los archivos leídos y la cantidad de caracteres, además de la cantidad de caracteres de la respuesta, y se le indicó que no hiciera commit del código

Plan de refactorización aplicado

  • Etapa 1 — Extraer la clase FirestoreClient

    • Separar las responsabilidades de coordinación de consultas de dominio y transporte HTTP de Firestore
    • Mover reqwest::Client, project_id, MetadataAuth, el manejo de URLs y encabezados de autenticación a una nueva estructura
    • Según el plan, reducir unas 1,200 líneas de la implementación de FirestoreStore y agregar unas 120 líneas al cliente
  • Etapa 2 — Extraer las funciones extract_doc_id y new_link

    • Unificar la extracción de ID en 20 parsers de documentos y la creación de Link repetida 62 veces
    • Se esperaba ahorrar unas 500 líneas
  • Etapa 3 — Extraer funciones de pipeline para consultas de links

    • Unificar el patrón de recolección de resultados de consultas en unos 15 lugares y el patrón de búsqueda de un ID de destino único en unos 8 lugares
    • Se esperaba ahorrar unas 200 líneas
  • Etapa 4 — Extraer funciones de condición de links en FakeStoreInner

    • Separar en dos métodos las variantes repetidas de inner.links.iter() en unos 15 métodos
    • Se esperaba ahorrar unas 120 líneas
  • Etapa 5 — Introducir funciones de creación de valores de Firestore

    • Reemplazar expresiones json! repetidas más de 128 veces para strings, timestamps, etc., por llamadas a cuatro funciones
    • Se esperaba ahorrar unas 80 líneas al convertir macros de varias líneas en llamadas de una línea
  • Etapa 6 — Extraer FieldsBuilder

    • Consolidar con un builder el patrón de creación de mapas de campos en unos 20 encoders
    • Se esperaba reducir encoders de unas 40 líneas a unas 12, con un ahorro total de 500 a 600 líneas
  • Etapa 7 — Separar queries.rs

    • Mover 32 constantes LinkQuery y tipos relacionados a un módulo separado
    • Reducir unas 800 líneas de mod.rs sin cambiar los sitios de llamada existentes
  • Etapa 8 — Separar traits.rs

    • Mover 17 traits públicos y tipos de error relacionados, y volver a exportarlos
    • Reducir unas 1,900 líneas de mod.rs, aunque el nuevo archivo también tendría unas 1,900 líneas
  • Etapa 9 — Separar traits/ por dominio

    • Dividir los traits en planning.rs, content.rs, people.rs y system.rs
    • Limitar el tamaño por archivo a unas 300–650 líneas sin cambiar definiciones ni sitios de llamada
  • Etapa 10 — Separar codec.rs

    • Mover encoders y decoders de documentos, parsers, FieldsBuilder y funciones de creación de valores
    • Después de la etapa 6, sería un módulo de unas 400–500 líneas y reduciría unas 500 líneas de mod.rs
  • Etapa 11 — Separar fake_store.rs

    • Mover FakeStore, FakeStoreInner y 18 implementaciones de traits
    • Reducir unas 4,700 líneas de mod.rs
  • Etapa 12 — Separar la implementación de FirestoreStore

    • Dejar en store/mod.rs la estructura, el constructor, FirestoreClient y MetadataAuth, y dividir las implementaciones de traits en archivos por dominio
    • Convertir un archivo de unas 10,000 líneas en 10 archivos de 120 a 650 líneas cada uno, y dejar mod.rs como un archivo de reexportación de unas 100 líneas
  • Etapa 13 — Colocar las pruebas junto con los módulos objetivo

    • Mover el código de pruebas debajo de cada archivo de implementación sin cambiarlo
    • Reducir unas 2,000 líneas de mod.rs y agregar pruebas relacionadas de 200 a 700 líneas a cada archivo

Limitaciones y experimentos posteriores

  • No se contaron por separado los tokens usados para escribir y ejecutar el plan de refactorización, por lo que no se puede calcular con precisión el costo de inversión de la refactorización
  • El límite superior, basado en el uso total durante ese periodo, es de 5 millones de tokens, pero incluye haber escrito el plan dos veces, el diseño del experimento y del cambio representativo, y otras tareas
  • El objeto del experimento todavía está en etapa greenfield y es una sola aplicación grande construida y mantenida por un único desarrollador, por lo que los resultados no se pueden generalizar
  • Como trabajo posterior, se necesita medir con precisión los tokens de refactorización, probar cambios más complejos, refactorizaciones de mayor alcance, refactorización continua y comparar el valor relativo de distintos enfoques
  • Este experimento es un punto de partida para medir tanto el valor en tiempo y dinero que produce la refactorización como el costo de la refactorización en sí

1 comentarios

 
GN⁺ 2 시간 전
Opiniones en Hacker News
  • Es interesante ver cómo las mejores prácticas para desarrolladores, que la mayoría de las empresas de TI ignoraban, se reinventan como mejores prácticas para IA.
    Antes, si decías que había que poner la documentación dentro del código, no limitarse a tirar tareas en Jira sino dar el contexto completo del proyecto, y refactorizar pensando en la productividad a largo plazo, lo consideraban aburrido.
    Ahora, si dices lo mismo como que la documentación para IA debe estar en el código y en CLAUDE.md, que no hay que controlar todo minuciosamente con prompts, y que refactoricemos por la productividad de la IA, se recibe con interés.

    • Es mucho más fácil hacer que un agente de IA realice el mismo trabajo de forma consistente que lograrlo con colegas humanos.
      Los humanos, aunque sepan cuál es la forma correcta, están ocupados o pierden la concentración; en cambio, los agentes no se cansan de las tareas tediosas, así que procedimientos cuya eficacia ya se había demostrado con humanos, pero que eran difíciles de aplicar de forma constante, se vuelven viables en la práctica.
      Hicimos que agentes separados escribieran la implementación y las pruebas a partir de una especificación común, y que un agente auditor las verificara para evitar que los resultados se contaminaran entre sí; eso es aplicar de manera amplia y consistente con IA la ingeniería de sala limpia que IBM desarrolló para humanos en la década de 1980.
    • La persona relacionada con este artículo es Martin Fowler, quien hace más de 20 años escribió el libro 《Refactoring》 y popularizó el término.
      No se trata de empaquetar viejas prácticas como si fueran nuevas al ritmo de la moda de la IA, sino de mostrar, con fundamentos, que mejores prácticas de hace más de 20 años siguen siendo válidas.
    • La gran diferencia entre antes y después de la IA es que los humanos tienen una capacidad de gestión de contexto a largo plazo bastante buena.
      Los agentes tienen que adquirir el contexto de nuevo en cada sesión, por lo que el valor de las mejores prácticas aumenta mucho y sus efectos se ven de inmediato.
    • Gracias al furor por la IA, ahora se puede conseguir presupuesto para las mejoras de experiencia de desarrollador que queríamos, aunque resulta amargo que el motivo sea el equivocado.
      Aun así, es bueno poder ejecutar una CLI 100 veces durante una hora para probar la usabilidad de una nueva bandera.
    • Los humanos, incluso con documentación vieja en SharePoint, el contexto general captado de pasada en reuniones y baja prioridad para la refactorización, de algún modo producen resultados, aunque la calidad y los plazos empeoren.
      En cambio, si la IA no cuenta con esa base, se desempeña muy mal o directamente no funciona, así que las prácticas de ingeniería saludables dejan de ser una mejora a largo plazo y pasan a ser un prerrequisito indispensable.
      Aunque el efecto neto real fuera nulo, incorporar IA al flujo de trabajo es útil en el sentido de que da una justificación para adoptar prácticas de desarrollo adecuadas.
  • Me gusta que este artículo critique las herramientas de IA de forma concreta y cuantitativa, basándose en cómo se usan realmente.
    Un texto que muestra con métricas qué es lo que la IA no puede hacer resulta mucho más útil que uno que habla vagamente de riesgos sociales sin casos de uso reales.
    Por la misma razón, también me pareció impactante este informe, que entrevistó a miembros de Boko Haram para investigar cómo se había usado la IA en el terrorismo.

  • Me encanta la refactorización hecha directamente, sin IA.
    No hay cambios visibles, pero da satisfacción convertir un sitio web que quizá no muestre resultados ahora mismo en algo mucho más fácil de manejar en el futuro.
    Es como un rompecabezas agradable encontrar código extraño del pasado que vuelve a resolver problemas ya solucionados con patrones establecidos, llevarlo hacia las mejores prácticas y hacerlo sin crear nueva deuda técnica.
    Implementé de forma torpe todo por mi cuenta, incluso la autenticación, y aprendí los principios internos de la manera difícil; como resultado, también me quedó material de refactorización para disfrutar durante los próximos 10 años.

    • Leí 《Refactoring》 de Fowler y dudaba de si también serviría para código científico y de investigación, pero después de aplicarlo experimentalmente a una estructura de código que me incomodaba, mi perspectiva cambió por completo.
      Llegué a entender de forma concreta la idea de que una base de código es un sistema, y empecé a verla en un nivel superior, como una organización continua o una red que se puede estirar y presionar.
      El hecho de que la IA pueda eliminar este proceso de aprendizaje resalta el problema de los desarrolladores junior. Para adquirir intuición no queda otra que meterse a fondo directamente y, aunque Naur lo advirtió hace 40 años, seguimos olvidando esta lección.
    • Quizá sea porque da una recompensa de dopamina, como al mirar la pantalla del desfragmentador de disco de Windows 98.
    • Ese sentimiento es orgullo de artesano. Para quien lo entiende no hace falta explicación; para quien no lo entiende, ninguna explicación sirve.
    • Me da curiosidad saber hasta qué punto se construyó una suite de pruebas como red de seguridad para evitar regresiones durante la refactorización.
    • Es disfrutable estudiar varios patrones de refactorización y casos reales de aplicación.
  • Considero que cuando un agente hace refactorización, la participación humana es indispensable
    Un modelo generativo puede concentrarse en el trabajo inicial y un modelo de revisión puede encontrar lo que se pasó por alto, pero queda la duda de si realmente puede entender el propósito de todo el proyecto y la forma en que el código se integra para distinguir duplicaciones o una estructura más elegante
    Encargarle la refactorización a un agente de coding es parecido a pedirle a un cirujano de trauma que mejore el rendimiento deportivo; para hacerlo bien se necesita una visión holística
    Dividir un archivo grande en varios archivos no pasa de ser una refactorización superficial. Si no hay una teoría sobre qué código debe estar junto y qué debe extraerse como funciones utilitarias, no es factorización, sino algo más cercano a partir un número grande en números pequeños y luego volver a sumarlos
    Un agente puede crear sistemas que vuelven a guardar y calcular valores que ya se obtienen desde una API, pero un humano puede mirar todo el proyecto y encontrar con precisión que los datos necesarios ya están en una clave específica del JSON

    • Los LLM actuales también lo hacen bastante bien si se les indica una refactorización concreta sobre una sección específica de código. Por ejemplo, pueden manejar un requisito complejo como implementar el patrón Command con functools.partial en lugar de clases de datos
      La idea de que los límites entre archivos representan los límites de subsistemas lógicos y facilitan el razonamiento, y de que el contenido de otros archivos se trata por defecto como opaco, también abunda en los datos de entrenamiento
      Creo que los beneficios de esta estructura no se deben solo a características accidentales de la cognición humana, sino que también tienen aspectos objetivos
    • Con un humano al lado explicando la dirección, terminamos en alrededor de una semana la mayor parte de una refactorización que habría tomado meses
      Ayudó mi experiencia en refactorización, la forma en que había trabajado con bases de código ajenas y el hecho de que, como diseñador original, podía explicar las intenciones pasadas y presentes
      Era un lenguaje de nicho, con pocas vulnerabilidades de dependencias y fácil de manejar para un LLM; después de eliminar el sesgo hacia JavaScript y Python, el ritmo de trabajo aumentó mucho
      Era un proyecto JSR-223 que escribía scripts en varios lenguajes populares, pero los ejecutaba todos en la JVM según las necesidades del entorno: https://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform
    • La idea de que los agentes no pueden refactorizar está desactualizada; hoy son muy buenos
      En este mercado laboral hay que usar agentes de coding basados en los modelos frontier más recientes y conocer con precisión sus capacidades y límites; dar una evaluación contraria en una entrevista puede ser motivo de descarte
  • Un contexto conciso no solo reduce el consumo de tokens, también mejora el razonamiento y permite meter más capas en un mismo contexto para manejarlas de forma inteligente
    La refactorización hacia buenas abstracciones produce software que generaliza mejor, con más probabilidad de acertar no solo en los casos probados, sino también en casos interpolados y extrapolados
    Hay teoría de la información y matemática bayesiana que respaldan esto, y parece una coincidencia elegante que el software más económico y eficiente energéticamente también sea más preciso
    La clave es reducir la entropía del código

    • En cualquier parte del mundo y del universo, una reducción de entropía puede verse como construir algo
    • Si se descarta la legibilidad humana como objetivo y se usa solo la reducción del consumo de tokens como función objetivo, es difícil saber adónde se llegará
      Los LLM ya infieren bastante bien el significado incluso con poco contexto
  • Me parece interesante que se hayan presentado datos, y coincide con mi impresión de que los LLM se benefician mucho del código bien separado, pero no son particularmente buenos para crear ese tipo de código por sí mismos
    Probablemente la mayoría de los desarrolladores humanos sean similares

    • Estoy presupuestando por separado tiempo para eliminar código descuidado, y ahora mismo estoy haciendo eso en la ventana de al lado
      En general, los beneficios de la IA son grandes, pero también se necesita tiempo de limpieza, y sigo pensando que hay que leer cada línea
      Para no bloquear el avance de otros equipos, postergué algunas revisiones y ahora estoy pagando una deuda técnica mayor de lo habitual, pero valió la pena destrabar primero el cuello de botella
      La IA hizo más fácil tomar deuda técnica en todos los sentidos, y si se la guía bien también es bastante buena para saldarla. Eso sí, los resultados varían según la persona: https://news.ycombinator.com/item?id=49035455
    • En el estado por defecto vi el mismo resultado, pero si se define concretamente la dirección de la refactorización, puede producir código mejor separado
      Ayuda mucho mostrarle qué hacer y qué no hacer mediante ejemplos de código bien estructurado o repositorios open source
  • La mayor parte del beneficio económico de la refactorización no viene del ahorro de tokens, sino de mejorar la comprensión humana
    Permite resolver más rápido una llamada por incidente a las 3 a. m., reducir los bugs que llegan a producción y lanzar más rápido que la competencia
    Sobre todo, cuando se entiende el sistema, uno está más dispuesto a asumir responsabilidad y ownership, así que cuando surge un problema lo corrige más rápido y también se involucra activamente en las mejoras

  • El punto es que la refactorización reduce el consumo de tokens, y está bien que se haya cuantificado el efecto en lugar de hablar en abstracto
    Pero Fowler dijo en 《Refactoring》 que el prerrequisito esencial para refactorizar son pruebas sólidas, y creo que ahí está el verdadero beneficio, independientemente de la IA
    Las buenas pruebas evitan regresiones creadas por humanos o robots, y dejan como código una especificación legible para ambos: https://www.oreilly.com/library/view/refactoring-improving-the/9780134757681/

    • El artículo está publicado en martinfowler.com, pero no lo escribió Martin; el autor figura como Giles Edwards-Alexander, CTO de Thoughtworks
    • El verdadero punto central es que el ahorro es de apenas unas decenas de centavos
      Si se calcula el precio de Sonnet 5 en 3 dólares por MTok, el ahorro en futuros cambios que toquen la capa de acceso a datos es de 39,7 centavos
      Considerando las bajas de precios de OpenAI, los modelos abiertos y la caída a largo plazo del precio de los tokens, puede que no justifique el costo de que un desarrollador senior de unos 100 dólares por hora guíe la refactorización
  • El código creado por agentes se convirtió en un bloque enorme que solo los agentes pueden leer y entender, y en ese caso la realidad en sí importa más que si eso es una funcionalidad, un bug o una propiedad emergente.
    Para manejar código generado con herramientas de IA, estamos volviendo a depender de herramientas de IA.
    Dicho eso, los humanos ya veníamos creando archivos monstruosamente grandes y monorepos, y gracias a los LLM, editarlos y refactorizarlos por fin se volvió manejable.
    En una situación en la que la base de código se volvió demasiado grande y caótica para que los humanos la entiendan, los LLM quizá puedan salvarnos; personalmente detesto los archivos gigantes, pero me resulta amargo pensar que los principios de ordenamiento al estilo Fowler tal vez ya no importen tanto.

    • Decir que el código de agentes solo puede ser entendido por agentes no es fundamentalmente cierto; si se siente así, lo que está mal es la forma de usar los LLM.
    • El mal código siempre existió, pero la IA es un problema nuevo porque multiplica por 1.000 el alcance del daño de una mala contratación.
      Incluso a un empleado promedio, o que a veces hace bien las cosas, puede convertirlo en un mal empleado al permitirle ejecutar a velocidad relámpago tareas que antes no podía hacer por los procesos de la empresa.
    • No tuve problemas para leer una base de código escrita 100% por un LLM ni para encontrar lo que quería; no fue más difícil que si la hubiera escrito yo mismo.
    • Nunca vi que el código creado por un agente fuera peor que el peor código hecho por humanos.
      Si un agente crea un archivo o una función enormes, basta con indicarle que no lo haga y obedece.
  • Considero que la refactorización es uno de los mejores indicios de un equipo de desarrollo saludable.
    La refactorización tiene beneficios propios, pero su valor no suele verse bien para el responsable de producto ni en la tabla de trabajo de funcionalidades.
    Si el equipo refactoriza por la salud del software en su conjunto, significa que los desarrolladores se sienten cómodos proponiendo mejoras para tener buen software y que esas propuestas se toman en serio.
    La degradación del software se vuelve más grave cuando el equipo no tiene motivación ni autoridad para hacer realidad una visión de software de alta calidad; si el equipo puede seguir su propio criterio de excelencia, en general es una buena señal.
    Claro que también hay excesos, como reescribir todo desde cero pasando por Ruby, Node y Rust para volver a una tecnología más amigable para agentes, pero en entornos empresariales es mucho más común encontrar equipos que sienten que no tienen permiso para mejorar.