Desarrollo Design-Driven con Asistentes de IA
Cómo gobernar tu arquitectura mediante el mapeo de supuestos
1. Vibe coding y el colapso de la arquitectura
Un error común al programar con inteligencia artificial es abusar del “vibe coding”, es decir, pedirle al asistente que desarrolle un sistema completo a partir de una descripción informal y broad. Este flujo suele incluir pasos que se repiten en un bucle desgastante:
- Escribir un prompt informal: “Escribí un programa en Python que busque negocios en Google Maps de una zona, extraiga sus datos y los guarde en un CSV”.
- Ejecutar el código generado.
- Fallar catastróficamente.
- Copiar el error en la ventana de chat y pedirle al asistente que lo corrija.
- Volver al punto (2) hasta que funcione por mera coincidencia.
Lo anterior, si bien puede llevar a un resultado transitorio “que funcione” (bajo condiciones desconocidas), no asegura la mejor implementación posible e introduce fallas de diseño profundas. Estas fragilidades impiden la estabilidad ante cambios de entorno o la escalabilidad ante nuevas funcionalidades.
Lo más dramático es la pérdida de comprensión sobre el porqué del sistema. ¿Qué problemas resuelve esta función? ¿Cómo los resuelve? Cuando no podemos responder esto, perdemos el control de nuestro propio código. Detrás de la ilusión de hiper-productividad se construye un castillo de naipes.
Para resolver esto, se debe dejar de delegar la arquitectura al asistente y asumir activamente la soberanía del diseño de software. Proponemos un enfoque claro: dejar de usar la IA como un generador de código ciego y empezar a tratarla como un implementador bajo contrato.
2. El Ciclo de Vida del Desarrollo con Asistentes (Las 5 Fases)
Para estructurar este desorden, proponemos un ciclo cerrado de desarrollo asistido por IA que prioriza la verificación empírica y la coincidencia técnica antes de escribir una sola línea de lógica comercial:
Diseño Técnico Inicial
Establecer firmas claras y lógica conceptual (Inputs, Lógica en pseudocódigo y Outputs esperados).
Mapeo de Supuestos
Identificar fragilidades externas en una tabla de control (APIs de terceros, selectores web, formatos de archivos).
Verificación de Supuestos (Pre-implementación)
Probar empíricamente los supuestos con micro-scripts. Si alguno falla, se detiene y se corrige el diseño. Solo si todos son verdaderos se avanza.
Implementación Restringida
Delegar la codificación al asistente de IA, restringiendo su libertad a cumplir el contrato acordado.
Match Checking
Verificación final. Evaluar si los desvíos del código tienen sentido arquitectónico. Si no, rechazar e iterar.
Este mapa no representa un proceso lineal e informal, sino un flujo de trabajo riguroso y cerrado. En las siguientes secciones, profundizamos en cómo aplicar cada fase.
3. El Enfoque Design-First y los Contratos Claros (Fase 1)
En la era del desarrollo asistido, el rol de la programación humana evoluciona. Ya no somos un “escribidor de sintaxis”, sino el Arquitecto Principal de Software. El asistente es una herramienta sumamente rápida e incansable, pero propensa a alucinaciones o a simplificar la lógica ante especificaciones ambiguas.
Para colaborar con éxito, es fundamental establecer contratos claros. Es decir, cada componente de software debe responder con precisión a su contrato de firma técnica.
El Documento de Diseño Técnico
El código es una consecuencia del diseño, nunca el punto de partida. En el enfoque Design-First, antes de pedirle al asistente que programe, se requiere la elaboración de un documento de diseño técnico donde cada función principal y clase esté documentada con:
- INPUT: Los datos y parámetros que ingresan a la función (especificando sus tipos de datos, estructuras y obligatoriedad).
- LÓGICA: El pseudocódigo o descripción secuencial del procesamiento interno (el algoritmo o “paso a paso” de la transformación).
- OUTPUT: El resultado devuelto en caso de éxito y el comportamiento (o excepciones) ante fallos.
Detectando “Frases Vagas” (Vague Phrases)
Durante la redacción del diseño técnico, tendemos a usar un lenguaje ambiguo para encubrir lagunas lógicas. Es común escribir o aceptar frases como: “El sistema obtendrá el precio del producto y lo normalizará”.
Como Arquitectos, debemos cazar activamente estas frases vagas. ¿Qué significa “obtener el precio”?
- ¿Es extraer un nodo de texto de un HTML usando un selector dinámico?
- ¿Cómo se maneja si el precio contiene el símbolo
$o separadores decimales europeos (1.200,50)? - ¿Qué pasa si el selector no existe en esa página?
Si permitimos que esa ambigüedad pase a la fase de implementación, el asistente alucinará un método ad-hoc inestable. Debemos forzar al diseño a concretar el mecanismo exacto y trasladar esa fragilidad a la Tabla de Supuestos.
4. La Clave Oculta: Identificar y Documentar Supuestos (Fase 2)
Todo software interactúa con un entorno que no controla (APIs externas, selectores de sitios web de terceros, inputs de usuarios, dependencias del sistema operativo). Un supuesto es cualquier hecho del cual depende la estabilidad del código pero que no puede ser garantizado por el compilador o el sistema de tipos.
Estructura de la Tabla de Supuestos
| ID | Supuesto Concreto | Componente Afectado | Riesgo y Plan de Contingencia |
|---|---|---|---|
| SUP-001 | La lista de precios recibida del distribuidor en PDF siempre mantiene una estructura de columnas de 4 campos (Código, Descripción, Precio, Categoría) en ese orden exacto. | src/parser.py | Alto. Si el proveedor cambia el orden de las columnas, la importación de datos se romperá silenciosamente cargando descripciones como precios. Contingencia: Validar que el campo Precio contenga caracteres numéricos; si no, abortar y disparar alerta descriptiva. |
| SUP-002 | El selector CSS de Google Maps para el teléfono del negocio (button[data-tooltip="Copiar teléfono"]) se mantiene estable en el DOM. | src/scraper/grid.py | Medio. Si Google rediseña la interfaz, el scraper no extraerá contactos. Contingencia: Si el selector devuelve nulo, intentar con expresiones regulares secundarias sobre los nodos de tipo botón y loguear warning para auditoría. |
| SUP-003 | La API del pipeline comercial (Airtable) responde en menos de 3000ms bajo condiciones normales de red. | src/portfolio/leads.js | Bajo. Si excede el tiempo, el lead podría perderse en la landing. Contingencia: Implementar un mecanismo de reintentos asíncronos con almacenamiento local temporal (localStorage). |
Al visibilizar los supuestos, la fragilidad se transforma en puntos de control explícitos. El código resultante ya no falla de forma misteriosa; si algo cambia en el entorno, el sistema sabe exactamente qué supuesto se rompió y lo notifica.
5. El Ciclo de Verificación de Supuestos - Pre-implementación (Fase 3)
En el desarrollo tradicional, el testing suele ser una fase de control de daños posterior a escribir el código. En este enfoque guiado por diseño y supuestos, el testeo opera de forma invertida: es el requisito previo para iniciar la implementación. No se comienza a codificar lógica de negocio sobre cimientos inestables.
El ciclo de verificación de supuestos sigue tres pasos indispensables:
- Probar que los supuestos son verdaderos: Antes de programar la lógica de negocio, se diseñan y ejecutan micro-tests de exploración piloto orientados exclusivamente a validar los supuestos del entorno (ej. hacer llamadas reales a la API externa para verificar tiempos de respuesta, o parsear el PDF de prueba del distribuidor para confirmar si el selector de columnas coincide).
- Corregir el diseño si los supuestos fallan: Si durante esta fase de exploración empírica se descubre que un supuesto es falso, se detiene el avance técnico de inmediato. No se escriben parches improvisados; en su lugar, se corrige el documento de diseño técnico para incorporar esta realidad y se reevalúa la arquitectura.
- Proceder a la implementación: Solo cuando se ha comprobado empíricamente que todos los supuestos de la tabla son verdaderos, se da luz verde al asistente para que proceda con la implementación de negocio definitiva.
6. Implementación (Fase 4) y Match Checking (Fase 5)
Solo cuando la fase previa de verificación confirma que todos los supuestos son verdaderos, se procede a la implementación. Durante esta etapa, el asistente opera bajo la pauta de implementar las firmas y la lógica acordadas.
El Proceso de Match Checking
Una vez que el asistente entrega la implementación, se ingresa en la fase de Match Checking. Aquí la pregunta central no es solo si el código compila, sino: ¿el código respeta el diseño y la intención del sistema?
Si el asistente introdujo variaciones, implementaciones alternativas o funciones extra, en el rol de Arquitecto debemos evaluar los siguientes puntos:
- ¿Las diferencias tienen sentido arquitectónico? Es decir, ¿se resuelven de manera elegante problemas no contemplados inicialmente en el diseño, o se descubren casos borde válidos?
- Si la respuesta es SÍ: El desvío es positivo. Se procede a actualizar el documento de diseño y la tabla de supuestos para que coincidan con la nueva y mejorada implementación. El diseño evoluciona de manera interactiva.
- ¿El desvío es una alucinación innecesaria o rompe el contrato técnico?
- Si la respuesta es NO: Se rechaza la implementación de inmediato. Se analiza por qué el agente no tuvo la salida esperada y se reajustan las instrucciones o el diseño para encauzarlo.
¿El código respeta el diseño y la intención del sistema?
↓
[SÍ] ──> ¿Hay desvíos o funciones extra?
↓
[SÍ] ──> ¿Tienen sentido arquitectónico?
↓
[SÍ] ──> Actualizar Diseño ──> Código Aprobado
[NO] ──> Rechazar e Iterar
[NO] ──> Código Aprobado
[NO] ──> Rechazar e Iterar Este enfoque permite ver el “delirio” o desvío de la IA de forma positiva: no como un error insalvable, sino como un mecanismo de feedback para evaluar el diseño original. Evaluar opciones bajo criterios cualitativos complejos (rendimiento, UX, facilidad de mantenimiento) es donde reside la verdadera soberanía del programador humano.
7. Conclusión: El desarrollador como “Gobernador” del software
Los asistentes de IA plantean dos caminos en el desarrollo de software: o bien se produce una pérdida de capacidad técnica, empeorando el código y relegando a los desarrolladores al rol de “operadores” vacíos de prompts; o, por el contrario, se impulsa la evolución hacia la arquitectura de software, situando al profesional en la posición de tomar decisiones profundas, considerando el impacto a futuro y manteniendo la soberanía de la implementación.
Adoptar este enfoque guiado por diseño y supuestos requiere paciencia conceptual. Puede parecer más lento al principio dedicar una hora a escribir tablas y pseudocódigo antes de escribir código real. Sin embargo, en proyectos de escala real, es la única estrategia que garantiza que el software siga siendo mantenible, robusto y, sobre todo, propio.
¿Revisamos la arquitectura de tu sistema?
Si tu empresa está escalando desarrollos asistidos por IA o necesita auditorías de robustez en sistemas de datos, dejanos tus datos y lo conversamos.