Salta ai contenuti

Python Agent Guardrails

Collega un Amazon Bedrock Guardrail a un Python 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. Supporta entrambi i framework py#agent, Strands e LangChain, con ogni protocollo.

  • guardrail.json accanto al tuo agent.py 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 nella 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, ad esempio agentcore.guardrails.MyAgent. Ogni agente protetto ha la propria voce.
  • guardrail.py definisce il modello Bedrock che il tuo agent.py utilizza. Prima di ogni chiamata al modello, il modello legge la voce dell’agente dalla runtime config e aggiunge quel guardrail alla richiesta.

Avrai bisogno di un progetto Python esistente contenente un agente creato con il generatore py#agent.

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

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

Obbligatorio

Opzioni del generatore2 opzioni
projectObbligatoriostring

Il progetto contenente il Python Agent

agentstring

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

Il generatore aggiunge i seguenti file accanto al tuo agente, dove <module> è il modulo Python del tuo progetto e <agent> è il nome snake-case del tuo componente agente (agent per impostazione predefinita):

  • Directory<your-project>/<module>/<agent>/
    • agent.py Il tuo agente, ora creato con il modello protetto
    • guardrail.json Le regole che il tuo guardrail applica
    • guardrail.py Definisce il modello Bedrock con il guardrail applicato

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

  • Directorypackages/common/constructs/src/app/guardrails/<agent-name>/
    • <agent-name>-guardrail.ts Costrutto CDK contenente il guardrail e la sua versione

Il generatore modifica agent.py in questo modo:

from .guardrail import get_guardrailed_model
from .session import get_session_manager
@contextmanager
def get_agent():
yield Agent(
model=get_guardrailed_model(),
name="MyAgent",

get_guardrailed_model() restituisce un GuardrailedBedrockModel, una sottoclasse di Strands BedrockModel. Utilizza lo stesso modello predefinito di un Agent creato senza un model.

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

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

Se un agente TypeScript in un altro progetto ha lo stesso nome di classe e ha già un guardrail, il generatore si ferma con un errore e non modifica alcun file. Entrambi gli agenti condividerebbero un costrutto runtime e un guardrail. Dai a uno degli agenti un nome diverso.

Se agent.py non ha la forma prevista, il generatore lo lascia invariato. Stampa il nome del file e le righe da aggiungere.

Questo accade quando la tua chiamata Agent(...) imposta già model. Per mantenere le tue opzioni del modello, crea il tuo modello con la classe GuardrailedBedrockModel da guardrail.py. Accetta le stesse opzioni di BedrockModel, ad esempio:

agent.py
from .guardrail import GuardrailedBedrockModel
agent = Agent(
model=GuardrailedBedrockModel(model_id="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, il modello non viene chiamato. Quando una regola ANONYMIZE corrisponde, la risposta contiene un segnaposto come {EMAIL} invece del valore. Quando il guardrail blocca una risposta, l’utente riceve il testo blockedOutputsMessaging.

Quando il guardrail blocca il messaggio di un utente, l’utente riceve il testo blockedInputMessaging. Strands sostituisce anche il messaggio bloccato nella cronologia della conversazione dell’agente con [User input redacted.].

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. Ad 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 attendibili, come descrive la guida Python Agent in “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. Ad 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 nella 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 tutte le proprietà del guardrail che passi.

Il tuo agente in esecuzione non ha bisogno di un riavvio. guardrail.py mantiene ciò che legge dalla runtime config per 5 secondi, quindi l’agente utilizza la nuova versione entro 5 secondi dalla distribuzione AppConfig. La vecchia versione viene eliminata dopo la distribuzione AppConfig. CloudFormation la elimina nel suo passaggio di pulizia, che in una misurazione (2026-10-24, us-east-1) è iniziato circa 7 secondi dopo il completamento della distribuzione. CloudFormation non garantisce quel ritardo. Terraform mantiene la vecchia versione per circa 15 secondi dopo il modulo di distribuzione, quindi la cache di 5 secondi non punta mai a una versione eliminata. Questo funziona quando aggiungi il modulo guardrail al depends_on di quel modulo, come mostrato in Collegamento del guardrail al tuo agente.

Il tuo agente non utilizza 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.py genera un errore se la versione nella runtime config non è un numero di versione.

Il generatore non modifica il tuo stack o il tuo modulo Terraform root, allo stesso modo in cui il generatore py#agent lascia a te la distribuzione dell’agente. Quando termina, stampa il codice seguente con i nomi del tuo agente compilati. Aggiungilo per creare il guardrail, scrivere la sua voce 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 nella 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 la 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. Ad esempio, aggiungi filtri di contenuto:

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

Il generatore aggiunge anche guardrail.json agli input synth di ogni progetto di infrastruttura CDK, quindi una modifica al file esegue nuovamente la sintesi invece di utilizzare la cache Nx.

Se dimentichi il collegamento, la 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. Se l’agente non può leggere affatto la runtime config, ad esempio perché RUNTIME_CONFIG_APP_ID non è impostato, ogni richiesta fallisce con l’errore del lettore runtime-config dell’agente.

Con il protocollo http, l’agente ha già iniziato a trasmettere la sua risposta quando il modello genera l’errore. Il chiamante non riceve quindi alcuna risposta e l’errore appare solo nel log dell’agente, per un agente distribuito nel suo gruppo di log runtime.

Il target <agent>-dev imposta LOCAL_DEV=true. Quando LOCAL_DEV è true e la variabile d’ambiente RUNTIME_CONFIG_APP_ID non è impostata, guardrail.py non legge la runtime config. Registra un avviso una volta e l’agente viene eseguito senza un 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 la runtime config o la voce è mancante, registra l’avviso una volta e viene eseguito senza un 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 della runtime config stessa.

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.

Mentre arrivano le richieste, ogni processo dell’agente legge la runtime config al massimo una volta ogni 5 secondi. Ogni lettura effettua due richieste AppConfig.

  • Questo generatore supporta agenti creati con py#agent, con i framework Strands e LangChain. 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.