Ir al contenido

TypeScript Agent Guardrails

Adjunta un Amazon Bedrock Guardrail a un TypeScript Agent. Un guardrail es un conjunto de reglas que Amazon Bedrock aplica a los mensajes que tu agente envía al modelo y a las respuestas del modelo. Sin uno, un usuario puede preguntarle a tu agente sobre cualquier tema, y el modelo puede repetir datos personales como direcciones de correo electrónico en sus respuestas.

El generador agrega un archivo de política que contiene tus reglas, el código que aplica el guardrail al modelo de tu agente, y la infraestructura que crea el guardrail en tu cuenta de AWS.

  • guardrail.json junto a tu agent.ts contiene las reglas: los temas que tu agente debe rechazar y los tipos de datos personales (PII, información de identificación personal) que debe ocultar o bloquear.
  • Tu constructo CDK o módulo Terraform lee guardrail.json cuando sintetizas o planificas. Crea el guardrail y una versión numerada del mismo. Una versión de guardrail es una instantánea de solo lectura de las reglas.
  • La infraestructura escribe el ID del guardrail y el número de versión en runtime config, la aplicación AWS AppConfig donde tu infraestructura almacena los detalles de los recursos desplegados. La entrada es agentcore.guardrails.<AgentClass>, nombrada según la clase de tu agente, por ejemplo agentcore.guardrails.MyAgent. Cada agente protegido tiene su propia entrada.
  • guardrail.ts construye el modelo Bedrock que tu llamada new Agent({...}) usa. Antes de cada llamada al modelo, el modelo lee la entrada del agente desde runtime config y aplica ese guardrail.

Necesitarás un proyecto TypeScript existente que contenga un agente creado con el generador ts#agent.

Ejecute este generador@aws/nx-plugin:ts#agent#guardrails

pnpm nx g @aws/nx-plugin:ts#agent#guardrails
Construya su comando2

Requerido

Opciones del generador2 opciones
projectRequeridostring

El proyecto que contiene el TypeScript Agent

agentstring

El nombre del componente Agent a proteger. Requerido cuando el proyecto contiene más de un TypeScript Agent.

El generador agrega los siguientes archivos junto a tu agente, donde <agent> es el nombre de tu componente de agente (agent por defecto):

  • Directorio<your-project>/src/<agent>/
    • agent.ts Your agent, now created with model: getGuardrailedModel()
    • guardrail.json The rules your guardrail applies
    • guardrail.ts Builds the Bedrock model with the guardrail applied

También agrega la infraestructura para tu proveedor iac seleccionado, donde <agent-name> es el nombre en kebab-case del constructo o módulo de tu agente:

  • Directoriopackages/common/constructs/src/app/guardrails/<agent-name>/
    • <agent-name>-guardrail.ts CDK construct containing the guardrail and its version

El generador edita agent.ts así:

import { getGuardrailedModel } from './guardrail.js';
import { Agent, tool } from '@strands-agents/sdk';
export const getAgent = async () => {
const agent = new Agent({
model: getGuardrailedModel(),
systemPrompt: `You are a mathematical wizard.

Ejecutar el generador nuevamente en el mismo agente no cambia ningún archivo, y mantiene tus ediciones a guardrail.json.

Si tu agente fue generado con infra: none, el generador agrega solo los archivos del agente e imprime una advertencia. Luego creas el guardrail tú mismo y escribes su ID y versión en runtime config en agentcore.guardrails.<AgentClass> como { guardrailId, guardrailVersion }.

Si tu llamada new Agent({...}) ya establece model, el generador deja agent.ts sin cambios. Imprime el nombre del archivo y las líneas a agregar. Para mantener tus propias opciones de modelo, crea tu modelo con la clase GuardrailedBedrockModel de guardrail.ts. Toma las mismas opciones que BedrockModel, por ejemplo:

agent.ts
import { GuardrailedBedrockModel } from './guardrail.js';
const agent = new Agent({
model: new GuardrailedBedrockModel({ modelId: 'my-model-id' }),
// ...
});

El guardrail verifica dos cosas en cada llamada al modelo:

  • la conversación que tu agente envía al modelo, incluyendo el último mensaje del usuario
  • la respuesta del modelo, antes de que tu agente la transmita de vuelta al usuario

Cuando el guardrail bloquea el mensaje de un usuario, el usuario recibe el texto blockedInputMessaging, y el modelo no es llamado. Strands también reemplaza el mensaje bloqueado en el historial de conversación del agente con [User input redacted.]. Cuando bloquea una respuesta, el usuario recibe el texto blockedOutputsMessaging. Cuando una regla ANONYMIZE coincide, la respuesta contiene un marcador de posición como {EMAIL} en lugar del valor.

El guardrail no verifica las definiciones de herramientas, los argumentos que el modelo pasa a tus herramientas, o los resultados que tus herramientas devuelven. Por ejemplo, si una herramienta devuelve la dirección de correo electrónico de un cliente desde una base de datos, el guardrail no la oculta del modelo. Trata los resultados de las herramientas como no confiables, como describe la guía de TypeScript Agent en “Securing your Agent”.

La política proporcionada es un ejemplo para el agente de matemáticas generado. Rechaza consejos de inversión y oculta o bloquea tres tipos de datos personales:

guardrail.json
{
"blockedInputMessaging": "Sorry, I can't help with that request.",
"blockedOutputsMessaging": "Sorry, I can't share that answer.",
"deniedTopics": [
{
"name": "Investment advice",
"definition": "Recommendations about which specific stocks, funds or other investments to buy or sell.",
"examples": ["Which stocks should I buy this year?"]
}
],
"piiEntities": [
{ "type": "EMAIL", "action": "ANONYMIZE" },
{ "type": "PHONE", "action": "ANONYMIZE" },
{ "type": "US_SOCIAL_SECURITY_NUMBER", "action": "BLOCK" }
]
}

Los campos son:

  • blockedInputMessaging: la respuesta que recibe un usuario cuando el guardrail bloquea su mensaje. Como máximo 500 caracteres.
  • blockedOutputsMessaging: la respuesta que recibe un usuario cuando el guardrail bloquea la respuesta del modelo. Como máximo 500 caracteres.
  • deniedTopics: temas que tu agente debe rechazar. Cada tema tiene un name (como máximo 100 letras, dígitos, espacios y los caracteres -_!?.), una definition de como máximo 1000 caracteres que describe el tema, y examples opcionales de como máximo 100 caracteres cada uno.
  • piiEntities: tipos de datos personales sobre los que actuar. type es un tipo de información sensible como EMAIL, PHONE o US_SOCIAL_SECURITY_NUMBER. action es ANONYMIZE para reemplazar el valor con un marcador de posición, o BLOCK para bloquear todo el mensaje o respuesta.

Escribe una definition de tema que describa el tema en sí. Por ejemplo, “Recommendations about which specific stocks to buy” funciona mejor que “Do not give investment advice”.

Cada vez que cambias guardrail.json y despliegas, la infraestructura crea una nueva versión numerada del guardrail y la escribe en runtime config. La descripción de la versión contiene el hash SHA-256 de guardrail.json, por lo que un cambio en el archivo cambia la descripción, y una nueva versión reemplaza a la anterior. Con el constructo CDK, el hash también cubre cualquier propiedad de guardrail que pases.

Tu agente en ejecución no necesita un reinicio. Almacena en caché lo que lee de runtime config durante 5 segundos, por lo que usa la nueva versión dentro de los 5 segundos del despliegue de AppConfig. La versión anterior se elimina después del despliegue de AppConfig: CloudFormation la elimina en su paso de limpieza, y Terraform la elimina después del módulo de despliegue cuando agregas el módulo de guardrail al depends_on de ese módulo, como se muestra en Conectar el guardrail a tu agente.

Tu agente nunca usa la versión DRAFT. DRAFT siempre contiene las últimas reglas, por lo que una edición hecha en la consola de AWS llegaría a tu agente en ejecución sin un despliegue. guardrail.ts lanza un error si la versión en runtime config no es un número de versión.

El generador no cambia tu stack o tu módulo raíz de Terraform, de la misma manera que el generador ts#agent deja el despliegue del agente a ti. Cuando termina, imprime el código a continuación con los nombres de tu agente completados. Agrégalo para crear el guardrail, escribir su entrada de runtime-config y permitir que el agente aplique el guardrail:

packages/infra/src/stacks/application-stack.ts
import { MyAgent, MyAgentGuardrail } from '@my-scope/common-constructs';
const agent = new MyAgent(this, 'MyAgent');
new MyAgentGuardrail(this, 'MyAgentGuardrail', { agent });

El constructo escribe el ID del guardrail y la versión en runtime config en agentcore.guardrails.MyAgent, y otorga al agent permiso para aplicar el guardrail. El constructo del agente ya permite que el agente lea runtime config.

El constructo expone:

  • guardrail (el CfnGuardrail) y version (el CfnGuardrailVersion)
  • guardrailId, guardrailArn y guardrailVersion
  • grantApply(grantee), que otorga bedrock:ApplyGuardrail en el guardrail a otro principal

También agrega las salidas de stack GuardrailId y GuardrailVersion. Sus props son agent y cualquier propiedad de CfnGuardrail. Las propiedades de CfnGuardrail tienen precedencia sobre guardrail.json. Por ejemplo, agrega filtros de contenido:

new MyAgentGuardrail(this, 'MyAgentGuardrail', {
agent,
contentPolicyConfig: {
filtersConfig: [
{ type: 'HATE', inputStrength: 'HIGH', outputStrength: 'HIGH' },
],
},
});

Si olvidas la conexión, runtime config no tiene entrada para tu agente. El modelo entonces lanza un error antes de llamar a Bedrock, por lo que el agente no se ejecuta sin su guardrail. Para MyAgent, el error es:

No guardrail for this agent in runtime config at agentcore.guardrails.MyAgent. Add the MyAgentGuardrail construct (CDK) or the guardrails/my-agent module (Terraform) to your infrastructure.

El agente inicia con cada protocolo (http, a2a y ag-ui), y cada solicitud falla con este error.

El objetivo <agent>-dev establece LOCAL_DEV=true. Cuando LOCAL_DEV es true y la variable de entorno RUNTIME_CONFIG_APP_ID no está establecida, guardrail.ts no lee runtime config. Imprime una advertencia una vez y el agente se ejecuta sin un guardrail:

Terminal window
pnpm nx agent-dev your-project

Para probar tus reglas localmente, despliega primero el guardrail. Luego establece RUNTIME_CONFIG_APP_ID al ID de tu aplicación de runtime-config desplegada, desde la salida de stack RuntimeConfigApplicationId (CDK) o module.runtime_config_appconfig.application_id (Terraform). Tu shell también necesita credenciales de AWS que puedan leer AppConfig y aplicar el guardrail:

Terminal window
RUNTIME_CONFIG_APP_ID=<application-id> pnpm nx agent-dev your-project

El agente entonces lee solo su propia entrada, por lo que varios agentes protegidos pueden ejecutarse localmente contra la misma aplicación. Si el agente no puede leer runtime config, o la entrada falta, imprime la advertencia una vez y se ejecuta sin un guardrail.

El objetivo <agent>-serve no establece LOCAL_DEV, por lo que necesita RUNTIME_CONFIG_APP_ID y la entrada desplegada, de lo contrario cada solicitud falla como se describe arriba. El objetivo <agent>-chat se conecta a un agente en ejecución y no necesita runtime config en sí mismo.

Amazon Bedrock cobra por cada política de guardrail que evalúa texto, tanto en la entrada como en la respuesta. Consulta precios de Amazon Bedrock.

Cada llamada al modelo también toma más tiempo, porque el guardrail verifica la respuesta antes de que tu agente la transmita al usuario.

  • Este generador soporta agentes creados con ts#agent. No soporta el AgentCore Harness.
  • guardrail.json contiene solo temas denegados y entidades PII. Agrega otras políticas, como filtros de contenido y filtros de palabras, con las props del constructo (CDK) o editando el módulo (Terraform).
  • El guardrail no verifica los resultados de las herramientas, como se describe en Qué verifica el guardrail.