Skip to content

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からエージェントのエントリを読み取り、そのガードレールをリクエストに追加します。

py#agentジェネレーターで作成されたエージェントを含む既存のPythonプロジェクトが必要です。

このジェネレーターを実行@aws/nx-plugin:py#agent#guardrails

pnpm nx g @aws/nx-plugin:py#agent#guardrails
コマンドを組み立てる2

必須

ジェネレーターオプション2 オプション
project必須string

Python Agentを含むプロジェクト

agentstring

ガードするAgentコンポーネントの名前。プロジェクトに複数のPython Agentが含まれている場合は必須です。

ジェネレーターは、エージェントの隣に以下のファイルを追加します。<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コンストラクト

ジェネレーターはagent.pyを次のように編集します:

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()は、Strands BedrockModelのサブクラスであるGuardrailedBedrockModelを返します。modelなしで作成されたAgentと同じデフォルトモデルを使用します。

同じエージェントでジェネレーターを再度実行してもファイルは変更されず、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と同じオプションを取ります。例:

agent.py
from .guardrail import GuardrailedBedrockModel
agent = Agent(
model=GuardrailedBedrockModel(model_id="my-model-id"),
# ...
)

ガードレールがチェックする内容

Section titled “ガードレールがチェックする内容”

ガードレールは、すべてのモデル呼び出しで2つのことをチェックします:

  • エージェントがモデルに送信する会話(ユーザーの最新メッセージを含む)
  • エージェントがユーザーにストリーミングバックする前のモデルの回答

ガードレールがユーザーのメッセージをブロックすると、モデルは呼び出されません。ANONYMIZEルールが一致すると、回答には値の代わりに{EMAIL}などのプレースホルダーが含まれます。ガードレールが回答をブロックすると、ユーザーはblockedOutputsMessagingテキストを受け取ります。

ガードレールがユーザーのメッセージをブロックすると、ユーザーはblockedInputMessagingテキストを受け取ります。Strandsは、エージェントの会話履歴内のブロックされたメッセージを[User input redacted.]に置き換えます。

ガードレールは、ツール定義、モデルがツールに渡す引数、またはツールが返す結果をチェックしません。例えば、ツールがデータベースから顧客のメールアドレスを返す場合、ガードレールはそれをモデルから隠しません。Python Agentガイドの「Securing your Agent」で説明されているように、ツールの結果を信頼できないものとして扱ってください。

提供されるポリシーは、生成された数学エージェントの例です。投資アドバイスを拒否し、3種類の個人データを隠すかブロックします:

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

フィールドは次のとおりです:

  • 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エントリを書き込み、エージェントがガードレールを適用できるようにします:

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 });

コンストラクトは、ガードレールのIDとバージョンをagentcore.guardrails.MyAgentのruntime configに書き込み、agentにガードレールを適用する権限を付与します。エージェントコンストラクトは、すでにエージェントがruntime configを読み取ることを許可しています。

コンストラクトは以下を公開します:

  • guardrail(CfnGuardrail)とversion(CfnGuardrailVersion)
  • guardrailId、guardrailArn、guardrailVersion
  • grantApply(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キャッシュを使用する代わりに合成を再度実行します。

配線を忘れると、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プロトコルでは、モデルがエラーを発生させたときにエージェントはすでに応答のストリーミングを開始しています。その後、呼び出し元は回答を受け取らず、エラーはエージェントのログにのみ表示されます。デプロイされたエージェントの場合は、そのランタイムログループに表示されます。

<agent>-devターゲットはLOCAL_DEV=trueを設定します。LOCAL_DEVがtrueで、RUNTIME_CONFIG_APP_ID環境変数が設定されていない場合、guardrail.pyはruntime configを読み取りません。警告を一度ログに記録し、エージェントはガードレールなしで実行されます:

Terminal window
pnpm nx agent-dev your-project

ルールをローカルでテストするには、最初にガードレールをデプロイします。次に、RUNTIME_CONFIG_APP_IDを、RuntimeConfigApplicationIdスタック出力(CDK)またはmodule.runtime_config_appconfig.application_id(Terraform)から、デプロイされたruntime configアプリケーションのIDに設定します。シェルには、AppConfigを読み取り、ガードレールを適用できるAWS認証情報も必要です:

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

その後、エージェントは自身のエントリのみを読み取るため、複数の保護されたエージェントが同じアプリケーションに対してローカルで実行できます。エージェントがruntime configを読み取れない場合、またはエントリが欠落している場合、警告を一度ログに記録し、ガードレールなしで実行されます。

<agent>-serveターゲットはLOCAL_DEVを設定しないため、RUNTIME_CONFIG_APP_IDとデプロイされたエントリが必要です。そうでない場合、各リクエストは上記のように失敗します。<agent>-chatターゲットは実行中のエージェントに接続し、runtime config自体は必要ありません。

Amazon Bedrockは、入力と回答の両方でテキストを評価する各ガードレールポリシーに対して課金します。Amazon Bedrock pricingを参照してください。

各モデル呼び出しも、ガードレールがエージェントがユーザーにストリーミングする前に回答をチェックするため、時間がかかります。

リクエストが到着している間、各エージェントプロセスは5秒ごとに最大1回runtime configを読み取ります。各読み取りは2つのAppConfigリクエストを行います。

  • このジェネレーターは、StrandsおよびLangChainフレームワークを使用してpy#agentで作成されたエージェントをサポートします。AgentCore Harnessはサポートしていません。
  • guardrail.jsonは、拒否されたトピックとPIIエンティティのみを保持します。コンテンツフィルターやワードフィルターなどの他のポリシーは、コンストラクトのプロパティ(CDK)を使用するか、モジュールを編集(Terraform)して追加します。
  • ガードレールは、ガードレールがチェックする内容で説明されているように、ツールの結果をチェックしません。