---
url: /blog/xnqa4psv/index.md
description: OpenAI 如何使用 Responses API、Shell 工具和托管容器构建智能体运行时，以运行带有文件、工具和状态的安全、可扩展智能体。
---
我们目前正经历一场变革：从使用擅长特定任务的模型 (Model)，转向使用能够处理复杂工作流的智能体 (Agent)。通过提示模型，你只能调用它已经学到的能力；但如果为模型提供一个计算机环境，就能实现更广泛的应用场景，例如运行服务、调用 API 请求数据，或生成电子表格和报告等更具实用价值的产物。

在构建智能体时，开发者通常会面临几个实际痛点：中间文件存放在哪？如何避免将庞大的表格直接粘贴到提示词中？如何在不造成安全隐患的前提下赋予工作流网络访问权限？以及如何在不自行搭建工作流系统的情况下处理超时和重试？

与其让开发者自行构建执行环境，我们直接打造了必要的组件，为 [Responses API⁠](https://developers.openai.com/api/docs/guides/migrate-to-responses) 配备了计算机环境，从而可靠地执行现实世界中的任务。

OpenAI 的 Responses API 结合 Shell 工具和托管容器工作空间 (Hosted Container Workspace)，旨在解决上述实际问题。模型提出步骤和命令，平台则在隔离环境中运行它们。该环境包含用于输入输出的文件系统、可选的结构化存储（如 SQLite）以及受限的网络访问。

本文将深入剖析我们是如何为智能体构建计算机环境的，并分享一些早期经验，探讨如何利用该环境实现更快速、更可重复且更安全的生产环境工作流。

## Shell 工具

一个优秀的智能体工作流始于一个紧密的执行循环 (Execution Loop)：模型提出操作建议（如读取文件或通过 API 获取数据），平台执行该操作，执行结果再反馈给下一步。我们将从 Shell 工具开始 — 这是观察这一循环运作最直观的方式 — 随后将涵盖容器工作空间、网络连接、可重用技能以及上下文压缩 (Context Compaction)。

要理解 Shell 工具，首先需要了解语言模型通常是如何使用工具的：比如调用函数或与计算机交互。在训练过程中，模型会逐步学习工具的使用示例及其产生的效果。这有助于模型学习判断何时以及如何使用工具。当我们说“使用工具”时，其本质是模型提出 (Propose) 一个工具调用请求，模型本身无法自行执行该调用。

![Shell 工具仅是“另一种工具”，带有示意图 ](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_The_shell_tool_is_just_another_tool_desktop-dark__3_.svg)

Shell 工具仅是“另一种工具”，带有示意图

Shell 工具极大增强了模型的能力：它通过命令行与计算机交互，从而执行从文本搜索到在本地发送 API 请求等各类任务。我们的 Shell 工具基于成熟的 Unix 工具链构建，支持所有预期功能，并预装了 `grep` 、 `curl` 和 `awk` 等开箱即用的工具。

与现有的代码解释器 (Code Interpreter) 相比 — 后者仅能执行 Python 代码 — Shell 工具支持更广泛的应用场景，例如运行 Go 或 Java 程序，或者启动 NodeJS 服务器。这种灵活性使模型能够完成复杂的智能体任务。

## 编排智能体循环

模型本身只能提出 Shell 命令，但这些命令是如何执行的？我们需要一个编排器 (Orchestrator) 来获取模型输出、调用工具，并将工具的响应结果循环反馈给模型，直到任务完成。

Responses API 是开发者与 OpenAI 模型交互的方式。当配合自定义工具使用时，Responses API 会将控制权交还给客户端，此时客户端需要自带运行框架 (Harness) 来驱动工具。然而，该 API 也可以直接开箱即用，在模型与托管工具之间进行编排。

当 Responses API 接收到提示词时，它会组装模型上下文：用户提示词、之前的对话状态以及工具指令。若要实现 Shell 执行，提示词必须声明使用 Shell 工具， *且* 所选模型必须经过“提出 Shell 命令”的专门训练 — GPT‑5.2 及更高版本的模型已具备此能力。基于所有这些上下文，模型随后决定下一步操作。如果它选择执行 Shell，会将一个或多个 Shell 命令返回给 Responses API 服务。API 服务将这些命令转发给容器运行时 (Container Runtime)，回传 Shell 输出流，并将其作为下一次请求的上下文提供给模型。随后，模型可以检查结果、发布后续命令或生成最终答案。Responses API 会不断重复此循环，直到模型返回不含额外 Shell 命令的最终结果。

![智能体循环示意图：Responses API 在容器中编排模型与 Shell 执行](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_Agent_loop__Responses_API_orchestrates_model_and_shell_execution_in_cont.svg)

智能体循环示意图：Responses API 在容器中编排模型与 Shell 执行

当 Responses API 执行一条 Shell 命令时，它会与容器服务保持流式连接 (Streaming Connection)。随着输出内容的产生，API 会近乎实时地将其转发给模型，以便模型决定是继续等待更多输出、运行另一条命令，还是直接进入最终回复阶段。

模型可以在单一步骤中提出多个 Shell 命令，而 Responses API 能够利用独立的容器会话并发执行 (Concurrently Execute) 这些命令。每个会话都会独立地产生输出流，API 则将这些流多路复用 (Multiplex)，整合回结构化的工具输出并作为上下文。换句话说，智能体循环可以实现任务的并行化 (Parallelize)，例如同时搜索文件、获取数据以及验证中间结果。

![Responses API 对命令执行会话进行多路复用](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_Responses_API_multiplexes_command_execution_sessions_desktop-dark__3_.svg)

Responses API 对命令执行会话进行多路复用

当命令涉及文件操作或数据处理时，Shell 输出可能会变得非常庞大，在不提供有效信号的情况下耗尽上下文配额 (Context Budget)。为了控制这一点，模型会为每个命令指定一个输出上限 (Output Cap)。Responses API 强制执行该上限，并返回一个有界结果 (Bounded Result)：该结果会保留输出的开头和结尾部分，并标记出省略的内容。例如，你可以将输出限制在 1,000 个字符内，并保留首尾：

`开头部分的文本 ... 已截断 1000 个字符 ... 结尾部分的文本`

并发执行与有界输出相结合，使智能体循环既快速又节省上下文，从而让模型能够持续对相关结果进行推理，而不至于被原始的终端日志淹没。

## 当上下文窗口填满时：自动压缩

智能体循环的一个潜在问题是，任务可能会运行很长时间。长耗时任务会填满上下文窗口，而上下文对于跨轮次和跨智能体提供背景信息至关重要。想象一下：一个智能体调用某项技能，获取响应，添加工具调用和推理总结 — 有限的上下文窗口很快就会占满。为了在智能体持续运行时避免丢失关键上下文，我们需要保留核心细节并移除无关信息。我们没有要求开发者自行设计和维护自定义的总结或状态保留系统，而是在 Responses API 中加入了原生压缩 (Native Compaction) 功能，其设计初衷是与模型的行为模式及训练方式保持高度一致。

我们最新的模型经过训练，可以分析先前的对话状态并生成一个压缩项 (Compaction Item)。该项以一种加密且节省 Token 的高效表示形式保留了先前的关键状态。压缩完成后，下一个上下文窗口将由该压缩项和早期窗口的高价值部分组成。这使得工作流能够跨越窗口边界保持连贯，即使是在超长、多步骤且由工具驱动的会话中也是如此。 [Codex 正是依赖这一机制](https://openai.com/zh-Hans-CN/index/unrolling-the-codex-agent-loop/) 来维持长耗时的编程任务和迭代式的工具执行，且不会降低质量。

压缩功能可以内置在服务器上，也可以通过独立的 /compact 端点调用。服务器端压缩允许你配置一个阈值，系统会自动处理压缩时机，从而省去了复杂的客户端逻辑。它允许一个略大的有效输入上下文窗口，以容忍压缩前的轻微超限，确保接近极限的请求仍能被处理和压缩，而不是被直接拒绝。随着模型训练的演进，原生压缩方案也会随每个 OpenAI 模型的发布而同步进化。

Codex 帮助我们构建了压缩系统，同时作为其早期用户使用该系统。当一个 Codex 实例遇到压缩错误时，我们会启动第二个实例进行调查。结果是，Codex 通过解决自身问题，获得了一套原生且高效的压缩系统。这种让 Codex 观察并完善自身的能力，已成为在 OpenAI 工作中最引人入胜的部分。大多数工具只要求用户学习如何使用；而 Codex 则与我们共同学习。

## 容器上下文

现在我们来谈谈状态和资源。容器不仅是运行命令的场所，更是模型的运行上下文。在容器内部，模型可以读取文件、查询数据库，并在网络策略控制下访问外部系统。

![一张展示运行时容器内部结构的示意图：文件、数据库、技能，以及受策略控制的网络](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_Inside_the_runtime_container_desktop-dark__2_.svg)

一张展示运行时容器内部结构的示意图：文件、数据库、技能，以及受策略控制的网络

容器上下文的第一部分是用于上传、组织和管理资源的文件系统。我们构建了 [容器和文件⁠](https://developers.openai.com/api/reference/resources/containers) API，旨在为模型提供可用数据的结构化视图，帮助其选择针对性的文件操作，而不是进行大范围、高噪声的扫描。

一种常见的反模式 (Anti-pattern) 是将所有输入直接打包进提示词上下文。随着输入内容的增加，过度填充提示词不仅昂贵，而且会让模型难以理清头绪。更好的模式是将资源暂存在容器文件系统中，让模型决定通过 Shell 命令打开、解析或转换哪些内容。就像人类一样，模型在处理结构化信息时表现更佳。

容器上下文的第二部分是数据库。在许多情况下，我们建议开发者将结构化数据存储在 SQLite 等数据库中并进行查询。例如，与其将整个电子表格复制到提示词中，不如为模型提供表格的描述（包含哪些列及其含义），让它按需提取所需的行。

举个例子，如果你问：“本季度哪些产品的销量有所下降？”模型可以 *仅* 查询相关的行，而无需扫描整个表格。这种方式更快、成本更低，且更容易扩展到大型数据集。

容器上下文的第三部分是网络访问，这是智能体工作负载中必不可少的一环。智能体工作流可能需要获取实时数据、调用外部 API 或安装软件包。与此同时，赋予容器不受限的互联网访问权限具有很高的风险：它可能导致信息泄露给外部网站、意外访问敏感的内部或第三方系统，或者导致凭据泄露和数据外传更难防范。

为了在不损害智能体实用性的前提下解决这些隐忧，我们为托管容器构建了一个边车出口代理 (Sidecar Egress Proxy)。所有出站网络请求都会流经一个中心化的策略层 (Policy Layer)，该层负责强制执行白名单和访问控制，同时保持流量的可观测性。针对凭据管理，我们在请求出口处使用域名作用域的机密注入 (Domain-scoped Secret Injection)。模型和容器只能看到占位符，而原始机密值始终保持在模型可见的上下文之外，且仅在访问获批目标时才会生效。这种做法在支持身份验证的外部调用的同时，降低了泄露风险。

![通过出口代理实现受控网络访问的示意图：容器配置](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_Controlled_network_access_via_access_egress_proxy_-_container_setup_desk.svg)

通过出口代理实现受控网络访问的示意图：容器配置

## 智能体技能

Shell 命令固然强大，但许多任务都在重复相同的多步模式。智能体在每次运行时都必须重新探索工作流 — 重新规划、重新发布命令并重新学习规范 — 这导致了结果的不一致和执行资源的浪费。 [智能体技能⁠](https://agentskills.io/home) 将这些模式封装为可重用、可组合的构建模块。技能本质上是一个打包的目录，其中包含 ‘ [SKILL.md⁠](http://skill.md/) ’（包含元数据和指令）以及任何支撑资源，如 API 规范和 UI 资产。

这种设计可以很好地对应我们前面描述的运行时 (runtime) 架构。容器提供了持久化文件和执行上下文，Shell 工具提供了执行接口。在两者齐备的情况下，模型可以在需要时通过 Shell 命令（如 ls、cat 等）发现技能文件、解析指令，并在同一个智能体循环中运行技能脚本。

我们在 OpenAI 平台提供了管理技能的 [API⁠](https://developers.openai.com/api/reference/resources/skills) 。开发者将技能文件夹作为带版本的包进行上传和存储，之后可通过技能 ID 进行检索。在将提示词发送给模型之前，Responses API 会加载该技能并将其纳入模型上下文。这一过程具有确定性：

1. 获取技能元数据，包括名称和描述。
2. 获取技能包，将其复制到容器中并解压。
3. 利用技能元数据和容器路径更新模型上下文。

在判断某项技能是否相关时，模型会逐步探索其指令，并通过容器中的 Shell 命令执行其脚本。

![技能加载流程示意图：注册表、包、运行时](./assets/从模型到智能体：为%20Responses%20API%20配备计算机环境/OAI_Equip_Responses_API_with_a_computer_environment_Skill_loading_pipeline_desktop-dark__3_.svg)

技能加载流程示意图：注册表、包、运行时

## 智能体是如何构建的

让我们把所有要素整合在一起： *Responses API* 提供编排能力， *Shell 工具* 提供可执行操作， *托管容器* 提供持久化的运行时上下文， *技能* 用于分层复用工作流逻辑，而 *压缩 (compaction)* 则让智能体在具备所需上下文的情况下能够长时间运行。

借助这些基础原语，一个简单的提示语就可以扩展为端到端的工作流：发现合适的技能、获取数据、将其转换为本地结构化状态、高效查询，并生成可持久化的产物。

下图展示了该系统如何利用实时数据创建电子表格。

## 自行构建智能体

如需查看将 Shell 工具与计算机环境结合以实现端到端工作流的深入示例，请参阅我们的 [开发者博客文章⁠](https://developers.openai.com/blog/skills-shell-tips) 和 [实用手册⁠](https://developers.openai.com/cookbook/examples/skills_in_api) ，其中演示了如何打包一个技能并通过 Responses API 予以执行。

我们很期待看到开发者基于这一组基础原语构建出精彩内容。语言模型的用途不应仅限于生成文本、图像和音频。我们将持续更新平台，使其在大规模处理复杂的真实世界任务方面变得更加强大。
