Amazon Bedrock AgentCore 开发实战(一):本地构建 AI Agent
在 AI Agent 开发过程中,快速迭代和即时反馈至关重要。Amazon Bedrock AgentCore 提供了完整的本地开发支持,让开发者能够在本地环境中构建、测试和调试 Agent,然后无缝部署到云端。
本文将带您从零开始,在本地搭建 AgentCore 开发环境,并通过详细的代码解析,帮助您深入理解每一个技术细节。
Amazon Bedrock AgentCore 简介
Amazon Bedrock AgentCore 是一套专为 AI Agent 设计的企业级基础设施服务。它解决了 Agent 从原型到生产过程中的核心挑战:
- AgentCore Runtime:无服务器运行时环境,支持最长 8 小时的任务执行和 100MB 的请求负载
- AgentCore Memory:提供短期和长期记忆管理,支持跨会话的上下文保持
- AgentCore Gateway:统一的工具网关,支持 MCP 协议的工具发现和调用
- AgentCore Identity:安全的身份认证和授权管理
本地开发的优势在于:开发者可以在熟悉的环境中快速验证想法,无需等待云端部署,同时保持与生产环境一致的代码结构。
第一部分:环境准备
1.1 安装 Python 包管理器
我们推荐使用 uv 作为 Python 包管理器,它具有更快的依赖解析速度和更可靠的环境隔离能力。
macOS 和 Linux 系统:
1 | curl -LsSf https://astral.sh/uv/install.sh | sh |
Windows 系统:
1 | powershell -c "irm https://astral.sh/uv/install.ps1 | iex" |
安装完成后,请重新打开终端以使环境变量生效。
1.2 配置 AWS 凭证
AgentCore 需要访问 Amazon Bedrock 服务,因此需要配置有效的 AWS 凭证。
1 | # 验证当前凭证配置 |
如果尚未配置凭证,请执行:
1 | aws configure |
系统会提示您输入 Access Key ID、Secret Access Key、默认区域和输出格式。
1.3 开启模型访问权限
在 AWS 控制台中,导航至 Amazon Bedrock 服务,在”Model access”页面中启用 Anthropic Claude 系列模型的访问权限。本文示例使用 Claude Sonnet 4 模型。
1.4 创建项目并安装依赖
1 | # 创建新项目,指定 Python 版本为 3.13 |
依赖包说明:
bedrock-agentcore:AgentCore 的 Python SDK,提供运行时封装和服务集成strands-agents:Strands Agent 框架,简化 Agent 的构建过程bedrock-agentcore-starter-toolkit:部署工具包,提供 CLI 命令和自动化部署能力
第二部分:构建第一个本地 Agent
2.1 创建 Agent 入口文件
在项目根目录下创建 main.py 文件:
1 | from bedrock_agentcore import BedrockAgentCoreApp |
2.2 代码逐行解析
让我们详细分析每一部分代码的作用:
导入模块:
1 | from bedrock_agentcore import BedrockAgentCoreApp |
BedrockAgentCoreApp 是 AgentCore 应用的核心类。它封装了 HTTP 服务器、请求路由和生命周期管理,使您的 Agent 代码能够以标准化的方式运行,无论是在本地还是云端。
1 | from strands import Agent |
Agent 是 Strands 框架的核心类,负责管理对话流程、工具调用和模型交互。它提供了简洁的 API 来构建具有推理能力的 AI Agent。
1 | from strands.models import BedrockModel |
BedrockModel 是 Bedrock 模型的封装类,处理与 Amazon Bedrock 服务的通信,包括认证、请求格式化和响应解析。
创建应用实例:
1 | app = BedrockAgentCoreApp(debug=True) |
创建 AgentCore 应用实例。debug=True 参数启用调试模式,会输出详细的请求和响应日志,便于开发阶段排查问题。在生产环境中,建议将此参数设为 False。
配置模型:
1 | model = BedrockModel( |
model_id:指定使用的基础模型。这里使用 Claude Sonnet 4,us.前缀表示使用美国区域的跨区域推理端点temperature:控制输出的随机性,范围 0-1。较低的值产生更确定性的输出,较高的值增加创造性max_tokens:限制单次响应的最大 token 数量,防止输出过长
创建 Agent:
1 | agent = Agent( |
model:传入上面配置的模型实例system_prompt:系统提示词,定义 Agent 的角色和行为准则。这段文本会在每次对话开始时发送给模型,引导其行为
定义入口函数:
1 |
|
@app.entrypoint 装饰器将 invoke 函数注册为 Agent 的入口点。当收到 HTTP 请求时,AgentCore 会自动调用此函数,并将请求体解析为 payload 字典传入。
1 | user_message = payload.get("prompt", "") |
从请求负载中提取 prompt 字段。使用 get 方法并提供默认值,可以安全地处理字段缺失的情况。
1 | if not user_message: |
输入验证:确保用户提供了有效的输入。返回的字典会被自动序列化为 JSON 响应。
1 | result = agent(user_message) |
调用 Agent 处理用户消息。Agent 会将消息发送给模型,获取响应,并在需要时执行工具调用。返回的 result 对象包含完整的对话结果。
1 | return {"response": result.message["content"][0]["text"]} |
从结果中提取文本响应并返回。result.message 是模型返回的消息对象,content 是内容数组,我们取第一个元素的 text 字段。
启动应用:
1 | if __name__ == "__main__": |
Python 的标准入口点检查。当直接运行此文件时,启动 HTTP 服务器。app.run() 默认在 0.0.0.0:8080 启动服务,这是 AgentCore Runtime 的标准端口。
2.3 运行和测试
启动 Agent:
打开终端,在项目目录下执行:
1 | uv run main.py |
您将看到类似以下的输出:
1 | INFO: Started server process [12345] |
发送测试请求:
打开另一个终端窗口,使用 curl 发送请求:
1 | curl -X POST http://localhost:8080/invocations \ |
运行结果示例:
1 | { |
从响应结果可以看到,Agent 成功接收了请求并返回了结构化的回答。响应时间约为 9 秒,这包括了模型推理的时间。
请求解析:
-X POST:指定 HTTP 方法为 POSThttp://localhost:8080/invocations:AgentCore 的标准调用端点-H "Content-Type: application/json":设置请求头,表明请求体为 JSON 格式-d '{"prompt": "..."}':请求体,包含发送给 Agent 的消息| jq .:将响应通过 jq 工具格式化输出(需要预先安装 jq)
第三部分:为 Agent 添加工具能力
Agent 的真正威力在于能够调用外部工具来完成任务。接下来,我们将为 Agent 添加自定义工具。
3.1 安装工具依赖
1 | uv add strands-agents-tools |
strands-agents-tools 包含了一系列预构建的工具,如计算器、文件操作等。
3.2 创建带工具的 Agent
更新 main.py 文件:
1 | from bedrock_agentcore import BedrockAgentCoreApp |
3.3 工具定义详解
@tool 装饰器:
1 |
|
@tool 装饰器将普通 Python 函数转换为 Agent 可调用的工具。Strands 框架会自动:
- 提取函数签名作为工具的输入参数定义
- 解析 docstring 作为工具的描述信息
- 处理参数类型转换和验证
类型注解的重要性:
1 | def get_weather(city: str) -> str: |
city: str:参数类型注解,告诉模型这个参数应该是字符串类型-> str:返回值类型注解,表明函数返回字符串
类型注解不仅是代码文档,更是模型理解工具用法的关键信息。模型会根据这些信息决定如何构造工具调用参数。
Docstring 规范:
1 | """ |
Docstring 遵循 Google 风格,包含三个部分:
- 第一行:工具的简要描述,模型会用它来判断何时使用此工具
Args部分:每个参数的详细说明,包括示例值Returns部分:返回值的描述
清晰的 docstring 能显著提高模型选择和使用工具的准确性。
带默认值的参数:
1 | def search_database(query: str, limit: int = 5) -> str: |
limit: int = 5 定义了一个带默认值的可选参数。模型可以选择是否提供此参数,如果不提供则使用默认值 5。
注册工具到 Agent:
1 | agent = Agent( |
tools 参数接受一个工具列表。calculator 是从 strands_tools 导入的内置工具,get_weather 和 search_database 是我们自定义的工具。
3.4 测试工具调用
重启 Agent 后,测试不同类型的请求:
测试计算功能:
1 | curl -X POST http://localhost:8080/invocations \ |
Agent 会识别这是一个数学计算问题,自动调用 calculator 工具。
计算功能运行结果:
1 | { |
测试天气查询:
1 | curl -X POST http://localhost:8080/invocations \ |
Agent 会调用 get_weather 工具,传入参数 city="上海"。
天气查询运行结果:
1 | { |
测试复合任务:
1 | curl -X POST http://localhost:8080/invocations \ |
这个请求需要 Agent 协调多个工具:先查询天气获取温度,然后根据条件决定是否进行计算。
复合任务运行结果:
1 | { |
从这个结果可以看到,Agent 成功地:
- 调用
get_weather工具获取北京天气 - 判断温度(22°C)超过 20 度
- 调用
calculator工具计算用电量 - 综合信息给出完整回答
第四部分:构建 MCP Server
Model Context Protocol(MCP)是一种标准化协议,允许 Agent 动态发现和调用工具。MCP Server 可以被任何支持 MCP 的客户端(如 Claude Desktop、Cursor、Kiro 等)调用。
4.1 安装 MCP 依赖
1 | uv add mcp |
4.2 创建 MCP Server
创建新文件 mcp_server.py:
1 | from mcp.server.fastmcp import FastMCP |
4.3 MCP Server 代码解析
导入 FastMCP:
1 | from mcp.server.fastmcp import FastMCP |
FastMCP 是 MCP Python SDK 提供的高级封装类,简化了 MCP Server 的创建过程。
创建 MCP Server 实例:
1 | mcp = FastMCP( |
name:Server 的名称,用于标识和日志记录host:监听地址,0.0.0.0表示接受所有网络接口的连接stateless_http=True:启用无状态 HTTP 模式,这是 AgentCore Runtime 要求的配置
定义工具:
1 |
|
@mcp.tool() 装饰器将 Python 函数注册为 MCP 工具:
- 函数名成为工具名称
- 参数类型注解定义输入参数的类型
- docstring 成为工具的描述信息
- 返回值类型注解定义输出类型
启动服务:
1 | mcp.run(transport="streamable-http") |
transport="streamable-http" 指定使用 Streamable HTTP 传输协议,这是 MCP 推荐的生产环境传输方式,支持流式响应。
4.4 运行和测试 MCP Server
启动服务:
1 | uv run mcp_server.py |
运行输出:
1 | MCP Server 启动中... |
使用 Python 客户端测试:
首先安装 MCP 客户端依赖(如果尚未安装):
1 | uv add mcp httpx |
创建测试客户端文件 mcp_client.py:
1 | import asyncio |
代码解析:
1 | from mcp import ClientSession |
导入 MCP 客户端所需的模块:
ClientSession:MCP 客户端会话管理类streamablehttp_client:Streamable HTTP 传输客户端,用于连接使用该协议的 MCP Server
1 | async with streamablehttp_client(mcp_url) as (read_stream, write_stream, _): |
建立与 MCP Server 的连接,返回读写流用于双向通信。
1 | async with ClientSession(read_stream, write_stream) as session: |
创建客户端会话并初始化,这会与服务器交换能力信息。
1 | tools = await session.list_tools() |
获取服务器提供的所有工具列表。
1 | result = await session.call_tool("add_numbers", {"a": 10, "b": 20}) |
调用指定工具,传入参数字典,返回执行结果。
运行测试:
确保 MCP Server 正在运行,然后执行:
1 | uv run mcp_client.py |
运行结果:
1 | 连接到 MCP Server: http://localhost:8000/mcp |
使用 curl 测试(CLI 方式):
MCP Server 使用 Streamable HTTP 传输协议,需要设置正确的 Accept header:
1 | # 初始化连接 |
1 | # 列出可用工具 |
1 | # 调用 add_numbers 工具 |
curl 响应示例:
列出工具的响应:
1 | { |
调用工具的响应:
1 | {"jsonrpc": "2.0", "id": 3, "result": {"content": [{"type": "text", "text": "30"}]}} |
注意:curl 命令必须包含
-H "Accept: application/json, text/event-stream"header,否则会收到 “Not Acceptable” 错误。
使用 MCP Inspector 测试(可选):
MCP Inspector 是一个可视化测试工具,提供图形界面来测试 MCP Server:
1 | npx @modelcontextprotocol/inspector |
在浏览器中打开 http://localhost:6274,选择 “Streamable HTTP” 传输类型,输入 MCP Server 地址 http://localhost:8000/mcp,即可进行交互式测试。您可以:
- 查看所有可用工具及其参数定义
- 手动调用工具并查看返回结果
- 调试工具执行过程
第五部分:构建 A2A Server
Agent-to-Agent(A2A)协议专为多 Agent 系统设计,允许 Agent 之间相互发现和通信。A2A 使用 JSON-RPC 格式进行通信,并通过 Agent Card 描述 Agent 的能力。
5.1 安装 A2A 依赖
1 | uv add 'strands-agents[a2a]' |
5.2 创建 A2A Server
创建新文件 a2a_server.py:
1 | import os |
5.3 A2A Server 代码解析
导入 A2A 模块:
1 | from strands.multiagent.a2a import A2AServer |
A2AServer 是 Strands SDK 提供的 A2A 协议实现,需要安装 strands-agents[a2a] 扩展包。
环境变量配置:
1 | runtime_url = os.environ.get( |
从环境变量读取运行时 URL,如果未设置则使用本地默认值。这种设计使同一份代码可以在本地和云端运行,只需通过环境变量切换配置。部署到 AgentCore Runtime 时,该环境变量会自动设置。
创建 A2A Server:
1 | a2a_server = A2AServer( |
agent:要暴露的 Strands Agent 实例http_url:Agent 的可访问 URL,用于生成 Agent Card 中的端点信息serve_at_root=True:在根路径(/)提供服务,这是 AgentCore Runtime 要求的配置
组合 FastAPI 应用:
1 | app = FastAPI(title="Calculator A2A Server") |
我们创建一个 FastAPI 应用作为容器,添加健康检查端点,然后将 A2A Server 挂载到根路径。A2A Server 默认使用 9000 端口,与 MCP Server(8000)和 AgentCore Runtime(8080)区分。
5.3 运行和测试 A2A Server
启动服务:
1 | uv run a2a_server.py |
获取 Agent Card:
1 | curl http://localhost:9000/.well-known/agent-card.json | jq . |
Agent Card 是 A2A 协议的核心概念,它描述了 Agent 的能力、支持的协议和调用方式。其他 Agent 可以通过读取 Agent Card 来了解如何与此 Agent 交互。
调用 Agent(使用 JSON-RPC 格式):
由于我们创建的是 Calculator Agent(计算器 Agent),测试请求应该是数学计算相关的问题:
1 | curl -X POST http://localhost:9000/ \ |
请求格式解析:
jsonrpc:JSON-RPC 协议版本id:请求标识符,用于匹配响应method:调用的方法,message/send是发送消息的标准方法params.message:消息内容role:消息角色,user表示用户消息parts:消息内容数组,支持多模态(文本、图片等)messageId:消息唯一标识
运行结果示例:
1 | { |
从响应可以看到,Calculator Agent 成功调用了 calculator 工具完成了数学计算,并返回了详细的计算过程。
第六部分:本地容器化部署
在部署到云端之前,我们可以先在本地使用 Docker 容器运行 Agent。AgentCore Starter Toolkit 提供了便捷的 CLI 命令,可以自动生成 Dockerfile 并在本地构建运行容器,无需手动编写配置文件。
7.1 配置 Agent
首先使用 agentcore configure 命令配置 Agent:
1 | agentcore configure -e main.py |
参数说明:
-e main.py:指定 Agent 的入口文件
如果是首次运行,CLI 会以交互式方式引导您完成配置,包括设置 Agent 名称、选择区域等。您也可以使用 -ni(non-interactive)参数跳过交互式提示,使用默认值:
1 | agentcore configure -e main.py -ni |
执行后,CLI 会在项目目录下生成 .agentcore/ 配置目录,包含配置文件和 Dockerfile。
7.2 本地容器运行
使用 agentcore launch --local 命令在本地 Docker 容器中构建并运行 Agent:
1 | agentcore launch --local |
此命令会自动:
- 生成优化的 Dockerfile
- 构建容器镜像
- 启动容器并映射端口 8080
- 挂载本地 AWS 凭证到容器中
- 输出容器日志到终端
运行输出示例:
1 | 🏠 Launching Bedrock AgentCore (local mode)... |
按 Ctrl+C 可以停止容器。
注意:
agentcore launch --local需要本地安装 Docker、Finch 或 Podman。
7.3 测试容器化 Agent
在另一个终端窗口中,发送测试请求:
1 | curl -X POST http://localhost:8080/invocations \ |
运行结果:
1 | { |
7.4 本地容器运行的优势
使用 agentcore launch --local 相比直接 uv run main.py 有以下优势:
- 环境一致性:容器环境与云端 AgentCore Runtime 一致,避免”本地能跑,云端报错”的问题
- 依赖隔离:所有依赖都在容器内,不会污染本地 Python 环境
- 真实模拟:模拟生产环境的资源限制和网络配置
- 快速验证:在部署到云端前,先在本地验证容器化后的行为
7.5 查看生成的 Dockerfile
如果您想了解 CLI 生成的 Dockerfile 内容,可以查看:
1 | cat .agentcore/Dockerfile |
生成的 Dockerfile 示例:
1 | FROM public.ecr.aws/docker/library/python:3.13-slim |
CLI 自动生成的 Dockerfile 遵循最佳实践,包括多阶段构建优化、依赖缓存等。
第七部分:部署到云端
本地开发和容器化测试完成后,可以使用 AgentCore Starter Toolkit 将 Agent 部署到 AWS。
7.1 使用 CLI 部署
如果您在第六部分已经执行过 agentcore configure,可以直接部署。否则先配置:
1 | agentcore configure -e main.py |
部署 Agent:
1 | agentcore launch |
此命令会(默认使用 CodeBuild 云端构建):
- 使用 AWS CodeBuild 构建 ARM64 容器镜像
- 将镜像推送到 ECR
- 创建 AgentCore Runtime
- 等待 Runtime 就绪
部署模式说明:
| 命令 | 构建位置 | 运行位置 | 说明 |
|---|---|---|---|
agentcore launch |
云端 (CodeBuild) | 云端 (AgentCore Runtime) | 推荐,无需本地 Docker |
agentcore launch --local |
本地 | 本地 | 本地开发测试 |
agentcore launch --local-build |
本地 | 云端 | 需要自定义构建时使用 |
测试云端 Agent:
1 | agentcore invoke '{"prompt": "你好,这是来自云端的测试"}' |
查看状态:
1 | agentcore status |
7.2 使用 Python SDK 部署
对于需要在 Jupyter Notebook 或 Python 脚本中进行更多控制的场景,可以使用 Python SDK:
1 | from bedrock_agentcore_starter_toolkit import Runtime |
配置输出示例:
1 | Bedrock AgentCore configured: /path/to/project/.bedrock_agentcore.yaml |
部署模式说明:
Python SDK 支持与 CLI 相同的三种部署模式:
1 | # 默认模式:CodeBuild 云端构建 + 云端部署(推荐) |
7.3 清理资源
1 | # 预览将要删除的资源(不实际删除) |
第八部分:常见问题与解决方案
8.1 端口占用
问题: 启动时提示端口 8080 已被占用
解决方案:
1 | # 查找占用端口的进程 |
8.2 模型访问权限
问题: 调用时报 AccessDeniedException
解决方案:
- 确认 AWS 凭证有效:
aws sts get-caller-identity - 确认已在 Bedrock 控制台开启模型访问权限
- 确认使用的区域支持所选模型
8.3 工具未被调用
问题: Agent 没有使用定义的工具
解决方案:
- 检查
@tool装饰器是否正确应用 - 确保 docstring 清晰描述了工具的用途
- 在 system_prompt 中明确说明可用的工具
- 检查工具是否已添加到 Agent 的
tools列表
8.4 部署超时
问题: agentcore launch 执行时间过长
解决方案:
- 检查网络连接是否稳定
- 确认 IAM 权限包含 CodeBuild、ECR、Bedrock 相关权限
- 查看 CodeBuild 控制台中的构建日志
8.5 本地容器构建失败:Multiple top-level modules
问题: 执行 agentcore launch --local 时报错:
1 | Multiple top-level modules discovered in a flat-layout: ['main', 'mcp_server', 'a2a_server', ...] |
原因: 项目目录中有多个 Python 文件(如 main.py、mcp_server.py、a2a_server.py 等),setuptools 无法确定哪个是主模块。
解决方案:
在 pyproject.toml 中添加 [tool.setuptools] 配置,明确指定要打包的模块:
1 | [project] |
添加 [tool.setuptools] 部分后,重新运行 agentcore launch --local 即可。
8.6 本地容器运行时 OTLP 导出错误
问题: 执行 agentcore launch --local 后,日志中出现大量重试警告:
1 | Transient error StatusCode.UNAVAILABLE encountered while exporting traces to localhost:4317, retrying in 1s. |
原因: 容器内的 OpenTelemetry 尝试将追踪数据发送到 localhost:4317(默认 OTLP 端点),但本地没有运行 OTLP 接收服务。
解决方案:
这个警告不影响 Agent 正常运行,可以忽略。如果想消除警告,可以禁用 OTLP 导出:
1 | agentcore launch --local \ |
总结
本文详细介绍了 Amazon Bedrock AgentCore 的本地开发流程:
- 环境搭建:安装 uv、配置 AWS 凭证、创建项目
- 基础 Agent:使用 BedrockAgentCoreApp 和 Strands Agent 构建简单的对话 Agent
- 工具集成:通过 @tool 装饰器定义自定义工具,扩展 Agent 能力
- MCP Server:构建 MCP 服务,支持工具发现和调用
- A2A Server:构建支持 Agent 间通信的服务
- 本地容器化:使用
agentcore launch --local在本地模拟生产环境 - 云端部署:使用
agentcore launch一键部署到 AWS
通过本文的学习,您已经掌握了从本地开发到容器化测试,再到云端部署的完整流程。这种渐进式的开发方式能够帮助您:
- 在本地快速验证 Agent 逻辑
- 通过容器化确保环境一致性
- 无缝迁移到 AgentCore Runtime 生产环境
本地开发与云端部署的无缝衔接,使开发者能够在保持高效迭代的同时,确保代码在生产环境中的可靠运行。
相关资源
- Amazon Bedrock AgentCore 官方文档:https://docs.aws.amazon.com/bedrock/latest/userguide/agentcore.html
- Strands Agents SDK 文档:https://strandsagents.com/
- MCP 协议规范:https://modelcontextprotocol.io/
- A2A 协议规范:https://google.github.io/A2A/
- AgentCore Starter Toolkit:https://github.com/aws/bedrock-agentcore-starter-toolkit
- AgentCore Python SDK:https://github.com/aws/bedrock-agentcore-sdk-python
- A2A 协议规范:https://a2a-protocol.org/
Amazon Bedrock AgentCore 开发实战(一):本地构建 AI Agent


