面向“真正做事”的长时运行智能体:Skills、Shell 与压缩(Compaction)实用技巧

2026-02-13 · 原文链接

我们正在从“一问一答”的助手,转向能够持续运行、承担真实知识工作(knowledge work)的智能体:阅读大规模数据集、修改文件、乃至编写应用。

基于开发者反馈,以及我们在构建 Codex 与内部智能体时的经验,我们发布了一组新的智能体原语(agentic primitives),让长周期任务更可行:

文档与 API 参考分别对以上内容逐项说明。本文重点分享我们在 OpenAI 自己的实践,以及在早期 skills 客户(Glean)的生产环境中,观察到的一些“不那么显而易见”、但很管用的技巧与模式。

一个简短的心智模型

Skills:模型可按需加载的「流程(Procedures)」

一个 skill 是一组文件的打包,外加一份包含前置元信息(frontmatter)与说明的 SKILL.md 清单。你可以把它理解成:当需要做“真活”时,模型可以随时翻阅的一本可版本化作业手册(playbook)。

当 skills 可用时,平台会把每个 skill 的 namedescriptionpath 暴露给模型。模型会利用这些元数据决定是否要调用某个 skill;一旦决定调用,就会读取 SKILL.md 获取完整工作流。

Shell 工具:智能体的「执行(Execution)」

shell 工具让模型在真实的终端环境里工作,方式有两种:

托管 shell 通过 Responses API 运行,这意味着你的请求会携带有状态的工作过程:工具调用、多轮续写,以及可回收的产物(artifacts)。

压缩(Compaction):让长任务继续往前走

当工作流变长,就会碰到上下文窗口的限制。服务端压缩通过管理上下文窗口、自动压缩对话历史,让长任务可以持续推进。

在 Responses API 里,压缩有两种使用方式:

为什么它们放在一起更好

实用技巧

1)把 skill 描述写得像路由逻辑(而不是营销文案)

skill 的 description 本质上就是模型的决策边界。它应该回答:

一个很实用的模式是:在 description 里直接加入简短的「Use when vs. don’t use when」区块,并保持足够具体(输入是什么、会用到哪些工具、预期产物是什么)。

2)加入负例与边界情况,减少误触发

一个容易被忽略的失败模式是:一旦把 skills 变得可用,最初反而会降低正确触发率。我们观察到,一个有效修复手段是加入负例(negative examples)与边界情况覆盖。

落地做法就是:明确写出几条「不要在这种场景调用本 skill……(而应该改用什么)」的例子。这样模型在路由时会更干净,尤其当你同时提供了多个“看起来很像”的 skills 时更有用。

Glean 在评测里就遇到过:基于 skills 的路由在目标评测中触发率先下降了大约 20%,但在他们把描述补上负例与边界覆盖后又恢复了。

3)把模板与示例放在 skill 内(不用时几乎不花 token)

如果你一直在把各种模板硬塞进 system prompt——停。

把模板与完整示例放进 skills 有两个优势:

这对知识工作型产物特别有效,例如:

Glean 报告说,这个模式在生产环境里带来了他们一些最大的质量与时延收益,因为示例只在触发 skill 的时候才会被加载。

4)尽早为长任务设计:容器复用 + 压缩

长周期智能体很少能靠一次性提示词成功。最好从一开始就为连续性做设计:

这些组合能减少“重启式行为”,并在对话变长时让多步骤任务仍保持一致性。

5)当你需要确定性时,明确告诉模型使用某个 skill

默认行为是:由模型自己决定何时使用某个 skill,这通常也是你想要的。

但如果你在跑的是一个生产工作流,契约很清晰(你宁愿更确定,而不是更“聪明”),那就直接说:

“Use the <skill name> skill.”

这是你能拉动的最简单可靠性杠杆:把模糊路由变成显式契约。

6)把 skills + 网络访问视为高风险组合(从一开始就做 containment 设计)

这是一个现在很容易略过、但未来很难补救的安全建议。

**把 skills 与开放网络访问结合,会形成高风险的数据外泄路径。**如果要用网络,请保持严格的 allowlist,把工具输出当作不可信,并避免在面向消费者、且用户期望强确认控制的流程里,使用“开放互联网 + 强力流程”的组合。

一个强默认姿态是:

7)把 /mnt/data 当作产物交接边界

在托管 shell 工作流里,把 /mnt/data 当作写入输出的标准位置,方便你后续取回、审阅,或在后续步骤中继续引用。例如报告、清洗后的数据集、最终表格等。

一个好用的心智模型是:工具写到磁盘 → 模型围绕磁盘推理 → 开发者从磁盘取回。

8)理解 allowlist 是两层系统(组织级 + 请求级)

网络访问会在两个地方被控制:

这带来两个重要的运维含义:

  1. 让组织级 allowlist 保持小且稳定(“你信任的目的地”集合)。
  2. 每次请求的 allowlist 再小一点(“这一次任务真的需要访问的目的地”集合)。

如果请求包含组织 allowlist 之外的域名,会直接报错。

9)认证调用用 domain_secrets(避免泄露凭据)

如果 allowlist 域名需要鉴权 header,请使用 domain_secrets,让模型永远看不到真实凭据。

运行时,模型看到的是占位符(例如 $API_KEY),而侧车(sidecar)只会对已批准的目的地注入真实值。这是任何需要在容器里调用受保护 API 的智能体,都应该默认采用的安全方式。

10)云端与本地用同一套 API

你可以同时使用这两类原语,而不必把一切都绑定到托管环境:

一个实用的开发迭代路径是:

  1. 先从本地开始(迭代快、可访问内部工具、易调试)。
  2. 当你需要可重复性、隔离与部署一致性时,再迁移到托管容器。
  3. Skills 在两种模式下保持一致(即使执行环境迁移了,工作流也不漂移)。

三种构建模式

你当然可以自由实验这些新的智能体原语。这里给出三种把它们组合起来构建应用的例子。

模式 A:Install -> fetch -> write artifact

这是从托管 shell 获益的最简单方式:智能体安装依赖、抓取外部数据,并产出一个具体可交付物。

例如:

这类模式是“真正做事的智能体”的基础,因为它建立了清晰的审阅边界:你的应用可以把产物展示给用户、记录、diff,或者喂给后续步骤继续处理。

模式 B:Skills + shell,构建可重复的工作流

当你做出一两个成功的 shell 工作流后,你会遇到下一个问题:它能跑,但提示词一漂移,可靠性就下降。

Skills 就是为此而来。一套更耐用的结构是:

  1. 把工作流(步骤、护栏、模板)编码到一个 skill 里。
  2. 将 skill 挂载到 shell 环境。
  3. 让智能体按 skill 的流程来更确定性地产出产物。

这对以下工作流特别有效:

模式 C(进阶):把 skills 当作企业工作流的载体

我们看到的一个早期模式是:单工具调用到多工具编排之间存在“准确率落差”。Skills 可以通过更程序化的工具推理来弥补这个落差,而不会把 system prompt 膨胀成巨型文档。

Glean 的一个具体例子:

这就是威力开始显现的形状:skills 变成“活的 SOP(标准作业流程)”——会随着组织演进而更新,并被智能体一致地执行。

一次构建,随处运行

当长周期智能体既能遵循流程、又能在计算机上做真实工作时,它们会变得更有用。Skills、托管 shell 与压缩共同构建了这个基础。总结一下:

现在就开始把它们用到你的应用里。可参考:skills 文档shell 文档compaction 文档