9 puntos por GN⁺ 2025-12-24 | 1 comentarios | Compartir por WhatsApp
  • Para usar LLMs de forma efectiva en bases de código grandes, la clave es invertir en ‘guía’ (guide) y ‘supervisión’ (oversight)
  • La guía proporciona contexto y entorno para ayudar al LLM a tomar mejores decisiones, y la supervisión valida los resultados y marca la dirección
  • Es importante construir una biblioteca de prompts para que el LLM entienda las reglas, la documentación y las mejores prácticas de la base de código
  • La gestión de deuda técnica y la simplicidad, modularidad y consistencia de la estructura del código están directamente conectadas con una mejor comprensión del código y una mayor productividad del LLM
  • Los sistemas automatizados de supervisión y verificación son clave para ayudar al LLM a generar código seguro y consistente a largo plazo

Conceptos clave para escalar LLMs

  • Todavía no existe una forma plenamente establecida de aplicar LLMs a bases de código grandes, pero se plantea que invertir en guía y supervisión es el enfoque más efectivo
  • Guía (Guidance) se refiere al contexto y entorno que ayudan al LLM a tomar decisiones correctas, mientras que Supervisión (Oversight) se encarga de validar los resultados generados y ajustar la dirección

Invertir en guía

  • Para que un LLM logre generar código de alta calidad en un solo intento, es decir, ‘one-shotting’, se necesita una guía clara
    • En cambio, cuando el resultado no es adecuado y requiere correcciones manuales, se convierte en retrabajo (rework), lo cual es ineficiente
  • Como el LLM genera todas las decisiones dentro del código —nombres de variables, estructura de funciones, stack tecnológico, etc.—, lo ideal es que el prompt contenga solo los requisitos de negocio y que el resto pueda inferirse o ya esté codificado

Construcción de una biblioteca de prompts

  • Una biblioteca de prompts es un conjunto de contexto para el LLM que incluye documentación, mejores prácticas y mapas estructurales de la base de código
    • Cada vez que la salida del LLM se desvíe, conviene revisar “qué debía haberse aclarado” y añadirlo a la biblioteca
    • Es importante mantener un equilibrio entre amplitud y concisión
  • En el ejemplo, se proporcionan al LLM documentos como @prompts/How_To_Write_Views.md y @prompts/The_API_File.md para guiar el desarrollo de funcionalidades
  • El prompt debe ser lo suficientemente específico, pero aun así debe revisarse cada línea del código generado

Entorno y calidad del código

  • Una base de código con mucha deuda técnica (technical debt) reduce la eficiencia del uso de LLMs
    • Se menciona que, en el caso de Meta, la deuda técnica dificultó alcanzar objetivos de automatización
  • Código limpio, modularidad, nombres claros y una estructura simple aumentan la comprensión y precisión del LLM
  • En el ejemplo con Django, el punto de entrada de cada app se coloca en un archivo _api.py para estructurar el proyecto de forma que el LLM pueda encontrar rápidamente la funcionalidad necesaria
    • Ejemplo: visit_api.handoff_to_doctor(user) como forma unificada de acceso externo
    • El patrón _api se especifica en la biblioteca de prompts para orientar al LLM a consultar el lugar correcto

Invertir en supervisión

  • La automatización con LLMs debe abordarse como una forma de potenciar al equipo, no de reemplazar a los ingenieros
  • La supervisión lleva a invertir en equipo, alineación (alignment) y flujo de trabajo
    • A nivel de equipo, es importante mejorar la capacidad de diseño, ya que esto se traduce en una mejor calidad arquitectónica
  • Como formas de fortalecer la capacidad de diseño, se proponen leer libros, blogs y código, replicar trabajos de maestros y practicar implementaciones propias
    • Ejemplo: ampliar el criterio de diseño mediante el análisis de código de TLDraw y SerenityOS Jakt

Supervisión automatizada

  • Parte de la validación de diseño puede automatizarse programáticamente
    • Ejemplo: ofrecer retroalimentación inmediata desde el entorno ante errores de tipos o violaciones de reglas
  • ‘Seguridad’ (safety) significa proteger las abstracciones
    • Según la definición de Pierce, un lenguaje seguro garantiza que el programador no pueda romper abstracciones accidentalmente
  • Ejemplo: automatizar con un script de inspección basado en AST una regla que prohíbe el acceso directo a archivos internos entre apps de Django
    • Detecta accesos ilegales con formas como from visit import logic.internal_file

Verificación (Verification)

  • Además del diseño y la implementación, la etapa de verificación (revisión de código, QA) es esencial para asegurar la calidad
  • A medida que aumenta la carga de trabajo, la velocidad de revisión se vuelve un cuello de botella, por lo que se proponen mejoras como las siguientes
    • Reducir la barrera de entrada para que pueda hacerse QA incluso sin entorno de desarrollo
    • Crear un entorno donde sea fácil escribir pruebas, incluida la generación de datos de prueba
    • Documentar la retroalimentación repetitiva en PRs para que el LLM pueda automatizar parte de la revisión
    • Incorporar reglas de seguridad como valores predeterminados del framework

Conclusión y observaciones adicionales

  • Los LLMs funcionan especialmente bien en proyectos greenfield
    • Porque no existe contexto previo y las exigencias de consistencia son menores
  • A medida que el proyecto crece, la consistencia y la modularidad pasan a determinar la productividad
    • Una estructura modular que reutiliza componentes validados es clave para un desarrollo eficiente

1 comentarios

 
GN⁺ 2025-12-24
Comentarios de Hacker News
  • A medida que los modelos mejoran, ya pueden manejar codebases complejas o archivos largos
    Por eso armé un framework loop simple que uso de forma repetida

    1. Research: hago que describa la funcionalidad actual y cargue en contexto los archivos relacionados
    2. Plan: hago que haga una lluvia de ideas sobre best practices para implementar una función nueva o hacer refactor. Luego le pido que escriba el resultado en un archivo md
    3. Clear: reinicio por completo el contexto. Da mejores resultados que una simple compresión
    4. Execute plan: vuelvo a cargar solo el plan para que lo ejecute. Si hace falta, repito preguntas
    5. Review & test: vuelvo a reiniciar el contexto y hago que revise si el plan quedó bien reflejado. En esta etapa agrego código de pruebas, lint, typecheck, etc.
      Si corro este loop durante 20~30 minutos, salen resultados bastante útiles. Al final, la clave es gestionar el contexto y crear un loop de feedback con pruebas
    • A diciembre de 2025, modelos como Sonnet/Opus y GPTCodex ya traen integrada una función de exploración con subagentes
      Si empiezas la exploración con la palabra clave “explore”, pueden hacer Research sin necesidad de escribir un plan aparte ni reiniciar el contexto
      Aun así, tienden a asumir que el lenguaje del código es C o Python, así que a veces generan código no estructurado, como dividir algo en cinco funciones en vez de encapsular el estado en un objeto
      Además, Claude a menudo ignora CLAUDE.md, así que es más estable hacer que primero lea ese archivo y luego pedirle “explore”
      Los modelos más recientes descartan bastante bien el contexto inútil, pero en modelos anteriores el enfoque basado en documentos de planificación todavía suele funcionar mejor
    • Si el modelo falla en la capacidad básica de razonamiento, ningún workflow sirve
      Muchas veces ejecutaba el plan y las guías exactamente al revés, o releía la misma frase y llegaba a la conclusión opuesta
      Durante un tiempo creí que se podía construir un proceso centrado en LLM, pero ahora tengo menos confianza
      Cuando el modelo está en un “buen estado” funciona, pero lograr que entre en ese estado todavía depende de la suerte
    • Yo también uso un enfoque parecido. Me inspiré en la guía Advanced Context Engineering de HumanLayer
      Agregué a Claude Code comandos personalizados como /research_codebase, /create_plan, /implement_plan
      Si revisas y corriges con cuidado, funciona muy bien, pero no hemos logrado extenderlo a todo el equipo
    • Yo casi no uso ese tipo de procedimiento. Con GitHub Copilot y Claude Sonnet 4.5, unas instrucciones claras suelen bastar para que lo resuelva bastante bien
      Solo reinicio el contexto cuando voy a crear una función completamente nueva. En Codespaces anda bien, pero la función Tasks casi no sirve
      Si le encargas algo grande, a veces se va por cualquier lado, así que hay que vigilarlo siempre
    • Yo también uso casi el mismo workflow. Dejo el archivo md del plan en el repositorio y hago que lo consulte al agregar funciones nuevas
      También sirve mucho para reencuadrar el contexto, así que lo uso seguido
  • Para que una biblioteca de prompts sea realmente útil, hace falta mejora iterativa
    Cada vez que el LLM se desvía un poco, me pregunto “¿qué debería haber dejado más claro?” y agrego esa respuesta al prompt
    Si solo aprietas Enter o apruebas todo automáticamente, lo único que haces es desperdiciar tokens. En cambio, conviene observar en qué se traba el LLM y anotarlo brevemente en CLAUDE.md
    Cuando el archivo de contexto crece demasiado, lo separo según el tipo de tarea
    Mis casos de uso principales son explorar la codebase, rastrear rutas de ejecución y dar resúmenes de los archivos necesarios. Si dejas especificado cómo debe entregar los resultados según el tipo de pregunta, todo se vuelve mucho más eficiente

    • Un método mejor que preguntarte “¿qué debería haber dejado más claro?” es hacer que el LLM se lo pregunte a sí mismo
      Yo a esto le digo “Student Pattern (Fresh Eyes)”. Un subagente lee la documentación o el código con ojos de principiante y detecta puntos de confusión, contradicciones e información faltante
      Es excelente para captar conocimiento implícito que el desarrollador pasa por alto. Sirve mucho como paso previo a revisar documentación nueva o evaluar prompts
    • Yo también hago eso, pero Claude Code suele ignorar prompts o documentación con bastante frecuencia
      Aunque le diga varias veces que lea CLAUDE.md, muchas veces no lo hace, e incluso justo después de empezar la sesión a veces se lo salta al azar
      Aunque prepares todos los documentos y comandos, igual a menudo termina “olvidándolos”
  • Estoy experimentando con estructurar grandes codebases de forma amigable para agentes
    Descompongo el proyecto en un grafo dirigido basado en nix flakes para que cada nodo tenga su propio entorno de desarrollo independiente
    Si ejecutas Claude Code dentro del devshell del flake, solo reconoce ese alcance y así se evita la sobrecarga de contexto
    Hago que colaboren mediante entradas y salidas entre flakes, intercambiando pedidos de funciones y pruebas
    Creo que esta división del contexto es la clave para reducir el problema de la explosión de tokens

    • Ese enfoque me parece interesante. Yo también estoy pensando en la correlación entre la estructura del software y sus propiedades
      En vez de simplemente mejorar workflows existentes, hay que diseñar estructuras nuevas que el LLM pueda escalar con facilidad
      Estoy explorando la relación entre propiedades como “testabilidad, escalabilidad y seguridad” y la estructura del código
    • No solo es interesante por la división del contexto, sino también por la reproducibilidad y fijación de dependencias
      Yo hice experimentos parecidos en proyectos basados en Docker, y estaría bueno que existiera una herramienta que automatizara esto
  • El LLM explica muy bien temas que no conozco mucho, pero en mi área de especialidad se equivoca con total seguridad

    • Esto se parece al efecto de amnesia de Gell-Mann
    • Varía mucho según el tema. En desarrollo web me resultó bastante preciso, pero con lenguajes raros como Hare fue un desastre
    • Creo que se siente así porque en áreas que no conocemos hacemos preguntas simples, y en las que sí conocemos hacemos preguntas mucho más difíciles
    • En realidad también puede ser que, en áreas que no conocemos, no sepamos distinguir el disparate
  • Yo tengo otra perspectiva. La mejor forma de mejorar el rendimiento del LLM es incorporar significado en la propia codebase
    Es decir, código estructurado como en DDD (Domain-Driven Design) también es más fácil de entender para un LLM
    Intentar forzar con herramientas el manejo de código complejo es tirar dinero
    Al final, lo que demostró el LLM es que la filosofía de DDD, con su énfasis en “lenguaje y significado”, era correcta
    Artículo relacionado: DDD & the Simplicity Gospel

    • Yo también administro dos codebases grandes, y el LLM entiende muchísimo mejor la que está más estructurada
  • Ante la pregunta “¿por qué el LLM funciona bien en proyectos greenfield?”, yo tuve la experiencia contraria
    Cuando un patrón se repite 2 o 3 veces en una codebase, el LLM lo aprende y lo replica de manera consistente
    Pero “consistencia” no es lo mismo que “calidad”. Si buscas consistencia sin criterios, terminas con código imposible de mantener

  • La frase “si un ingeniero no puede entender el código, el LLM tampoco” es cierta, pero el inverso no se cumple
    Hay muchos casos donde los humanos sí entienden algo y los agentes no
    Hacer que una codebase sea más fácil de entender para agentes que para humanos es todavía más difícil
    También se dice que “si trasladas el feedback a la computadora, sube la tasa de éxito al primer intento”, pero eso se parece a afirmar P=NP
    Que verificar sea fácil no significa que encontrar la respuesta también lo sea
    Lenguajes como ATS o Idris permiten escribir junto al código pruebas de corrección
    Si esa afirmación fuera cierta, los LLM deberían rendir mejor precisamente en esos lenguajes
    Pero la realidad no es así. Al final, por ahora pienso que es mejor esperar a que mejoren los modelos

  • Por estos problemas, creo que los frameworks opinionados van a aumentar la productividad de programación con IA
    Como el LLM ya conoce las reglas del framework, no hacen falta guías adicionales

    • Trabajo en una codebase de 1.6 millones de líneas, y en las partes donde hay mucha inconsistencia de patrones el LLM casi no servía
    • Hice la misma app en varios lenguajes: con Rails quedó casi terminada de inmediato, y con Bun también fue bastante bien
      En cambio, con Go, Rust, Elixir y C# necesitó muchas más dependencias e instrucciones
      Rust dio buenos resultados, pero se trajo más de 200 paquetes y eso fue una carga importante
  • El principio de “Garbage in, garbage out” es válido, pero no aplica del todo a los LLM
    Aunque se entrenaron con los datos ruidosos de todo internet, aun así funcionan bastante bien
    Las alucinaciones (hallucinations) ocurren más seguido por contexto inexacto que por simple ruido
    Incluso una codebase mal estructurada puede seguir aportando contexto útil si contiene mucha información

  • Al final, la gente está reaprendiendo principios básicos
    Se está redescubriendo que la documentación (=biblioteca de prompts) y una estructura de código ordenada aceleran el desarrollo

    • Aun así, si gracias a eso más gente empieza a escribir pruebas, no me parece algo malo