Cómo llevar una plataforma LLM con estado a producción sin reescribir el producto
La arquitectura de producción de una plataforma LLM con estado reúne los límites que permiten operar una aplicación de IA de forma segura y repetida para varios usuarios. Incluye datos autoritativos, identidad, acceso a objetos, trabajo costoso en segundo plano, interfaces externas, despliegue, recuperación y verificación. La llamada al modelo es solo un componente dentro de ese sistema operativo.
Este artículo responde a una pregunta concreta: ¿cómo se transforma una aplicación LLM con muchas funciones, pensada para investigación local, en un piloto compartido y controlado? No decide si necesitas un grafo de conocimiento, tema que cubre nuestra guía de decisión sobre ingeniería de grafos. Tampoco repite la guía general del prototipo a producción. Aquí importa el orden de dependencias para una plataforma que ya contiene lógica de producto valiosa.
¿Qué diferencia una aplicación LLM con estado de una demo?
Una demo puede guardar el contexto en una sesión del navegador, recargar fixtures desde archivos y esperar de forma síncrona a que responda el modelo. Una plataforma compartida no puede depender de eso. Los usuarios esperan que sus datos sobrevivan a un despliegue, que los permisos se apliquen en todas las interfaces y que una operación larga siga siendo comprensible después de un timeout, una recarga o un error.
La aplicación inicial de este proyecto ya contenía lógica importante para datos de dominio estructurados, operaciones sobre grafos, ingestión de documentos, conversaciones fundamentadas, entrevistas, simulaciones y evaluación. La carencia no era una lista de funciones. Era la propiedad operativa de los caminos que conectaban esas funciones.
| Supuesto cómodo para investigación | Requisito de plataforma compartida | Fallo si queda implícito |
|---|---|---|
| Los archivos son el estado vivo | Un almacén transaccional autoritativo | Los despliegues o usuarios concurrentes divergen. |
| Un solo operador de confianza | Identidad y acceso a objetos validados en servidor | Un usuario válido alcanza datos ajenos. |
| La petición espera al modelo | Jobs con propietario, observables y recuperables | Los timeouts parecen fallos y los reintentos duplican trabajo. |
| El navegador es el único cliente | Política coherente en navegador, API y MCP | Una interfaz nueva evita reglas presentes solo en la UI. |
| Un proceso activo está sano | Readiness consciente de dependencias y rollback | El tráfico llega a una app incapaz de responder correctamente. |
| Las pruebas manuales validan el release | Checks automáticos más QA de flujos reales | Las regresiones entre capas reaparecen. |
La secuencia de producción en siete capas
El orden importa. Pulir la interfaz antes de resolver persistencia y acceso solo facilita demostrar un comportamiento inestable. Añadir una API externa antes de centralizar la autorización crea un segundo modelo de seguridad. Por eso cada base tuvo un propietario estable antes de ampliar la superficie superior.
1. Definir el perímetro operativo antes de elegir infraestructura
El objetivo era una primera versión controlada, no una afirmación de infraestructura empresarial redundante a escala global. Eso fijó criterios de aceptación concretos: despliegue HTTPS repetible, datos persistentes, onboarding controlado, releases recuperables, logs útiles y una lista explícita del trabajo pendiente de escala y disponibilidad.
Esta precisión evita el teatro de arquitectura. Una sola tarea de aplicación y una base de datos en una zona pueden ser razonables para un piloto con design partners si se documentan fallos, copias y escalado de incidentes. No son alta disponibilidad. Nombrar el perímetro permite comprar la siguiente capa de fiabilidad cuando el uso la justifique.
2. Trasladar el estado autoritativo a PostgreSQL
La aplicación tenía archivos seed portables y flujos locales útiles durante la investigación. Wavect conservó esos archivos como material de arranque controlado, pero trasladó objetos de dominio, ontologías, usuarios, organizaciones, permisos, sesiones y credenciales de máquina a stores respaldados por PostgreSQL.
La decisión importante era la propiedad, no la marca de base de datos. Cada dominio recibió un contrato de store o repositorio, conexiones agrupadas y operaciones CRUD explícitas. El arranque podía sembrar un entorno vacío de manera determinista, pero un contenedor en ejecución dejó de tratar archivos mutables como fuente de verdad. Las pruebas de integración usaron la misma persistencia que el despliegue compartido.
3. Centralizar identidad, pertenencia al tenant y autorización por objeto
La autenticación demuestra quién envía una petición. No demuestra que esa persona pueda abrir un objeto, un grafo o un job concreto. La plataforma combinó sesiones de navegador revocables y validadas en servidor, roles administrativos, pertenencia a organizaciones y permisos por objeto detrás de una sola decisión de acceso. Las rutas web, APIs JSON y clientes externos debían hacer la misma pregunta.
Este es el límite descrito por OWASP API1:2023 Broken Object Level Authorization: todo endpoint que recibe un identificador debe comprobar que el usuario autenticado puede realizar la acción solicitada sobre ese objeto. Un UUID, un JWT válido o un botón oculto no sustituyen esa comprobación.
La matriz práctica cruzó roles, organizaciones, objetos y transportes. Un usuario normal no debía acceder cambiando un ID. Un administrador de organización debía permanecer dentro de su organización. Una sesión o API key revocada debía dejar de funcionar sin esperar a otro despliegue.
4. Tratar el trabajo LLM largo como jobs con propietario
La extracción de documentos, las entrevistas, la generación de perfiles y las simulaciones pueden durar más que una petición HTTP normal. Aumentar el timeout del servidor solo reduce un síntoma. No responde quién posee el trabajo, si un reintento es seguro ni cómo entiende el usuario lo sucedido.
Wavect introdujo un contrato de jobs independiente del backend con estados tipados, registro de handlers, límites de concurrencia por usuario, claves de idempotencia, cancelación cooperativa, resultados y errores almacenados, caducidad de trabajos terminados y apagado ordenado. El polling ofrecía una base simple. Server-Sent Events añadía progreso y heartbeat sin convertir la conexión del navegador en propietaria del job.
| Propiedad del job | Pregunta que debe responder | Evidencia de release |
|---|---|---|
| Propiedad | ¿Qué usuario puede observarlo o cancelarlo? | Las pruebas entre usuarios fallan de forma cerrada. |
| Idempotencia | ¿Qué ocurre si se envía dos veces? | El duplicado produce una sola ejecución intencionada. |
| Progreso | ¿Se distinguen activo, bloqueado, fallido y completo? | Polling y eventos muestran el mismo estado. |
| Cancelación | ¿Puede parar el trabajo caro en un punto seguro? | El handler coopera y registra el estado final. |
| Apagado | ¿Qué ocurre durante un despliegue? | La cola drena o marca trabajo pendiente para recuperación. |
Un executor en proceso fue un trade-off consciente del piloto, no la solución final de escala. El contrato permitía migrar después a una cola duradera sin reescribir cada flujo de producto. La clave es separar el ciclo de vida del job del primer backend que lo ejecuta.
5. Dar contratos de seguridad explícitos a navegador, API y MCP
La API externa se reorganizó en grupos modulares con dependencias compartidas, errores estándar, scopes, autorización por objeto y throttling. Sesiones humanas, JWTs y API keys hasheadas servían a clientes distintos, pero convergían en los mismos permisos de dominio. La administración podía desactivar acceso externo por objeto en lugar de exponer toda capacidad por defecto.
MCP exige la misma disciplina. Una llamada de herramienta no es fiable solo porque la inicia un agente. Siguen siendo necesarias la validación de IDs, la separación de scopes de lectura y escritura, los límites y los errores saneados. La especificación actual de autorización de Model Context Protocol exige solicitudes ligadas al recurso y validación de la audiencia del token. Las integraciones nuevas deben seguir el protocolo vigente, no copiar supuestos de sesión o transporte de una implementación anterior.
6. Hacer que la salud del despliegue refleje el servicio real
La infraestructura como código definió red, servicio de contenedores, base privada, balanceador, TLS, DNS, registro de imágenes, logs y permisos. Un workflow construía una imagen versionada, actualizaba el servicio y esperaba estabilidad. El endpoint de salud comprobaba PostgreSQL, así que un proceso vivo sin acceso al store autoritativo no contaba como listo.
Los controles de despliegue necesitan una acción de fallo. AWS documenta circuit breakers de despliegue y alarmas de CloudWatch que pueden detectar despliegues ECS fallidos y volver al último estado bueno. En este programa, el despliegue basado en salud y el rollback eran parte del diseño del release, no una reacción improvisada.
7. Combinar pruebas automatizadas con QA repetida en navegador
Las pruebas unitarias cubrían de forma aislada grafos, retrieval, grounding, seguridad y jobs. Un track de integración separado usaba PostgreSQL real para persistencia, autenticación, API y MCP. Así el feedback rápido seguía siendo rápido sin simular precisamente los límites que más podían fallar en el entorno compartido.
La automatización no sustituyó la QA exploratoria. Pasadas repetidas de navegador descubrieron fallos en expiración de login, selección, progreso de tareas largas, edición de grafos, cálculos, sincronización de temas, errores y carga. Cada defecto se corrigió en el propietario estable más bajo y, cuando tenía sentido, recibió una prueba de regresión.
Este enfoque ordenado por riesgo coincide con el NIST Secure Software Development Framework, que organiza el desarrollo seguro en preparación, protección del software, producción de releases seguros y respuesta a vulnerabilidades residuales. NIST lo presenta como una base adaptable para mejora según riesgo, no como una lista universal.
¿Qué evidencia hace creíble un piloto controlado?
La preparación para producción no es una propiedad binaria del repositorio. Es una afirmación de release respaldada con evidencia en todo el perímetro operativo. Para esta clase de plataforma, el conjunto mínimo útil es el siguiente:
| Límite | Evidencia antes del release | Riesgo residual que declarar |
|---|---|---|
| Datos | Pruebas de persistencia y seeds en PostgreSQL, con proceso de backup y restore | Madurez de migración y recuperación |
| Acceso | Pruebas de rol, tenant y objeto con sesiones y tokens | Abuso administrativo y crecimiento de políticas |
| Jobs LLM | Duplicados, cancelación, timeout, error y apagado | Durabilidad y capacidad de una cola local al proceso |
| Interfaces externas | Scopes, rate limits, entradas inválidas y errores saneados | Evolución del protocolo y clientes de terceros |
| Despliegue | Rollout basado en salud, fallo observable y rollback probado | Disponibilidad de una tarea y una zona |
| Flujos de usuario | Recorridos reales con recuperación desde estados caducados o parciales | Combinaciones no vistas en una interfaz amplia |
Por qué la producción incremental venció a la reescritura
La aplicación ya codificaba comportamiento de producto ganado con esfuerzo. Una reescritura habría cambiado deuda técnica visible por riesgo oculto de regresión del producto. El camino más rápido fue conservar los flujos validados, instalar propiedad estable debajo y corregir defectos sobre esa nueva base.
No significa conservar todas las decisiones. Los archivos dejaron de ser estado autoritativo. Las comprobaciones salieron de rutas individuales. El trabajo largo dejó de pertenecer a una petición. Las dependencias de API se hicieron explícitas. Los patrones compartidos sustituyeron arreglos locales. La producción incremental es reemplazo selectivo con trazabilidad, no parcheo infinito.
Para productos con esta forma, el servicio de AI enablement y arquitectura de Wavect cubre evaluación, límites, hardening y transferencia. El caso anonimizado de una plataforma analítica muestra por separado cómo estabilizar un producto de datos complejo sin nombrar al cliente. Para decidir qué conservar o reconstruir, usa la guía del prototipo a producción, o solicita una revisión de arquitectura de producción con tus restricciones actuales.
Preguntas sobre arquitectura de producción para plataformas LLM con estado
¿Qué es una plataforma LLM con estado?
¿Qué debe llevarse primero a producción en una aplicación LLM?
¿Debe el trabajo LLM largo quedarse en una petición HTTP?
¿Cómo debe acceder un servidor MCP a los datos?
¿Un piloto exitoso significa alta disponibilidad?
¿Cuándo se justifica una reescritura?
Reflexiones finales
Una plataforma LLM con estado se vuelve operable cuando cada estado y autoridad importante tiene propietario. PostgreSQL posee los datos duraderos. Una política central posee el acceso por tenant y objeto. La capa de jobs posee el trabajo costoso. API y MCP reutilizan esas decisiones. La salud del despliegue refleja dependencias reales, y las pruebas con QA de navegador aportan evidencia.
Conserva el comportamiento que los usuarios ya valoran. Sustituye las bases que no soportan operación compartida. Sobre todo, nombra con honestidad el perímetro operativo. Un piloto controlado con trade-offs explícitos es un resultado de ingeniería más fuerte que una afirmación indefinida de preparación para producción.
