Aller au contenu

Python Agent

Générez un agent IA Python pour construire des agents avec des outils, et déployez-le optionnellement sur Amazon Bedrock AgentCore Runtime. Choisissez le framework d’agent avec l’option framework : Strands (par défaut) ou LangChain (construit sur LangGraph).

Le générateur expose votre agent via un protocol de serveur. Les deux frameworks supportent HTTP (par défaut), le protocole Agent-to-Agent (A2A) pour l’interopérabilité avec d’autres agents compatibles A2A, et le protocole AG-UI pour l’intégration directe avec le frontend via CopilotKit.

Vous pouvez générer un Agent Python de deux manières :

Exécuter ce générateur@aws/nx-plugin:py#agent

pnpm nx g @aws/nx-plugin:py#agent
Composez votre commande9

Requis

infra = agentcore | agentcore-ecr

Options du générateur9 options
projectRequisstring

Le projet auquel ajouter l'Agent

frameworkenumPar défaut: strands

Le SDK d'agent à utiliser.

strandslangchain
authenuminfra = agentcore | agentcore-ecrPar défaut: iam

La méthode utilisée pour s'authentifier auprès de votre Agent. Applicable uniquement lorsque infra est défini (ignoré lorsque infra est none).

iamcognito
protocolenumPar défaut: http

Le protocole serveur pour votre Agent. HTTP expose un serveur HTTP FastAPI. A2A expose un serveur de protocole Agent-to-Agent. AG-UI expose un serveur de protocole Agent-User Interaction pour l'intégration directe avec le frontend.

httpa2aag-ui
iacenumPar défaut: inherit

Le fournisseur IaC préféré. Par défaut, ceci est hérité de votre sélection initiale.

inheritcdkterraform
infraenumPar défaut: agentcore

Le type d'infrastructure pour héberger votre Agent. agentcore déploie votre code sous forme de zip vers un runtime géré par AgentCore pour le cycle de build et déploiement le plus rapide. agentcore-ecr construit et héberge une image conteneur à la place, pour un contrôle au niveau de l'OS ou un pipeline de conteneurs établi.

agentcoreagentcore-ecrnone
sessionenumPar défaut: s3

Le stockage utilisé pour persister la session de votre Agent. LangChain prend en charge 's3' ou 'dynamodb-s3' ; Strands prend en charge 's3' ; 'in-memory' est valide pour les deux.

s3dynamodb-s3in-memory
namestring

Le nom de votre Agent (par défaut : agent)

preferInstallDependenciesbooleanPar défaut: true

Indique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir sur false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin.

Le générateur ajoutera les fichiers suivants à votre projet Python existant. Les fichiers générés dépendent du protocol choisi :

protocol = http
  • Répertoireyour-project/
    • Répertoireyour_module/
      • Répertoireagent/ (or custom name if specified)
        • __init__.py Python package initialization
        • init.py FastAPI application setup with CORS and error handling middleware
        • agent.py Main agent definition with sample tools
        • session.py Resolves the framework-specific session persistence implementation
        • Répertoiremiddleware/
          • __init__.py Python package initialization
          • session_id_middleware.py Binds the inbound AgentCore session ID for the request
        • main.py FastAPI entry point for Bedrock AgentCore Runtime
        • Dockerfile Container image definition (only when infra is agentcore-ecr)
    • pyproject.toml Updated with Strands dependencies
    • project.json Updated with agent serve targets
protocol = a2a

Le point d’entrée expose votre agent via le protocole A2A (Strands utilise le Strands A2A Server ; LangChain enveloppe le graphe dans un exécuteur a2a-sdk), monté sur une application FastAPI :

  • Répertoireyour-project/
    • Répertoireyour_module/
      • Répertoireagent/ (or custom name if specified)
        • __init__.py Python package initialization
        • agent.py Main agent definition with sample tools
        • session.py Resolves the framework-specific session persistence implementation
        • Répertoiremiddleware/
          • __init__.py Python package initialization
          • session_id_middleware.py Binds the inbound AgentCore session ID for the request
        • main.py A2A server entry point
        • Dockerfile Container image definition (only when infra is agentcore-ecr)
    • pyproject.toml Updated with framework and A2A dependencies
    • project.json Updated with agent serve targets
protocol = ag-ui

Le point d’entrée expose votre agent via le protocole AG-UI pour l’intégration directe avec le frontend via CopilotKit. Les agents Strands utilisent l’intégration ag-ui-strands ; les agents LangChain utilisent ag-ui-langgraph :

  • Répertoireyour-project/
    • Répertoireyour_module/
      • Répertoireagent/ (or custom name if specified)
        • __init__.py Python package initialization
        • agent.py Main agent definition with sample tools
        • session.py Resolves the framework-specific session persistence implementation
        • Répertoiremiddleware/
          • __init__.py Python package initialization
          • session_id_middleware.py Binds the inbound AgentCore session ID for the request
        • main.py AG-UI server entry point
        • Dockerfile Container image definition (only when infra is agentcore-ecr)
    • pyproject.toml Updated with framework and AG-UI dependencies
    • project.json Updated with agent serve targets

L’option infra sélectionne la manière dont votre code est empaqueté et hébergé sur Amazon Bedrock AgentCore Runtime :

  • agentcore (par défaut) utilise le déploiement direct de code : votre code compilé est empaqueté sous forme de .zip, téléchargé vers S3, et exécuté sur un runtime de langage géré par AgentCore. Il n’y a pas d’image de conteneur à construire, pas de dépôt ECR à gérer, et pas d’image à pousser, ce qui permet un cycle de construction et de déploiement nettement plus rapide.
  • agentcore-ecr construit une image de conteneur arm64 à partir d’un Dockerfile fourni et l’héberge depuis le registre partagé core/asset-ecr, aux côtés de tous les autres conteneurs de l’espace de travail. Choisissez cette option lorsque vous avez besoin de contrôler l’image du système d’exploitation — par exemple pour installer des bibliothèques système natives — ou lorsque vous disposez d’un pipeline de conteneurs établi. Cette option fournit également une cible d’analyse d’image Trivy (voir Analyse d’image ci-dessous).
  • none ne génère aucune infrastructure, de sorte que le projet ne peut être exécuté que localement.
infra = agentcore | agentcore-ecr

Étant donné que ce générateur fournit de l’infrastructure en tant que code basée sur votre iac choisi, il créera un projet dans packages/common qui inclut les constructs CDK ou modules Terraform pertinents.

Le projet d’infrastructure en tant que code commun est structuré comme suit :

  • Répertoirepackages/common/constructs
    • Répertoiresrc
      • Répertoireapp/ Constructs pour l’infrastructure spécifique à un projet/générateur
      • Répertoirecore/ Constructs génériques qui sont réutilisés par les constructs dans app
      • index.ts Entry point exporting constructs from app
    • project.json Project build targets and configuration

Pour déployer votre Agent, les fichiers suivants sont générés :

  • Répertoirepackages/common/constructs/src
    • Répertoireapp
      • Répertoireagents
        • Répertoire<agent-name>
          • <agent-name>.ts CDK construct for deploying your agent
infra = none

Si vous avez sélectionné none pour infra, aucune construction CDK ou module Terraform n’est généré — l’Agent ne peut être exécuté que localement. L’option auth est ignorée dans ce mode car il n’y a pas de point de terminaison hébergé à authentifier.

Lorsqu’il est déployé sur Bedrock AgentCore Runtime, le code de votre agent est empaqueté sous forme de zip et exécuté dans le runtime géré AgentCore. Les clients invoquent le point de terminaison du plan de données AgentCore Runtime, qui transmet les requêtes à votre agent. L’agent appelle Amazon Bedrock pour l’inférence du modèle et peut invoquer des outils, des serveurs MCP ou des API en aval.

Loading the diagram…

Vous pouvez éditer agent.py pour ajouter des outils, configurer le modèle et personnaliser le prompt système. L’API dépend du framework que vous avez choisi.

Les outils sont des fonctions que l’agent IA peut appeler pour effectuer des actions. Les deux frameworks utilisent une approche basée sur des décorateurs pour définir les outils, dérivent le nom et la description de l’outil à partir du nom de la fonction et de la docstring, et génèrent le schéma d’entrée à partir de vos annotations de type.

Définissez l’outil, puis ajoutez-le à la liste tools dans get_agent() :

packages/my-project/my_module/agent/agent.py
from contextlib import contextmanager
from strands import Agent, tool
from strands.hooks import HookCallback, HookProvider
from strands_tools import current_time
from my_scope_agent_connection import log_model_errors, log_tool_errors
from .session import get_session_manager
@tool
def subtract(a: int, b: int) -> int:
return a - b
@tool
def get_weather(city: str) -> str:
"""Get weather information for a city"""
# Your weather API integration here
return f"Weather in {city}: Sunny, 25°C"
AGENT_HOOKS: list[HookProvider | HookCallback] = [log_model_errors, log_tool_errors]
@contextmanager
def get_agent():
yield Agent(
name="MyAgent",
description="MyAgent Strands Agent",
system_prompt="You are a helpful assistant with access to various tools.",
tools=[subtract, current_time, get_weather],
hooks=AGENT_HOOKS,
session_manager=get_session_manager(),
)

Strands fournit une collection d’outils pré-construits via le package strands-agents-tools, que le générateur ajoute déjà au pyproject.toml de votre projet. Importez les outils que vous souhaitez et ajoutez-les à get_agent() :

packages/my-project/my_module/agent/agent.py
from strands_tools import current_time, file_read, http_request
# ...
@contextmanager
def get_agent():
yield Agent(
name="MyAgent",
description="MyAgent Strands Agent",
system_prompt="You are a helpful assistant.",
tools=[current_time, file_read, http_request],
hooks=AGENT_HOOKS,
session_manager=get_session_manager(),
)

L’agent généré utilise le modèle Strands par défaut sur Amazon Bedrock. Pour le configurer, passez un model à l’Agent. Consultez la documentation Strands sur les fournisseurs de modèles pour les fournisseurs disponibles et leurs options :

packages/my-project/my_module/agent/agent.py
from strands.models import BedrockModel
# ...
MODEL = BedrockModel(
model_id="anthropic.claude-sonnet-4-20250514-v1:0",
region_name="us-west-2",
temperature=0.3,
)
@contextmanager
def get_agent():
yield Agent(
model=MODEL,
name="MyAgent",
description="MyAgent Strands Agent",
system_prompt="You are a helpful assistant.",
tools=[subtract, current_time],
hooks=AGENT_HOOKS,
session_manager=get_session_manager(),
)

Pour consommer des serveurs MCP que vous avez créés en utilisant les générateurs py#mcp-server ou ts#mcp-server, vous pouvez utiliser le générateur connection, qui intègre les outils du serveur MCP dans votre agent pour les deux frameworks.

Exécuter ce générateur@aws/nx-plugin:connection

pnpm nx g @aws/nx-plugin:connection
Composez votre commande5

Requis

Requis

Consultez le guide du générateur connection pour plus de détails sur la configuration de la connexion.

Pour d’autres serveurs MCP, consultez la documentation MCP de Strands ou LangChain.

Pour un guide plus approfondi sur l’écriture d’agents, consultez la documentation de Strands ou LangChain.

Le protocole serveur de votre agent détermine comment il communique. Toutes les options sont servies par FastAPI — le point d’entrée diffère :

  • HTTP (par défaut) : Un serveur FastAPI standard avec un point de terminaison /invocations personnalisé, CORS et streaming. Idéal pour les intégrations client personnalisées.
  • A2A : Un serveur Agent-to-Agent monté sur une application FastAPI (Strands utilise le Strands A2A Server ; LangChain utilise le a2a-sdk agnostique du framework). Idéal lorsque votre agent doit être découvrable et invocable par d’autres agents compatibles A2A.
  • AG-UI : Le protocole AG-UI via SSE (Strands utilise ag-ui-strands ; LangChain utilise ag-ui-langgraph). Idéal pour l’intégration directe avec le frontend via CopilotKit dans un site web React.

Le point d’entrée du serveur diffère selon le framework (Strands produit un Agent géré par contexte, tandis que LangChain pilote un graphe create_agent compilé), mais le contrat externe pour chaque protocole est le même.

Tous les protocoles exposent /ping pour le contrat de vérification de santé du runtime AgentCore. Les agents A2A écoutent sur le port 9000 ; les agents HTTP et AG-UI écoutent sur le port 8080. L’infrastructure générée est configurée pour vous.

protocol = http

Le serveur HTTP généré inclut :

  • Configuration de l’application FastAPI avec middleware CORS
  • Middleware de gestion des erreurs
  • Génération de schéma OpenAPI
  • Point de terminaison de vérification de santé (/ping)
  • Point de terminaison d’invocation de l’agent (/invocations)

Personnaliser les entrées et sorties d’invocation avec Pydantic

Section intitulée « Personnaliser les entrées et sorties d’invocation avec Pydantic »

Le point de terminaison d’invocation de l’agent utilise des modèles Pydantic pour définir et valider les schémas de requête et de réponse. Vous pouvez personnaliser ces modèles dans main.py pour correspondre aux exigences de votre agent.

Le modèle InvokeInput par défaut accepte un prompt.

from pydantic import BaseModel, Field
class InvokeInput(BaseModel):
prompt: str = Field(max_length=100000)

Vous pouvez étendre ce modèle pour inclure tous les champs supplémentaires dont votre agent a besoin.

L’identifiant de session est extrait de l’en-tête HTTP x-amzn-bedrock-agentcore-runtime-session-id, conformément au contrat de session Bedrock AgentCore Runtime. Si l’en-tête n’est pas fourni, un UUID aléatoire est généré comme solution de repli.

Pour les réponses en streaming, le générateur fournit JsonStreamingResponse qui sérialise automatiquement les modèles Pydantic au format JSON Lines (application/jsonl). Ce format est compatible avec la spécification de streaming d’OpenAPI 3.2 et fonctionne de manière transparente avec le client TypeScript généré.

Par défaut, l’agent produit des objets StreamChunk contenant le texte de réponse de l’agent :

class StreamChunk(BaseModel):
content: str

Vous pouvez personnaliser le modèle StreamChunk selon vos besoins :

from pydantic import BaseModel
class StreamChunk(BaseModel):
content: str
timestamp: str
token_count: int

Il existe une demande de fonctionnalité ouverte pour le support natif dans FastAPI.

Le générateur inclut une dépendance au SDK Python Bedrock AgentCore pour les constantes PingStatus. Si vous le souhaitez, il est simple d’utiliser BedrockAgentCoreApp au lieu de FastAPI, mais notez que la sécurité des types est perdue.

Vous pouvez trouver plus de détails sur les capacités du SDK dans la documentation ici.

protocol = a2a

Le main.py généré monte un serveur A2A sur une application FastAPI parente qui expose également /ping. Les agents Strands utilisent le A2AServer de Strands ; les agents LangChain enveloppent le graphe compilé dans un AgentExecutor a2a-sdk. L’URL annoncée dans la carte d’agent provient de la variable d’environnement AGENTCORE_RUNTIME_URL, avec un repli sur http://localhost:<port>/ pour le développement local.

La plupart des utilisateurs n’auront pas besoin de modifier ce fichier ; éditez agent.py pour changer les outils ou le prompt système. Le serveur A2A remplit la carte d’agent (/.well-known/agent-card.json) à partir du name et de la description de l’agent.

protocol = ag-ui

Le main.py généré expose un seul point de terminaison POST qui diffuse des événements AG-UI via Server-Sent Events (SSE), ainsi que /ping pour la vérification de santé du runtime AgentCore. Le câblage dépend du framework :

  • Strands : enveloppe votre Agent dans un ag_ui_strands.StrandsAgent, construit à l’intérieur d’un gestionnaire lifespan FastAPI (de sorte que la construction se produit au démarrage du conteneur/session plutôt qu’au moment de l’importation), et servi à partir d’une boucle /invocations FastAPI faite à la main.
  • LangChain : enveloppe le graphe compilé dans un ag_ui_langgraph.LangGraphAgent, construit de la même manière à l’intérieur de lifespan, et servi à partir d’une boucle /invocations FastAPI faite à la main.

La plupart des utilisateurs n’auront pas besoin de modifier ce fichier — éditez agent.py pour changer les outils ou le prompt système.

Pour exécuter votre Agent (et tout ce qui y est connecté) localement, utilisez la cible dev du projet :

Terminal window
pnpm nx dev your-project

Si vous avez ajouté plusieurs composants à votre projet (agents, serveurs MCP, etc.), cela les démarre tous. Pour exécuter uniquement cet agent, ciblez sa cible <your-agent-name>-dev :

Terminal window
pnpm nx agent-dev your-project

Cela utilise uv run pour exécuter votre Agent en utilisant le SDK Python Bedrock AgentCore.

L’agent écoute sur un port attribué à partir du pool de l’espace de travail lors de sa génération. Lisez-le depuis metadata.ports dans le project.json du projet, ou depuis le flag --port dans la commande de la cible <your-agent-name>-dev. Les exemples ci-dessous utilisent 8081, le port attribué à un premier agent HTTP dans un espace de travail neuf.

Une cible <your-agent-name>-serve est également générée, qui exécute l’agent contre votre infrastructure déployée et nécessite donc que RUNTIME_CONFIG_APP_ID soit défini. Consultez le guide Développement local pour la différence entre dev et serve.

Le générateur configure une cible Nx <your-agent-name>-chat qui vous place dans un chat terminal interactif avec votre agent.

La cible de chat s’exécute de manière autonome. Par défaut, elle se connecte à votre agent en cours d’exécution localement, donc démarrez d’abord la cible <your-agent-name>-dev de l’agent (dans un terminal séparé) :

Terminal window
pnpm nx agent-dev your-project

Ensuite, dans un autre terminal, démarrez le chat :

Terminal window
pnpm nx run your-project:agent-chat

Le générateur émet un scripts/<your-agent-name>/chat.ts pour chaque protocole. Il se connecte à l’agent local par défaut, ou à votre agent déployé lorsque RUNTIME_CONFIG_APP_ID est défini (voir Discuter avec votre agent déployé ci-dessous).

protocol = http

Pour les agents HTTP, le script de chat utilise un client TypeScript type-safe généré à partir de la spécification OpenAPI de l’agent. Le générateur émet également :

  • scripts/<your_agent_name>_openapi.py — un petit script qui exporte la spécification OpenAPI de l’agent (nommé avec le nom de votre agent en snake_case)
  • Une cible Nx <your-agent-name>-openapi qui l’exécute
  • Une cible Nx <your-agent-name>-generate-client qui produit un client TypeScript type-safe sous scripts/<your-agent-name>/generated/

Lorsque vous personnalisez la forme d’entrée de l’agent (par exemple, ajoutez de nouveaux champs à InvokeInput), mettez à jour chat.ts pour passer les nouveaux champs lors de l’invocation de l’agent et le reste fonctionne automatiquement.

infra = agentcore | agentcore-ecr

Pour discuter avec votre agent déployé sur Bedrock AgentCore, définissez la variable d’environnement RUNTIME_CONFIG_APP_ID sur l’identifiant d’application AppConfig du déploiement (sortie en tant que RuntimeConfigApplicationId par la pile déployée). Le script de chat résout l’ARN du runtime de votre agent à partir de la configuration du runtime et se connecte au point de terminaison déployé :

Pour les agents authentifiés par IAM, les requêtes sont signées avec SigV4 en utilisant vos informations d’identification AWS par défaut. Assurez-vous que l’environnement dispose d’informations d’identification AWS avec la permission d’invoquer le runtime :

Terminal window
RUNTIME_CONFIG_APP_ID=<app-id> pnpm nx run your-project:agent-chat
infra = agentcore | agentcore-ecr

Déployer votre Agent sur Bedrock AgentCore Runtime

Section intitulée « Déployer votre Agent sur Bedrock AgentCore Runtime »

Si vous avez sélectionné agentcore ou agentcore-ecr pour infra, l’infrastructure CDK ou Terraform pertinente est générée et vous pouvez l’utiliser pour déployer votre Agent sur Amazon Bedrock AgentCore Runtime.

Un construct CDK est généré pour votre agent, nommé en fonction du name que vous avez choisi lors de l’exécution du générateur, ou <ProjectName>Agent par défaut.

Vous pouvez utiliser ce construct CDK dans une application CDK :

import { MyProjectAgent } from '@my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
new MyProjectAgent(this, 'MyProjectAgent');
}
}

Le générateur fournit une option auth pour configurer l’authentification de votre Agent. Vous pouvez choisir entre l’authentification IAM (par défaut) ou Cognito lors de la génération de votre agent.

Par défaut, votre Agent sera sécurisé en utilisant l’authentification IAM, déployez-le simplement sans aucun argument :

import { MyProjectAgent } from '@my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
new MyProjectAgent(this, 'MyProjectAgent');
}
}

Vous pouvez accorder l’accès pour invoquer votre agent sur Bedrock AgentCore Runtime en utilisant la méthode grantInvokeAccess, par exemple :

import { MyProjectAgent } from '@my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
const agent = new MyProjectAgent(this, 'MyProjectAgent');
const lambdaFunction = new Function(this, ...);
agent.grantInvokeAccess(lambdaFunction);
}
}

Lorsque vous sélectionnez l’authentification Cognito, le générateur configure l’agent pour utiliser Cognito pour l’authentification.

Le construct généré accepte une prop identity qui configure l’authentification Cognito :

import { MyProjectAgent, UserIdentity } from '@my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
const identity = new UserIdentity(this, 'Identity');
new MyProjectAgent(this, 'MyProjectAgent', {
identity,
});
}
}

Le construct UserIdentity peut être généré en utilisant le générateur ts#website#auth, ou vous pouvez créer votre propre UserPool et UserPoolClient CDK.

Afin de construire votre Agent pour Bedrock AgentCore Runtime, une cible bundle est ajoutée à votre projet, qui :

  • Exporte vos dépendances Python vers un fichier requirements.txt en utilisant uv export
  • Installe les dépendances pour la plateforme cible (aarch64-manylinux_2_28) en utilisant uv pip install
infra = agentcore

Une cible <your-agent-name>-package est également ajoutée, qui assemble le package de code déployable : le bundle de dépendances aarch64, votre arborescence de modules Python et un point d’entrée main.py racine. L’infrastructure générée télécharge ce répertoire sous forme de .zip — via AgentRuntimeArtifact.fromCodeAsset sous CDK, ou archivé dans le bucket d’actifs partagé sous Terraform.

infra = agentcore-ecr

Une cible docker spécifique à votre Agent est également ajoutée, qui copie le Dockerfile et les artefacts groupés dans un répertoire de contexte docker. Cela co-localise le Dockerfile avec la sortie construite, permettant à CDK de construire l’image Docker directement en utilisant AgentRuntimeArtifact.fromAsset.

L’image Docker construite pour ce projet peut être analysée pour détecter les vulnérabilités à l’aide de Trivy, exécuté depuis l’image Trivy hébergée sur ECR.

Une cible trivy est ajoutée à votre projet qui analyse l’image construite et se termine avec un code non nul si une vulnérabilité de gravité HIGH ou CRITICAL est trouvée. Le Dockerfile généré utilise une image de base sans vulnérabilité corrigeable connue de ces gravités au moment de la génération, et met à niveau les outils fournis (tels que npm) pour maintenir cet état.

L’analyse utilise le même moteur de conteneur que votre construction d’image (docker ou finch), donc aucun outillage supplémentaire n’est requis. L’analyse n’est pas mise en cache, car l’image qu’elle lit se trouve dans le moteur de conteneur plutôt que sur le disque — elle analyse donc toujours l’image réelle et échoue bruyamment plutôt que de signaler un succès mis en cache pour une image qui n’est plus là. Chaque exécution prend donc des dizaines de secondes par image et actualise la base de données de vulnérabilités de Trivy, elle nécessite donc un accès réseau. Le script racine trivy fourni analyse chaque image dans l’espace de travail :

Terminal window
pnpm trivy

Il peut y avoir des cas où vous souhaitez supprimer une vulnérabilité spécifique, par exemple lorsqu’aucun correctif n’est encore disponible et que vous avez évalué le risque comme acceptable.

Ajoutez l’ID de vulnérabilité (un par ligne) au fichier .trivyignore à la racine de votre projet (c’est-à-dire à côté de votre project.json) :

.trivyignore
# node-tar arbitrary file write - not exploitable in our usage
CVE-2024-XXXXX

Pour plus de détails sur le filtrage des résultats, consultez la documentation de filtrage Trivy.

Votre agent est automatiquement configuré avec l’observabilité en utilisant l’AWS Distro for Open Telemetry (ADOT).

Vous pouvez trouver les traces dans la console AWS CloudWatch, en sélectionnant “GenAI Observability” dans le menu. Notez que pour que les traces soient remplies, vous devrez activer Transaction Search.

Pour plus de détails, consultez la documentation AgentCore sur l’observabilité.

L’option session correspond à un concept de persistance sous-jacent différent selon le framework que vous avez choisi : le concept de gestion de session de Strands pour le framework strands, ou le concept de checkpointer de LangGraph pour le framework langchain.

framework = strands

L’option session contrôle comment votre agent persiste l’état de conversation (historique des messages, état des outils, etc.) entre les invocations, en utilisant le SessionManager du SDK Strands :

  • s3 (par défaut) : L’infrastructure CDK/Terraform provisionne un bucket S3 dédié pour les données de session, chiffré avec une clé KMS dédiée et avec tout accès public bloqué ; les journaux d’accès au serveur sont livrés à un groupe de journaux CloudWatch Logs via la même clé. Le rôle IAM de l’agent se voit accorder un accès en lecture/écriture/liste/suppression au bucket et un accès decrypt/generate-data-key à la clé, et le nom du bucket est enregistré aux côtés de l’ARN de l’agent dans la configuration du runtime AppConfig.
  • in-memory : Aucun bucket n’est provisionné. L’état de conversation est conservé en mémoire uniquement pendant la durée de vie du processus en cours d’exécution et ne survit pas aux redémarrages ou à la réduction d’échelle.

Ceci est implémenté dans le session.py généré, qui exporte une fonction get_session_manager() résolvant un SessionManager pour la session actuelle.

L’identifiant de session lui-même provient de la session AgentCore Runtime (propagée via l’en-tête x-amzn-bedrock-agentcore-runtime-session-id) et est lié à un contexte basé sur contextvars.ContextVar afin que get_current_session_id() puisse le résoudre n’importe où dans la requête — y compris dans tous les clients MCP ou A2A en aval câblés via le générateur connection, de sorte que toute la chaîne d’appels partage une session cohérente.

L’identifiant de session provient de l’appelant, donc en soi il identifie une conversation mais pas à qui appartient la conversation. AgentCore Runtime autorise une invocation contre l’ARN de ressource du runtime de l’agent plutôt que contre une session individuelle, ce qui laisse l’agent libre de décider ce qu’une session signifie pour votre application.

Pour restreindre chaque utilisateur à ses propres conversations :

  1. Ajoutez une API pour créer une session, en utilisant tRPC, FastAPI ou Smithy. Générez un identifiant de session opaque (au moins 33 caractères) et stockez-le aux côtés de l’identifiant de l’utilisateur appelant — par exemple dans une table créée avec le générateur py#dynamodb. Chaque guide d’API montre comment récupérer l’identifiant de l’utilisateur appelant.
  2. Dans votre agent, recherchez l’identifiant utilisateur stocké pour l’identifiant de session qui lui a été donné, et rejetez la requête lorsqu’il ne correspond pas à l’appelant. Avec auth=cognito, le JWT de l’appelant atteint votre code d’agent, donc sa revendication sub les identifie.

Générez l’identifiant de session plutôt que de le dériver de valeurs fournies par l’utilisateur telles qu’un nom de conversation — tout ce qu’un appelant peut prédire, un appelant peut envoyer.

framework = langchain

L’option session contrôle comment le checkpointer LangGraph de votre agent persiste l’état de conversation :

  • s3 (par défaut) : L’agent déployé utilise un S3CheckpointSaver avec le bucket de session provisionné, stockant les points de contrôle et les écritures en attente sous le préfixe checkpoints/. Cette classe se trouve dans s3_checkpoint_saver_langchain.py dans le projet de connexion d’agent partagé.
  • dynamodb-s3 : L’infrastructure CDK/Terraform provisionne une table DynamoDB pour les points de contrôle, configurée comme recommandé dans la documentation AWS sur l’utilisation de DynamoDB comme magasin de points de contrôle pour les agents LangGraph (schéma PK/SK unifié, facturation PAY_PER_REQUEST, récupération point-in-time et un attribut ttl), plus un bucket S3 pour décharger les points de contrôle de plus de 350 Ko. Les deux sont chiffrés avec une clé KMS dédiée ; les journaux d’accès au serveur du bucket sont livrés à un groupe de journaux CloudWatch Logs via la même clé. Le rôle IAM de l’agent se voit accorder un accès en lecture/écriture à la table et au bucket, et les noms de table/bucket sont enregistrés aux côtés de l’ARN de l’agent dans la configuration du runtime AppConfig.
  • in-memory : Aucune table ou bucket n’est provisionné. L’état de conversation est conservé en mémoire uniquement pendant la durée de vie du processus en cours d’exécution et ne survit pas aux redémarrages ou à la réduction d’échelle.

Ceci est implémenté dans le session.py généré, qui exporte une fonction get_checkpointer() appelée depuis l’appel create_agent(..., checkpointer=get_checkpointer()) de agent.py.

protocol = http

Démarrez votre agent avec la cible <your-agent-name>-dev :

Terminal window
pnpm nx agent-dev your-project

Ensuite, envoyez une requête POST à /invocations sur le port sur lequel votre agent local s’exécute. Substituez le port attribué à votre agent — lisez-le depuis metadata.ports dans le project.json du projet, ou depuis le flag --port dans la commande de la cible <your-agent-name>-dev. Un premier agent HTTP dans un espace de travail neuf se voit attribuer 8081 :

Fenêtre de terminal
curl -N -X POST http://localhost:8081/invocations \
-d '{"prompt": "what is 3 + 5?"}' \
-H "Content-Type: application/json"

Pour invoquer votre Agent déployé sur Bedrock AgentCore Runtime, vous pouvez envoyer une requête POST au point de terminaison du plan de données Bedrock AgentCore Runtime avec votre ARN encodé en URL.

Vous pouvez obtenir l’ARN du runtime depuis votre infrastructure comme suit :

import { CfnOutput } from 'aws-cdk-lib';
import { MyProjectAgent } from '@my-scope/common-constructs';
export class ExampleStack extends Stack {
constructor(scope: Construct, id: string) {
const agent = new MyProjectAgent(this, 'MyProjectAgent');
new CfnOutput(this, 'AgentArn', {
value: agent.agentCoreRuntime.agentRuntimeArn,
});
}
}

L’ARN aura le format suivant : arn:aws:bedrock-agentcore:<region>:<account>:runtime/<agent-runtime-id>.

Vous pouvez ensuite encoder l’ARN en URL en remplaçant : par %3A et / par %2F.

L’URL du plan de données Bedrock AgentCore Runtime pour invoquer l’agent est la suivante :

https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-arn>/invocations

La manière exacte d’invoquer cette URL dépend de la méthode d’authentification utilisée.

Pour l’authentification IAM, la requête doit être signée en utilisant AWS Signature Version 4 (SigV4).

Fenêtre de terminal
acurl <region> bedrock-agentcore -N -X POST \
'https://bedrock-agentcore.<region>.amazonaws.com/runtimes/<url-encoded-arn>/invocations' \
-d '{"prompt": "what is 3 + 5?"}' \
-H 'Content-Type: application/json'
Cliquez ici pour plus de détails sur la configuration de la commande acurl ci-dessus

Pour invoquer votre Agent depuis un site web React, vous pouvez utiliser le générateur connection, qui configure automatiquement un client avec l’authentification correcte (IAM ou Cognito).

Exécuter ce générateur@aws/nx-plugin:connection

pnpm nx g @aws/nx-plugin:connection
Composez votre commande5

Requis

Requis

Consultez le guide du générateur connection pour plus de détails sur la configuration de la connexion.

protocol = a2a

Pour déléguer du travail de cet agent à un agent A2A distant (soit TypeScript soit Python), utilisez le générateur connection. Il fournit un client authentifié SigV4 pour l’agent cible et transforme par AST le agent.py de cet agent pour enregistrer l’agent A2A distant en tant que délégué décoré @tool.

Exécuter ce générateur@aws/nx-plugin:connection

pnpm nx g @aws/nx-plugin:connection
Composez votre commande5

Requis

Requis

Consultez le guide du générateur connection pour plus de détails sur la configuration de la connexion.

protocol = ag-ui

Pour invoquer votre agent AG-UI depuis un site web React, utilisez le générateur connection, qui configure un client CopilotKit configuré pour votre agent déployé avec l’authentification correcte (IAM ou Cognito).

Exécuter ce générateur@aws/nx-plugin:connection

pnpm nx g @aws/nx-plugin:connection
Composez votre commande5

Requis

Requis

Consultez le guide du générateur connection pour plus de détails sur la configuration de la connexion.

Les agents agissent sur des entrées non fiables et peuvent déclencher des actions réelles via leurs outils, il est donc important de considérer la sécurité dès le départ. Les pratiques suivantes s’appliquent à l’agent généré.

Traiter les entrées et sorties du modèle comme non fiables

Section intitulée « Traiter les entrées et sorties du modèle comme non fiables »

Les prompts peuvent contenir des instructions adverses (injection de prompt), et la sortie du modèle est non déterministe — ni l’un ni l’autre ne doivent être considérés comme fiables dans une logique sensible à la sécurité :

  • Définissez des schémas d’entrée stricts pour vos outils, comme dans l’exemple d’outil généré. Contraignez les valeurs à ce dont l’outil a réellement besoin (énumérations, limites de longueur, plages numériques) plutôt que d’accepter des chaînes de caractères libres.
  • Ne passez jamais la sortie du modèle directement dans des commandes shell, des requêtes SQL, une évaluation de code ou du HTML rendu sans validation ou encodage.
  • Appliquez des vérifications d’autorisation dans vos outils et services en aval — ne comptez pas sur le prompt système pour empêcher le modèle d’utiliser à mauvais escient un outil auquel il a accès.

Les guides Prompt Engineering et Responsible AI de Strands couvrent la rédaction de prompts système robustes et soucieux de la sécurité.

Accordez au rôle IAM de l’agent uniquement les permissions dont ses outils ont besoin. Les constructs CDK et modules Terraform fournis exposent des méthodes grant* et des politiques limitées à cet effet — par exemple, accorder à un agent l’accès pour invoquer une API spécifique plutôt que d’attacher de larges politiques gérées. Lorsqu’un outil agit au nom d’un utilisateur, préférez autoriser l’action en utilisant l’identité de l’utilisateur appelant (transmise via le contexte de la requête) plutôt que les permissions ambiantes de l’agent lui-même.

Étant donné que le comportement du modèle peut changer de manière inattendue, prévoyez de désactiver ou de remplacer rapidement le modèle sans modification de code :

  • Lisez l’ID du modèle depuis la configuration (par exemple une variable d’environnement MODEL_ID) afin que les opérateurs puissent changer ou revenir à un modèle différent en mettant à jour la configuration.
  • Placez l’agent derrière un feature flag afin que sa fonctionnalité IA puisse être désactivée entièrement. Lorsqu’elle est désactivée, renvoyez un message générique plutôt qu’une erreur, et assurez-vous que le reste de votre application se dégrade gracieusement.

Documentez comment activer ces contrôles dans votre manuel opérationnel.

  • Évitez de journaliser les prompts et les complétions, qui peuvent contenir des données utilisateur. Le hook de journalisation des erreurs du modèle de l’agent généré journalise uniquement les métadonnées d’erreur, pas le contenu de la conversation — conservez cette propriété lors de l’ajout de votre propre journalisation.
  • Renvoyez des messages d’erreur génériques aux utilisateurs ; journalisez les erreurs détaillées côté serveur.
  • Isolez l’état de conversation entre les utilisateurs et les sessions, et autorisez l’accès à toutes les données de session persistées.
  • Masquez les informations personnellement identifiables (PII) des prompts et des sorties — soit avec un filtre d’informations sensibles Amazon Bedrock Guardrail (ci-dessous), soit, pour les agents Strands, les approches du guide PII Redaction.

Amazon Bedrock Guardrails fournit des filtres de contenu configurables, des sujets interdits et des filtres d’informations sensibles (PII) qui sont évalués sur l’entrée et la sortie du modèle. Vous pouvez attacher un guardrail au modèle utilisé par l’agent généré :

agent.py
import os
from strands import Agent
from strands.models import BedrockModel
model = BedrockModel(
model_id=os.environ.get("MODEL_ID"),
guardrail_id=os.environ["GUARDRAIL_ID"],
guardrail_version=os.environ.get("GUARDRAIL_VERSION", "DRAFT"),
)
agent = Agent(model=model)

Consultez le guide Strands sur les Guardrails pour plus de détails.

Utilisez le générateur connection pour intégrer ce projet avec d’autres dans votre espace de travail. Les connexions suivantes impliquent ce projet :

Strands AgentsPython
React to Python AgentCall a Python Agent from a React website
CopilotKit
React to AG-UI AgentCall an Agent exposing the AG-UI protocol from a React website via CopilotKit
Strands AgentsPythonModel Context Protocol
Python Agent to MCPConnect a Python Agent to an MCP server
Strands AgentsPythonAgent2Agent
Python Agent to A2A AgentConnect a Python Agent to a remote A2A agent
Strands AgentsTypeScriptAgent2Agent
TypeScript Agent to A2A AgentConnect a TypeScript Agent to a remote A2A agent
Strands AgentsPythonAmazon DynamoDBPython
Python Agent to Python DynamoDBConnect a Python Agent to a DynamoDB table
Strands AgentsPythonAmazon Bedrock AgentCore Gateway
Python Agent to AgentCore GatewayConnect a Python Agent to an AgentCore Gateway
Amazon Bedrock AgentCore GatewayStrands Agents
AgentCore Gateway to AgentFront an agent with an AgentCore Gateway as a runtime target