Antes de que el modelo se ejecute
El usuario proporciona un prompt y un alias como cheap, fast o smart. El servidor de producción verifica autenticación, propiedad del espacio y permiso antes de aceptar la tarea. Los IDs de modelo y secretos de proveedor permanecen detrás de esa frontera — el alias amigable es el único vocabulario de modelo que el cliente necesita, porque el mapeo a un modelo de proveedor real es configuración, no contrato.
Un registro de tarea duradero da a la petición una identidad antes de que comience la ejecución en segundo plano. Esa identidad enlaza envío, worker, registros de uso y resultado. También da al usuario una forma de recuperar el trabajo tras navegar a otra parte.
El orden importa: el trabajo caro solo empieza después de que pasen las comprobaciones baratas. Verificar autenticación, propiedad y permiso antes de encolar nada evita que peticiones no autenticadas o no pagadas lleguen jamás a un proveedor — y hace el fallo explicable al usuario. La guía del módulo de AI documenta dónde viven esas comprobaciones; el post sobre fronteras de espacio explica por qué la propiedad se deriva en el servidor en lugar de confiarse al cliente.
Decide de quién son las claves y de quién los límites
Una función de AI es una decisión de gasto. supastack permite a los espacios traer sus propias claves de proveedor — guardadas cifradas, nunca expuestas a los clientes — o funcionar con claves de plataforma, y hace valer presupuestos por espacio contra un catálogo de precios de modelos. Sea cual sea tu implementación, las preguntas son las mismas: ¿quién paga y dónde se hace valer el límite?
La aplicación del límite pertenece al workflow del servidor, no a una estimación del navegador. Un presupuesto comprobado tras la generación solo registra el exceso; comprobado antes del dispatch, lo previene. Configuración de claves de proveedor cubre el lado de la configuración.
Haz la ejecución explícita
Trigger.dev ejecuta el workflow ai.generate. El router sensible a capacidades elige un modelo según la política configurada y los requisitos de la petición. Trata esa política como una entrada operativa: un alias no disponible no debe aparecer como una opción funcional en la interfaz.
Un fallo de red durante el envío puede dejar al cliente inseguro sobre si el trabajo se encoló. La ruta de producción usa una clave de idempotencia delimitada a la tarea y un envío guardado para que la recuperación reutilice la petición original. Enviar una nueva tarea tras cada timeout arriesga trabajo y coste duplicados.
La durabilidad también es lo que mantiene simple la interfaz: la pantalla lee el estado de la tarea y lo renderiza en lugar de orquestar reintentos. Cuando la generación abarca llamadas a modelos, pasos de herramientas o programaciones, el contrato de workflow explícito — encolar, estado, cancelar — es lo que mantiene honesto el «en curso».
Pon nombre a los modos de fallo
Entre la petición y el resultado hay un conjunto concreto y finito de cosas que salen mal. Diseña para cada una por su nombre en lugar de para «errores» en abstracto — cada tarea debería terminar en un estado explicable: encolada, en curso, fallida con un motivo o completa con un resultado. Recuperación de tareas es la referencia del kit para el lado de la recuperación.
El requisito de interfaz debajo es que ningún estado puede mentir. Un spinner que sobrevive al trabajo, o un mensaje de éxito para una tarea que nunca corrió, es un ticket de soporte y una disputa de facturación esperando a ocurrir.
- El envío agotó el tiempo — recupéralo mediante el envío guardado y la clave de idempotencia delimitada a la tarea en lugar de volver a encolar.
- El proveedor falló a mitad de tarea — marca la tarea como fallida con un motivo que la interfaz pueda mostrar.
- Presupuesto agotado — rechaza antes del dispatch, no después del gasto.
- El usuario navegó a otra parte — el registro duradero y la URL de recuperación restauran estado y resultado.
Sigue lo que ocurrió
La generación produce más que texto. La aplicación registra el uso y un resultado de tarea, y la interfaz lee el estado mediante la API autenticada. El registro de uso es lo que hace exigible el presupuesto — se escribe antes de devolver el resultado, no se estima después.
El email de finalización es un paso separado con registros de entrega separados. Una respuesta de modelo exitosa no establece que un email se haya entregado. Mantener estos resultados distintos hace los fallos más fáciles de explicar y reintentar sin volver a ejecutar el modelo innecesariamente.
El resultado también necesita un hogar al que el usuario pueda volver: una página de tarea, una lista de historial, una URL de recuperación entregada en ese email de finalización. Una generación que solo existe en una notificación transitoria es trabajo que te pedirán producir dos veces.
Verifica cada frontera
Usa adaptadores fake deterministas para probar primero las decisiones de la aplicación: acceso denegado, alias desactivados, envíos duplicados, recuperación de resultados y errores genéricos. Estos tests deben ejecutarse sin credenciales de proveedor.
Usa después el proceso de smoke de proveedor explícitamente opt-in para las integraciones reales. Exige la configuración sandbox documentada y una aprobación para hacer llamadas externas. La distinción mantiene el desarrollo ordinario rápido mientras hace las pruebas de producción específicas y trazables.
Mantén estable esa división a medida que el producto cambia: cobertura determinista cerca de cada decisión de frontera, para que un cambio de proveedor, de política del router o un alias nuevo rompa un test en lugar de fallar a un cliente.
Preguntas frecuentes sobre funciones de AI en SaaS
Algunas preguntas salen en cada conversación sobre poner AI detrás de un paywall.
- ¿Dónde debería ocurrir la autorización de las funciones de AI? — Antes de encolar nada: autentica, resuelve el espacio, comprueba el permiso y después crea la tarea. Las comprobaciones que corren tras la generación solo documentan el mal uso.
- ¿Necesito soporte de BYOK? — Si tus clientes tienen sus propias relaciones con proveedores, sí: decide quién paga y quién posee los límites de ritmo. Guarda las claves cifradas y mantenlas fuera de los clientes — la guía de configuración de AI cubre el modelo.
- ¿Cómo evito que los reintentos cobren dos veces? — Delimita la clave de idempotencia a la tarea y reutiliza el envío guardado durante la recuperación, para que un timeout no pueda crear una segunda ejecución facturable.
- ¿Qué datos de uso debería registrar? — Por tarea: modelo, unidades consumidas, coste contra el catálogo de precios y el espacio — suficiente para hacer valer presupuestos y responder preguntas de gasto sin volver a ejecutar jobs.
- ¿Cuándo pertenece la generación a un job en segundo plano? — Siempre que pueda sobrevivir a una petición. La latencia del modelo, los reintentos y el trabajo de varios pasos abogan por ejecución duradera; solo las llamadas instantáneas y baratas pertenecen en línea.