📢 转载信息
原文链接:https://openai.com/index/equip-responses-api-computer-environment
原文作者:Bo Xu、Danny Zhang 和 Rohit Arunachalam
我们目前正经历一场变革:从使用擅长特定任务的模型 (Model),转向使用能够处理复杂工作流的智能体 (Agent)。通过提示模型,你只能调用它已经学到的能力;但如果为模型提供一个计算机环境,就能实现更广泛的应用场景,例如运行服务、调用 API 请求数据,或生成电子表格和报告等更具实用价值的产物。
在构建智能体时,开发者通常会面临几个实际痛点:中间文件存放在哪?如何避免将庞大的表格直接粘贴到提示词中?如何在不造成安全隐患的前提下赋予工作流网络访问权限?以及如何在不自行搭建工作流系统的情况下处理超时和重试?
与其让开发者自行构建执行环境,我们直接打造了必要的组件,为 Responses API(在新窗口中打开)配备了计算机环境,从而可靠地执行现实世界中的任务。
OpenAI 的 Responses API 结合 Shell 工具和托管容器工作空间 (Hosted Container Workspace),旨在解决上述实际问题。模型提出步骤和命令,平台则在隔离环境中运行它们。该环境包含用于输入输出的文件系统、可选的结构化存储(如 SQLite)以及受限的网络访问。
本文将深入剖析我们是如何为智能体构建计算机环境的,并分享一些早期经验,探讨如何利用该环境实现更快速、更可重复且更安全的生产环境工作流。
Shell 工具
一个优秀的智能体工作流始于一个紧密的执行循环 (Execution Loop):模型提出操作建议(如读取文件或通过 API 获取数据),平台执行该操作,执行结果再反馈给下一步。我们将从 Shell 工具开始 — 这是观察这一循环运作最直观的方式 — 随后将涵盖容器工作空间、网络连接、可重用技能以及上下文压缩 (Context Compaction)。
要理解 Shell 工具,首先需要了解语言模型通常是如何使用工具的:比如调用函数或与计算机交互。在训练过程中,模型会逐步学习工具的使用示例及其产生的效果。这有助于模型学习判断何时以及如何使用工具。当我们说“使用工具”时,其本质是模型提出 (Propose) 一个工具调用请求,模型本身无法自行执行该调用。
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 命令时,它会与容器服务保持流式连接 (Streaming Connection)。随着输出内容的产生,API 会近乎实时地将其转发给模型,以便模型决定是继续等待更多输出、运行另一条命令,还是直接进入最终回复阶段。
Responses API 会流式传输 Shell 命令的输出
模型可以在单一步骤中提出多个 Shell 命令,而 Responses API 能够利用独立的容器会话并发执行 (Concurrently Execute) 这些命令。每个会话都会独立地产生输出流,API 则将这些流多路复用 (Multiplex),整合回结构化的工具输出并作为上下文。换句话说,智能体循环可以实现任务的并行化 (Parallelize),例如同时搜索文件、获取数据以及验证中间结果。
当命令涉及文件操作或数据处理时,Shell 输出可能会变得非常庞大,在不提供有效信号的情况下耗尽上下文配额 (Context Budget)。为了控制这一点,模型会为每个命令指定一个输出上限 (Output Cap)。Responses API 强制执行该上限,并返回一个有界结果 (Bounded Result):该结果会保留输出的开头和结尾部分,并标记出省略的内容。例如,你可以将输出限制在 1,000 个字符内,并保留首尾:
开头部分的文本 ... 已截断 1000 个字符 ... 结尾部分的文本
并发执行与有界输出相结合,使智能体循环既快速又节省上下文,从而让模型能够持续对相关结果进行推理,而不至于被原始的终端日志淹没。
当上下文窗口填满时:自动压缩
智能体循环的一个潜在问题是,任务可能会运行很长时间。长耗时任务会填满上下文窗口,而上下文对于跨轮次和跨智能体提供背景信息至关重要。想象一下:一个智能体调用某项技能,获取响应,添加工具调用和推理总结 — 有限的上下文窗口很快就会占满。为了在智能体持续运行时避免丢失关键上下文,我们需要保留核心细节并移除无关信息。我们没有要求开发者自行设计和维护自定义的总结或状态保留系统,而是在 Responses API 中加入了原生压缩 (Native Compaction) 功能,其设计初衷是与模型的行为模式及训练方式保持高度一致。
我们最新的模型经过训练,可以分析先前的对话状态并生成一个压缩项 (Compaction Item)。该项以一种加密且节省 Token 的高效表示形式保留了先前的关键状态。压缩完成后,下一个上下文窗口将由该压缩项和早期窗口的高价值部分组成。这使得工作流能够跨越窗口边界保持连贯,即使是在超长、多步骤且由工具驱动的会话中也是如此。 Codex 正是依赖这一机制 来维持长耗时的编程任务和迭代式的工具执行,且不会降低质量。
压缩功能可以内置在服务器上,也可以通过独立的 /compact 端点调用。服务器端压缩允许你配置一个阈值,系统会自动处理压缩时机,从而省去了复杂的客户端逻辑。它允许一个略大的有效输入上下文窗口,以容忍压缩前的轻微超限,确保接近极限的请求仍能被处理和压缩,而不是被直接拒绝。随着模型训练的演进,原生压缩方案也会随每个 OpenAI 模型的发布而同步进化。
Codex 帮助我们构建了压缩系统,同时作为其早期用户使用该系统。当一个 Codex 实例遇到压缩错误时,我们会启动第二个实例进行调查。结果是,Codex 通过解决自身问题,获得了一套原生且高效的压缩系统。这种让 Codex 观察并完善自身的能力,已成为在 OpenAI 工作中最引人入胜的部分。大多数工具只要求用户学习如何使用;而 Codex 则与我们共同学习。
容器上下文
现在我们来谈谈状态和资源。容器不仅是运行命令的场所,更是模型的运行上下文。在容器内部,模型可以读取文件、查询数据库,并在网络策略控制下访问外部系统。
文件系统
容器上下文的第一部分是用于上传、组织和管理资源的文件系统。我们构建了 容器和文件(在新窗口中打开) API,旨在为模型提供可用数据的结构化视图,帮助其选择针对性的文件操作,而不是进行大范围、高噪声的扫描。
一种常见的反模式 (Anti-pattern) 是将所有输入直接打包进提示词上下文。随着输入内容的增加,过度填充提示词不仅昂贵,而且会让模型难以理清头绪。更好的模式是将资源暂存在容器文件系统中,让模型决定通过 Shell 命令打开、解析或转换哪些内容。就像人类一样,模型在处理结构化信息时表现更佳。
数据库
容器上下文的第二部分是数据库。在许多情况下,我们建议开发者将结构化数据存储在 SQLite 等数据库中并进行查询。例如,与其将整个电子表格复制到提示词中,不如为模型提供表格的描述(包含哪些列及其含义),让它按需提取所需的行。
举个例子,如果你问:“本季度哪些产品的销量有所下降?”模型可以仅查询相关的行,而无需扫描整个表格。这种方式更快、成本更低,且更容易扩展到大型数据集。
网络访问
容器上下文的第三部分是网络访问,这是智能体工作负载中必不可少的一环。智能体工作流可能需要获取实时数据、调用外部 API 或安装软件包。与此同时,赋予容器不受限的互联网访问权限具有很高的风险:它可能导致信息泄露给外部网站、意外访问敏感的内部或第三方系统,或者导致凭据泄露和数据外传更难防范。
为了在不损害智能体实用性的前提下解决这些隐忧,我们为托管容器构建了一个边车出口代理 (Sidecar Egress Proxy)。所有出站网络请求都会流经一个中心化的策略层 (Policy Layer),该层负责强制执行白名单和访问控制,同时保持流量的可观测性。针对凭据管理,我们在请求出口处使用域名作用域的机密注入 (Domain-scoped Secret Injection)。模型和容器只能看到占位符,而原始机密值始终保持在模型可见的上下文之外,且仅在访问获批目标时才会生效。这种做法在支持身份验证的外部调用的同时,降低了泄露风险。
智能体技能
Shell 命令固然强大,但许多任务都在重复相同的多步模式。智能体在每次运行时都必须重新探索工作流 — 重新规划、重新发布命令并重新学习规范 — 这导致了结果的不一致和执行资源的浪费。 智能体技能(在新窗口中打开)将这些模式封装为可重用、可组合的构建模块。技能本质上是一个打包的目录,其中包含 ‘SKILL.md(在新窗口中打开)’(包含元数据和指令)以及任何支撑资源,如 API 规范和 UI 资产。
这种设计可以很好地对应我们前面描述的运行时 (runtime) 架构。容器提供了持久化文件和执行上下文,Shell 工具提供了执行接口。在两者齐备的情况下,模型可以在需要时通过 Shell 命令(如 ls、cat 等)发现技能文件、解析指令,并在同一个智能体循环中运行技能脚本。
我们在 OpenAI 平台提供了管理技能的 API(在新窗口中打开)。开发者将技能文件夹作为带版本的包进行上传和存储,之后可通过技能 ID 进行检索。在将提示词发送给模型之前,Responses API 会加载该技能并将其纳入模型上下文。这一过程具有确定性:
- 获取技能元数据,包括名称和描述。
- 获取技能包,将其复制到容器中并解压。
- 利用技能元数据和容器路径更新模型上下文。
在判断某项技能是否相关时,模型会逐步探索其指令,并通过容器中的 Shell 命令执行其脚本。
智能体是如何构建的
让我们把所有要素整合在一起:Responses API 提供编排能力,Shell 工具提供可执行操作,托管容器提供持久化的运行时上下文,技能用于分层复用工作流逻辑,而压缩 (compaction) 则让智能体在具备所需上下文的情况下能够长时间运行。
借助这些基础原语,一个简单的提示语就可以扩展为端到端的工作流:发现合适的技能、获取数据、将其转换为本地结构化状态、高效查询,并生成可持久化的产物。
下图展示了该系统如何利用实时数据创建电子表格。
Responses API 对一个智能体任务进行编排
自行构建智能体
如需查看将 Shell 工具与计算机环境结合以实现端到端工作流的深入示例,请参阅我们的 开发者博客文章(在新窗口中打开)和 实用手册(在新窗口中打开),其中演示了如何打包一个技能并通过 Responses API 予以执行。
我们很期待看到开发者基于这一组基础原语构建出精彩内容。语言模型的用途不应仅限于生成文本、图像和音频。我们将持续更新平台,使其在大规模处理复杂的真实世界任务方面变得更加强大。
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区