在 AWS Bedrock AgentCore 上部署 CopilotKit 智能体:LangGraph 与 Strands 双模式实战指南
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
导读
本文基于 CopilotKit 仓库中的 examples/integrations/agentcore 示例,完整讲解如何将 CopilotKit 前端(Vite + React 聊天界面、生成式图表、共享 Todo 画布与内联工具渲染)部署到 AWS Bedrock AgentCore 运行时之上。读完本文,你将掌握两条部署路径:基于 LangGraph 的单智能体与基于 Strands 的单智能体,能够独立完成从环境准备、CDK 基础设施部署、前端发布到本地 Docker 全链路调试的全部操作,并理解 AG-UI 桥接、Cognito 鉴权与 AgentCore Gateway MCP 工具调用的底层工作原理。
示例概览与能力清单
该示例项目构建了一个"带生成式图表的聊天 UI + 共享状态 Todo 画布 + 内联工具渲染"的完整应用,后端运行在 AWS Bedrock AgentCore 上,且提供了 LangGraph 与 Strands 两种智能体实现供选择:
- 生成式图表:智能体调用
query_data工具读取数据库(agents/langgraph-single-agent/tools/query_data.py),再调用pieChart、barChart等前端工具渲染图表组件(见 frontend/src/components/generative-ui/BarChart.tsx); - 共享状态 Todo 画布:通过
manage_todos/get_todos工具维护用户级共享状态,前端由 frontend/src/components/canvas/TodoCanvas.tsx 渲染; - 内联工具渲染:CopilotKit 将 AgentCore 流式返回的 AG-UI 事件渲染为原生 UI 组件。
项目目录结构中的关键组成(对应 README 的 "What's inside"):
| 组成部分 | 作用 |
|---|---|
frontend/ | Vite + React,包含 CopilotKit 聊天、图表、Todo 画布 |
agents/langgraph-single-agent/ | LangGraph 智能体,含工具与共享 Todo 状态 |
agents/strands-single-agent/ | Strands 智能体,含工具与共享 Todo 状态 |
pyproject.toml/uv.lock | scripts/辅助脚本的 Python 依赖 |
infra-cdk/ | CDK 定义:Cognito、AgentCore、CopilotKit Lambda 桥、Amplify |
infra-terraform/ | 不依赖托管 Intelligence 的基础 AgentCore 基础设施(Terraform 版) |
docker/ | 本地开发的 Docker Compose 编排 |
前置条件与依赖管理
在开始前,需要准备以下工具链(对应 README 的 Prerequisites 表格):
| 工具 | 要求 |
|---|---|
| AWS CLI | 已配置(执行过aws configure) |
| Node.js | 18+ |
| uv | 任意较新版本 |
| Docker | 运行中 |
值得注意的一点是:Python 端完全由 uv 管理。uv 会负责解析并安装 Python 解释器,因此不存在单独的 Python 安装步骤。这与仓库中 Agent 构建的方式一致——两个智能体的 Dockerfile 均使用uv sync --locked安装依赖,确保镜像获取到的是 lockfile 中固定的依赖集合,而非"当天能解析出的任何版本"。
Agent 依赖的细节约定
每个位于agents/下的单智能体目录(langgraph-single-agent/与strands-single-agent/)都是独立的 uv 项目,各自拥有自己的uv.lock。而agents/utils/是例外:它是被两个 Dockerfile 通过COPY复制的共享源码,本身不是项目,因此没有自己的pyproject.toml或 lockfile——凡是它 import 的包,都必须由复制它的每个智能体在自己项目的依赖中显式声明。
当你需要给某个 Agent 新增依赖时(对应 README 的 "Agent dependencies"):
cd agents/langgraph-single-agent uv add some-package # 或者直接编辑 pyproject.toml,然后执行:uv lock无论走哪条路,都要把更新后的uv.lock与pyproject.toml一起提交。Terraform 会对两者做哈希校验,因此依赖变更会在下一次 apply 时自动触发镜像重新构建。
托管 Intelligence 凭据配置
在部署或本地运行之前,先创建根环境文件(对应 README 的 "Managed Intelligence credentials"):
cp .env.example .env然后在.env中填写:
CPK_INTELLIGENCE_API_KEY:你的托管 CopilotKit Intelligence 项目的 API Key,必填;CPK_TELEMETRY_ID:可选的遥测分析标识,非敏感信息,可以留空。
.env.example的实际内容(.env.example)还包含两个被注释掉的本地 Intelligence 端点:
# INTELLIGENCE_API_URL=http://host.docker.internal:4201 # INTELLIGENCE_GATEWAY_WS_URL=ws://host.docker.internal:4401这两行用于 Docker Compose 把域名解析到运行本地 Intelligence 的主机;使用托管 Intelligence 时保持注释状态即可。
部署到 AWS
第一步:创建环境与配置
cp .env.example .env cp config.yaml.example config.yaml # 编辑 .env 和 config.yaml在config.yaml中需要设置stack_name_base与admin_user_email。从 config.yaml.example 可以看到完整可编辑项:
# ── User-editable settings ────────────────────────────────────────────────── stack_name_base: my-copilotkit-agentcore-lg # max 35 chars; used as prefix for all AWS resources admin_user_email: # e.g. you@example.com — auto-creates a Cognito user copilotkit_intelligence_api_key_secret_name: copilotkit/intelligence/api-key backend: # Set automatically by deploy scripts — do not edit. pattern: langgraph-single-agent # overwritten by deploy-langgraph.sh / deploy-strands.sh deployment_type: docker # docker (default) or zip network_mode: PUBLIC # PUBLIC (default) or VPC部署脚本会把.env中的托管 Intelligence Key 存入配置的 AWS Secrets Manager 密钥中(密钥名由copilotkit_intelligence_api_key_secret_name指定,默认copilotkit/intelligence/api-key),而 CDK 只在创建 CopilotKit Runtime Lambda 时才解析该密钥——这一流程可以在 deploy-langgraph.sh 的第 116~126 行看到:脚本先查询密钥是否存在,不存在则create-secret,存在则put-secret-value更新版本,随后把返回的VersionId以CPK_INTELLIGENCE_API_KEY_SECRET_VERSION_ID导出给 CDK。
关于端点有一个关键约束:托管 Intelligence 使用默认端点;若要使用自托管 Intelligence,必须设置 AWS 可达的端点覆盖。严禁使用localhost、127.0.0.1或仅在 Docker 内有效的host.docker.internal(它们出现在.env.example的注释中只是为本地运行准备的)。这一点在部署脚本中有对应的硬校验:validate_remote_override函数(见 deploy-langgraph.sh 第 63~76 行)会拒绝命中localhost|127.0.0.1|host.docker.internal的地址,并强制INTELLIGENCE_API_URL使用https://、INTELLIGENCE_GATEWAY_WS_URL使用wss://协议。
第二步:执行部署
./deploy-langgraph.sh # LangGraph 智能体(基础设施 + 前端) ./deploy-langgraph.sh --skip-frontend # 仅基础设施/智能体 ./deploy-langgraph.sh --skip-backend # 仅前端 # 或 ./deploy-strands.sh # AWS Strands 智能体 ./deploy-strands.sh --skip-frontend ./deploy-strands.sh --skip-backend # 仅自托管 Intelligence 时: INTELLIGENCE_API_URL=https://intelligence.example.com \ INTELLIGENCE_GATEWAY_WS_URL=wss://gateway.example.com \ ./deploy-langgraph.sh INTELLIGENCE_API_URL=https://intelligence.example.com \ INTELLIGENCE_GATEWAY_WS_URL=wss://gateway.example.com \ ./deploy-strands.sh说明要点:
- 以命令前缀方式传入的端点值会覆盖托管默认值;配合
--skip-frontend或--skip-backend时同样可以使用这一前缀; - 两个脚本使用不同的栈后缀保持隔离:LangGraph 使用
-lg,Strands 使用-st。脚本会自动改写config.yaml中的pattern(langgraph-single-agent/strands-single-agent)与stack_name_base(剥离已有的-lg/-st后缀后追加本脚本的后缀); - 首次运行基础设施部署大约需要 10~15 分钟,期间脚本会执行
npm install并调用npx cdk@latest deploy --all --require-approval never; - 部署前脚本会做完整预检(deploy-langgraph.sh 第 60~87 行):检查
aws、uv、node、docker是否安装,校验端点格式,并通过aws sts get-caller-identity验证 AWS 凭据有效。
第三步:访问应用
打开部署结束时打印的Amplify URL,使用你的邮箱登录即可。admin_user_email会在 Cognito 中自动创建对应用户。
本地开发
部署好 AWS 栈之后(本地链路依赖已部署的栈提供 Memory 与 Gateway),即可进入本地开发模式:
cp .env.example .env cp docker/.env.example docker/.env cd docker # 在 docker/.env 中填入 AWS 凭据 —— STACK_NAME、MEMORY_ID 与 aws-exports.json 会自动解析 # 使用本地 Intelligence 时,取消 ../.env 中 host.docker.internal 相关行的注释 ./up.sh --build关键体验:
- Frontend→ 保存即热更新(卷挂载 + Vite);
- Agent→ 变更后执行
docker compose up --build agent重建; - 浏览器→ 访问
http://localhost:3000,认证会重定向回 localhost。
up.sh是一个便捷包装脚本(docker/up.sh),它做三件事:从config.yaml推导栈名(根据AGENT选择-lg/-st后缀);从 CloudFormation 栈输出中读取MemoryArn并提取最后的MEMORY_ID回填到docker/.env;生成指向 localhost 的本地aws-exports.json(copilotKitRuntimeUrl指向http://localhost:3001/copilotkit),然后以--watch模式启动 Compose。
完整的本地调用链为:browser:3000 → bridge:3001 → agent:8080。AWS 仅用于 Memory 和 Gateway(SSM/OAuth2)。从 docker/docker-compose.yml 可以看到三个服务的完整定义:agent暴露 8080 端口并接收MEMORY_ID、STACK_NAME、AWS 临时凭据与AGUI_ENABLED=true等环境变量;bridge把AGENTCORE_AG_UI_URL指向http://agent:8080/invocations;frontend通过卷挂载实现热更新。docker/.env.example中明确提示:Docker 容器读不到~/.aws/credentials,需要粘贴凭据,可通过aws configure export-credentials --format env(适用于 SSO/临时凭据)生成。
架构:一次请求的完整旅程
README 给出的架构图完整描绘了运行时链路:
Browser → API Gateway → CopilotKit Lambda (Node.js, AG-UI bridge) ↓ AgentCore Runtime ↓ langgraph_agent.py / strands_agent.py ↓ MCP (OAuth2 M2M) AgentCore Gateway → Lambda tools- 鉴权:Cognito OIDC 签发 Bearer Token,从浏览器经 Lambda 转发至 AgentCore;
- AG-UI 桥:CopilotKit Lambda 是 Node.js 实现的 AG-UI 桥(位于 infra-cdk/lambdas/copilotkit-runtime),负责把前端请求转为 AG-UI
RunAgentInput协议; - 运行时:AgentCore Runtime 承载 Python 智能体;
- 工具调用:智能体通过 MCP 协议(OAuth2 M2M)连接 AgentCore Gateway,再经 Gateway 调用 Lambda 工具。
LangGraph 智能体源码视角
agents/langgraph-single-agent/langgraph_agent.py 展示了关键实现:
- 模型:
ChatBedrock使用us.anthropic.claude-sonnet-4-5-20250929-v1:0,temperature=0.1,max_tokens=16384,开启 streaming; - 持久化:
AgentCoreMemorySaver以MEMORY_ID+ 区域(默认us-east-1)把对话状态存入 AgentCore Memory; - Gateway 工具:
create_gateway_mcp_client()从 SSM 参数/{stack_name}/gateway_url读取 Gateway 地址,并用@requires_access_token装饰器配合 M2M 流程换取新鲜 Bearer Token,通过MultiServerMCPClient的streamable_http传输接入;Gateway 不可用时(如纯本地运行)会降级为gateway_tools = []并继续运行; - CopilotKit 集成:
create_agent挂载CopilotKitMiddleware()与StateStreamingMiddleware(将manage_todos工具的参数todos映射为状态键todos,实现共享状态的前端即时更新),再封装为LangGraphAGUIAgent; - 身份提取:优先从 JWT 上下文提取
actor_id,失败时回退到forwarded_props中的actor_id/actorId/user_id/userId/sub键,两者皆缺则报错拒绝执行; - 异常处理:任何运行异常都会以 AG-UI 的
RunErrorEvent流式返回给前端。
Strands 智能体源码视角
agents/strands-single-agent/strands_agent.py 则展示了 Strands 侧的等价实现:
- 记忆:
AgentCoreMemorySessionManager按memory_id + session_id + actor_id提供云端持久会话历史,与 LangGraph 方案的AgentCoreMemorySaver思路一致; - 会话管理:
session_id取自请求thread_id,缺失时回退为actor_id,确保每个用户拥有独立持久会话线程;同时把thread_id回写进 payload,以命中预置的 agent 缓存; - Gateway 客户端:
MCPClient接收一个lambda工厂而非直接连接对象,确保每次 MCP 重连时重新获取新鲜的get_gateway_access_token()(源码注释明确说明这是为了避免"闭包陷阱"); - 共享状态:
manage_todos配置了state_from_args(工具调用即触发StateSnapshotEvent让前端立刻更新,无需等待工具结果返回)与predict_state映射;state_context_builder把当前 todos 注入系统提示词,省去单独的get_todos工具; - 前端工具行为:
pieChart、barChart、toggleTheme、scheduleTime等前端工具配置continue_after_frontend_call=False并保留MessagesSnapshotEvent——源码注释特别指出,若无此配置流会中止,且 CopilotKit v2 会因缺少快照而清空 UI; - 追踪:
trace_attributes记录user.id与session.id,便于可观测性关联。
两条路径共享同一套前端与基础设施,差异仅在智能体实现,这正体现了该示例"Pick LangGraph or Strands"的设计意图。
拆除资源
不再需要时,可通过 CDK 一键销毁(注意两个栈使用不同的输出目录):
cd infra-cdk && npx cdk@latest destroy --all --output ../cdk.out-lg # LangGraph 栈 cd infra-cdk && npx cdk@latest destroy --all --output ../cdk.out-st # Strands 栈备选路径:Terraform 基础设施
如果不想使用托管 Intelligence 的 Threads 能力,仓库还提供了纯 Terraform 的基础设施方案(infra-terraform/README.md)。它覆盖基础的 AgentCore 智能体、Gateway、认证与前端基础设施,但不会把托管 Intelligence 凭据注入 CopilotKit Runtime Lambda——需要托管 Threads 与 Intelligence 路径时请回到 CDK 部署。使用方式:
cd infra-terraform cp terraform.tfvars.example terraform.tfvars # 编辑 terraform.tfvars —— 设置 stack_name_base、backend_pattern、aws_region terraform init terraform plan terraform apply在docker模式(backend_deployment_type默认值)下,一次 apply 会先构建 Agent 的 ARM64 镜像并推送到 ECR,再创建运行时,无需单独构建步骤。部署完成后可用uv run scripts/test-agent.py 'Hello'测试 Agent(依赖来自示例根目录的pyproject.toml,uv 会向上查找项目)。注意该 README 也如实标注了当前 Terraform 前端部署脚本因缺少feedback_api_url输出而暂不可用——需要部署前端时应使用infra-cdk/路径。
小结
通过本示例可以完整掌握一条"前端 → AG-UI 桥 → AgentCore Runtime → MCP Gateway"的生产级部署链路:LangGraph 与 Strands 两种智能体在工具接入、共享状态流式更新、会话记忆与身份鉴权上各有实现特色,但都统一在 AG-UI 协议与 CopilotKit 前端运行时之下。无论选择 CDK 托管部署还是 Terraform 基础方案,这套示例都为你提供了一个可直接复用的 AgentCore 生产化蓝本。
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考