View a markdown version of this page

Déploiement direct de code pour Node.js - Base rocheuse de l'Amazonie AgentCore

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Déploiement direct de code pour Node.js

Le déploiement direct du code vous permet d'intégrer votre Node.js-based agent à Amazon Bedrock AgentCore Runtime simplement en empaquetant le code de l'agent et ses dépendances dans une archive de fichiers .zip. Votre agent doit toujours respecter les exigences AgentCore d'exécution  : disposer d'un .js fichier de point d'entrée qui implémente les points de terminaison des serveurs /invocations POST et /ping GET.

Vous pouvez inclure les dépendances telles qu'elles sont fournies node_modules/ dans votre ZIP ou sous la forme d'un fichier unique groupé par esbuild. .js

Conditions préalables

Avant de commencer, assurez-vous de disposer des éléments suivants :

Étape 1 : Configuration du projet et installation des dépendances

Initialisez votre projet à l'aide des commandes suivantes :

mkdir agentcore_runtime_node_deploy cd agentcore_runtime_node_deploy npm init -y

Si vous le souhaitez, exécutez npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation pour activer les traces d' AgentCore observabilité d'Amazon Bedrock.

Étape 2 : Créez votre code d'agent

Créez le point d'entrée de votre agent. Votre agent doit implémenter le contrat HTTP AgentCore Runtime avec un endpoint /ping GET health et un gestionnaire /invocations POST.

Exemple
Strands Agents SDK

Installez le SDK Strands Agents et ses dépendances :

npm install @strands-agents/sdk express zod npm install -D @types/express @types/node typescript

Créez un fichier nommé src/app.ts :

import express, { Request, Response } from "express"; import { Agent, tool } from "@strands-agents/sdk"; import z from "zod"; const PORT = 8080; const app = express(); app.use(express.json()); const currentTime = tool({ name: "current_time", description: "Returns the current date and time", inputSchema: z.object({}), callback: () => { return new Date().toISOString(); }, }); const agent = new Agent({ tools: [currentTime], printer: false, }); app.get("/ping", (_req: Request, res: Response) => { res.json({ status: "Healthy" }); }); app.post("/invocations", async (req: Request, res: Response) => { const prompt = req.body?.prompt || "No prompt provided"; try { const result = await agent.invoke(prompt); res.json({ result: result.lastMessage }); } catch (error: unknown) { const message = error instanceof Error ? error.message : String(error); res.status(500).json({ error: message }); } }); app.listen(PORT, "0.0.0.0", () => { console.log("Strands agent listening on port " + PORT); });

Compilez TypeScript les deux JavaScript :

npx tsc --init --target ES2022 --module commonjs --outDir ./dist npx tsc

La sortie compilée dist/app.js est celle que vous déployez. Lors de la création de l'agent, utilisez "entryPoint": ["dist/app.js"] la JavaScript sortie compilée, pas la .ts source.

HTTP (no framework)

Cet exemple utilise le node:http module intégré sans dépendances externes.

Créez un fichier nommé app.js :

const http = require("node:http"); const PORT = 8080; const server = http.createServer((req, res) => { if (req.url === "/ping" && req.method === "GET") { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ status: "Healthy" })); } else if (req.url === "/invocations" && req.method === "POST") { let body = ""; req.on("data", (chunk) => { body += chunk; }); req.on("end", () => { try { const input = JSON.parse(body); const prompt = input.prompt || input.command || "No prompt provided"; res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ result: "Hello from Node.js managed runtime! You said: " + prompt, runtime: "NODE_22", nodeVersion: process.version, timestamp: new Date().toISOString() })); } catch (e) { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ result: "Hello from Node.js managed runtime!", runtime: "NODE_22", nodeVersion: process.version, input: body, timestamp: new Date().toISOString() })); } }); } else { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ message: "Node.js managed runtime agent is running" })); } }); server.listen(PORT, "0.0.0.0", () => { console.log("Node.js agent listening on port " + PORT); });

Étape 3 : Testez localement

Assurez-vous que le port 8080 est libre avant de démarrer. Consultez la section Résoudre les problèmes si le port est déjà utilisé.

Ouvrez une fenêtre de terminal et démarrez votre agent :

Exemple
Strands Agents SDK
node dist/app.js

Ouvrez une autre fenêtre de terminal et appelez l'agent :

curl -X POST http://localhost:8080/invocations \ -H "Content-Type: application/json" \ -d '{"prompt": "What time is it right now?"}'

Succès : vous devriez voir une réponse contenant l'heure actuelle renvoyée par l'current_timeoutil de l'agent. Dans la fenêtre du terminal qui exécute l'agent, entrez Ctrl+C pour arrêter l'agent.

HTTP (no framework)
node app.js

Ouvrez une autre fenêtre de terminal et appelez l'agent :

curl -X POST http://localhost:8080/invocations \ -H "Content-Type: application/json" \ -d '{"prompt": "Hello!"}'

Succès : vous devriez voir une réponse du type{"result": "Hello from Node.js managed runtime! You said: Hello!","runtime":"NODE_22",…​}. Dans la fenêtre du terminal qui exécute l'agent, entrez Ctrl+C pour arrêter l'agent.

Étape 4 : Activez l'observabilité pour votre agent

Amazon Bedrock AgentCore Observability vous permet de suivre, de déboguer et de surveiller les agents que vous hébergez dans Runtime. AgentCore Activez d'abord CloudWatch la recherche de transactions en suivant les instructions de la section Activation de l'observabilité de l' AgentCore environnement d'exécution d'Amazon Bedrock. Pour observer votre agent, voir Afficher les données d'observabilité de vos agents Amazon Bedrock AgentCore .

Pour activer l'instrumentation automatique pour votre Node.js agent, ajoutez le package ADOT :

npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation
Important

L'auto-instrumentation ADOT fonctionne en corrigeant les Node.js require() appels lors de l'exécution. Cela signifie qu'il n'est compatible qu'avec la sortie du module CommonJS. Si vous compilez TypeScript avec --module nodenext ou --module esnext (en produisant des import instructions ESM), l'instrumentation ADOT échoue silencieusement et aucune trace n'est émise. Pour utiliser ADOT, compilez avec --module commonjs ou utilisez esbuild with --platform=node (qui préserve les require() appels aux modules Node.js intégrés).

Lors du déploiement, node_modules/ incluez-le dans votre ZIP et utilisez le opentelemetry-instrument préfixe dans votre point d'entrée (voir Étape 5).

Étape 5 : Déployer sur AgentCore Runtime et invoquer

Note

AgentCore Le moteur d'exécution n'exécute pas les fichiers TypeScript (.ts) de manière native. Vous devez TypeScript transpiler vers JavaScript avant de déployer. Pour plus d'informations, consultez Travailler avec TypeScript .

Créez un fichier .zip contenant le code de votre agent et ses dépendances. AgentCore Runtime ne prend en charge que l'architecture du jeu d'instructions arm64. Assurez-vous que tous les modules (.nodefichiers) natifs sont compilés pour arm64.

Exemple
Strands Agents SDK

Package de la sortie compilée et des dépendances fournisseurs :

npm install --production zip -r deployment_package.zip dist/ node_modules/ package.json

Lors de la création de l'agent, utilisez "entryPoint": ["dist/app.js"] la JavaScript sortie compilée, pas la .ts source.

HTTP (no framework)

Comme cet exemple ne comporte aucune dépendance externe, seul le fichier du point d'entrée est nécessaire :

zip deployment_package.zip app.js

Lors de la création de l'agent, utilisez"entryPoint": ["app.js"].

Note

. La taille maximale d'un package de déploiement .zip pour AgentCore Runtime est de 250 Mo (compressé) et 750 Mo (décompressé). Notez que cette limite s'applique à la taille combinée de tous les fichiers que vous téléchargez. Le AgentCore Runtime a besoin d'une autorisation pour lire les fichiers de votre package de déploiement. En notation octale des autorisations Linux, AgentCore Runtime a besoin de 644 autorisations pour les fichiers non exécutables (rw-r—r--) et de 755 autorisations (rwxr-xr-x) pour les répertoires et les fichiers exécutables. Sous Linux et macOS, utilisez la commande chmod pour modifier les autorisations de fichiers sur les fichiers et les répertoires de votre package de déploiement. Par exemple, pour attribuer les autorisations appropriées à un fichier non exécutable, exécutez la commande suivante,chmod 644 <filepath>. Pour modifier les autorisations relatives aux fichiers dans Windows, voir Définir, afficher, modifier ou supprimer des autorisations sur un objet dans la documentation Microsoft Windows. +.. Si vous n'accordez pas à AgentCore Runtime les autorisations dont il a besoin pour accéder aux répertoires de votre package de déploiement, AgentCore Runtime définit les autorisations pour ces répertoires sur 755 (rwxr-xr-x).

Une archive ZIP contenant les dépendances de Linux arm64 doit être téléchargée sur S3 comme condition préalable à Create Agent Runtime. Le code ci-dessous nécessite que le compartiment S3 spécifié existe déjà. Veuillez suivre la AWS documentation disponible ici pour créer un bucket. Le TypeScript code suivant téléchargera l'archive du fichier .zip sur S3 et créera un environnement d'exécution Amazon Bedrock AgentCore .

import { readFileSync } from "node:fs"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { BedrockAgentCoreControlClient, CreateAgentRuntimeCommand, } from "@aws-sdk/client-bedrock-agentcore-control"; const accountId = "your-aws-account-id"; const agentName = "nodejs_agent"; const region = "us-west-2"; const bucketName = `bedrock-agentcore-code-${accountId}-${region}`; const s3Client = new S3Client({ region }); console.log("Uploading deployment_package.zip to S3..."); await s3Client.send(new PutObjectCommand({ Bucket: bucketName, Key: `${agentName}/deployment_package.zip`, Body: readFileSync("deployment_package.zip"), ExpectedBucketOwner: accountId, })); console.log(`Upload completed. S3 location: s3://${bucketName}/${agentName}/deployment_package.zip`); const controlClient = new BedrockAgentCoreControlClient({ region }); const response = await controlClient.send(new CreateAgentRuntimeCommand({ agentRuntimeName: agentName, agentRuntimeArtifact: { codeConfiguration: { code: { s3: { bucket: bucketName, prefix: `${agentName}/deployment_package.zip`, }, }, runtime: "NODE_22", entryPoint: ["dist/app.js"], }, }, networkConfiguration: { networkMode: "PUBLIC" }, roleArn: `arn:aws:iam::${accountId}:role/AmazonBedrockAgentCoreSDKRuntime-${region}`, lifecycleConfiguration: { idleRuntimeSessionTimeout: 300, maxLifetime: 1800, }, })); console.log(`Agent Runtime created successfully!`); console.log(`Agent Runtime ARN: ${response.agentRuntimeArn}`); console.log(`Status: ${response.status}`);

Pour activer l'auto-instrumentation OTEL, incluez node_modules/@aws/aws-distro-opentelemetry-node-autoinstrumentation/ dans votre ZIP et utilisez le opentelemetry-instrument préfixe au point d'entrée :

entryPoint: ["opentelemetry-instrument", "dist/app.js"],

Pour appeler un agent sur Amazon Bedrock AgentCore Runtime par programmation, voir Invoquer un agent par programmation.

Étape 6 : arrêt de la session, mise à jour ou nettoyage

TypeScript Le code suivant mettra à jour un AgentCore Runtime. Téléchargez le nouveau package de déploiement sur S3, puis appelez UpdateAgentRuntimeCommand :

import { readFileSync } from "node:fs"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { BedrockAgentCoreControlClient, UpdateAgentRuntimeCommand, } from "@aws-sdk/client-bedrock-agentcore-control"; const accountId = "your-aws-account-id"; const agentName = "nodejs_agent"; const region = "us-west-2"; const bucketName = `bedrock-agentcore-code-${accountId}-${region}`; const s3Client = new S3Client({ region }); console.log("Uploading deployment_package.zip to S3..."); await s3Client.send(new PutObjectCommand({ Bucket: bucketName, Key: `${agentName}/deployment_package.zip`, Body: readFileSync("deployment_package.zip"), ExpectedBucketOwner: accountId, })); console.log("Upload completed successfully!"); const controlClient = new BedrockAgentCoreControlClient({ region }); const response = await controlClient.send(new UpdateAgentRuntimeCommand({ agentRuntimeId: "<your-agent-runtime-id>", agentRuntimeArtifact: { codeConfiguration: { code: { s3: { bucket: bucketName, prefix: `${agentName}/deployment_package.zip`, }, }, runtime: "NODE_22", entryPoint: ["dist/app.js"], }, }, networkConfiguration: { networkMode: "PUBLIC" }, roleArn: `arn:aws:iam::${accountId}:role/AmazonBedrockAgentCoreSDKRuntime-${region}`, })); console.log(`Agent Runtime updated successfully!`); console.log(`Agent Runtime ARN: ${response.agentRuntimeArn}`); console.log(`Status: ${response.status}`);

Pour arrêter la session en cours avant la configuration IdleRuntimeSessionTimeout (15 minutes par défaut) et économiser sur les éventuels coûts exorbitants, utilisez le code suivant :

import { BedrockAgentCoreClient, StopRuntimeSessionCommand, } from "@aws-sdk/client-bedrock-agentcore"; const region = "us-west-2"; const dataClient = new BedrockAgentCoreClient({ region }); const response = await dataClient.send(new StopRuntimeSessionCommand({ agentRuntimeArn: "arn:aws:bedrock-agentcore:us-west-2:<account-id>:runtime/<agent-runtime-id>", runtimeSessionId: "<your-session-id>", qualifier: "DEFAULT", })); console.log("Session stopped successfully!");

TypeScript Le code suivant supprimera un environnement d' AgentCore exécution Amazon Bedrock et le fichier d'archive .zip dans S3.

import { S3Client, DeleteObjectCommand } from "@aws-sdk/client-s3"; import { BedrockAgentCoreControlClient, DeleteAgentRuntimeCommand, } from "@aws-sdk/client-bedrock-agentcore-control"; const accountId = "your-aws-account-id"; const agentName = "nodejs_agent"; const region = "us-west-2"; const bucketName = `bedrock-agentcore-code-${accountId}-${region}`; const controlClient = new BedrockAgentCoreControlClient({ region }); console.log("Deleting Agent from Amazon Bedrock AgentCore Runtime!"); const response = await controlClient.send(new DeleteAgentRuntimeCommand({ agentRuntimeId: "<your-agent-runtime-id>", })); console.log(`Agent Runtime deleted successfully!`); console.log(`Status: ${response.status}`); const s3Client = new S3Client({ region }); console.log("Deleting deployment archive from S3..."); await s3Client.send(new DeleteObjectCommand({ Bucket: bucketName, Key: `${agentName}/deployment_package.zip`, ExpectedBucketOwner: accountId, })); console.log("Archive deleted successfully from S3!");

Node.js-specific concepts pour le déploiement direct de code

Découvrez Node.js-specific les concepts liés au déploiement direct de code avec Amazon Bedrock AgentCore Runtime.

Rubriques

    AgentCore Runtime for Node.js n'accepte que les points .js d'entrée. TypeScript les fichiers (.ts) ne sont pas acceptés directement. Vous devez les transpiler JavaScript avant de les emballer. Nous vous recommandons d'utiliser esbuild pour transpiler et regrouper en une seule étape. Ajoutez esbuild en tant que dépendance de développement avecnpm install -D esbuild.

    Les points d'entrée peuvent se trouver dans des sous-répertoires. Par exemple, src/app.js ou dist/index.js sont des points d'entrée valides. Node.js module resolution parcourt l'arborescence des répertoires à partir de l'emplacement du point d'entrée, de sorte que les dépendances situées node_modules/ à la racine de votre ZIP sont détectées automatiquement. Aucune NODE_PATH configuration n'est nécessaire.

    Lorsque vous spécifiez un point d'entrée de sous-répertoire, assurez-vous que le chemin entryPoint de votre configuration correspond au chemin du fichier ZIP.

    Il existe deux approches pour empaqueter les dépendances des Node.js agents :

    Dépendances fournisseurs (les plus simples) :

    Incluez node_modules/ directement dans votre code postal à côté de votre point d'entrée :

    npm install --production zip -r my-agent.zip app.js node_modules/ package.json

    Cela produit un ZIP avec la structure suivante :

    my-agent.zip
    ├── app.js
    ├── package.json
    └── node_modules/

    Fourni avec esbuild (le plus petit ZIP) :

    Utilisez esbuild pour regrouper toutes les dépendances dans un seul fichier :

    npx esbuild app.js --bundle --platform=node --target=node22 --outfile=bundle.js zip my-agent.zip bundle.js

    Cela produit un ZIP minimal :

    my-agent.zip
    └── bundle.js

    Les deux approches fonctionnent. Les déploiements groupés sont généralement inférieurs à 10 Mo et se déploient plus rapidement. Les déploiements fournis par les fournisseurs sont plus simples et ne nécessitent pas d'étape de génération, mais peuvent être plus importants.

    AgentCore Runtime ne prend en charge que l'architecture du jeu d'instructions arm64. Si votre agent utilise des packages npm qui incluent des modules natifs (compilés .node ou .so fichiers), ces binaires doivent être compilés pour Linux arm64.

    AgentCore Runtime valide l'architecture de tous les .so fichiers .node et de votre package de déploiement en lisant leurs en-têtes ELF. Si un fichier binaire est compilé pour une architecture différente (telle que x86_64 ou macOS), la création de votre agent échouera avec le statut. CREATE_FAILED

    Pour installer des modules natifs compatibles avec arm64 :

    • Installer les dépendances sur une machine arm64 (telle qu'une instance AWS Graviton-based Amazon EC2)

    • Utilisez les npm --arch et les --platform drapeaux :

      npm install --arch=arm64 --platform=linux
    • Utilisez esbuild pour regrouper votre code si le module natif peut être évité lors de l'exécution

    Les packages npm les plus populaires (Express, Axios, Fastify, Hono, ws) sont purs JavaScript et ne contiennent pas de modules natifs.

    AgentCore Le moteur d'exécution n'exécute pas TypeScript les fichiers directement. Vous devez compiler votre code TypeScript source JavaScript avant de le déployer. Il s'agit du même modèle que celui utilisé par AWS Lambda.

    À l'aide du TypeScript compilateur (tsc) :

    npm install -g typescript npx tsc --init --target ES2022 --module commonjs --outDir ./dist npx tsc

    Ensuite, empaquetez la sortie compilée :

    cd dist zip -r ../deployment_package.zip .

    Lors de la création de l'agent, définissez le point d'entrée du .js fichier compilé (par exemple, app.js ou dist/app.js en fonction de votre structure ZIP).

    En utilisant esbuild (recommandé pour simplifier l'empaquetage) :

    npx esbuild app.ts --bundle --platform=node --target=node22 --outfile=app.js zip deployment_package.zip app.js

    esbuild compile TypeScript et regroupe les dépendances en une seule étape, produisant un petit fichier autonome. .js

    Si vous package.json incluez un engines.node champ, AgentCore Runtime confirme que la plage spécifiée est compatible avec la Node.js version que vous avez sélectionnée (par exemple, Node.js 22 lors de l'utilisation du NODE_22 runtime). Si la plage exclut cette version, la création de votre agent échouera avec le statutCREATE_FAILED.

    Par exemple, les engines déclarations suivantes sont compatibles avec Node.js 22 :

    { "engines": { "node": ">=18" } } { "engines": { "node": ">=14 <18 || >=20" } } { "engines": { "node": "22" } }

    Les déclarations suivantes sont incompatibles et entraîneront l'échec de la création de l'agent :

    { "engines": { "node": "<18" } } { "engines": { "node": ">=14 <18" } }

    AgentCore Runtime vérifie également engines.node dans le champ les dépendances courantes dans votrenode_modules/. Si l'un d'entre eux déclare une plage de Node.js versions qui exclut la version d'exécution cible, la création de l'agent échouera.

    Si vous rencontrez une engines.node incompatibilité, mettez à jour le package vers une version compatible avec votre Node.js version cible ou supprimez le engines champ de votrepackage.json. Pour les Node.js versions prises en charge, consultez la section Exécutions linguistiques prises en charge.