Python Agent Guardrails
Python AgentにAmazon Bedrock Guardrailをアタッチします。ガードレールは、エージェントがモデルに送信するメッセージとモデルの回答に対してAmazon Bedrockが適用する一連のルールです。ガードレールがない場合、ユーザーはエージェントに任意のトピックについて質問でき、モデルはメールアドレスなどの個人データを回答に含めて返すことができます。
ジェネレーターは、ルールを保持するポリシーファイル、エージェントのモデルにガードレールを適用するコード、およびAWSアカウントにガードレールを作成するインフラストラクチャを追加します。すべてのプロトコルで、両方のpy#agentフレームワーク(StrandsとLangChain)をサポートします。
agent.pyの隣にあるguardrail.jsonがルールを保持します:エージェントが拒否する必要があるトピックと、隠すかブロックする必要がある個人データ(PII、個人を特定できる情報)のタイプ。- CDKコンストラクトまたはTerraformモジュールは、合成または計画時に
guardrail.jsonを読み取ります。ガードレールとその番号付きバージョンを作成します。ガードレールバージョンは、ルールの読み取り専用スナップショットです。 - インフラストラクチャは、ガードレールのIDとバージョン番号をruntime config(インフラストラクチャがデプロイされたリソースの詳細を保存するAWS AppConfigアプリケーション)に書き込みます。エントリは
agentcore.guardrails.<AgentClass>で、エージェントのクラスにちなんで名付けられます(例:agentcore.guardrails.MyAgent)。保護された各エージェントには独自のエントリがあります。 guardrail.pyは、agent.pyが使用するBedrockモデルを定義します。各モデル呼び出しの前に、モデルはruntime configからエージェントのエントリを読み取り、そのガードレールをリクエストに追加します。
Agent Guardrailsの生成
Section titled “Agent Guardrailsの生成”py#agentジェネレーターで作成されたエージェントを含む既存のPythonプロジェクトが必要です。
このジェネレーターを実行@aws/nx-plugin:py#agent#guardrails
pnpm nx g @aws/nx-plugin:py#agent#guardrails yarn nx g @aws/nx-plugin:py#agent#guardrails npx nx g @aws/nx-plugin:py#agent#guardrails bunx nx g @aws/nx-plugin:py#agent#guardrails- インストール Nx Console VSCode Plugin まだインストールしていない場合
- VSCodeでNxコンソールを開く
- クリック
Generate (UI)"Common Nx Commands"セクションで - 検索
@aws/nx-plugin - py#agent#guardrails - 必須パラメータを入力
- クリック
Generate
コマンドを組み立てる2
必須
project必須stringPython Agentを含むプロジェクト
agentstringガードするAgentコンポーネントの名前。プロジェクトに複数のPython Agentが含まれている場合は必須です。
ジェネレーターの出力
Section titled “ジェネレーターの出力”ジェネレーターは、エージェントの隣に以下のファイルを追加します。<module>はプロジェクトのPythonモジュール、<agent>はエージェントコンポーネントのスネークケース名(デフォルトはagent)です:
Directory<your-project>/<module>/<agent>/
- agent.py ガードレール付きモデルで作成されたエージェント
- guardrail.json ガードレールが適用するルール
- guardrail.py ガードレールが適用されたBedrockモデルを定義
また、エージェントのiacプロバイダーのインフラストラクチャも追加します。<agent-name>はエージェントのコンストラクトまたはモジュールのケバブケース名です:
Directorypackages/common/constructs/src/app/guardrails/<agent-name>/
- <agent-name>-guardrail.ts ガードレールとそのバージョンを含むCDKコンストラクト
Directorypackages/common/terraform/src/app/guardrails/<agent-name>/
- <agent-name>-guardrail.tf ガードレールとそのバージョンを含むTerraformモジュール
ジェネレーターはagent.pyを次のように編集します:
from .guardrail import get_guardrailed_modelfrom .session import get_session_manager
@contextmanagerdef get_agent(): yield Agent( model=get_guardrailed_model(), name="MyAgent",get_guardrailed_model()は、Strands BedrockModelのサブクラスであるGuardrailedBedrockModelを返します。modelなしで作成されたAgentと同じデフォルトモデルを使用します。
from langchain_aws import ChatBedrockConversefrom langchain_core.tools import tool
from .guardrail import GuardrailedChatBedrockConversefrom .session import get_checkpointer
def get_agent(): model = ChatBedrockConverse(model=MODEL_ID, region_name=REGION) model = GuardrailedChatBedrockConverse(model=MODEL_ID, region_name=REGION)GuardrailedChatBedrockConverseはChatBedrockConverseのサブクラスです。ジェネレーターはChatBedrockConverse(...)呼び出しの引数を保持します。
同じエージェントでジェネレーターを再度実行してもファイルは変更されず、guardrail.jsonとguardrail.pyへの編集は保持されます。
エージェントがinfra: noneで生成された場合、ジェネレーターはエージェントファイルのみを追加し、警告を出力します。その後、ガードレールを自分で作成し、そのIDとバージョンをagentcore.guardrails.<AgentClass>のruntime configに{ guardrailId, guardrailVersion }として書き込みます。
別のプロジェクトのTypeScriptエージェントが同じクラス名を持ち、すでにガードレールを持っている場合、ジェネレーターはエラーで停止し、ファイルを変更しません。両方のエージェントが1つのランタイムコンストラクトと1つのガードレールを共有することになります。エージェントの1つに別の名前を付けてください。
すでにモデルを設定しているエージェント
Section titled “すでにモデルを設定しているエージェント”agent.pyが期待される形状でない場合、ジェネレーターはそれを変更せずに残します。ファイル名と追加する行を出力します。
これは、Agent(...)呼び出しがすでにmodelを設定している場合に発生します。独自のモデルオプションを保持するには、guardrail.pyのGuardrailedBedrockModelクラスでモデルを作成します。これはBedrockModelと同じオプションを取ります。例:
from .guardrail import GuardrailedBedrockModel
agent = Agent( model=GuardrailedBedrockModel(model_id="my-model-id"), # ...)これは、agent.pyにChatBedrockConverse(...)呼び出しがない場合に発生します。例えば、別の方法でモデルを作成している場合です。guardrail.pyのGuardrailedChatBedrockConverseクラスでモデルを作成します。これはChatBedrockConverseと同じ引数を取ります。例:
from .guardrail import GuardrailedChatBedrockConverse
model = GuardrailedChatBedrockConverse(model=MODEL_ID, region_name=REGION)ガードレールがチェックする内容
Section titled “ガードレールがチェックする内容”ガードレールは、すべてのモデル呼び出しで2つのことをチェックします:
- エージェントがモデルに送信する会話(ユーザーの最新メッセージを含む)
- エージェントがユーザーにストリーミングバックする前のモデルの回答
ガードレールがユーザーのメッセージをブロックすると、モデルは呼び出されません。ANONYMIZEルールが一致すると、回答には値の代わりに{EMAIL}などのプレースホルダーが含まれます。ガードレールが回答をブロックすると、ユーザーはblockedOutputsMessagingテキストを受け取ります。
ガードレールがユーザーのメッセージをブロックすると、ユーザーはblockedInputMessagingテキストを受け取ります。Strandsは、エージェントの会話履歴内のブロックされたメッセージを[User input redacted.]に置き換えます。
ガードレールがユーザーのメッセージをブロックすると、モデルの回答はblockedInputMessagingテキストになり、ユーザーはそのテキストを受け取ります。
同じセッション内の後のモデル呼び出しでは、guardrail.pyは、Strandsと同様に、ガードレールがブロックした各ユーザーメッセージの代わりに[User input redacted.]を送信します。ガードレールはすべての呼び出しで会話全体をチェックするため、これがないとブロックされたメッセージがセッション内の後のすべてのメッセージをブロックします。チェックポインターは元のメッセージを保存します。
ガードレールは、ツール定義、モデルがツールに渡す引数、またはツールが返す結果をチェックしません。例えば、ツールがデータベースから顧客のメールアドレスを返す場合、ガードレールはそれをモデルから隠しません。Python Agentガイドの「Securing your Agent」で説明されているように、ツールの結果を信頼できないものとして扱ってください。
guardrail.jsonの編集
Section titled “guardrail.jsonの編集”提供されるポリシーは、生成された数学エージェントの例です。投資アドバイスを拒否し、3種類の個人データを隠すかブロックします:
{ "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" } ]}フィールドは次のとおりです:
blockedInputMessaging:ガードレールがメッセージをブロックしたときにユーザーが受け取る返信。最大500文字。blockedOutputsMessaging:ガードレールがモデルの回答をブロックしたときにユーザーが受け取る返信。最大500文字。deniedTopics:エージェントが拒否する必要があるトピック。各トピックには、name(最大100文字の英字、数字、スペース、および文字-_!?.)、トピックを説明する最大1000文字のdefinition、およびオプションで各最大100文字のexamplesがあります。piiEntities:アクションを実行する個人データのタイプ。typeはEMAIL、PHONE、US_SOCIAL_SECURITY_NUMBERなどの機密情報タイプです。actionは、値をプレースホルダーに置き換えるANONYMIZE、またはメッセージまたは回答全体をブロックするBLOCKです。
トピックdefinitionは、トピック自体を説明するように記述してください。例えば、「Recommendations about which specific stocks to buy」は「Do not give investment advice」よりもうまく機能します。
バージョンが番号付けされている理由
Section titled “バージョンが番号付けされている理由”guardrail.jsonを変更してデプロイするたびに、インフラストラクチャは新しい番号付きガードレールバージョンを作成し、runtime configに書き込みます。バージョンの説明にはguardrail.jsonのSHA-256ハッシュが保持されるため、ファイルへの変更は説明を変更し、新しいバージョンが古いバージョンを置き換えます。CDKコンストラクトでは、ハッシュは渡すガードレールプロパティもカバーします。
実行中のエージェントは再起動する必要がありません。guardrail.pyはruntime configから読み取った内容を5秒間保持するため、エージェントはAppConfigデプロイメントの5秒以内に新しいバージョンを使用します。古いバージョンはAppConfigデプロイメント後に削除されます。CloudFormationはクリーンアップステップでそれを削除します。これは、ある測定(2026-10-24、us-east-1)では、デプロイメント完了後約7秒で開始されました。CloudFormationはその遅延を保証しません。Terraformは、デプロイメントモジュール後約15秒間古いバージョンを保持するため、5秒のキャッシュが削除されたバージョンを指すことはありません。これは、エージェントへのガードレールの配線で示されているように、ガードレールモジュールをそのモジュールのdepends_onに追加すると機能します。
エージェントはDRAFTバージョンを使用しません。DRAFTは常に最新のルールを保持するため、AWSコンソールで行われた編集は、デプロイメントなしで実行中のエージェントに到達します。runtime config内のバージョンがバージョン番号でない場合、guardrail.pyはエラーを発生させます。
エージェントへのガードレールの配線
Section titled “エージェントへのガードレールの配線”ジェネレーターは、py#agentジェネレーターがエージェントのデプロイをユーザーに任せるのと同じように、スタックまたはルートTerraformモジュールを変更しません。完了すると、エージェントの名前が入力された以下のコードを出力します。これを追加して、ガードレールを作成し、そのruntime configエントリを書き込み、エージェントがガードレールを適用できるようにします:
import { MyAgent, MyAgentGuardrail } from '@my-scope/common-constructs';
const agent = new MyAgent(this, 'MyAgent');new MyAgentGuardrail(this, 'MyAgentGuardrail', { agent });コンストラクトは、ガードレールのIDとバージョンをagentcore.guardrails.MyAgentのruntime configに書き込み、agentにガードレールを適用する権限を付与します。エージェントコンストラクトは、すでにエージェントがruntime configを読み取ることを許可しています。
コンストラクトは以下を公開します:
guardrail(CfnGuardrail)とversion(CfnGuardrailVersion)guardrailId、guardrailArn、guardrailVersiongrantApply(grantee):別のプリンシパルにガードレールに対するbedrock:ApplyGuardrailを付与します
また、GuardrailIdとGuardrailVersionのスタック出力も追加します。そのプロパティはagentと任意のCfnGuardrailプロパティです。CfnGuardrailプロパティはguardrail.jsonよりも優先されます。例えば、コンテンツフィルターを追加します:
new MyAgentGuardrail(this, 'MyAgentGuardrail', { agent, contentPolicyConfig: { filtersConfig: [ { type: 'HATE', inputStrength: 'HIGH', outputStrength: 'HIGH' }, ], },});ジェネレーターは、各CDKインフラストラクチャプロジェクトのsynth入力にguardrail.jsonも追加するため、ファイルへの変更はNxキャッシュを使用する代わりに合成を再度実行します。
エージェントをデプロイするルートモジュールに、示されているようにmy_agent_guardrailモジュールを追加します。既存のmy_agentモジュールブロックにadditional_iam_policy_statements行を追加します。runtime_config_appconfig_deploymentモジュールのdepends_onリストにmodule.my_agent_guardrailを追加して、デプロイメントにガードレールのruntime configエントリが含まれ、Terraformがデプロイメント後にのみ古いガードレールバージョンを削除するようにします。ルートモジュールがまだエージェントをデプロイしていない場合は、Python Agentガイドで説明されているように、最初にエージェントのモジュールを追加してください。
module "my_agent_guardrail" { source = "../../common/terraform/src/app/guardrails/my-agent"}
module "my_agent" { source = "../../common/terraform/src/app/agents/my-agent" # ...existing arguments... additional_iam_policy_statements = module.my_agent_guardrail.iam_policy_statements}
module "runtime_config_appconfig_deployment" { # ...existing arguments... depends_on = [ # ...existing modules... module.my_agent_guardrail, ]}エージェントモジュールがすでにadditional_iam_policy_statementsを設定している場合は、リストを結合します:
additional_iam_policy_statements = concat(module.my_agent_guardrail.iam_policy_statements, local.my_statements)モジュールは、ガードレールのIDとバージョンをagentcore.guardrails.MyAgentのruntime configに書き込みます。agentcore名前空間は、runtime configモジュールのデフォルトのnamespacesにあるため、追加する必要はありません。エージェントモジュールは、すでにエージェントがruntime configを読み取ることを許可しています。
モジュールはtags変数を取り、guardrail_id、guardrail_arn、guardrail_version、iam_policy_statementsを出力します。コンテンツフィルターなどの他のガードレールポリシーを追加するには、モジュール内のaws_bedrock_guardrailリソースを編集します。
モジュールは、ガードレールバージョンにcreate_before_destroyを設定するため、Terraformは古いバージョンを削除する前に新しいバージョンを作成します。hashicorp/timeプロバイダーのtime_sleepリソースは、runtime configデプロイメント後約15秒間古いバージョンを保持し、runtime configエントリはそこからガードレールIDとバージョンを読み取ります。この待機のため、terraform destroyも約15秒長くかかります。
runtime configエントリの欠落
Section titled “runtime configエントリの欠落”配線を忘れると、runtime configにエージェントのエントリがありません。その後、モデルはBedrockを呼び出す前にエラーを発生させるため、エージェントはガードレールなしでは実行されません。MyAgentの場合、エラーは次のとおりです:
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.エージェントはすべてのプロトコル(http、a2a、ag-ui)で起動し、各リクエストはこのエラーで失敗します。エージェントがruntime configをまったく読み取れない場合(例えば、RUNTIME_CONFIG_APP_IDが設定されていない場合)、各リクエストは代わりにエージェントのruntime configリーダーからのエラーで失敗します。
httpプロトコルでは、モデルがエラーを発生させたときにエージェントはすでに応答のストリーミングを開始しています。その後、呼び出し元は回答を受け取らず、エラーはエージェントのログにのみ表示されます。デプロイされたエージェントの場合は、そのランタイムログループに表示されます。
ローカル開発
Section titled “ローカル開発”<agent>-devターゲットはLOCAL_DEV=trueを設定します。LOCAL_DEVがtrueで、RUNTIME_CONFIG_APP_ID環境変数が設定されていない場合、guardrail.pyはruntime configを読み取りません。警告を一度ログに記録し、エージェントはガードレールなしで実行されます:
pnpm nx agent-dev your-projectyarn nx agent-dev your-projectnpx nx agent-dev your-projectbunx nx agent-dev your-projectルールをローカルでテストするには、最初にガードレールをデプロイします。次に、RUNTIME_CONFIG_APP_IDを、RuntimeConfigApplicationIdスタック出力(CDK)またはmodule.runtime_config_appconfig.application_id(Terraform)から、デプロイされたruntime configアプリケーションのIDに設定します。シェルには、AppConfigを読み取り、ガードレールを適用できるAWS認証情報も必要です:
RUNTIME_CONFIG_APP_ID=<application-id> pnpm nx agent-dev your-projectRUNTIME_CONFIG_APP_ID=<application-id> yarn nx agent-dev your-projectRUNTIME_CONFIG_APP_ID=<application-id> npx nx agent-dev your-projectRUNTIME_CONFIG_APP_ID=<application-id> bunx nx agent-dev your-projectその後、エージェントは自身のエントリのみを読み取るため、複数の保護されたエージェントが同じアプリケーションに対してローカルで実行できます。エージェントがruntime configを読み取れない場合、またはエントリが欠落している場合、警告を一度ログに記録し、ガードレールなしで実行されます。
<agent>-serveターゲットはLOCAL_DEVを設定しないため、RUNTIME_CONFIG_APP_IDとデプロイされたエントリが必要です。そうでない場合、各リクエストは上記のように失敗します。<agent>-chatターゲットは実行中のエージェントに接続し、runtime config自体は必要ありません。
コストとレイテンシー
Section titled “コストとレイテンシー”Amazon Bedrockは、入力と回答の両方でテキストを評価する各ガードレールポリシーに対して課金します。Amazon Bedrock pricingを参照してください。
各モデル呼び出しも、ガードレールがエージェントがユーザーにストリーミングする前に回答をチェックするため、時間がかかります。
リクエストが到着している間、各エージェントプロセスは5秒ごとに最大1回runtime configを読み取ります。各読み取りは2つのAppConfigリクエストを行います。
- このジェネレーターは、StrandsおよびLangChainフレームワークを使用して
py#agentで作成されたエージェントをサポートします。AgentCore Harnessはサポートしていません。 guardrail.jsonは、拒否されたトピックとPIIエンティティのみを保持します。コンテンツフィルターやワードフィルターなどの他のポリシーは、コンストラクトのプロパティ(CDK)を使用するか、モジュールを編集(Terraform)して追加します。- ガードレールは、ガードレールがチェックする内容で説明されているように、ツールの結果をチェックしません。