👁 221 次阅读
过去一年搭 AI 代理,你要自己写的那段循环,现在被官方收编了
过去一年,把一个 AI 代理做成能交付的东西,起点几乎都一样:调模型,解析它返回的工具调用,执行,把结果塞回上下文,再循环;等 demo 要变成产品时,再往上补会话存储、上下文压缩、失败重试和断点恢复。这些活的代码量和业务代码常常一样多。
2026 年 10 月初的 OpenAI DevDay 2026 上,官方把这段循环本身打包成了接口。据 OpenAI 官方文档(developers.openai.com/api/docs/guides/agents-api/overview)与 InfoQ 的 DevDay 回顾(2026-10-02),Agents API 目前已进入 public beta:你只管提供工具、决定执行环境、写下任务契约,OpenAI 侧的托管 Codex harness 接管 sessions、orchestration、context compaction 和 recovery。同一个引擎也驱动着 DevDay 上发布的 Dots 那些常驻代理;Assistants API 在 8 月停止之后,Agents API 是平台上走有状态路线的官方出口。
本文按官方 quickstart 和 openai-cookbook 的 agents_api 示例(代码核对到 openai Python SDK 3.22.0 的 beta.agents 命名空间)分 6 步走完:建一把最小权限的 key、跑通第一个 session、三种 environment 怎么选、把工具接上(含 MCP)、用 session 而不是请求来组织代码、并行子代理。末尾是四种代理方案的对照表、三份成本与合规清单,以及 5 个最常见的坑。

准备:一把 key、一个 SDK、一笔预算
先把三件事备齐,后面每一步都依赖它。
一把只带三个权限的应用级 API key
在 OpenAI platform 的项目里创建 application API key,只授三个 scope:api.agents.read 和 api.agents.write 负责会话操作,api.responses.write 负责模型推理。然后导出环境变量:
export OPENAI_API_KEY=sk-your-key-here
官方文档反复强调两件事,而它们恰恰最容易做错。其一,这把 key 不要放进代理的沙箱里——代理本身是跑代码的,任何位于它环境内部的凭据都应默认视为它可触及。其二,每次 Agents API 请求都需要 OpenAI-Beta: agents=v1 请求头;官方 SDK 会自动加上,但一旦你用 cURL 或其他 HTTP 客户端手打请求,就得显式带上,否则请求直接失败。
Python 3.10 及以上与新版 SDK
装 openai 包的 3.13.0 或更高版本:pip install --upgrade openai。本文代码在 SDK 3.22.0 上验证过,包括 beta.agents 命名空间。
预算与合规约束,先摆在台面上
- beta 期没有单独的 Agents API 费用。你付的是所选用模型的 API 价,OpenAI 工具按其标准费率,OpenAI 托管沙箱按标准容器费率。
- public beta 意味着接口还可能变。把
openai版本 pin 死,升级前看 changelog。 - 数据驻留仅限美国,且不支持 Zero Data Retention——哪怕你带自己的沙箱也不行。碰受监管数据前必须先确认这一点。
第 1 步:跑通第一个 session,并学会读事件流
最快的上手方式是官方的 quickstart:让代理写一个 tree.py 脚本,运行它,然后把目录树报告回来。
from openai import OpenAI
with OpenAI() as client:
with client.beta.agents.sessions.create(
agent={
"model": "gpt-6-astra",
"instructions": "Write clean code, run it, and report the actual output.",
},
environment={"type": "openai_hosted"},
input="Create tree.py, a Python script that prints a readable tree "
"of the files in the current directory. Run it and show me the output.",
stream=True,
) as events:
for event in events:
print(event.to_json(indent=None), flush=True)
存成 quickstart.py,用 python quickstart.py 跑起来。就这一个调用,它创建了 session、拉起一个 OpenAI 托管沙箱、启动一轮工作,并把过程以 JSON 事件流出来。成功的情况下,代理会在沙箱里创建 tree.py、执行它,并回报一棵包含该文件的目录树。
事件流是你主要的调试界面,所以值得把它读熟。官方文档明确警告:agent.session.turn.completed 表示这一轮结束了,但一轮完成并不等于每个工具调用都成功了,必须自己去看代理回报的结果。以 turn.failed、turn.cancelled、session.failed 结尾的事件表示失败或取消。只出现 agent.session.idle 并不表示成功。如果流提前断掉,先取出 session 和它已保存的 items 再重试——那些工作是服务端持久的。
现在就该养成的一个习惯:从事件里存下 session_id。第 4 步开始的所有操作都要用到它。
第 2 步:三种 environment,选错就是错的架构决策
environment 决定代理的命令在哪里执行、文件存在哪里。这是整个教程里影响最大的那个架构决策,官方给了三个选项。
| 取值 | 干什么用 | 要注意的点 |
|---|---|---|
| openai_hosted | OpenAI 为你拉起并管理一个 Linux 沙箱。凡是『跑代码或碰文件』的场景默认选它 | 配置好就能开工,起步最快 |
| none | 完全没有沙箱。给那些只回答问题、或只调外部工具、不跑本地命令也不碰本地文件的代理 | 失去一切本地文件与命令执行能力 |
| self_hosted | 代理跑在你自己的基础设施上,应用侧启动 codex exec-server 并把返回的 session.environment.id 和 remote_url 喂给它 |
自己搭执行器;还要单独发一把带 api.agents.environments.connect 权限的受限 key |
把 environment 当成一个同时涉及安全、成本、网络、产物与数据治理的决策,而不只是一个配置开关。托管沙箱是起步最快的路;self_hosted 是代理必须触碰你的 VPC、你的数据或你的工具链时的答案。self_hosted 的执行器要单独用一把受限的 OPENAI_EXECUTOR_API_KEY(带 api.agents.environments.connect scope)做认证,它的 IP 限制还得允许来自沙箱出口网络的请求。
session = client.beta.agents.sessions.create(
agent={"model": "gpt-6-astra"},
environment={"type": "self_hosted", "workspace_directory": "/workspace"},
)

第 3 步:把工具接上,MCP 的接线其实只有两行
工具是和模型、instructions 并列声明在 agent 上的。API 支持自定义函数、web_search 和 programmatic_tool_calling 这类内置工具,以及 MCP 服务器。下面这段改编自官方文档,把一个研究助手接到 OpenAI 自己的文档 MCP 服务器外加联网搜索。
session = client.beta.agents.sessions.create(
agent={
"model": "gpt-6-astra",
"instructions": (
"Use the OpenAI documentation MCP and web search to answer "
"technical questions accurately. Delegate independent research "
"tasks to subagents when useful."
),
"tools": [
{"type": "programmatic_tool_calling"},
{
"type": "mcp",
"server_label": "openai_docs",
"transport": {
"type": "http",
"server_url": "https://developers.openai.com/mcp",
},
},
{"type": "web_search"},
],
"multi_agent": {"enabled": True, "max_concurrent_subagents": 4},
},
environment={"type": "none"},
input="Research how to connect an MCP server to an OpenAI agent, "
"check for recent updates, and summarize the recommended setup.",
)
有几处值得单独指出。MCP 工具只需要 server_label 和一个带 server URL 的 HTTP transport——这就是全部的接线工作。这里的 environment 被刻意设成 none:这个代理只读网页,不需要沙箱。而 multi_agent 则打开了子代理,第 5 步详述。
第 4 步:用 session 组织代码,而不是用请求
session 才是持久单位:代理配置、对话、已保存的产物都跨轮次留存,你再也不必手工重建上下文。要继续干活,就用它的 ID 往同一个 session 里流式推新输入。
with client.beta.agents.sessions.stream(
session_id, # 第2步保存下来的
input="Add a maximum-depth option to tree.py, run it, and show me the output.",
) as events:
for event in events:
print(event.to_json(indent=None), flush=True)
先在发追问之前把事件流打开,否则会漏掉早期的事件。harness 负责上下文压缩——在会话接近上下文上限时把之前的工作摘要化——所以长会话不会在上下文边缘死掉,一个 session 还能从它停下的地方续跑。
会话做过的一切事后都可查:
turns = client.beta.agents.sessions.turns.list(session_id)
items = client.beta.agents.sessions.items.list(session_id)
subs = client.beta.agents.sessions.subagents.list(session_id)
files = client.beta.agents.sessions.artifacts.list(session_id)
# 活干完了,先下载需要的产物,再删会话
client.beta.agents.sessions.delete(session_id)
turns 带每一轮的状态与用量;items 是已保存的输出(消息、推理、函数调用、工具输出);artifacts 是代理产出的文件。活干完了先把需要的产物下载下来,再删掉 session,因为它会一直留着直到你自己删。
第 5 步:用子代理并行,4 个并发是官方给的天花板
当工作能拆成互不依赖的几块——调研三个 API、分诊三条告警——用一个代理顺序做完就浪费了 harness 提供的并行度。设了 multi_agent.enabled 之后,主代理会把活拆成子任务委派给子代理,每个子代理有各自独立的上下文。
session = client.beta.agents.sessions.create(
agent={
"model": "gpt-6-astra",
"instructions": "Research the topic and delegate independent subtasks.",
"multi_agent": {"enabled": True, "max_concurrent_subagents": 4},
},
environment={"type": "none"},
input="Compare the release notes of the last three OpenAI model launches.",
)
官方那个『用子代理对比发布说明』的例子是标准范式:每个子代理独立调查,主代理再把发现合并成一个答案。两条经验法则:只委派真正独立的工作;涉及共享状态时要小心协调——给每个子代理独立的目录或输出文件,避免写入互相覆盖。四个并发子代理是一个合理的上限,这也正好是官方示例里用的值。随时可以用第 4 步的 sessions.subagents.list(session_id) 查看子代理的活动。
四种代理方案对照:你该用哪一条路
在 OpenAI 平台上交付一个代理有四条路。选错路线比写错代码代价大得多,因为它决定你接下来几个月在补谁的活。
| 方案 | 适合什么时候用 | 代价是什么 |
|---|---|---|
| Agents API(本文) | 跑一个要执行代码/工具、且希望会话持久化和自动恢复的长任务:事故响应、深度调研、数据分析、代码仓库维护 | 编排细节不再完全自己掌控;public beta 稳定性;数据驻留仅限美国 |
| Responses API + 自己写循环 | 已有编排层,或必须完全控制重试、压缩和工具执行决策 | 开发速度;管理框架包办的那些边角情况全部退回给你 |
| Agents SDK(openai-agents 包) | 要一个轻量的、跑在单进程内的代理,配 handoffs 和 guardrails | 托管会话、托管沙箱、服务端自动恢复 |
| Dots(产品形态) | 你是终端用户,要一个常驻在线的助手,而不是开发者接口 | 全部可编程能力,它是产品不是 API |
任务和工具重、时长长,就默认走 Agents API:事故响应、深度调研、数据分析、代码仓库维护都属于这一类。等 harness 的那些默认决策开始硌得慌了,再降到 Responses API。SDK 夹在两者中间,适合单进程代理。
一个真实形状的用法:给仓库搭一个带审批的事故响应代理
官方 cookbook 里列的完整示例应用(incident response agent、Slack bot、data analyst、GitHub issue investigator、document reviewer)都是这个形态。拿事故响应这一条拆成你会真的写出的样子,六步就能对上号。
场景:线上告警进来,代理要读日志、定位原因、给出恢复建议——但真正执行恢复动作前必须有人批准。
- agent 怎么定:model 用
gpt-6-astra(这类活要看长上下文,价格放第二位),instructions 里写死那条红线——排查可以自行执行,恢复动作必须先请求批准。tools 里放programmatic_tool_calling接你的监控与日志查询接口,需要查文档时再挂一个 MCP server。 - environment 选 openai_hosted:它要跑脚本解析日志,不是只读问答,所以不能用
none。如果日志在你自己的 VPC 里,那就升级成 self_hosted,别为了省事把敏感日志搬到外部沙箱。 - session 是你的告警工单:一次告警一个 session_id,存到工单系统里。同一条告警后续的追问、补充信息都往这个 session 里流式推,不用重建上下文。
- 子代理分头查:同一次事故往往横跨三个服务,设
multi_agent.enabled、max_concurrent_subagents: 4,让主代理给每个服务分一个子代理,各自独立日志、独立输出文件,最后由主代理合并成一份判断。 - 事后审计靠 turns 和 items:工单结单前,把
turns.list的用量和items.list的推理过程存下来。出了争议,你能回放它当时为什么这么判断——这一点是『自己写循环』很难顺手拿到的。 - 收尾动作:下载 artifacts(报告、生成的修复补丁),然后
delete(session_id)。不删它就一直留着,数据足迹和成本都跟着涨。
这一形态之所以值得单独写,是因为它把六步的每一步都用满了:沙箱跑脚本、工具接内部系统、session 承载长期工单、子代理并行分诊、turns/items 做事后审计、delete 收尾。缺任何一块,就退回到自己维护循环的那条老路。
成本、限额与合规:先记住这三条
- 模型是你最大的成本杠杆。quickstart 用的是
gpt-6-astra;对价格敏感的工作负载,DevDay 上发布的 GPT-6.1 Sol 是官方点名的高性价比选择——输入 $2/百万 tokens、缓存输入 $0.10/百万、输出 $10/百万,官方定位是接近 Astra 的智力、约五分之一的价格。只改model字段、其余代码一字不动就能换过去,跑一版对一下账单。 - 盯着那些按量计费的附加项。模型 tokens 只是账单的一部分:OpenAI 工具按标准费率,托管沙箱按标准容器费率。长会话里高频用工具会累积,每轮的
usage是审计位置。 - 为 beta 而设计。把
openaipin 在 requirements 里,升级前重读 changelog。密钥别进沙箱,key 只授那三个权限,碰受监管数据时记牢仅限美国驻留与无 ZDR。
| 模型 | 定位与依据 | 怎么选 |
|---|---|---|
| gpt-6-astra | Dots 背后的主力模型,也是官方 quickstart 默认值,任务重、要质量时选它 | 贵;账单杠杆在这里 |
| GPT-6.1 Sol | DevDay 2026 发布的更新版,面向编程、computer use 与专业任务。官方定价:输入 $2/百万 tokens、缓存输入 $0.10/百万、输出 $10/百万,定位是接近 Astra 的智力、约其五分之一的价格 | 便宜,只改 model 字段、其余代码完全不用动 |
| Luna | 更小的模型。另一个 DevDay 产品 Decisions API(有限预览)用它从一组预设答案里做选择,官方点名分类、请求路由、决定代理下一步动作 | 只适合做一类单一选择的低自由度决策,别拿它跑复杂任务 |
5 个最容易踩的坑,都在官方文档里有明确依据
- 看到 turn.completed 就以为成功了。官方警告:一轮完成不代表每个工具调用都成了。必须检查代理回报的结果,这是本文最贵的一条。
- 把
agent.session.idle当成成功信号。它只说明代理当前不忙,不代表任务成了。 - 用 cURL 调试却忘了
OpenAI-Beta: agents=v1。SDK 自动带上,裸 HTTP 调用不会,请求直接失败且报错信息不指向这里。 - 把 API key 放进沙箱。代理会跑代码,沙箱内的一切凭据都应默认视为它可触及。self_hosted 场景下还要额外留意执行器那把受限 key 的 IP 限制配置。
- 干完活不删 session。会话会一直留存直到你删除,既占成本也留数据足迹。先下载 artifacts,再
delete(session_id)。
小结:session 不是请求,那才是你该围绕它构建的单位
Agents API 把过去几个月的代理基建工作——循环本身、会话存储、上下文压缩、断点恢复、沙箱供给——压缩成了一个 sessions.create。剩下的事,也一直是难的那部分:任务契约、工具选择、环境选择,以及判断代理何时算做完。
路径也很清楚:从托管沙箱和上面的 quickstart 起步;当你的安全姿态要求更高时,再切到 none 或 self_hosted;然后让 session、而不是 request,成为你写代码时围绕的那个单位。
参考来源:OpenAI 官方 Agents API 概览与 quickstart(developers.openai.com/api/docs/guides/agents-api/overview、/quickstart);openai-cookbook 的 agents_api 示例;InfoQ《OpenAI DevDay 2026 Recap for Developers》(2026-10-02);AI Frontier Post《Stop writing your own agent loop》(2026-10)。GPT-6.1 Sol 的定价与 Dots 的定位依据官方 DevDay 2026 发布信息与 InfoQ 报道。