Bedrock AgentCore实战:Terraform、LangGraph及发现的潜在问题
AgentCore的运行时、网关、内存及身份功能是什么,以及六种部署注意事项、大致成本,并与在AWS上自行构建代理进行对比分析。
来源: Amazon Bedrock AgentCore, What It Is, How to Use It, and What Hosting Looks Like
在 AWS 上手动托管 AI 智能体意味着需要自行解决会话隔离、工具访问、内存管理以及身份认证等问题。Amazon Bedrock AgentCore 就是针对同一问题的托管版本,自 2025 年 10 月起正式提供。判断这类平台的一个实用方法就是停止阅读相关资料,直接动手构建实际应用,而这里就实现了一个小型只读的 DevOps 分类智能体来满足这一需求。该智能体是使用 Terraform 而非 AWS 自带的 CLI 工具进行部署的,代码也是用 LangGraph 编写而非 AWS 的 Strands SDK。这两个选择都是经过深思熟虑的,因为目的在于了解在非标准化环境中哪些方案依然可行。
AgentCore 是什么
AgentCore是一组管理组件的集合,负责处理在生产环境中运行代理时那些繁琐且关键的环节,同时允许现有的任何代理框架继续使用。其核心承诺是支持任意框架,这一承诺在大多数情况下都得到了实现。LangGraph、LangChain、CrewAI、Strands以及普通的API调用均被支持。
这些组件及其功能如下:
- Runtime负责托管代理的代码,并为每个会话提供独立的微虚拟机。空闲时它会缩减到零资源占用,而在运行时会按秒计费。
- Gateway可将现有的Lambda函数或API转换为代理能够调用的MCP兼容工具,因此无需手动编写MCP服务器。
- Memory以短期事件的形式存储对话历史,还可根据需要跨会话提取长期的语义知识。
2026 年 6 月的 AWS Summit 上宣布新增了 Harness 层和原生网页搜索功能。由于这些功能尚处于发展初期,关键基础设施暂不宜依赖它们。
入门流程已经重新设计过一次。原来的 Starter Toolkit CLI 现已过时,取而代之的是基于 CDK 的 npm 包 @aws/agentcore。有些教程将 agentcore 的配置和启动描述为两个独立的步骤,其实那是在介绍旧有的流程。这一细节很重要,因为它反映了变化的速度:在产品正式发布九个月后,入门路径就已经被重新设计,因此任何关于该产品的描述都具有时效性。
测试项目
该代理可以回答诸如是否有 CloudWatch 警报触发,或是某个特定 EC2 实例的状态如何之类的问题。它拥有两个真正的只读工具,因此其所能使用的功能仅限于观察基础设施状况,而无法对其进行修改。它能记住多轮对话的内容,且组件之间的每一次交互都会经过身份验证。
选择 LangGraph 而非 Strands 是因为 Strands 为 AWS 自研框架,在所有官方示例中都能实现最顺畅的运行流程。使用其他框架才是对“通用框架”这一宣称的真实考验,而 LangGraph 则与现有工具更为匹配。出于类似原因,选择了 Terraform 而非 CLI——其向导功能可帮助快速运行演示,而此处的目标是要清晰地查看每一项 IAM 信任关系以及组件间的所有连接,而非让这些内容在后台默默生成。事实证明,这种透明度比预期更为重要。
该架构由一个运行 LangGraph 代理的运行时容器构成,该代理通过 MCP 与一个网关通信,网关则提供两个基于 Lambda 的工具。AgentCore Memory 用于存储对话内容,而 Cognito 会为每一步骤生成机器对机器的令牌。
编写脚本前请先浏览
在编写任何 Terraform 代码之前,人们先尝试过使用控制台版本进行配置,主要是为了了解哪些流程是自动化的。即使后续由 Terraform 负责实际部署,这种习惯依然值得保持,因为看过它们填充的表单后,阅读基础设施相关文件会容易得多。
无论使用何种工具处理其他环节,容器注册表都需手动操作,因为这是Terraform无法完成的步骤。创建仓库仅需在控制台完成一次操作,但镜像却必须通过其他方式获取,因为控制台上没有用于生成Dockerfile的按钮。在linux/arm64平台上,需通过终端执行“docker buildx build”命令来构建镜像,之后再将其推送。手动指定平台类型是整个流程的关键;如果不指定,镜像虽能成功构建,但在运行时尝试启动时会默默被拒绝,因为运行时仅支持Graviton架构。
镜像生成后,控制台会显示其确切的URI地址。这条字符串就是必须从手动操作的结果中传递到Terraform认知范围内的唯一状态信息,它可能被保存在tfvars文件中,也可能由仍在使用控制台的用户直接输入到运行时的容器镜像字段中。
AgentCore 的内存、网关和运行时相关设置分别位于 Bedrock 控制台的独立板块中。每个板块都是用于填写 Terraform 所定义的相同字段的表单,这很合理,因为 Terraform 在底层调用的其实是相同的 API。
- 内存设置板块需要输入名称以及短期事件的保留时长。
- 网关设置板块需要指定协议、执行角色以及调用者身份验证方式。下面将介绍的 Cognito 中 audience 与 client-id 的混淆问题就出现在这里,表现为一个强制要求选择的下拉菜单。
- 运行时设置板块需要输入注册表 URI、角色以及与网关相同的授权器配置。
一旦这些表单呈现在面前,其实并没有什么难处。但对于那些需要长期使用的场景而言,Terraform 仍然是更好的选择,因为要在三个控制台板块中依次填写七份表单,绝不是任何人愿意重复或交给同事处理的部署流程。
被咬伤的位置
图片必须是ARM64格式
运行环境仅支持Graviton架构,没有例外。在大多数笔记本电脑上使用常规的docker构建方式会生成amd64格式的镜像,这类镜像在部署时会被直接拒绝。每次构建都必须使用带有arm64平台标志的buildx命令。在Dockerfile的FROM行上方添加注释是一种简单的防护措施,否则很容易被忽略。
网关的Lambda合约
有几篇博客文章提到,Lambda事件被封装在包含toolName和参数的封套中。实际上,真正的事件是以扁平字典形式存在的工具输入属性。真正的工具名称则存储在context.client_context.custom下的bedrockAgentCoreToolName键中,该名称以网关目标名称为前缀,并加上三个下划线作为分隔符。只有直接阅读AWS官方的Lambda目标文档,而非依赖二手总结,才能发现这一差异。关于该产品的许多信息要么来自预览阶段,要么本身就是错误的。
Cognito令牌缺少aud声明
这个问题需要花些时间来分析。由于使用了 Cognito 进行机器对机器认证,且通过 client_credentials 授权方式无需人工登录,因此 Cognito 会颁发访问令牌而非身份令牌。访问令牌从不包含 aud 字段,只有身份令牌才包含该字段;而在机器对机器场景中不存在需要颁发令牌的用户,因此也不会有身份令牌。需将 AgentCore 的 JWT 授权器配置为根据此类令牌检查 allowed_audience,这样就会返回无明确原因的 403 错误。解决办法是使用 allowed_clients,它能够检查 Cognito 访问令牌中确实存在的 client_id 字段。
boto3 无法调用受 JWT 保护的运行时环境
这真是最大的惊喜——它并非某种变通方法,而是直接出现在AWS官方API参考文档中的说明。如果代理使用OAuth风格的接入认证方式,就根本无法通过AWS SDK调用InvokeAgentRuntime函数。此时需要通过原始的HTTPS请求来实现,该请求在Authorization标头中包含承载令牌,并将运行时环境的全局唯一标识符以百分比编码的形式嵌入到URL路径中。所有boto3示例都基于默认的IAM及SigV4认证路径。一旦配置了自定义_jwt_authorizer(对于任何非纯内部系统而言都是必要的),这类示例就不再适用了。
Python包冲突问题
mcp Python 包已发布 2.0.0 版本,该版本重新命名了内部模块,而 langchain-mcp-adapters 尚未跟进更新。它声明兼容 mcp 1.24.0 及更高版本,但未设定上限,因此直接使用 pip 安装会导致不兼容。至少会出现明显的导入错误,而非隐性的漏洞。测试项目将 mcp 固定在 1.29.0 版本,需检查这一固定版本是否仍有必要,因为一些悄无声息的补丁可能会让修复措施变成多余的冗余代码。
部署并非简单的应用操作
运行时资源需要一个已存储在注册表中的容器镜像,而 Terraform 无法在其自身的应用流程中构建并推送镜像。正确的操作顺序是先创建注册表仓库,在 Terraform 之外构建并推送镜像,然后再应用其他所有内容。那些使用更大规模 AgentCore 架构的工程师通过 null_resource 将 CodeBuild 整合到 Terraform 流程中,以此弥补这一缺陷。这是合理的下一步举措,也表明这个问题较为普遍,并非个人操作失误。
对话状态应集中存储在一处
这并非漏洞,而是设计选择:该智能体刻意不使用 LangGraph 自带的对话状态检查点器,尽管大多数 LangGraph 教程都将其设为默认选项。运行时的会话规模可降至零,并且可在多次调用之间切换全新的微虚拟机,因此仅存储在进程内存中的数据都会消失。AgentCore Memory 才是这一机制中持久化的部分。在 Memory 旁边运行本地检查点器会导致同一对话出现两份相互矛盾的记录,迟早会在已说内容上产生分歧。必须二选一。Memory 是更合理的选择,因为它能在冷启动后依然保留数据。
成本是多少
定价采用按使用量计费模式且无最低消费限制,这对于大部分时间都在等待大语言模型响应的系统而言十分合适。其结果是账单由多个独立计费的项目加总而成,而非一个单一数字。截至本文撰写时:
- 运行时费用约为每 vCPU 小时 9 美分,每 GB 小时约 1 美分,按秒计费且最低计费单位为 1 秒,因此一个持续三秒的查询将按三秒收费,而非向上取整到一分钟。
- 网关的调用费用约为每千次 MCP 调用 0.5 美分。
- 内存存储费用为每存储 1,000 次事件 0.25 美分,每检索 1,000 次事件 0.5 美分。
- 通过运行时或网关使用身份验证功能而非直接调用时无需付费,这一规则几乎适用于所有配置场景。
上述所有内容均未包括模型调用费用,对于超出简单测试规模的场景,这项费用将是账单中的最大支出,而且AgentCore无法影响这一数值。这其实就是Bedrock针对所选模型收取的费用。新账户会获得200美元的AgentCore积分,足够多次构建和拆解类似项目。在参考任何数字之前都应先查看官方定价页面,因为自该服务正式推出以来价格已多次变动,未来很可能还会继续变化。
托管平台还是自行搭建主机?
手工构建的代理托管架构提供了一个有用的对比参考,而客观的结论其实有两面性。AgentCore提供了会话隔离、托管式MCP网关、持久化内存以及相互协作的认证机制,其效率远高于手动设计IAM信任策略——而我们之前恰恰在那些策略上花费了数小时时间。这大大减轻了大量重复性的基础设施工作负担。对于那些负责开发代理而非其底层托管平台的人来说,这种权衡显然是值得的。
该平台并未提供关于应允许代理执行哪些操作、实际应用中的成本应定为多少,或是何种框架更优的判断标准——实际上,任何带有AWS官方最佳文档支持的框架都可被视为优选。此外,该平台也缺乏稳定性。CLI已经重新构建过一次,至少有三个地方出现AWS文档与实际API在细节上存在差异,尽管这些差异影响不大但足以造成问题。不过这并不意味着该产品很糟糕,它只是体现了一种正在快速发展的新兴托管服务特性:在开始使用之前了解其情况会比在部署过程中才发现问题要好得多。
实际上所有内容都是实际构建完成的,而非仅停留在描述层面。每个资源都通过 Terraform 完成配置,代理功能也已实现,Lambda 工具也存在,而且测试套件无需 AWS 凭证,因此所有可验证的内容都已率先得到确认。在类似的构建过程中,最容易遇到问题的地方通常是两处:镜像的 ARM64 平台标识,以及 Cognito 授权设置中的 allowed_clients 参数。