23 oct 2025·8 min

Código generado por IA revisable: del prototipo a la entrega al equipo

Haz que el código generado por IA sea revisable estandarizando carpetas, nombres e invariantes escritas para que un equipo humano pueda hacerse cargo y enviar cambios con seguridad.

Código generado por IA revisable: del prototipo a la entrega al equipo

Por qué los prototipos de IA son difíciles de entregar

Los prototipos de IA suelen triunfar por una razón: te llevan a “funcionar” rápido. El problema aparece cuando “funcionar” debe convertirse en “mantenible por un equipo”. Un prototipo puede tolerar atajos porque la misma persona (o el mismo hilo de chat) tiene todo el contexto. Un equipo no.

El código generado por IA también puede parecer más difícil de revisar que el código escrito por humanos porque la intención no siempre es visible. El código humano suele dejar un rastro: patrones consistentes, decisiones repetidas y algunos comentarios que explican por qué existe algo. La salida de la IA puede ser correcta, pero mezclar estilos, cambiar patrones entre archivos y ocultar suposiciones en lugares donde los revisores no las esperan.

El objetivo es previsibilidad: lugares previsibles, nombres previsibles, comportamiento predecible. Cuando un compañero puede adivinar dónde vive algo, cómo se llama y cómo se comporta, la revisión pasa a ser una comprobación rápida en lugar de una investigación.

Lo que suele salir mal cuando un prototipo se convierte en proyecto de equipo:

  • Características similares se implementan de formas distintas porque la IA cambió su enfoque entre prompts.
  • Los archivos terminan donde encajan en el momento, así que el código relacionado se dispersa.
  • El nombrado varía (userId vs userid vs user_id), haciendo que las búsquedas sean poco fiables y que los bugs pasen desapercibidos.
  • La configuración y los “valores mágicos” se duplican.
  • El manejo de errores y la validación divergen, de modo que los casos límite se comportan distinto entre pantallas o endpoints.

Las pequeñas inconsistencias multiplican el tiempo de mantenimiento porque obligan a tomar decisiones repetidas. Si cada nueva pantalla tiene una ubicación de carpeta, un nombre de componente y un estilo de obtención de datos ligeramente distintos, los revisores no pueden construir un modelo mental estable. Tienen que reaprender el código cada vez.

Un ejemplo realista: una fundadora no técnica usa una herramienta de vibe-coding para crear un CRM simple. Funciona bien en la demo, pero cuando un pequeño equipo lo retoma, encuentran tres maneras distintas de almacenar el estado de autenticación, dos estilos de nombres para componentes React y reglas de negocio repartidas entre el código de UI y manejadores de backend. Nada está “roto”, pero cada cambio se siente arriesgado porque nadie sabe qué patrones son los reales.

La entrega se facilita cuando reduces las opciones. Los equipos van más rápido cuando la base de código les dice, de manera consistente, qué hacer a continuación.

Qué significa “revisable” en la práctica

“Revisable” significa que un desarrollador nuevo puede abrir el repo, encontrar el lugar correcto para cambiar, hacer el cambio y confirmar que nada más se rompió. Eso es básico, y también es lo que muchos prototipos de IA no cumplen.

Para hacer que el código generado por IA sea revisable, céntrate menos en la originalidad y más en cuán seguro es que un humano lo toque. La revisabilidad se trata de reducir el riesgo de cambio.

Qué necesitan ver los revisores

Cuando un compañero revisa un pull request, intenta responder algunas preguntas rápido:

  • ¿Para qué sirve este cambio, en palabras sencillas?
  • ¿Dónde vive el comportamiento (UI, API, base de datos), y por qué allí?
  • ¿Cuáles son los límites (qué no debería afectar este cambio)?
  • ¿Cómo puedo verificarlo (tests, pasos manuales o ambos)?
  • ¿Cuál es el plan de reversión si falla?

Los diffs pequeños ayudan, pero “pequeño” no es solo número de líneas. También significa límites estables: un cambio en un área no debería requerir tocar archivos no relacionados.

Señales de que una base de código es revisable

No necesitas perfección. Necesitas convenciones, algo de documentación, un par de tests y guardarraíles que eviten la deriva futura.

Un revisor se siente más seguro cuando puede detectar rápidamente:

  • Estructura y nombres predecibles.
  • Intención clara en funciones y componentes (sin helpers misteriosos).
  • Un README corto para ejecutar, probar y flujos comunes.
  • Un par de tests de alto valor alrededor de flujos críticos.
  • Reglas explícitas sobre comportamientos que “no deben romperse” (invariantes).

Ejemplo: construiste un frontend en React y una API en Go. El prototipo funciona, pero el flujo “crear cliente” está repartido entre el código de UI, los handlers de la API y las llamadas a la base de datos con nombres de campo ligeramente distintos. Hacerlo revisable significa alinear esos nombres, mantener clara la frontera de la API y escribir las reglas (por ejemplo, “el email debe ser único” y “el estado solo puede ser active o paused”).

No pretendas reescribir todo hasta que parezca un proyecto de libro. El código listo para entrega es claro, consistente y seguro de cambiar, aunque no sea la versión más pulida.

Estructura de carpetas que facilita la navegación

Un equipo puede perdonar código imperfecto. Lo que les cuesta es no saber dónde está algo. Si quieres que el código generado por IA sea revisable, haz que el proyecto sea fácil de escanear: un pequeño conjunto de carpetas top-level, nombres consistentes y un hogar obvio para la configuración.

Una estructura simple que funciona

Mantén el mapa top-level estable a medida que la app crece. Muchas entregas fallan porque aparecen carpetas nuevas para cada experimento. En su lugar, separa tres preocupaciones: composición de la app (pantallas, rutas), reglas centrales de negocio y la infraestructura.

Aquí tienes un patrón práctico que puedes adaptar (ejemplo web app):

/
  /app            # routes/pages and UI composition
  /core           # domain logic: entities, rules, use-cases
  /ui             # reusable components, styles, design tokens
  /infra          # db, api clients, queues, auth adapters
  /config         # env schema, feature flags, app settings
  /scripts        # local tooling, seed data, one-off tasks
  /docs           # handoff notes, invariants, decisions

Si tu primera versión se generó rápidamente, mantiene esa separación visible. Coloca módulos generados reemplazables bajo algo como /generated, y conserva los módulos editados por humanos bajo /core o /app. La idea es evitar ediciones accidentales en código que podrías regenerar más tarde.

Haz que la respuesta a “¿dónde está esto?” sea posible en 10 segundos

Antes de la entrega, haz una prueba rápida de navegación con un compañero (o con tu yo futuro). Pregunta dónde vive la UI de login, dónde están las reglas de autorización, dónde se define el acceso a la base de datos, dónde se fijan las URLs base de la API y las feature flags, y dónde están los scripts “especiales”.

Si alguna respuesta empieza con “depende” o “búscalo”, ajusta la estructura hasta que cada tema tenga un único hogar, aburrido y claro. Esa sensación de aburrimiento es lo que hace que el mantenimiento sea rápido y seguro.

Convenciones de nombres en las que los humanos pueden confiar

Una convención de nombres es una promesa: un revisor debería poder adivinar qué es algo, dónde vive y cómo se usa antes de abrir el archivo.

Empieza por los nombres de archivos y mantén un estilo en todo el repo. Un defecto simple es: carpetas en kebab-case, componentes React en PascalCase y archivos TypeScript no componentes en camelCase. Rompe la regla solo cuando el ecosistema lo espera (por ejemplo, convenciones estándar de Flutter o archivos estándar como README).

Los nombres deben revelar intención, no implementación:

  • Bueno: BillingSummaryCard.tsx (qué representa)
  • Arriesgado: StripeCard.tsx (incluye una elección de proveedor)
  • Arriesgado: RenderBilling.tsx (describe cómo, no por qué)

Sé estricto con las categorías vagas. Archivos llamados utils, helpers o common se convierten rápido en cajones de sastre, especialmente cuando el código se genera en ráfagas. Si necesitas código compartido, nómbralo por alcance y propósito, como auth/tokenStorage.ts o billing/billingCalculations.ts.

Carpetas por funcionalidad vs carpetas técnicas

Las carpetas por funcionalidad describen el espacio del problema del usuario. Las carpetas técnicas describen infraestructura transversal. Mezclarlas oculta los límites.

Una separación práctica es características como billing, onboarding, inventory, y áreas técnicas como api, db, routing, design-system. Cuando tienes múltiples clientes (web, server, móvil), mantener los mismos nombres de funcionalidad en las capas facilita rastrear cambios.

Una rúbrica rápida de nombres para revisores

Usa esta rúbrica corta en la revisión de código:

  • ¿Puedes saber qué es en 3 segundos solo por el nombre?
  • ¿El nombre coincide con el nivel (nombres de features para lógica de negocio, nombres técnicos para infraestructura)?
  • ¿Seguiría teniendo sentido si la implementación cambiara?
  • ¿Es consistente con archivos y carpetas cercanas?

Renombra pronto. Los renombres son baratos durante la entrega y caros después de que el equipo construye sobre la confusión.

Documenta las invariantes (las reglas que deben mantenerse)

Lanza una demo revisable
Despliega y aloja tu app cuando el prototipo sea lo bastante estable para compartir.

Una invariante es una regla de la que tu app depende para seguir siendo correcta, incluso cuando cambian las funciones. El código generado por IA a menudo “funciona” porque el generador asumió un conjunto de reglas, pero esas reglas pueden vivir solo en prompts o en la cabeza de alguien. Escríbelas para que los revisores sepan qué no debe cambiar en silencio.

Las invariantes buenas son aburridas, específicas y comprobables. Evita frases vagas como “validar entradas”. Di exactamente qué está permitido, quién puede hacer qué y qué sucede cuando se rompe la regla.

Ejemplos útiles de invariantes (que los revisores buscan)

La mayoría del dolor en las entregas proviene de las mismas áreas:

  • Permisos: “Solo los dueños del proyecto pueden invitar miembros; los admins pueden eliminar miembros; los miembros pueden ver pero no editar la facturación.”
  • Propiedad de datos: “Cada Tarea pertenece exactamente a un Proyecto. Un usuario solo puede acceder a Tareas de Proyectos de los que es miembro.”
  • Reglas de ID y formato: “Los IDs públicos son strings UUIDv4. Los IDs numéricos internos nunca salen en las respuestas del servidor.”
  • Transiciones de estado: “El estado de la orden puede moverse draft -> paid -> shipped. shipped nunca puede volver a paid.”
  • Integridad de datos: “El email es único (case-insensitive). Eliminar un proyecto hace un soft-delete de las tareas; las tareas nunca se borran permanentemente.”

Si puedes convertir la frase en un test unitario o un test de API, es el nivel adecuado.

Dónde documentar las invariantes para que se revisen

Pon las invariantes donde la gente mira durante la revisión:

  • En el README del repo: una sección corta “Reglas del sistema” con las invariantes principales.
  • Junto al código que las aplica: comentarios breves cerca de checks de auth, validaciones y transiciones de estado.
  • En una nota de decisión de una página para reglas grandes: modelo de auth, elecciones del modelo de datos, estados de workflow.

Evita ocultar invariantes en docs largos que nadie abre. Si no aparecen en una revisión de PR normal, se olvidarán.

Cómo escribir invariantes (y cómo cambiarlas con seguridad)

Frasea cada invariante con alcance, regla y punto de aplicación. Ejemplo: “Para todos los endpoints bajo /api/projects/:id, el solicitante debe ser miembro del proyecto; aplicado en el middleware de auth y comprobado de nuevo en las actualizaciones de tareas.”

Cuando una invariante cambia, hazlo explícito. Actualiza la línea en el doc, apunta a las ubicaciones de código que cambiaron y añade o actualiza un test que fallaría con la regla antigua. Si no, el equipo tiende a quedar con la mitad del comportamiento antiguo y la mitad del nuevo.

Si usas una plataforma de vibe-coding como Koder.ai, un paso de entrega útil es pedirle que liste las invariantes que asumió al generar la app. Luego convierte eso en un pequeño conjunto de reglas comprobables que el equipo pueda revisar y mantener.

Paso a paso: convertir un prototipo en código listo para entregar

Una entrega no es lo mismo que “funciona en mi máquina”. El objetivo es que el proyecto sea fácil de leer, seguro de cambiar y predecible cuando alguien nuevo lo abra.

Comienza por congelar el alcance. Elige una fecha y una lista corta de lo que debe ser estable (pantallas centrales, flujos clave, integraciones). También escribe lo que está explícitamente fuera de alcance para que nadie siga añadiendo funciones mientras limpias.

Luego haz limpieza antes de añadir nada nuevo. Aquí es donde aparece la revisabilidad: la base de código se comporta como un producto, no como una demo.

Una secuencia práctica:

  • Bloquea el alcance de entrega: 3 a 5 recorridos de usuario que deben funcionar, más 3 a 5 cosas que no cambiarás.
  • Normaliza carpetas y nombres: mueve archivos a una estructura predecible, renombra módulos confusos, borra código muerto.
  • Añade notas pequeñas en módulos donde la gente las verá: “Qué hace esto” y “Qué no debe hacer”, mantenidas en pocas líneas.
  • Coloca las invariantes junto al código que las aplica: escribe la regla sobre la función, la consulta o el componente que la hace cumplir.
  • Crea un plan mínimo de pruebas de humo: una lista corta que coincida con el alcance congelado y las invariantes.

Mantén la lista de pruebas de humo pequeña pero real. Para una app React con una API en Go y Postgres, eso podría ser: iniciar sesión, crear un registro, refrescar, confirmar que persiste y confirmar que una acción restringida falla.

Haz un ciclo de revisión que se enfoque en legibilidad, no en funciones. Pide a un compañero que dedique 30 minutos a responder: “¿Puedo encontrar cosas?” “¿Los nombres coinciden con el comportamiento?” “¿Las invariantes son obvias?” Arregla lo que les haga perder tiempo, y luego para.

Comprobaciones rápidas antes de entregar al equipo

Haz que el código de IA esté listo para el equipo
Construye tu próximo prototipo en chat y mantenlo consistente para la entrega.

Antes de la entrega, haz una prueba de “ojos frescos”. Pide a alguien que no construyó el prototipo que abra el repo y narre lo que cree que hace. Si no pueden encontrar puntos de inicio rápido, el equipo pagará ese coste en cada cambio.

Una regla simple: un desarrollador nuevo debe poder localizar los puntos de entrada principales en menos de dos minutos. Eso suele significar un README claro que nombre uno o dos lugares para empezar (entrada web, entrada de la API, config), y esos archivos no están enterrados.

También revisa el tamaño de las revisiones. Si los módulos clave requieren un scroll sin fin, los revisores dejan de detectar problemas. Divide archivos largos para que cada uno tenga una sola responsabilidad y pueda entenderse en una sentada.

Una checklist corta de entrega:

  • Los puntos de entrada son obvios: dónde arranca la app, dónde viven las rutas, dónde se leen las settings de entorno.
  • Archivos tamaño bocado: la mayoría caben en una o dos pantallas; no hay “archivos dios”.
  • Los nombres coinciden con el comportamiento: validateUser valida, no escribe también en la base de datos.
  • Las invariantes están cerca del código: comentarios o un pequeño bloque de doc con reglas que deben mantenerse.
  • Cada cambio es fácil de verificar: una comprobación rápida que pruebe los flujos núcleo.

Un escenario de entrega realista

Maya es una fundadora no técnica. Construyó un MVP describiendo el producto en chat: un CRM simple para un pequeño negocio de servicios. Funciona: login, clientes, deals, notas y una pantalla de admin básica. Tras unas semanas, contrata a dos desarrolladores para llevarlo de “funciona en mi portátil” a algo en lo que el negocio pueda confiar.

El primer día no empiezan reescribiendo. Empiezan haciendo el código revisable. Su primer movimiento es mapear la app en dos cubos: módulos core (de los que depende cada feature) y features (pantallas y workflows que usan los usuarios). Eso les da un lugar para poner decisiones y un lugar para poner cambios.

Acordaron un mapa simple de features: core (auth, acceso a DB, permisos, logging, componentes UI) y features (customers, deals, notes, admin).

Luego ajustaron las carpetas para que coincidieran con ese mapa. Antes, los archivos estaban dispersos, con nombres mezclados como CustomerPage.tsx, customer_view.tsx y custPageNew.tsx. Después, cada feature tiene un hogar y el código core está claramente separado. Las revisiones se aceleran porque los PR tienden a quedarse dentro de una carpeta de feature, y los cambios en core se vuelven evidentes.

Una pequeña regla de nombres hace la mayor parte del trabajo: “las carpetas son sustantivos, los componentes en PascalCase, las funciones en verbo y no abreviamos”. Así custPageNew.tsx pasa a CustomerDetailsPage.tsx, y doStuff() se convierte en saveCustomerNote().

Una invariante que evita bugs silenciosos

Escriben una regla clave que debe permanecer siempre verdadera y la colocan en un corto INVARIANTS.md dentro de la carpeta de la feature.

Invariante ejemplo para el CRM:

Solo el owner del deal o un admin pueden editar un deal. Todos los demás pueden verlo, pero no cambiar estado, valor ni notas.

Esa frase guía checks del backend, consultas de DB y estados de UI del frontend. Cuando alguien añade “edición masiva” más adelante, los revisores saben exactamente qué no debe romperse.

Cómo se ve “suficientemente bien” tras una semana

Después de una semana, el código no es perfecto, pero la entrega es real:

  • Cada feature vive en una carpeta con nombres de archivo predecibles.
  • Los módulos core están separados y se reutilizan, no se copian.
  • Las invariantes están escritas donde ocurren los cambios, no enterradas en el historial del chat.
  • Los cambios nuevos se envían mediante PR pequeños y fáciles de revisar.

Errores comunes que hacen frágil el código de IA

Exporta y entrega de forma ordenada
Entrega un código limpio exportando la fuente para flujos de trabajo normales en Git.

La IA puede llevarte a un prototipo funcional rápido. El problema es que “funcionar” suele depender de suposiciones ocultas. Cuando un equipo lo toca después, pequeños cambios rompen cosas en lugares inesperados.

Un error común es refactorizarlo todo de una vez. Las limpiezas grandes satisfacen, pero dificultan ver qué cambió y por qué. Define límites primero: decide qué módulos son estables, dónde se permite nuevo código y qué comportamiento no debe cambiar. Luego mejora una área a la vez.

Otro problema frecuente son conceptos duplicados con nombres distintos. La IA creará felizmente UserService y AccountManager para el mismo trabajo, o plan vs pricingTier para una idea. Elige un término para cada concepto clave y renombra de forma consistente en UI, API y DB.

Las reglas ocultas también son una gran fuente de fragilidad. Si la lógica de negocio real vive en prompts o en el historial de chat, el repo se hace difícil de mantener. Pon las reglas en la base de código como comentarios claros, tests o un doc corto de invariantes.

Las carpetas catch-all como shared, common o utils se convierten en cajones de sastre. Si necesitas módulos compartidos, define qué poseen (entradas, salidas, responsabilidades) y mantenlos estrechos.

Mezclar reglas de negocio en el código UI es otra trampa. Una condicional rápida en un componente React se convierte en el único lugar donde existe una regla de precios. Después, la app móvil o el backend discrepan. Mantén las reglas de negocio en una capa (a menudo backend o un módulo de dominio) y que la UI las consuma en lugar de reimplementarlas.

Finalmente, el código frágil suele venir de saltarse normas de revisión. Los equipos necesitan diffs pequeños, commits claros e intención explicada. Incluso si un generador produjo el cambio, trátalo como un PR normal: mantén el alcance ajustado, explica qué cambió y facilita la verificación.

Siguientes pasos: convertir el mantenimiento en un flujo normal

Trata la entrega como el comienzo del mantenimiento, no como la meta final. El objetivo sigue siendo simple: una persona nueva puede hacer un cambio pequeño sin romper reglas ocultas.

Convierte las preferencias del equipo en unos pocos valores por escrito: un mapa de carpetas que todos sigan, un estilo de nombres y una plantilla para invariantes. Cuando esas reglas se acuerdan desde el inicio, los comentarios de revisión dejan de ser gustos personales y se convierten en comprobaciones coherentes.

Mantén un “handoff README” que apunte a los pocos lugares que importan: dónde viven las invariantes, cómo ejecutar la app, cómo añadir una feature de forma segura y qué no cambiar sin discusión. Un compañero nuevo debería encontrar respuestas en menos de cinco minutos.

Si tu flujo soporta reversibilidad, úsala. Por ejemplo, Koder.ai soporta snapshots y rollback, lo que puede ser una red de seguridad antes de refactors o actualizaciones de dependencias. Cuando estés listo para transferir la propiedad, exportar el código fuente desde Koder.ai da al equipo un punto de partida limpio para el trabajo normal con Git.

Preguntas frecuentes

¿Por qué un prototipo de IA parece “bien” hasta que un equipo intenta mantenerlo?

Empieza por hacer el código predecible. Alinea la estructura de carpetas, el nombrado y los límites para que un compañero pueda adivinar dónde vive cada cosa y cómo se comporta, sin tener que buscar por todo el repositorio.

¿Cuál es la forma más rápida de reducir las “tres maneras diferentes” de hacer lo mismo?

Elige un patrón para cada tarea recurrente (estado de autenticación, obtención de datos, validación, manejo de errores) y aplícalo en todo el proyecto. El objetivo no es “lo mejor”, sino “consistente”, de modo que los revisores no tengan que reaprender la app en cada cambio.

¿Qué significa realmente “revisable” para el código generado por IA?

Un código revisable permite a un desarrollador nuevo encontrar el lugar correcto para cambiar, hacer una edición pequeña y verificarla con seguridad. Si los cambios suelen afectar archivos no relacionados o requieren adivinar reglas, aún no es revisable.

¿Qué estructura de carpetas facilita más la entrega y la navegación?

Usa un pequeño conjunto estable de carpetas top-level y coloca cada preocupación en un hogar obvio. Separa composición de la app (rutas/pantallas), reglas de negocio y la infraestructura para que la navegación tome segundos y no parezca trabajo de detective.

¿Cómo evito editar código que podría regenerarse más tarde?

Pon el código que podrías regenerar bajo una carpeta clara como /generated, y conserva el código editado por humanos en áreas estables como /core y /app. Así evitas editar accidentalmente código que luego se sobrescribirá y aclaras la propiedad durante las revisiones.

¿Qué convenciones de nombres importan más durante una entrega?

Elige una convención y aplícala en todo el repositorio: casing consistente para carpetas y archivos, nombres de componentes coherentes y campos con los mismos nombres en UI, API y base de datos. La consistencia hace las búsquedas fiables y reduce errores sutiles por nombres distintos.

¿Qué son las “invariantes” y por qué debo documentarlas?

Las invariantes son reglas que deben permanecer verdaderas a medida que el producto cambia, como permisos, restricciones únicas y transiciones de estado permitidas. Documentarlas convierte suposiciones ocultas en comprobaciones visibles que los revisores pueden proteger.

¿Dónde deben vivir las invariantes para que realmente se revisen?

Ponlas donde la gente realmente las vea: una sección corta en el README y notas breves junto al código que hace cumplir la regla. Si la regla no aparece durante una revisión de PR normal, se olvidará.

¿Cuál es un plan práctico paso a paso para preparar un prototipo para entrega?

Congela el alcance primero: elige pocas rutas de usuario núcleo que deben funcionar y qué está explícitamente fuera de alcance. Luego normaliza carpetas y nombres, elimina código muerto, añade una lista mínima de pruebas de humo y haz una pasada de revisión enfocada en legibilidad.

¿Cuáles son los errores más comunes que vuelven frágil el código de IA tras la entrega?

Evita refactorizaciones masivas que toquen todo, carpetas cajón como utils, y reglas de negocio mezcladas en condicionales de UI o en historial de chat. Vigila conceptos duplicados con nombres distintos y validaciones/manejo de errores que divergen entre endpoints y pantallas.

Related posts