Salta ai contenuti

TypeScript Agent Guardrails

Collega un Amazon Bedrock Guardrail a un TypeScript Agent. Un guardrail è un insieme di regole che Amazon Bedrock applica ai messaggi che il tuo agente invia al modello e alle risposte del modello. Senza uno, un utente può chiedere al tuo agente qualsiasi argomento e il modello può ripetere dati personali come indirizzi email nelle sue risposte.

Il generatore aggiunge un file di policy che contiene le tue regole, il codice che applica il guardrail al modello del tuo agente e l’infrastruttura che crea il guardrail nel tuo account AWS.

  • guardrail.json accanto al tuo agent.ts contiene le regole: gli argomenti che il tuo agente deve rifiutare e i tipi di dati personali (PII, personally identifiable information) che deve nascondere o bloccare.
  • Il tuo costrutto CDK o modulo Terraform legge guardrail.json quando sintetizzi o pianifichi. Crea il guardrail e una versione numerata di esso. Una versione del guardrail è uno snapshot di sola lettura delle regole.
  • L’infrastruttura scrive l’ID del guardrail e il numero di versione nel runtime config, l’applicazione AWS AppConfig dove la tua infrastruttura memorizza i dettagli delle risorse distribuite. La voce è agentcore.guardrails.<AgentClass>, denominata in base alla classe del tuo agente, per esempio agentcore.guardrails.MyAgent. Ogni agente protetto ha la propria voce.
  • guardrail.ts costruisce il modello Bedrock che la tua chiamata new Agent({...}) utilizza. Prima di ogni chiamata al modello, il modello legge la voce dell’agente dal runtime config e applica quel guardrail.

Avrai bisogno di un progetto TypeScript esistente contenente un agente creato con il generatore ts#agent.

Esegui questo generatore@aws/nx-plugin:ts#agent#guardrails

pnpm nx g @aws/nx-plugin:ts#agent#guardrails
Componi il tuo comando2

Obbligatorio

Opzioni del generatore2 opzioni
projectObbligatoriostring

Il progetto contenente il TypeScript Agent

agentstring

Il nome del componente Agent da proteggere. Obbligatorio quando il progetto contiene più di un TypeScript Agent.

Il generatore aggiunge i seguenti file accanto al tuo agente, dove <agent> è il nome del tuo componente agente (agent per impostazione predefinita):

  • Directory<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

Aggiunge anche l’infrastruttura per il tuo provider iac selezionato, dove <agent-name> è il nome in kebab-case del costrutto o modulo del tuo agente:

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

Il generatore modifica agent.ts in questo modo:

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.

Eseguire nuovamente il generatore sullo stesso agente non modifica alcun file e mantiene le tue modifiche a guardrail.json.

Se il tuo agente è stato generato con infra: none, il generatore aggiunge solo i file dell’agente e stampa un avviso. Dovrai quindi creare il guardrail tu stesso e scrivere il suo ID e versione nel runtime config a agentcore.guardrails.<AgentClass> come { guardrailId, guardrailVersion }.

Se la tua chiamata new Agent({...}) imposta già model, il generatore lascia agent.ts invariato. Stampa il nome del file e le righe da aggiungere. Per mantenere le tue opzioni del modello, crea il tuo modello con la classe GuardrailedBedrockModel da guardrail.ts. Accetta le stesse opzioni di BedrockModel, per esempio:

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

Il guardrail controlla due cose ad ogni chiamata al modello:

  • la conversazione che il tuo agente invia al modello, incluso l’ultimo messaggio dell’utente
  • la risposta del modello, prima che il tuo agente la trasmetta all’utente

Quando il guardrail blocca il messaggio di un utente, l’utente riceve il testo blockedInputMessaging e il modello non viene chiamato. Strands sostituisce anche il messaggio bloccato nella cronologia delle conversazioni dell’agente con [User input redacted.]. Quando blocca una risposta, l’utente riceve il testo blockedOutputsMessaging. Quando una regola ANONYMIZE corrisponde, la risposta contiene un segnaposto come {EMAIL} invece del valore.

Il guardrail non controlla le definizioni degli strumenti, gli argomenti che il modello passa ai tuoi strumenti o i risultati che i tuoi strumenti restituiscono. Per esempio, se uno strumento restituisce l’indirizzo email di un cliente da un database, il guardrail non lo nasconde al modello. Tratta i risultati degli strumenti come non affidabili, come descrive la guida TypeScript Agent nella sezione “Securing your Agent”.

La policy fornita è un esempio per l’agente matematico generato. Rifiuta consigli sugli investimenti e nasconde o blocca tre tipi di dati personali:

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" }
]
}

I campi sono:

  • blockedInputMessaging: la risposta che un utente riceve quando il guardrail blocca il suo messaggio. Al massimo 500 caratteri.
  • blockedOutputsMessaging: la risposta che un utente riceve quando il guardrail blocca la risposta del modello. Al massimo 500 caratteri.
  • deniedTopics: argomenti che il tuo agente deve rifiutare. Ogni argomento ha un name (al massimo 100 lettere, cifre, spazi e i caratteri -_!?.), una definition di al massimo 1000 caratteri che descrive l’argomento ed examples opzionali di al massimo 100 caratteri ciascuno.
  • piiEntities: tipi di dati personali su cui agire. type è un tipo di informazione sensibile come EMAIL, PHONE o US_SOCIAL_SECURITY_NUMBER. action è ANONYMIZE per sostituire il valore con un segnaposto, o BLOCK per bloccare l’intero messaggio o risposta.

Scrivi una definition dell’argomento che descriva l’argomento stesso. Per esempio, “Recommendations about which specific stocks to buy” funziona meglio di “Do not give investment advice”.

Ogni volta che modifichi guardrail.json e distribuisci, l’infrastruttura crea una nuova versione numerata del guardrail e la scrive nel runtime config. La descrizione della versione contiene l’hash SHA-256 di guardrail.json, quindi una modifica al file cambia la descrizione e una nuova versione sostituisce quella vecchia. Con il costrutto CDK, l’hash copre anche qualsiasi proprietà del guardrail che passi.

Il tuo agente in esecuzione non ha bisogno di un riavvio. Memorizza nella cache ciò che legge dal runtime config per 5 secondi, quindi utilizza la nuova versione entro 5 secondi dalla distribuzione AppConfig. La vecchia versione viene eliminata dopo la distribuzione AppConfig: CloudFormation la elimina nella sua fase di pulizia e Terraform la elimina dopo il modulo di distribuzione quando aggiungi il modulo guardrail al depends_on di quel modulo, come mostrato in Collegamento del guardrail al tuo agente.

Il tuo agente non usa mai la versione DRAFT. DRAFT contiene sempre le regole più recenti, quindi una modifica effettuata nella console AWS raggiungerebbe il tuo agente in esecuzione senza una distribuzione. guardrail.ts genera un errore se la versione nel runtime config non è un numero di versione.

Il generatore non modifica il tuo stack o il tuo modulo Terraform radice, allo stesso modo in cui il generatore ts#agent lascia a te la distribuzione dell’agente. Quando termina, stampa il codice qui sotto con i nomi del tuo agente compilati. Aggiungilo per creare il guardrail, scrivere la sua voce nel runtime-config e consentire all’agente di applicare il 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 });

Il costrutto scrive l’ID del guardrail e la versione nel runtime config a agentcore.guardrails.MyAgent e concede all’agent il permesso di applicare il guardrail. Il costrutto dell’agente consente già all’agente di leggere il runtime config.

Il costrutto espone:

  • guardrail (il CfnGuardrail) e version (il CfnGuardrailVersion)
  • guardrailId, guardrailArn e guardrailVersion
  • grantApply(grantee), che concede bedrock:ApplyGuardrail sul guardrail a un altro principal

Aggiunge anche gli output dello stack GuardrailId e GuardrailVersion. Le sue props sono agent e qualsiasi proprietà CfnGuardrail. Le proprietà CfnGuardrail hanno la precedenza su guardrail.json. Per esempio, aggiungi filtri di contenuto:

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

Se dimentichi il collegamento, il runtime config non ha alcuna voce per il tuo agente. Il modello genera quindi un errore prima di chiamare Bedrock, quindi l’agente non viene eseguito senza il suo guardrail. Per MyAgent, l’errore è:

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.

L’agente si avvia con ogni protocollo (http, a2a e ag-ui) e ogni richiesta fallisce con questo errore.

Il target <agent>-dev imposta LOCAL_DEV=true. Quando LOCAL_DEV è true e la variabile d’ambiente RUNTIME_CONFIG_APP_ID non è impostata, guardrail.ts non legge il runtime config. Stampa un avviso una volta e l’agente viene eseguito senza guardrail:

Terminal window
pnpm nx agent-dev your-project

Per testare le tue regole localmente, distribuisci prima il guardrail. Quindi imposta RUNTIME_CONFIG_APP_ID sull’ID della tua applicazione runtime-config distribuita, dall’output dello stack RuntimeConfigApplicationId (CDK) o module.runtime_config_appconfig.application_id (Terraform). La tua shell ha anche bisogno di credenziali AWS che possano leggere AppConfig e applicare il guardrail:

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

L’agente legge quindi solo la propria voce, quindi diversi agenti protetti possono essere eseguiti localmente contro la stessa applicazione. Se l’agente non può leggere il runtime config o la voce è mancante, stampa l’avviso una volta e viene eseguito senza guardrail.

Il target <agent>-serve non imposta LOCAL_DEV, quindi ha bisogno di RUNTIME_CONFIG_APP_ID e della voce distribuita, altrimenti ogni richiesta fallisce come descritto sopra. Il target <agent>-chat si connette a un agente in esecuzione e non ha bisogno del runtime config stesso.

Amazon Bedrock addebita per ogni policy del guardrail che valuta il testo, sia sull’input che sulla risposta. Vedi Amazon Bedrock pricing.

Ogni chiamata al modello richiede anche più tempo, perché il guardrail controlla la risposta prima che il tuo agente la trasmetta all’utente.

  • Questo generatore supporta agenti creati con ts#agent. Non supporta AgentCore Harness.
  • guardrail.json contiene solo argomenti negati ed entità PII. Aggiungi altre policy, come filtri di contenuto e filtri di parole, con le props del costrutto (CDK) o modificando il modulo (Terraform).
  • Il guardrail non controlla i risultati degli strumenti, come descritto in Cosa controlla il guardrail.