内容
# 智能代理平台与 Amazon Bedrock AgentCore
## 概述
本项目是基于 [Amazon Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/) 构建的内部智能代理平台的参考实现。它展示了平台团队如何通过一个门户提供两种托管模型:
- **交互式云工作空间**:在 AgentCore Runtime 内启动完整的 Claude Code CLI,并通过浏览器 Web 终端使用它。进程运行在持久的 tmux 会话中,因此断开连接或切换会话时,对话和正在进行的任务仍继续运行;文件和对话历史记录持久存储到 S3,并在容器重启后仍然可用。
- **无头代理内核**:将基于 Claude Agent SDK 的代理作为 AgentCore Runtime 端点发布,任何应用程序都可以通过单一的 `/invocations` 接口调用它们。
两种内核都通过可配置的 **LLM 网关**(例如 LiteLLM)路由模型流量,并使用 **固定出口 IP**(VPC 模式 + NAT 网关),因此该平台适用于强制实施模型允许列表、预算和源 IP 限制的企业。支持直接访问 Bedrock(跨区域推理)作为替代方案。


## 目录结构
```
├── runtimes/
│ ├── claude-code-kernel/ # 交互式内核:Web 终端(ttyd+tmux)+ Claude Code + S3 工作空间持久性
│ ├── agent-sdk-kernel/ # 无头内核:Claude Agent SDK 背后是 AgentCore /invocations 接口
│ └── mcp-tools-kernel/ # 演示 MCP 服务器(协议=MCP):在 AgentCore Runtime 上模拟内部工具
├── backend/ # FastAPI 控制平面:会话、终端 URL、内核目录、MCP/技能注册表
├── frontend/ # React 门户:工作台、发布、调试、调度器、MCP 和技能、通道、内存、可观察性、评估、治理
├── infrastructure/ # CDK(Python):VPC/NAT 网络、平台资源、AgentCore 运行环境、门户托管 + 调度器引擎
├── scripts/ # 镜像构建和部署助手
└── docs/ # 架构、部署和使用指南
```
## 生态系统(第 2 阶段)
门户维护一个 **MCP 服务器** 注册表(托管在 AgentCore Runtime 上,协议=MCP,通过 `mcp-proxy-for-aws` 或任何普通的流式 HTTP URL 访问)和 **技能包**(SKILL.md 存储在 S3 中)。在创建 Dev Workbench 会话时附加它们 - 内核写入 `.mcp.json` 并在 Claude Code 启动前安装技能 - 或将 MCP 服务器和技能传递给无头内核:相同的注册表条目在两种托管模式下表现相同。
## 内置工具(第 3 阶段)
注册表还包含两个 **AgentCore 内置工具** - **代码解释器**(隔离的 Python/shell 沙盒)和 **浏览器**(托管的云 Chromium 代理通过 Playwright 驱动)。两者都封装为本地 stdio MCP 服务器,在每个内核内,因此它们通过与任何其他 MCP 服务器相同的“类型”机制附加,并使用容器的 IAM 角色针对 AWS 管理的工具运行。
## 平台操作(第 4 阶段)
门户的信息架构其余部分都已上线:
- **自助服务发布**:在 Dev Workbench 工作空间中放置一个 `agent.yaml` 清单文件,并将其发布为一个**版本化代理**(系统提示 + 工具附件 + 内存绑定,由共享的无头内核提供服务 - 无需镜像构建)。重新发布以增加版本号;从调试、通道、调度器、评估或普通 HTTP 调用。
- **调度器**:针对任何内核或已发布的代理的 cron / `rate(N 分钟)` 调度,由 **EventBridge Scheduler → Lambda**(重试 + DLQ)触发,并具有进程内 tick 环作为本地开发的备用方案。
- **通道**:外部系统的令牌身份验证 webhook 端点(机器人、CI、运维钩子);`conversation_id` 保持一个温暖的运行时会话。
- **内存**:门户管理的 AgentCore 内存;将一个绑定到任何无头调用,内核在运行前检索相关长期记录,并在运行后追加交换(跨会话回忆)。
- **可观察性**:一个平台调用账本(延迟、回合、成本、来源)超过每个受管调用,补充 CloudWatch GenAI 跟踪。
- **评估**:针对任何目标执行固定的任务套件,并由 LLM 评判;比较已发布的代理与原始内核在发布前。
- **治理**:每日配额(按用户 + 平台)、按来源的终止开关、回合上限和每个平台操作的审计跟踪。所有调用路径都通过一个受管管道。
## 先决条件
- 具有 Amazon Bedrock AgentCore 的 AWS 账户(在目标区域可用)
- 具有 `linux/arm64` 构建支持的 Docker(AgentCore Runtime 是 ARM64)
- Node.js ≥ 20,Python ≥ 3.11,AWS CDK v2
- 以下之一:
- 兼容 Anthropic 的 LLM 网关端点(例如 LiteLLM)和 API 密钥,或
- Amazon Bedrock 模型访问(通过跨区域推理的 Claude 模型)
## 快速入门
```bash
# 1. 配置网络 + 平台资源
cd infrastructure
pip install -r requirements.txt
cdk deploy NetworkStack PlatformStack
# 2. 存储您的 LLM 网关密钥(如果使用 Bedrock 直接访问则跳过)
aws secretsmanager put-secret-value \
--secret-id agent-platform/llm-gateway-key \
--secret-string '{"api_key":"sk-..."}'
# 3. 构建和推送运行时镜像(ARM64)
./scripts/build-and-push.sh
# 4. 创建 AgentCore 运行环境(VPC 模式,固定出口 IP)
cdk deploy RuntimeStack
# 5. 在您的 LLM 网关上允许列出 NAT EIP,然后运行门户
cdk deploy PortalStack # 或:本地运行后端 + 前端,参见 docs/deployment.md
```
完整的操作指南:[docs/deployment.md](docs/deployment.md)。部署完成后,将用户指南交给用户;使用 `scripts/e2e_platform.py` 验证部署(20 个自动端到端检查)。
## 适应性
本示例旨在 fork。将其指向您的环境中使用环境变量和 CDK 上下文(无需跟踪代码编辑),并通过编辑单个内容模块替换启动目录 - [`backend/app/services/seed_data.py`](backend/app/services/seed_data.py) - 使上游更新合并干净。[**EXTENDING.md**](EXTENDING.md) 将代码库映射到“上游拥有”与“您需要更改的内容”,并涵盖上游同步工作流程。
## 路线图
第 1 阶段涵盖交互式工作空间和无头内核托管;第 2 阶段添加 MCP 和技能生态系统(注册表、会话附件、按调用工具);第 3 阶段通过相同的注册表连接 AgentCore 内置工具(代码解释器 + 浏览器);第 4 阶段发布平台操作层 - 自助服务发布、调度器、通道、内存、可观察性、评估和治理(调度在 EventBridge Scheduler + Lambda 上运行)。剩余的想法(基于镜像的自定义内核发布,通过 CodeBuild、CloudWatch GenAI 仪表板深层链接、DLQ 警报)被记录为 [EXTENDING.md](EXTENDING.md) 中的扩展点。
## 安全
参见 [CONTRIBUTING.md](CONTRIBUTING.md#security-issue-notifications) 以了解如何报告安全问题。
门户由 Amazon Cognito 用户池保护(每个 API 调用都验证 ID 令牌)。Web 终端在运行时容器**内**授予一个 shell;隔离依赖于 AgentCore microVM 会话隔离和 VPC 出口安全组。在将门户暴露给演示受众以外的用户之前,请查看 [docs/architecture.md — 安全说明](docs/architecture.md#security-notes)。
### 静态分析抑制
存储库由 gitleaks、semgrep、checkov、bandit、grype、cfn-nag 和 syft 扫描,以及 GitHub 代码扫描(CodeQL)和公共存储库上的 Dependabot。扫描是干净的;少量发现被抑制(工具原生注释或 CodeQL 文档免责声明),因为它们是针对此架构的特意设计或误报。每个抑制都有其原因;它们是:
| 工具/规则 | 位置 | 原因 |
|---|---|---|
| bandit `B104`(绑定 0.0.0.0) | `mcp-tools-kernel/src/server.py` | AgentCore 的 MCP 合同要求容器监听 `0.0.0.0:8000`;没有其他网络路径存在(microVM + VPC 出口 SG)。 |
| bandit `B108`(临时目录) | `agent-sdk-kernel/src/main.py` | 调用期间的临时目录在短暂的、单租户的 microVM 中。 |
| bandit `B106`(硬编码密码) | `infrastructure/stacks/platform_stack.py` | 误报 - 字符串是 Secrets Manager 秘密**名称**,不是凭证。 |
| semgrep `using-http-server` | `claude-code-kernel/contract-server/main.js` | AgentCore 在边缘终止 TLS;容器在其单个路由端口上侦听纯文本。 |
| semgrep `dockerfile-source-not-pinned` | 所有 Dockerfiles | 将 `FROM` 固定到摘要将阻止采用者使用当前基础镜像补丁重建。 |
| checkov `CKV_DOCKER_2`(健康检查) | 所有 Dockerfiles | 健康由 AgentCore 的 `/ping` 合同(或 ECS/ALB 目标组的后端)管理,而不是 Docker HEALTHCHECK。 |
| checkov `CKV_DOCKER_3`(非 root 用户) | 所有 Dockerfiles | 运行时内核在每个会话的 AgentCore microVM 内作为 root 运行(Claude Code 需要 root in-sandbox);后端采用者负责强化。 |
| semgrep JS/TS 规则(i18n 等) | `frontend/`(通过 `.semgrepignore`) | 参考门户是单语言演示 UI;国际化超出范围。安全逻辑存在于后端和内核中,仍然被扫描。 |
| semgrep `arbitrary-sleep` | `scripts/e2e_platform.py` | E2E 测试工具中的故意轮询间隔(等待异步服务器端工作:评估运行、内存提取、调度器滴答)。 |
| semgrep `detect-non-literal-fs-filename` | `claude-code-kernel/contract-server/main.js` | 技能安装目录是固定前缀加上一个名称,剥离到 `[a-zA-Z0-9_-]` - 没有点或斜杠在净化后存活,因此无法进行 `../` 遍历。 |
| semgrep `dynamic-urllib-use-detected` | `scripts/e2e_platform.py` | 测试工具包仅;URL 是固定 https 门户基址加上文字 API 路径 - 没有用户控制的输入。 |
| CodeQL `py/clear-text-logging-sensitive-data` | `agent-sdk-kernel/src/main.py` | 误报 - 记录的值是 Secrets Manager 秘密**名称**(在“无法读取”错误中),不是秘密值。在 GitHub 上使用此原因禁用。 |
## 许可证
本库根据 MIT-0 许可证授权。参见 [LICENSE](LICENSE) 文件。