Serverless Framework 实战:在 AWS Bedrock AgentCore 上部署带代码解释器的 LangGraph JavaScript Agent
2026/9/10 14:42:04 网站建设 项目流程

Serverless Framework 实战:在 AWS Bedrock AgentCore 上部署带代码解释器的 LangGraph JavaScript Agent

【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless

本文基于 Serverless Framework 仓库中bedrock-agentcore插件的官方示例,完整讲解如何使用LangGraph JS + AWS 托管代码解释器(Code Interpreter)构建一个可执行 Python/JavaScript/TypeScript 代码、读写沙箱文件、运行 Shell 命令的 AI Agent,并把它部署到 AWS Bedrock AgentCore。读完本文,你将掌握示例工程的结构、serverless.yml中最简配置的写法、沙箱代码执行工具的实现方式、本地端到端测试(test-invoke.js)以及后续移除资源的标准流程。

示例工程完整源码位于 langgraph-code-interpreter 示例目录,配套插件说明见 Bedrock AgentCore Plugin 文档。

示例概览:让 Agent 真正"动手算"

大模型本身的弱点是"只说不做"。本示例解决的核心问题就是:当模型需要精确计算、生成/分析数据或运行脚本时,如何安全地让它执行真实代码

它由两部分协作构成:

  • LangGraph JS Agent:采用 LangChain/LangGraph 生态的createAgent(ReAct 模式的 Agent),由 Claude(Amazon Bedrock 上的ChatBedrockConverse)驱动,负责理解用户问题并自主决定何时调用工具;
  • AWS 托管代码解释器:示例直接使用AWS 管理的默认解释器(SANDBOX 模式),无需自建容器,模型通过一组文件/命令工具驱动解释器在隔离沙箱中执行代码。

示例声明的核心能力(对应 README):

  • 沙箱化执行:在 SANDBOX 环境中运行 Python、JavaScript 或 TypeScript;
  • 文件操作:在沙箱中读取、写入、列出文件;
  • Shell 命令:执行 Shell 命令;
  • LangGraph JS:ReAct 模式的 Agent + 代码执行工具链。

提供给 Agent 的 5 个工具

示例中所有能力都以工具(tool)形式暴露给模型,由模型按需自主调用:

工具作用
execute_code在沙箱中执行 Python / JavaScript / TypeScript 代码
execute_command运行 Shell 命令
read_files读取沙箱中的文件内容
write_files向沙箱写入文件
list_files列出目录内容

这 5 个工具并不是凭空注册的——它们分别是对CodeInterpreter客户端方法的薄封装(详见下文 index.js 实现解析)。仓库中还有一组同主题的 Python 版本示例可供对照:langgraph-code-interpreter(Python)。

工程结构与零配置 serverless.yml

示例目录文件如下:

langgraph-code-interpreter/ ├── serverless.yml # Serverless Framework 配置(Agent 定义) ├── index.js # LangGraph JS Agent 主逻辑(入口) ├── test-invoke.js # 本地端到端测试脚本 ├── package.json # npm 依赖与 Node 版本声明 ├── package-lock.json └── README.md

其中最值得一提的是serverless.yml只有寥寥几行

# Deploy: serverless deploy # Test: RUNTIME_ARN=<arn> node test-invoke.js service: langgraph-code-interpreter provider: name: aws ai: agents: # Runtime agent with code execution capabilities # Uses AWS-managed default code interpreter (SANDBOX mode) codeAgent: {}

对应 serverless.yml 的完整内容。它之所以能这么简洁,是因为:

  1. ai顶级配置属性由 Serverless Framework 的 Bedrock AgentCore 插件解析(见插件 README),负责把ai.agents.codeAgent翻译成 AgentCore 的 CloudFormation 资源;
  2. 不需要显式声明代码解释器:默认的 AWS 托管代码解释器(SANDBOX 模式)由 AgentCore 自动检测并注入,这正是本示例与"自定义解释器"示例的最大区别;
  3. 部署形态:目录中没有Dockerfile,插件会自动根据package.json检测 Node.js 运行环境、执行依赖安装并构建 ARM64 容器镜像——这与 langgraph-basic 示例 描述的"免 Dockerfile 构建"机制一致;
  4. package.json通过engines.node声明24.x(见 package.json),作为容器基础镜像选型的依据。

ai顶层属性下实际上支持 6 类资源:agents(运行时 Agent)、memory(对话记忆)、tools(Lambda/OpenAPI/Smithy/MCP 工具)、gateways(工具路由网关)、browsers(浏览器能力)与codeInterpreters(自定义代码解释器)。每种资源使用独立的节区,不存在type判别字段。本示例只用到agents,且整个 Agent 采用默认配置。

核心实现 index.js 解析

index.js采用BedrockAgentCoreApp的运行时编程模型,整体流程是:初始化 LLM → 注册 Agent 应用 → 在每次请求中创建独立的CodeInterpreter→ 用 5 个工具包裹其方法 →createAgent组装 → 调用并返回结果。

1. 模型与运行时初始化

const AWS_REGION = process.env.AWS_REGION || 'us-east-1' const MODEL_ID = process.env.MODEL_ID || 'us.anthropic.claude-sonnet-4-5-20250929-v1:0' const model = new ChatBedrockConverse({ model: MODEL_ID, region: AWS_REGION, }) const app = new BedrockAgentCoreApp({ invocationHandler: { requestSchema: z.object({ prompt: z.string().describe('The user message to process'), }), async process(request, context) { /* ... */ }, }, }) app.run()

关键点:

  • 模型默认使用 Claude Sonnet 4.5(us.anthropic.claude-sonnet-4-5-20250929-v1:0),均可用MODEL_IDAWS_REGION环境变量覆盖;其中AWS_REGION会被 AgentCore 自动注入到运行时;
  • 运行时 SDK 来自bedrock-agentcore/runtime(npm 依赖bedrock-agentcore,见 package.json 第 13 行);
  • requestSchema用 zod 声明请求载荷为{ prompt },与客户端test-invoke.js发送的 JSON 一一对应。

2. 每次请求创建独立的代码解释器会话

const sessionId = context?.sessionId || 'default' // Create code interpreter per request (for session isolation) const codeInterpreter = new CodeInterpreter({ region: AWS_REGION })

示例刻意在process内部创建解释器实例,以便实现会话级隔离:每个请求拥有独立的执行沙箱,互不污染。

3. 工具封装:5 个工具对应 5 个方法

下面完整展示 5 个工具的定义(均使用 LangChain 的tool()与 zod schema),这是理解"代码解释器如何变成 Agent 工具"的核心代码。

执行代码:

const executeCode = tool( async ({ code, language }) => { const result = await codeInterpreter.executeCode({ code, language: language || 'python', }) return result || 'Code executed successfully (no output)' }, { name: 'execute_code', description: 'Execute code in a secure sandbox. Supports Python, JavaScript, and TypeScript.', schema: z.object({ code: z.string().describe('Code to execute'), language: z .enum(['python', 'javascript', 'typescript']) .optional() .describe('Programming language (default: python)'), }), }, )

执行 Shell 命令:

const executeCommand = tool( async ({ command }) => { const result = await codeInterpreter.executeCommand({ command }) return result || 'Command executed successfully (no output)' }, { name: 'execute_command', description: 'Execute a shell command in the sandbox.', schema: z.object({ command: z.string().describe('Shell command to execute'), }), }, )

读取文件:

const readFiles = tool( async ({ paths }) => { const result = await codeInterpreter.readFiles({ paths }) return result || 'No content' }, { name: 'read_files', description: 'Read contents of files in the sandbox.', schema: z.object({ paths: z.array(z.string()).describe('List of file paths to read'), }), }, )

写入文件:

const writeFiles = tool( async ({ files }) => { const result = await codeInterpreter.writeFiles({ files }) return result || 'Files written successfully' }, { name: 'write_files', description: 'Write files in the sandbox.', schema: z.object({ files: z .array( z.object({ path: z.string().describe('File path'), content: z.string().describe('File content'), }), ) .describe('Files to write'), }), }, )

列出目录:

const listFiles = tool( async ({ path }) => { const result = await codeInterpreter.listFiles({ path: path || '.' }) return result || 'No files found' }, { name: 'list_files', description: 'List files in the sandbox directory.', schema: z.object({ path: z .string() .optional() .describe('Directory path (default: current directory)'), }), }, )

4. 组装 Agent 并完成一轮推理

const codeTools = [executeCode, executeCommand, readFiles, writeFiles, listFiles] const agent = createAgent({ model, tools: codeTools, }) const result = await agent.invoke({ messages: [{ role: 'user', content: request.prompt }], }) const finalMessage = result.messages[result.messages.length - 1] const response = finalMessage.content return JSON.stringify({ result: response, tools_used: codeTools.map((t) => t.name), interpreter_type: 'default', })

这段代码体现了 ReAct 模式的精髓:Agent 根据用户问题规划步骤,若需要计算/文件操作便自主挑选合适工具调用,最后把推理结果作为result返回给客户端。

5. 会话清理

无论成功还是失败,方法都在finally中显式停止解释器会话,避免沙箱资源泄漏:

} finally { try { await codeInterpreter.stopSession() console.log('Code interpreter session stopped') } catch { // ignore cleanup errors } }

沙箱模式说明(SANDBOX / PUBLIC / VPC)

本示例使用的是AWS 托管默认代码解释器,网络模式为SANDBOX(无网络访问),适合纯隔离计算场景。从底层编译器源码可以确认这种模式划分:

compilers/codeInterpreter.js中的buildCodeInterpreterNetworkConfiguration会将配置归一化映射为AWS::BedrockAgentCore::CodeInterpreterCustom资源的NetworkConfiguration

// mode 缺省时大写归一为 SANDBOX,支持 PUBLIC / SANDBOX / VPC const networkMode = (network.mode || 'SANDBOX').toUpperCase()

对应 CloudFormation 模式枚举:PUBLIC(可访问外网)、SANDBOX(默认,隔离无网)、VPC(私有网络,需提供 Subnets 与 SecurityGroups)

插件 README 中关于ai.codeInterpreters的配置表也印证了这一点:

属性是否必填说明
network.modesandbox(默认)、publicvpc
network.subnetsVPC 子网 ID(vpc模式必填)
network.securityGroupsVPC 安全组 ID(vpc模式必填)
descriptionCodeInterpreter 描述(≤1200 字符)
roleIAM 角色 ARN 或定制化对象
tags资源标签键值对

因此:只要你的场景是"隔离的数值/数据处理",默认解释器(如本示例)就是最省事的方案;当 Agent 需要调用外部 API、抓取网页等联网能力时,才需要显式声明一个network.mode: public的自定义解释器。

补充:需要公网时的自定义解释器

仓库提供了配套对照示例 langgraph-code-interpreter-custom,两示例的差异可概括为:

维度默认解释器(本示例)自定义解释器(custom 示例)
网络模式SANDBOX(无网络)PUBLIC(可访问公网)
标识AWS 托管(aws.codeinterpreter.v1自定义解释器 ID
典型场景隔离计算外部 API 调用、网页抓取

自定义示例的serverless.yml会在ai.codeInterpreters下定义解释器、通过!GetAtt拿到CodeInterpreterId写入环境变量,并手动授予StartCodeInterpreterSession/InvokeCodeInterpreter/StopCodeInterpreterSession权限;而本示例由于使用托管默认解释器,上述 IAM 授权全部由插件自动生成,无需任何手工配置

从部署到端到端验证

1. 部署

在示例目录下执行:

npm install sls deploy

前置条件(与仓库其他 LangGraph JS 示例一致,参见 langgraph-basic README):

  • Node.js 20+
  • Docker(用于自动构建容器镜像)
  • 已配置 AWS 凭证
  • Serverless Framework CLI(npm install -g serverless

sls deploy完成后,从 CloudFormation 输出中取出 Agent 的Runtime ARN。按插件约定,每个 Agent 资源都会自动生成形如{Name}RuntimeArn的输出(AgentCore 插件的输出命名规则见 CloudFormation Outputs 一节),因此本例可在部署输出中找到codeAgentRuntimeArn

2. 本地端到端测试

测试脚本通过InvokeAgentRuntimeCommand直接调用已部署的 Agent,读取环境变量RUNTIME_ARN与可选AWS_REGION,并为每次运行生成随机SESSION_ID

RUNTIME_ARN=<your-runtime-arn> node test-invoke.js

脚本内置了两组真实场景的测试用例(见 test-invoke.js):

  • Test 1:让 Agent"编写并执行 Python 代码,计算并展示前 20 个斐波那契数";
  • Test 2:让 Agent"生成 1~100 之间的 10 个随机数,并计算它们的均值、中位数与标准差"。

这两组用例都要求模型真正调用execute_code工具让沙箱执行代码,而不是凭语言模型"猜答案",能非常直观地验证代码解释器是否正常工作。

调用协议方面值得注意的实现细节(同样来自test-invoke.js):

const command = new InvokeAgentRuntimeCommand({ agentRuntimeArn: RUNTIME_ARN, runtimeSessionId: SESSION_ID, payload: Buffer.from(JSON.stringify({ prompt: inputText })), contentType: 'application/json', accept: 'application/json, text/event-stream', })
  • payload的 JSON 结构{ prompt }必须与index.jsrequestSchema的 zod 声明严格一致;
  • accept同时声明 JSON 与text/event-stream,脚本对异步迭代的响应体逐块聚合后尝试JSON.parse,优先输出result字段。

此外,index.js通过tools_used字段会把本次实际调用的工具列表随结果返回,方便你在测试输出中确认 Agent 是否真的按预期执行了代码——例如{"result":"...", "tools_used":["execute_code"], "interpreter_type":"default"}

3. 更多验证与清理手段

插件为 AgentCore 资源提供了一组配套 CLI 命令(见插件 README 的 Commands 一节),部署完成后也可以直接调用:

sls invoke --agent codeAgent -d "Hello" # 直接调用已部署的 Agent sls logs --agent codeAgent # 拉取 Agent 运行日志 sls package # 仅生成 CloudFormation,不部署

不再需要时执行资源清理:

sls remove

延伸阅读

如果你希望进一步探索 AgentCore 代码执行能力的边界,建议继续阅读仓库内以下相关内容:

  • 自定义代码解释器示例(JavaScript):同主题的 PUBLIC 网络版对照实现;
  • 自定义代码解释器示例(Python):Python 语言版本的自定义解释器写法;
  • 代码解释器编译器源码:底层 CloudFormation 资源生成逻辑;
  • Bedrock AgentCore Plugin 文档:ai配置全部资源类型的完整参考与输出变量说明;
  • langgraph-basic 示例:理解"免 Dockerfile 自动构建"的 Agent 基础部署方式。

【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询