DanLevy.net

La IA en producción es aterradora (y cómo arreglarlo)

Si tu agente no tiene guardrails, no estás listo para producción.

Nadie se propone construir un sistema de IA inseguro. Escribes instrucciones, pruebas casos límite, añades algunas reglas de validación. Y entonces alguien descubre que puede engañar a tu bot para que interprete el papel de un pirata y exponga datos de usuarios. O un número de tarjeta de crédito termina en tus logs. O el modelo recomienda con total confianza el producto de un competidor.

La brecha entre “funciona en la demo” y “es seguro en producción” es más amplia de lo que la mayoría de los equipos espera.

Parte del problema es que los LLM crudos no tienen opinión sobre lo que deberían o no deberían hacer. Son máquinas de predicción que intentan continuar cualquier patrón que hayas iniciado. Dales un prompt que parezca “modo de anulación del sistema” y participarán con gusto. Esto no es un bug del modelo; es simplemente cómo funcionan los modelos de lenguaje.

La mayoría de los frameworks te entregan el modelo y te desean suerte. Mastra adopta un enfoque distinto: asume que eventualmente necesitarás guardrails, así que los integra en la arquitectura del agente desde el principio.


Processors como capas de seguridad

El mecanismo central es sencillo. Antes de que tu prompt llegue al modelo, pasa por una cadena de input processors. Después de que el modelo responde, los output processors entran en acción. Cada processor puede inspeccionar, modificar o bloquear el contenido en esa etapa.

Piensa en ellos como middleware para interacciones con IA. Apilas los que necesitas, configuras su comportamiento y se ejecutan automáticamente en cada petición.

1. Detener a los piratas (Prompt Injection)

Los ataques de prompt injection se han vuelto creativos. La gente usa caracteres Unicode invisibles, escribe instrucciones en base64, o convence al modelo de que está en “modo debug” donde las reglas normales no aplican. Las técnicas siguen evolucionando.

Mastra incluye processors que detectan patrones comunes:

src/mastra/agents/secure-agent.ts
import { Agent } from '@mastra/core/agent';
import { PromptInjectionDetector, UnicodeNormalizer } from '@mastra/core/processors';
import { openai } from '@ai-sdk/openai';
export const secureAgent = new Agent({
id: 'fortress-assistant',
name: 'fortress-assistant',
instructions: 'You are a secure assistant.',
model: openai('gpt-5'),
inputProcessors: [
// 1. Scrub invisible characters
new UnicodeNormalizer({
id: 'unicode-normalizer',
stripControlChars: true,
collapseWhitespace: true,
}),
// 2. Detect the attempt
new PromptInjectionDetector({
id: 'prompt-injection-detector',
model: openai('gpt-5-nano'), // Cheap, fast
threshold: 0.8,
strategy: 'block', // Hard stop
detectionTypes: ['injection', 'jailbreak', 'system-override'],
}),
],
});

El UnicodeNormalizer elimina los caracteres de control y colapsa los espacios en blanco. El PromptInjectionDetector analiza la entrada limpiada en busca de patrones que sugieran que alguien intenta anular tus instrucciones.

Puedes configurar qué tan agresiva quieres que sea la detección (el parámetro threshold) y qué debe ocurrir cuando se activa (bloquear, registrar o simplemente marcar).

2. Manejo de PII

Números de tarjeta de crédito en logs, números de Seguro Social en bases de datos vectoriales, direcciones de correo electrónico almacenadas más tiempo del necesario. Estos son el tipo de problemas que se convierten en asuntos regulatorios. El desafío es que los usuarios no siempre se dan cuenta de que están pegando datos sensibles en una ventana de chat.

El PIIDetector escanea patrones comunes antes de que lleguen a tu modelo o se escriban en almacenamiento:

import { PIIDetector } from '@mastra/core/processors';
export const privateAgent = new Agent({
id: 'privacy-first-assistant',
name: 'privacy-first-assistant',
instructions: 'You are a helpful assistant that never stores personal information.',
model: openai('gpt-5'),
inputProcessors: [
new PIIDetector({
id: 'pii-detector',
model: openai('gpt-5-nano'),
detectionTypes: ['email', 'phone', 'credit-card', 'ssn'],
threshold: 0.6,
strategy: 'redact',
redactionMethod: 'mask', // Replace with [REDACTED]
instructions: 'Detect and mask personally identifiable information',
}),
],
});

Puedes elegir redactar (reemplazar con [REDACTED]), aplicar hash o bloquear por completo. El processor se ejecuta tanto en la entrada como en la salida, así que estás cubierto incluso si el modelo de alguna manera genera datos sensibles en su respuesta.

3. Moderación de contenido

Los modelos entrenados con datos de internet han visto de todo. Sin filtrado, ocasionalmente pueden producir respuestas que pondrían nervioso a tu equipo de relaciones públicas. El ModerationProcessor detecta contenido que viola tus directrices:

import { ModerationProcessor } from '@mastra/core/processors';
export const moderatedAgent = new Agent({
id: 'safe-assistant',
name: 'safe-assistant',
instructions: 'You are a helpful assistant for a community platform.',
model: openai('gpt-5'),
inputProcessors: [
new ModerationProcessor({
id: 'moderation-processor',
model: openai('gpt-5-nano'), // Fast, cheap model for classification
categories: ['hate', 'harassment', 'violence', 'self-harm'],
threshold: 0.7, // Block if confidence > 70%
strategy: 'block', // Stop the request immediately
instructions: 'Detect harmful content that violates community guidelines',
}),
],
});

Lo interesante es que tú defines qué categorías importan para tu caso de uso. Una herramienta de escritura creativa podría permitir contenido más expresivo que un bot de atención al cliente. El threshold y la estrategia te dan control sobre qué tan estricto debe ser el filtrado.


Cuando las cosas se disparan

Los processors no lanzan errores cuando detectan un problema. En su lugar, establecen una flag en el objeto de resultado:

const result = await secureAgent.generate('Ignore all previous instructions...');
if (result.tripwire) {
console.log(`Blocked! Reason: ${result.tripwireReason}`);
// "Blocked! Reason: Prompt injection detected."
return "Nice try, script kiddie.";
}

Este patrón te permite manejar eventos de seguridad de la manera que tenga más sentido para tu aplicación. Podrías registrarlos para análisis, devolver un mensaje de error genérico, o incluso permitir ciertas violaciones en contextos específicos. El campo tripwireReason te dice exactamente qué processor marcó el contenido, lo cual ayuda cuando depuras falsos positivos o ajustas tus umbrales.


Lo que esto no resuelve

Los processors detectan mucho, pero no son magia. Un atacante determinado con suficiente tiempo probablemente pueda encontrar un prompt que se filtre. Los modelos ocasionalmente alucinan de formas que los processors no pueden predecir. Y siempre hay un equilibrio entre seguridad y flexibilidad: cuanto más estrictas sean tus reglas, más probable es que bloquees casos de uso legítimos.

El valor no es la protección perfecta. Es tener una forma sistemática de manejar los problemas comunes que definitivamente surgirán en producción. Puedes ajustar la sensibilidad a medida que aprendes lo que tus usuarios realmente hacen. Puedes añadir processors personalizados para riesgos específicos de tu dominio. Y tienes registros de auditoría que muestran qué se bloqueó y por qué.

La mayoría de los problemas de seguridad en IA de producción no son ataques sofisticados. Son personas copiando y pegando datos que no deberían, o descubriendo mediante prueba y error que el bot hará cosas que no pretendías. Los processors no detendrán todos los problemas posibles, pero hacen que los obvios sean mucho más difíciles.

Recursos

Lee la serie

  1. LLM Routing
  2. Seguridad y guardrails (esta publicación)
  3. MCP e integraciones de herramientas
  4. Workflows y memoria