View a markdown version of this page

Node.js 的直接程式碼部署 - Amazon Bedrock AgentCore

Node.js 的直接程式碼部署

直接程式碼部署可讓您將 Node.js 型代理程式帶到 Amazon Bedrock AgentCore 執行期,只需在 .zip 封存檔中封裝代理程式程式碼及其相依性即可。您的代理程式仍然需要遵循 AgentCore 執行期要求:具有實作 /invocations POST 和 /ping GET 伺服器端點的進入點.js檔案。

您可以在 ZIP node_modules/中包含做為廠商的相依性,或做為 esbuild 綁定的單一.js檔案。

先決條件

開始前,請確保您具備以下條件:

  • AWS 已設定登入資料的帳戶。若要設定您的 AWS 登入資料,請參閱 CLI AWS 中的組態和登入資料檔案設定。

  • 已安裝 Node.jsnpm。我們建議您安裝計劃在 AgentCore 執行期部署的相同主要版本 (例如執行NODE_22期的 Node.js 22)。如需支援的版本,請參閱支援的語言執行時間

  • AWS 許可 :若要建立和部署代理程式,您必須擁有適當的許可。如需詳細資訊,請參閱 AgentCore 執行期許可

  • 模型存取 :Amazon Bedrock 主控台中啟用 Anthropic Claude Sonnet 4.0。如需搭配 Strands Agents 使用不同模型的詳細資訊,請參閱 Strands Agents SDK 文件中的模型提供者一節。

步驟 1:設定專案並安裝相依性

使用以下命令初始化您的專案:

mkdir agentcore_runtime_node_deploy cd agentcore_runtime_node_deploy npm init -y

或者,執行 npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation以啟用 Amazon Bedrock AgentCore 可觀測性追蹤

步驟 2:建立您的代理程式程式碼

建立您的客服人員進入點。您的代理程式必須使用 /ping GET 運作狀態端點和 /invocations POST 處理常式實作 AgentCore 執行期 HTTP 合約。

範例
Strands Agents SDK

安裝 Strands Agents SDK 及其相依性:

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

建立名為 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); });

將 TypeScript 編譯至 JavaScript:

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

中的編譯輸出dist/app.js是您部署的輸出。建立代理程式時,請使用 "entryPoint": ["dist/app.js"] - 編譯的 JavaScript 輸出,而不是.ts來源。

HTTP (no framework)

此範例使用沒有外部相依性的內建node:http模組。

建立名為 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); });

步驟 3:在本機測試

開始之前,請確定連接埠 8080 是免費的。請參閱常見問題和解決方案中的連接埠 8080 使用中 (僅限本機)

開啟終端機視窗並啟動您的代理程式:

範例
Strands Agents SDK
node dist/app.js

開啟另一個終端機視窗並叫用代理程式:

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

成功:您應該會看到回應,其中包含客服人員current_time工具傳回的目前時間。在執行代理程式的終端機視窗中,輸入 Ctrl+C以停止代理程式。

HTTP (no framework)
node app.js

開啟另一個終端機視窗並叫用代理程式:

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

成功:您應該會看到類似 {"result": "Hello from Node.js managed runtime! You said: Hello!","runtime":"NODE_22",…​} 的回應。在執行代理程式的終端機視窗中,輸入 Ctrl+C以停止代理程式。

步驟 4:啟用代理程式的可觀測性

Amazon Bedrock AgentCore 可觀測性可協助您追蹤、偵錯和監控您在 AgentCore 執行期中託管的代理程式。首先,遵循啟用 Amazon Bedrock AgentCore 執行時間可觀測性 中的指示來啟用 CloudWatch 交易搜尋。若要觀察您的代理程式,請參閱檢視 Amazon Bedrock AgentCore 代理程式的可觀測性資料

若要為您的 Node.js 代理程式啟用自動檢測,請新增 ADOT 套件:

npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation
重要

ADOT 自動檢測的運作方式是在執行時間修補 Node.js require()呼叫。這表示它僅與 CommonJS 模組輸出相容。如果您使用 --module nodenext--module esnext(產生 ESM import陳述式) 編譯 TypeScript,ADOT 檢測會無提示地失敗,而且不會發出任何追蹤。若要使用 ADOT,請搭配 編譯--module commonjs或使用 esbuild 搭配 --platform=node(保留對 Node.js 內建模組的require()呼叫)。

部署時,請在 ZIP node_modules/中包含 ,並在進入點中使用 opentelemetry-instrument 字首 (請參閱步驟 5)。

步驟 5:部署至 AgentCore 執行期並叫用

注意

AgentCore 執行期不會原生執行 TypeScript (.ts) 檔案。部署之前,您必須將 TypeScript 傳輸到 JavaScript。詳細資訊,請參閱使用 TypeScript

使用代理程式程式碼和相依性建立 .zip 檔案。AgentCore 執行期僅支援 arm64 指令集架構 — 確保針對 arm64 編譯任何原生模組 (.node 檔案)。

範例
Strands Agents SDK

封裝編譯的輸出和廠商的相依性:

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

建立代理程式時,請使用 "entryPoint": ["dist/app.js"] - 編譯的 JavaScript 輸出,而不是.ts來源。

HTTP (no framework)

由於此範例沒有外部相依性,因此只需要進入點檔案:

zip deployment_package.zip app.js

建立代理程式時,請使用 "entryPoint": ["app.js"]

注意

。 AgentCore 執行期的 .zip 部署套件大小上限為 250 MB (壓縮) 和 750 MB (解壓縮)。請注意,此限制適用於您上傳之所有檔案的合併大小。AgentCore 執行期需要讀取部署套件中檔案的許可。在 Linux 許可八進位表示法中,AgentCore 執行期需要 644 個不可執行檔案的許可 (rw-r—r--),以及 755 個目錄和可執行檔案的許可 (rwxr-xr-x)。在 Linux 和 MacOS 中,使用 chmod 命令變更部署套件中檔案和目錄的檔案許可。例如,若要為非可執行檔提供正確的許可,請執行下列命令 chmod 644 <filepath> 。若要在 Windows 中變更檔案許可,請參閱 Microsoft Windows 文件的 Set, View, Change, or Remove Permissions on an Object。+ .. 如果您未授予 AgentCore Runtime 存取部署套件中目錄所需的許可,AgentCore Runtime 會將這些目錄的許可設定為 755 (rwxr-xr-x)。

包含 Linux arm64 相依性的 ZIP 封存需要上傳到 S3 作為建立代理程式執行期的先決條件。下列程式碼要求指定的 S3 儲存貯體已存在。請依照此處 AWS 的文件來建立儲存貯體。下列 TypeScript 程式碼會將 .zip 檔案封存上傳至 S3,並建立 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}`);

若要啟用 OTEL 自動檢測,請在 ZIP node_modules/@aws/aws-distro-opentelemetry-node-autoinstrumentation/ 中包含 ,並在進入點中使用 opentelemetry-instrument字首:

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

若要以程式設計方式叫用 Amazon Bedrock AgentCore 執行期上的代理程式,請參閱:以程式設計方式叫用代理程式

步驟 6:停止工作階段、更新或清除

下列 TypeScript 程式碼會更新 AgentCore 執行期。將新的部署套件上傳至 S3,然後呼叫 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}`);

若要在可設定 IdleRuntimeSessionTimeout(預設為 15 分鐘) 之前停止執行中的工作階段,並節省任何潛在的失控成本,請使用下列程式碼:

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 程式碼會刪除 S3 中的 Amazon Bedrock AgentCore 執行期和 .zip 封存檔案。

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 特定概念

了解搭配 Amazon Bedrock AgentCore 執行期使用直接程式碼部署時的 Node.js 特定概念。

主題

    Node.js 的 AgentCore 執行期只接受.js進入點。TypeScript 檔案 (.ts) 不直接接受 - 您必須在封裝之前將檔案轉換為 JavaScript。我們建議在單一步驟中使用 esbuild 來傳輸和綁定。使用 新增 esbuild 做為開發相依性npm install -D esbuild

    進入點可以位於子目錄中。例如, src/app.jsdist/index.js是有效的進入點。Node.js 模組解析度會從進入點的位置上移目錄樹狀目錄,因此會自動在 ZIP node_modules/根目錄找到 中的相依性,無需NODE_PATH設定。

    當您指定子目錄進入點時,請確定entryPoint組態中的路徑與 ZIP 檔案中的路徑相符。

    封裝 Node.js 代理程式相依性的方法有兩種:

    廠商相依性 (簡單):

    node_modules/ 與您的進入點一起直接包含在 ZIP 中:

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

    這會產生具有下列結構的 ZIP:

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

    與 esbuild (最小 ZIP) 綁定:

    使用 esbuild 將所有相依性綁定到單一檔案中:

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

    這會產生最小的 ZIP:

    my-agent.zip
    └── bundle.js

    這兩種方法都可運作。綁定部署通常低於 10 MB,且部署速度更快。廠商部署更簡單,不需要建置步驟,但可以更大。

    AgentCore 執行期僅支援 arm64 指令集架構。如果您的代理程式使用包含原生模組 (編譯.node.so檔案) 的 npm 套件,則必須針對 Linux arm64 編譯這些二進位檔。

    AgentCore Runtime 透過讀取部署套件中的所有 .node.so 檔案的架構,來驗證其 ELF 標頭。如果針對不同的架構 (例如 x86_64 或 macOS) 編譯任何二進位檔,您的代理程式建立將會失敗,狀態為 CREATE_FAILED

    若要安裝與 arm64 相容的原生模組:

    • 在 arm64 AWS 機器上安裝相依性 (例如 Graviton 型 Amazon EC2 執行個體)

    • 使用 npm --arch--platform旗標:

      npm install --arch=arm64 --platform=linux
    • 如果可在執行時間避免原生模組,請使用 esbuild 綁定您的程式碼

    最熱門的 npm 套件 (Express、Axios、Fastify、Hono、ws) 是純 JavaScript,不包含原生模組。

    AgentCore 執行期不會直接執行 TypeScript 檔案。部署之前,您必須將 TypeScript 原始程式碼編譯至 JavaScript。這是 AWS Lambda 使用的相同模式。

    使用 TypeScript 編譯器 (tsc):

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

    然後封裝編譯的輸出:

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

    建立代理程式時,請將進入點設定為編譯.js的檔案 (例如,app.jsdist/app.js取決於您的 ZIP 結構)。

    使用 esbuild (建議用於更簡單的封裝):

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

    esbuild 會在單一步驟中編譯 TypeScript 和套件相依性,產生小型、獨立的.js檔案。

    如果您的 package.json包含 engines.node 欄位,AgentCore 執行期會驗證指定的範圍是否與您選取的 Node.js 版本相容 (例如,使用NODE_22執行期時的 Node.js 22)。如果範圍排除該版本,您的客服人員建立將會失敗,狀態為 CREATE_FAILED

    例如,下列engines宣告與 Node.js 22 相容:

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

    下列宣告不相容,會導致代理程式建立失敗:

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

    AgentCore 執行期也會檢查 engines.node 欄位中是否有 node_modules/ 中的常見相依性。如果其中任何一個宣告排除目標執行時間版本的 Node.js 版本範圍,則代理程式建立將會失敗。

    如果您遇到engines.node不相容的情況,請將套件更新為支援目標 Node.js package.json 版本的版本,或從中移除 engines 欄位。如需支援的 Node.js 版本,請參閱支援的語言執行時間