Generative Design System (GenDS): cómo construir la base de una GenUI en Flutter que no se te vaya de las manos

La pregunta que casi nadie responde sobre GenUI no es qué es —una interfaz que un modelo compone en tiempo real según la intención del usuario—, sino qué tienes que construir para que funcione sin romper tu marca, tu accesibilidad y tu seguridad. La respuesta es el Generative Design System (GenDS): la capa que define cómo se le permite adaptarse a una interfaz generativa. Sin ella, GenUI es un experimento bonito; con ella, es un producto.

En Dribba ya explicamos qué es la GenUI y el protocolo A2UI, y cuándo conviene o no usarla. Este artículo va un paso más allá y es práctico: cómo se diseña y construye el GenDS en un proyecto Flutter real. La terminología de GenDS la ha popularizado Very Good Ventures; aquí la aterrizamos a decisiones de ingeniería y diseño.

Las tres capas de una GenUI gobernada

Una GenUI seria no deja que el modelo "dibuje píxeles". El LLM actúa como orquestador que elige entre componentes pre-aprobados y nunca genera UI en crudo. Eso se sostiene sobre tres capas:

CapaQué defineQuién la posee
System promptReglas, tono, restricciones y lógica de marcaDiseño + producto
User contextIntención en tiempo real, preferencias, estado del entornoIngeniería (datos de sesión)
Catalog itemsComponentes y patrones aprobados que el modelo puede componerDesign system + ingeniería

El GenDS es, en esencia, el diseño deliberado de estas tres capas y de cómo interactúan. Vamos una por una.

1. El catálogo: tu frontera de seguridad y de marca

El catálogo es la pieza más importante y la que más se subestima. Es la lista cerrada de componentes que el agente puede usar. Si un widget no está en el catálogo, no existe para el modelo. Esto convierte al catálogo en tu límite de seguridad (el agente no puede inyectar UI arbitraria) y en tu garantía de marca y accesibilidad.

Un ítem de catálogo bien definido no es solo "un botón". Es un componente con su contrato explícito:

{
  "id": "product_filter_group",
  "description": "Grupo de filtros para acotar un listado de productos.",
  "props": {
    "facets": "lista de facetas seleccionables (máx. 6)",
    "selected": "facetas activas"
  },
  "states": ["default", "loading", "empty", "error"],
  "a11y": "cada faceta es un control con label y estado announced",
  "when_to_use": "cuando el usuario expresa intención de acotar resultados"
}

Reglas que aplicamos al construir un catálogo:

  • Cada componente declara sus estados (carga, vacío, error), no solo el feliz. El modelo compondrá el estado que toque; si no existe, tendrás huecos.
  • Accesibilidad horneada en el componente, no delegada al modelo. El LLM decide qué componer; el componente garantiza cómo se anuncia.
  • description y when_to_use son prompt, no documentación. El modelo lee esos textos para decidir. Escríbelos pensando en que los va a interpretar una IA, con criterios claros de cuándo aplica cada uno.
  • Catálogo pequeño y curado > catálogo enorme. Menos componentes bien definidos producen composiciones más predecibles y sesiones más baratas en tokens.

2. El system prompt: gobernanza, no personalidad

El system prompt de una GenUI no es "eres un asistente simpático". Es el reglamento: qué puede y qué no puede hacer el orquestador, en qué orden prioriza, qué tono usa, qué nunca compone. Es donde codificas restricciones de negocio ("en flujos de pago no adaptes la UI, usa la pantalla fija") y de marca.

Un patrón que funciona: el system prompt referencia el catálogo por sus id y describe políticas, no maquetas. Deja el "qué existe" al catálogo y usa el prompt para el "cómo combinarlo y cuándo abstenerse". Y versiónalo como código —un cambio en el system prompt puede alterar todas las pantallas generadas, así que merece revisión y pruebas como cualquier release.

3. El modelo de intención: el contexto que alimenta la decisión

La capa de user context es la que convierte GenUI en algo útil en lugar de aleatorio. Aquí ingeniería aporta la intención y el estado: qué está intentando hacer el usuario, sus preferencias conocidas, el estado del entorno (dispositivo, conectividad, permisos). Cuanta más señal fiable, mejores composiciones; pero cuidado con meter datos sensibles en el contexto sin control —aplican las mismas cautelas de seguridad que en cualquier stack con agentes.

El cambio de mentalidad: de diseñar pantallas a diseñar capacidades

Aquí está el giro que un equipo tiene que asumir. En GenUI, diseño deja de dibujar pantallas y empieza a diseñar un sistema de capacidades: los componentes, sus reglas de composición y los límites. Es más parecido a diseñar un buen design system —como ya defendíamos en design systems y consistencia con IA— que a maquetar flujos. Si tu design system actual es débil o inconsistente, GenUI amplificará el caos, no lo resolverá. Un GenDS sólido presupone un design system sólido debajo.

Cómo se integra en Flutter sin reescribir la app: como una "GenUI Surface" aditiva dentro de la app existente. No migras la aplicación entera; introduces una superficie generativa en el flujo concreto donde aporta, y el resto sigue siendo UI fija. Flutter renderiza el mismo catálogo con calidad nativa en móvil, web y pantallas físicas desde un solo código.

Lo que nadie te cuenta: estado, fallback y latencia

La teoría es limpia; la implementación tiene tres frentes que decidirán si GenUI sobrevive a producción:

  • Estado durante la inferencia. Mientras el modelo compone, la UI necesita un estado intermedio real (skeletons, no pantallas en blanco). Diséñalo en el catálogo desde el día uno.
  • Fallback determinista. ¿Qué pasa si el modelo tarda, falla o devuelve algo inválido? Necesitas una versión fija de esa superficie a la que caer. Sin fallback, no es apto para producción.
  • Latencia y coste. Cada composición es una llamada al modelo. Cachea composiciones estables, limita el tamaño del catálogo y decide qué se compone en servidor y qué con un modelo on-device. La UX de navegación de alta frecuencia raramente tolera esperar a un LLM.

Cuándo NO montar un GenDS (todavía)

Sé honesto con el momento del proyecto:

  • No tienes design system maduro. Construye eso primero; GenUI sin base es inconsistencia a escala.
  • Pantallas críticas o deterministas (pago, legal, onboarding regulado): UI fija, siempre.
  • El problema ya está resuelto con una pantalla estática bien hecha. GenUI añade coste y complejidad; úsalo donde la adaptación al contexto crea valor real (retail con filtros dinámicos, reservas que responden a la intención, dashboards personalizados), no por moda.

Conclusión

GenUI no se gana con el modelo más grande, sino con el Generative Design System mejor construido: un catálogo curado que hace de frontera de marca y seguridad, un system prompt que gobierna, y un modelo de intención que aporta contexto fiable. La parte de IA es la fácil; la difícil —y la que decide el resultado— es la disciplina de diseño y de ingeniería alrededor.

En Dribba llevamos 15 años construyendo apps y somos Flutter Partner oficial de Google desde 2017 —la única agencia española en el directorio—, con equipo senior in-house. Si estás valorando dónde encaja una GenUI en tu producto y cómo construir el GenDS sin comprometer marca ni accesibilidad, hablémoslo.