

# 将 Lambda MicroVM 用作 OpenAI Agents API 的沙盒
<a name="microvms-integrations-openai-agents-api"></a>

对于使用 OpenAI Agents API 构建的代理，您可以将 AWS Lambda MicroVM 用作自托管环境，从而将工作区文件、工具执行和网络访问权限保留在自己控制的基础设施中。OpenAI 负责运行代理 Harness，Lambda MicroVM 则负责执行您的任务。在此示例中，它运行 `codex exec-server`，后者执行代理的工具调用并保存会话的工作区文件。您可以决定映像内容、执行器可采用的网络路径，以及其执行角色权限范围内的 AWS 资源。

每个 MicroVM 均以 Firecracker 隔离环境的形式运行，该环境从您的映像快照启动。MicroVM 的总生命周期最长为 8 小时，包括运行和暂停时间。在最后一个轮次结束后将其终止，或者在两个轮次之间将其暂停。您构建一个可重用的映像，然后从您的应用程序或 Webhook 启动程序启动 MicroVM。两种方法使用相同的映像和凭证。有关更多详细信息，请查看 Lambda MicroVM 上 OpenAI Agents API 自托管沙盒的[参考示例](https://github.com/openai/openai-cookbook/tree/main/examples/agents_api/sandboxes/aws)。

## 工作原理
<a name="microvms-integrations-openai-agents-api-how-it-works"></a>

在 Webhook 托管路径中，启动程序 Lambda 函数会在会话首次需要执行器时启动 MicroVM。它会重用现有的 MicroVM，如果其已暂停，则先进行恢复。您的应用程序将在最后一个轮次结束后将其终止。图 1 显示该流程：

1. 您的应用程序创建自托管会话，并将输入发送到 Agents API。

1. 当会话需要执行器时，OpenAI 会向您账户中的 Amazon API Gateway 端点发送包含 `agent.session.action_required` 操作的 `environment_connection` Webhook。

1. 启动程序 Lambda 函数验证 Webhook 签名，检索当前会话，并且确认处理程序拥有该会话。

1. 启动程序使用映像、执行角色、网络连接器以及携带会话连接值的 `runHookPayload` 调用 `RunMicrovm`。

1. MicroVM 的 `/run` 钩子使用其 IAM 执行角色从 AWS Secrets Manager 中检索执行器密钥并启动 Codex。

1. 执行器在 `https://api.openai.com` 中向 OpenAI 注册。然后，它会打开指向 `wss://codex-cloud-environments.chatgpt.com` 的安全 WebSocket 连接，以此接收工具命令和返回结果。

1. 您的应用程序可以通过 MicroVM 已通过身份验证的 HTTPS 端点上传输入文件和下载输出文件。它跟踪会话事件流，并且可以在两个轮次之间暂停 MicroVM。

1. 最后一个轮次结束后，您的应用程序会终止 MicroVM。

![用于 AWS Lambda MicroVM 上 Agents API 沙盒的 Webhook 托管预置](https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/images/microvms-openai-agents-webhook-architecture.png)


图 1. 用于 AWS Lambda MicroVM 上 Agents API 沙盒的 Webhook 托管预置。

将应用程序密钥和 Webhook 签名机密保存在 MicroVM 外部。启动程序仅传递执行器密钥的机密 ARN；VM 使用其执行角色检索该密钥。

## 密钥属性
<a name="microvms-integrations-openai-agents-api-properties"></a>


| 属性 | 优势 | 
| --- | --- | 
| Firecracker 隔离 | 每个会话的 MicroVM 的硬件虚拟化边界 | 
| 基于快照的启动 | 每个 MicroVM 均从已准备映像的快照启动 | 
| 通过执行角色使用 IAM | /run 钩子使用 MicroVM 的执行角色读取执行器密钥；该密钥不存储在映像中 | 
| 有状态持续时间 | 每个 MicroVM 最多可运行 8 小时，包括暂停时间 | 
| 在轮次之间暂停和恢复 | 内存和磁盘状态得以保留，因此后续轮次可在同一环境中继续运行 | 
| 基于用量的计算 | 运行 VM 会产生计算费用。暂停操作将停止产生计算费用；快照存储及读/写操作将单独计费。 | 

## 先决条件
<a name="microvms-integrations-openai-agents-api-prereqs"></a>
+ 具有 Lambda MicroVM 访问权限的 AWS 账户、包括 `lambda-microvms` 的 AWS CLI 版本，以及构建映像和运行 MicroVM 的相应权限。要创建 Amazon Simple Storage Service（Amazon S3）构件存储桶和 AWS Identity and Access Management（IAM）映像构建角色，请参阅[创建您的第一个 Lambda MicroVM](microvms-getting-started.md)。
+ 用于创建会话和提交输入的 OpenAI 应用程序密钥（`OPENAI_API_KEY`）。
+ 单独的 OpenAI 执行器密钥（`OPENAI_EXECUTOR_API_KEY`），与会话使用相同的组织、项目及用户或服务账户。将其存储在 Secrets Manager 中，例如作为 `codex/agents-api/executor` 存储。`/run` 钩子以 `CODEX_API_KEY` 的形式将其传递给 Codex。
+ 只能读取执行器密钥机密的 microVM 执行角色。如果机密使用客户托管的 AWS Key Management Service（AWS AWS KMS）密钥，请添加解密权限。请参阅[安全性和权限](microvms-security.md)。

## 准备 microVM 映像
<a name="microvms-integrations-openai-agents-api-image"></a>

构建一个映像，其中包括 Codex CLI、工具依赖项、工作目录（如 `/workspace`）以及用于生命周期钩子的 HTTP 服务器。


| 钩子 | 行为 | 
| --- | --- | 
| /aws/lambda-microvms/runtime/v1/ready | 当服务器准备好让 Lambda 拍摄快照时，会返回 HTTP 200。执行器保持断开连接状态。 | 
| /aws/lambda-microvms/runtime/v1/run | 读取会话连接值和机密 ARN，获取执行器密钥，然后启动执行器。 | 
| /aws/lambda-microvms/runtime/v1/validate | 可选。检查 Codex 是否正在运行以及工作区是否为可写状态。 | 
| /aws/lambda-microvms/runtime/v1/suspend | 暂停/恢复所必需。在 AWS 对 VM 拍摄快照之前，停止执行器并刷新写入内容。 | 
| /aws/lambda-microvms/runtime/v1/resume | 暂停/恢复所必需。再次获取密钥，并且为相同环境重新启动执行器。 | 
| /aws/lambda-microvms/runtime/v1/terminate | 可选。在终止之前停止执行器并刷新写入内容。 | 

将 `Dockerfile` 和钩子服务器打包到 Amazon S3 构件中，然后构建采用 8 GB 基准内存（4 vCPU 基准）的 `codex-executor` 映像。在映像配置中启用所选钩子，然后将钩子端口设置为与您的服务器匹配。将会话 ID、凭证和实时执行器连接保留在映像快照外部。有关构建和钩子配置，请参阅[MicroVM 映像](microvms-images.md)。

启动后，您的应用程序或启动程序会在 `runHookPayload` 中将以下值序列化为 JSON：


| 值 | 用途 | 
| --- | --- | 
| session.environment.id | 标识执行器所连接的环境 | 
| session.environment.remote\_url | 提供执行器的 OpenAI 连接 URL | 
| 执行器密钥的机密 ARN | 可让钩子使用 MicroVM 的执行角色检索密钥 | 

执行器进程启动后，立即从 `/run` 钩子返回且无需等待轮次完成，以此避免钩子超时。

## 启动 MicroVM
<a name="microvms-integrations-openai-agents-api-launching"></a>

您可以从应用程序或 Webhook 启动程序启动 MicroVM。在这两种情况下，请保持会话事件流处于打开状态，直到该轮次结束。

### 应用程序托管预置
<a name="microvms-integrations-openai-agents-api-launching-application"></a>

1. 创建其工作目录与映像匹配的自托管会话，然后打开其事件流。

1. 使用映像 ARN 和版本、执行角色、网络连接器以及 `runHookPayload` 调用 `RunMicrovm`。将返回的 `microvmId` 与会话 ID 一起保存。

1. 等待 `agent.session.environment.connected`，然后发送输入并跟踪轮次的结果。

1. 按照 [结束轮次](#microvms-integrations-openai-agents-api-ending-turn) 中所述，检索输出文件并结束轮次。

### Webhook 托管预置
<a name="microvms-integrations-openai-agents-api-launching-webhook"></a>

您的应用程序创建会话，打开其流并提交输入。当 Webhook 到达时，启动程序会处理剩余的工作。

1. 在 Amazon API Gateway 中部署调用启动程序的 `POST /webhook` 路由。授予启动程序以下权限：读取其凭证，从选取的映像检查、启动、恢复和终止 MicroVM，传递 MicroVM 执行角色，以及使用已配置的网络连接器。

1. 针对 `agent.session.action_required` 和 `agent.session.failed` 注册端点。使用启动程序的应用程序密钥将端点的签名机密存储在 Secrets Manager 中。

1. 在访问会话或启动计算之前，根据原始请求正文验证 Webhook 签名。然后，检索当前会话并确认处理程序拥有该会话，例如通过匹配专用的已保存代理。

1. 如果 `environment_connection` 仍处于待处理状态，请使用 `GetMicrovm` 检查已记录的 MicroVM。如果其已暂停，请使用 `ResumeMicrovm` 进行恢复。仅在未记录任何 VM 时调用 `RunMicrovm`，然后保存其 ID。如果保存失败，请终止您启动的 VM。如果执行器在连接超时之前连接，则等待中的输入将继续执行，无需重新提交。

1. 对于 `agent.session.failed` 事件，检索当前会话，并且仅在其状态仍为失败时终止其记录的 MicroVM。忽略已删除的会话、已解决的操作以及由其他处理程序拥有的会话。

[参考示例](https://github.com/openai/openai-cookbook/tree/main/examples/agents_api/sandboxes/aws)将 MicroVM ID 保存在会话元数据中。并发的 Webhook 传送可在该 ID 保存之前启动额外的 VM。在投入生产使用之前，请防止同一会话的并发启动，并对 webhook 事件进行重复数据删除处理。

## 结束轮次
<a name="microvms-integrations-openai-agents-api-ending-turn"></a>

图 2 展示单个轮次的 MicroVM 生命周期，以及后续轮次的可选暂停与恢复路径。

![一个 Agents API 轮次的 MicroVM 生命周期](https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/images/microvms-openai-agents-turn-lifecycle.png)


图 2. 一个 Agents API 轮次的 MicroVM 生命周期。`RunMicrovm` 启动 MicroVM，`/run` 钩子启动执行器，环境完成连接，该轮次运行，然后轮次结束。在单个轮次的路径中，您检索文件并调用 `TerminateMicrovm`。在多个轮次的路径中，MicroVM 在每个轮次结束后暂停，并在下一个连接请求上恢复。

在会话流中，等待主代理的 `agent.session.turn.completed`、`agent.session.turn.failed` 或 `agent.session.turn.cancelled`，其中 `event.turn.subagent_id` 为 `null`。子代理共享 MicroVM，因此它们的终端事件不会触发清理。检索所需的文件。在最后一个轮次结束后，调用 `TerminateMicrovm` 并确认 VM 已到达 `TERMINATED` 状态。对于后续轮次，请保持其运行或将其暂停。如果您的应用程序遇到错误，请运行清理操作。

轮次结果以流事件的形式送达，而非作为 Webhook 订阅。`agent.session.failed` Webhook 涵盖会话失败的情况，但并不涵盖每个失败的轮次。因此，不要仅根据 `agent.session.idle` 就终止，因为它可能在等待输入开始之前就已到达该状态。

若要在清理操作未运行时界定 MicroVM 的生命周期，请在启动时配置以下设置：


| 设置 | 指南 | 
| --- | --- | 
| maximumDurationInSeconds | 为工作负载设置上限，例如，针对 15 分钟测试可设置为 900。即使工作正在进行中，此限制仍然适用。 | 
| maxIdleDurationSeconds | 涵盖预期的工作负载。Lambda 衡量入站流量，因此执行器的出站连接不会重置此计时器。 | 
| suspendedDurationSeconds / autoResumeEnabled | 对于不会恢复已暂停 MicroVM 的单一轮次模式，请使用 0/false。 | 

有关生命周期和空闲控制的信息，请参阅[运行和使用 MicroVM](microvms-launching.md)。

单独删除会话。删除会话不会停止 MicroVM，也不会发送删除 Webhook 命令。保留映像和执行器密钥机密，以便重复使用。有关处理后续轮次的信息，请参阅[沙盒生命周期](https://developers.openai.com/api/docs/guides/agents-api/environments/providers/aws)。

## 在轮次之间暂停和恢复
<a name="microvms-integrations-openai-agents-api-suspend-resume"></a>

要在轮次之间保持内存和磁盘状态，请在主代理的轮次结束且所有工具和子代理完成后暂停 MicroVM。当会话下次需要执行器时，恢复同一 MicroVM。
+ 设置非零的 `suspendedDurationSeconds`。MicroVM 暂停期间将收取快照存储费用。
+ 启用 `/suspend` 钩子以刷新写入并关闭连接，启用 `/resume` 钩子以刷新凭证并重新连接执行器。
+ 在应用程序管理的路径中，系统会在发送下一个输入之前恢复 VM。在 Webhook 管理的路径中，提交输入会触发恢复 VM 的连接请求。执行器重新连接后，该轮次即可继续。

**注意**  
`maximumDurationInSeconds` 将总运行和暂停时间限制为 8 小时。要按需恢复，请调用 `ResumeMicrovm`。自动恢复需要流向 MicroVM 的入站流量；仅靠 Agents API 输入无法将其恢复。

## 联网
<a name="microvms-integrations-openai-agents-api-networking"></a>

允许执行器所需的 OpenAI 出站连接以及 Secrets Manager 访问权限。要访问私有资源或应用自定义网络限制，请在启动时附加 VPC 出口连接器。请参阅[使用出口网络连接器](microvms-networking.md#microvms-networking-connectors)。

该示例支持通过 MicroVM 的 HTTPS 端点上传和下载文件，并且使用范围限定于服务器端口的身份验证令牌。

## 监控
<a name="microvms-integrations-openai-agents-api-monitoring"></a>

运行任一示例，然后确认 `hello.txt` 下载成功、MicroVM 已到达 `TERMINATED` 状态，以及已删除的会话返回 HTTP 404。

**启动程序日志。**在 CloudWatch Logs 中查看启动程序 Lambda 函数的日志：

```
aws logs tail /aws/lambda/codex-agents-api-webhook --since 10m
```

**运行 MicroVM。**将 `MICROVM_IMAGE_ARN` 设置为您的映像 ARN，使用部署所在的 AWS 区域，并且列出适用于该映像的 MicroVM：

```
aws lambda-microvms list-microvms \
  --image-identifier "$MICROVM_IMAGE_ARN" \
  --query 'items[].{id:microvmId,state:state}' --output table
```

同时记录会话 ID 和 MicroVM ID，以便端到端地跟踪运行情况。请勿将凭证和原始 Webhook 正文写入日志。

## 问题排查
<a name="microvms-integrations-openai-agents-api-troubleshooting"></a>


| 症状 | 检查内容 | 
| --- | --- | 
| Webhook 签名被拒绝 | 使用端点的签名机密，并且验证请求正文未经修改。 | 
| 无 MicroVM 启动 | 检查 Webhook 订阅、会话所有权筛选条件、待处理的 environment\_connection 操作以及启动程序的 IAM 权限。 | 
| 映像构建失败 | 检查 Amazon S3 构件、映像构建角色以及 /ready 钩子响应。 | 
| /run 失败或超时 | 检查机密访问权限和执行器启动情况。在启动该进程后返回，而非在轮次结束后返回。 | 
| 执行器无法连接 | 检查环境 ID、远程 URL、密钥所有权和出站网络访问权限。 | 
| MicroVM 在某个轮次中停止 | 检查最长生命周期和空闲策略。出站执行器流量不计为入站活动。 | 

对于连接失败的情况，请检查 `agent.session.environment.failed` 事件和执行器日志。有关共享执行器合同的信息，请参阅[自托管沙盒](https://developers.openai.com/api/docs/guides/agents-api/environments/providers/aws)。

## 相关资源
<a name="microvms-integrations-openai-agents-api-related"></a>
+ [AWS Lambda MicroVMs](lambda-microvms-guide.md)
+ [运行和使用 MicroVM](microvms-launching.md)
+ [安全性和权限](microvms-security.md)
+ [RunMicrovm API 参考](https://docs.aws.amazon.com/cli/latest/reference/lambda-microvms/run-microvm.html)
+ [OpenAI Agents API 自托管沙盒](https://developers.openai.com/api/docs/guides/agents-api/environments/providers/aws)
+ [AWS 上的 OpenAI Agents API 指南](https://developers.openai.com/api/docs/guides/agents-api/environments/providers/aws)