返回博客

OpenAI Agents API 公测实测|托管 Harness 省 Token

人工智能5007
OpenAI Agents API 公测实测|托管 Harness 省 Token

OpenAI 把 Codex 背后的托管智能体 harness 以 Agents API 的形式开放了公开测试(public beta),Meta 也在 Muse 应用里推出共享智能体(Shared Agents),托管 harness 正在成为大厂共同押注的中间层。我维护一套自建 harness 一年多,正好借这次公测,把自建与托管的账摊开算一遍。

一、开篇痛点:自建 harness 的三类隐性成本

先交代背景。我的生产链路一直是三层:业务应用、中转、模型,中转用 4sapi(https://4sapi.com),密钥集中管理,用量和账单在一个后台看全。harness 部分最初选择自建——任务循环、上下文裁剪、工具注册、子任务调度,全部自己写。一年多下来,交付没问题,但有三类成本越积越重。

第一类是上下文工程的重复劳动。历史轮次怎么截断、工具结果怎么裁剪、什么时候做摘要、摘要放在哪一层,这些逻辑每次换模型、每次调整任务类型都要重调一遍。调好了算性能优化,调不好就是一台隐性的 token 放大器。

第二类是失败处理的长尾。超时、限流、工具报错、子任务半途而废,每一类失败都需要单独的重试和降级策略。重试逻辑一旦散落在各处,就会出现同一份工单被创建两次这类事故。长任务的断点续跑更麻烦:进程重启后从哪里恢复、恢复时怎么避免重复执行,都要自己实现。

第三类是 token 浪费难归因。system prompt 每轮全量重复、历史轮次全量重放、子智能体各自带一份大上下文,账单涨了却说不清是哪一步烧的。归因做不出来,优化就无从下手。

这三类成本单次看都不大,累积起来吃掉的是迭代速度:真正交付业务逻辑的时间,往往不到投入的三成。所以这次 Agents API 公测,我关心的不是它多了多少新能力,而是它能把上面三类成本接管多少。

二、Agents API 托管了什么:六件套逐个看

OpenAI 这次把 Agents API 以 public beta 的形式开放给开发者,核心动作是把 Codex 背后的托管智能体 harness 与对应基础设施开放出来,定位是支撑可长时间运行的智能体。既然是公开测试,能力边界和字段都可能随版本演进,接入前要按官方文档核对现状。托管范围包括六件事,逐个对应到我前面的痛点。

上下文管理。托管层负责维护任务的对话状态:历史轮次、工具结果、阶段性摘要都由平台处理。这直接对应第一类成本——截断与摘要策略不再自己写,也不随换模型而重调。

工具调用。工具的注册、参数校验、调用与结果回填在托管侧闭环。自建系统里最容易出事故的"模型输出参数不可信"问题,校验逻辑收敛到平台一层,行为更可预期。

子智能体(subagents)。平台原生提供子智能体机制,主任务可以拆出子任务,不再自建任务队列和结果汇总。子智能体拥有独立上下文,干完活把结论交回来,这是控制主上下文膨胀的关键手段。

持久执行(persistent execution)。任务状态持久化在平台侧,进程重启、网络中断之后可以按 run id 恢复。这是我自建方案里做得最痛苦的部分,也是"可长时间运行"这个定位的技术前提。

文件。文件作为一等公民挂进任务,中间产物和结果文件有地方放,不用把大段内容塞进提示词,也不用在提示词里传 base64。

代码环境。托管侧提供沙箱化的代码执行环境,计算、格式转换、数据统计这类子任务交给真实代码跑,不依赖模型心算,也不必自己维护一个执行沙箱。

六件套合起来看,是把 harness 该干的活从项目目录搬到了平台上。行业侧的动向也在往同一方向走:Meta 在 Muse 应用中推出共享智能体(Shared Agents),可定制、可分享给他人使用,面向客服、销售等小微业务工作流。两家大厂的动作指向同一层——托管智能体中间层。

三、原理速览:一条请求要穿过四层

接入之前先把分层画清楚。我的链路里,中转层负责接入与计费,托管 harness 负责智能体运行时:

text
应用层(业务代码)
   |  下发任务:目标 + 验收标准 + 工具清单 + 预算上限
   v
中转层(OpenAI 兼容端点)
   |  统一鉴权、按渠道负载均衡、聚合计费与用量报表
   v
托管 harness(Agents API)
   |  上下文管理 / 工具调用 / 子智能体 / 持久执行 / 文件 / 代码环境
   v
模型层
      生成推理与动作,由 harness 把动作落到对应执行环境

这张图里值钱的不是箭头,是每一层"对什么负责"的边界。应用层只关心业务目标和验收标准,不关心模型怎么管理上下文;中转层解决接入工程问题——一份密钥、一份账单、渠道间负载均衡,用量按任务维度可查;托管 harness 把原本散落在自建代码里的循环、重试、状态管理收编成平台能力;模型层保持无状态,上下文由 harness 组织后送进来。

分层的实际意义是可替换性。模型可以换,中转渠道可以换,托管与自建理论上也可以混用——把六件套里自己最有把握的一两件留在自建侧,其余交给平台,是一条渐进式迁移路径,而不是一次非黑即白的二选一。判断在哪一层动手改造之前,先让每一层的职责边界稳定下来。

四、托管与自建:一张对比表

把取舍压缩成一张表。token 一栏的数字是估算口径,依据是我自己系统里两处典型浪费——历史轮次全量重放、工具原始结果不裁剪——按托管侧摘要回填的通行做法折算,最终以实际账单回放为准。

维度自建 harness托管 harness(Agents API)
迭代速度换模型或改任务类型都要调管道代码平台侧升级,应用层主要改配置(定性)
上下文控制粒度完全可控,可做领域裁剪策略由平台决定,可调项有限
审计日志在本地,格式自定依赖平台留存与导出,接入前先确认口径
迁移成本前期投入高,换运行时要重写前期低,退出成本需提前评估
token 开销重放与摘要策略自己定,容易放大上下文由平台压缩管理,估算可省 20%–40%(估算口径)
长任务可靠性断点续跑自己实现persistent execution 原生支持
子智能体自建队列与汇总平台原生,独立上下文

表里唯一给出数字的是 token 一栏,其余保持定性,因为迭代速度、审计这类维度强依赖团队现状,拍一个百分比没有意义。我的判断是:验证期的新业务优先托管,先把迭代速度拿到手;有强合规留存要求或深度领域裁剪需求的部分,保留自建,或采用自建加托管的混合形态。取舍的关键不是哪个更先进,而是哪一类成本在当前业务里更稀缺。

五、接入教程:从环境准备到跑通第一个智能体

环境准备按下面的清单走:

下面的 Python 示例演示完整链路:通过中转创建客户端,定义一个只读查询工具,创建一个带代码环境的子智能体,再创建挂载工具与子智能体的主智能体并运行任务。字段命名是示意写法,具体字段以官方文档为准:

python
import os
import time

from openai import OpenAI

# 中转接入:base_url 指向 OpenAI 兼容端点,密钥走环境变量
client = OpenAI(
    api_key=os.environ["OPENAI_API_KEY"],
    base_url=os.environ["OPENAI_BASE_URL"],
)

# 定义只读工具:查询订单状态(参数结构为示意,以官方文档为准)
query_order_tool = {
    "type": "function",
    "name": "query_order",
    "description": "按订单号查询订单状态与金额,只读操作",
    "parameters": {
        "type": "object",
        "properties": {
            "order_id": {"type": "string", "description": "订单号,例如 A1024"}
        },
        "required": ["order_id"],
    },
}

# 创建子智能体:数据分析外包出去,结论控制在 300 字内
analyst = client.agents.create(
    name="data-analyst",
    instructions="对收到的数据做分析,输出关键结论、依据和风险点,不超过 300 字。",
    tools=["code_interpreter"],  # 代码环境由托管侧提供,标识以官方文档为准
)

# 创建主智能体:挂载工具与子智能体
agent = client.agents.create(
    name="order-support",
    instructions=(
        "处理订单咨询。先查订单状态;金额异常时把明细交给子智能体分析,"
        "避免主上下文膨胀;最终回复包含结论与处理建议。"
    ),
    tools=[query_order_tool],
    subagents=[{"agent_id": analyst.id, "scenario": "金额异常数据分析"}],
)

# 运行任务:入口声明 token 预算,超限由平台侧熔断
run = client.agents.runs.create(
    agent_id=agent.id,
    input="客户反馈订单 A1024 金额异常,先查状态,再判断是否需要数据分析。",
    token_budget=50000,  # 字段名为示意,以官方文档为准
)

# 持久执行:轮询状态;进程重启后按 run_id 恢复,不从头重跑
while run.status in ("queued", "in_progress"):
    time.sleep(3)
    run = client.agents.runs.retrieve(run_id=run.id)

print(run.status)
print(run.output_text)

三个接入要点展开说。第一,工具与子智能体都在创建阶段声明,运行期不改结构,这既保证任务行为可预期,也让审计有固定对象。第二,run 有独立 id,配合持久执行,长任务中断后按 id 恢复,这是托管侧相对自建最省心的一点。第三,token_budget 放在任务入口而不是散在代码里,超限熔断发生在平台侧,预算纪律从"约定"升级成"机制"。中转侧的价值在接入时顺带体现:一份密钥接完整条链路,所有任务的用量与账单落在同一个后台,归因时不必跨多个控制台对数。

六、token 预算设计:主任务与子智能体分账

托管不等于不管预算。子智能体有独立上下文,用得爽也烧得快,预算要从"总数"细化到"分账"。我的设计原则有三条:主任务上下文只保留目标、当前状态与决策摘要;计算、长文阅读这类重活下放子智能体;子智能体只返回压缩结论,不回传原始数据。

按这个原则给一个中等复杂度任务做预算分配(估算口径):

预算项估算区间说明
主任务基础上下文8k–16k tokens任务目标、工具清单、阶段性摘要
单次工具调用往返0.5k–2k tokens原始结果裁剪后回填
子智能体单次任务10k–30k tokens独立上下文,返回 300 字内结论
主任务汇总与终稿2k–5k tokens写结论与处理建议
全任务熔断线100k tokens任一维度触顶即停,人工介入

分账的核心收益是可归因。账单涨了,能定位到是某个子智能体的任务量变多,还是主循环轮次变长,而不是对着一笔总数发呆。配合托管侧的持久执行还有一层隐性收益:任务恢复时上下文按任务状态重建,避免了自建方案里"恢复即重放全部历史"的最大单点浪费。预算区间本身不神秘,拿十个真实任务回放一遍,就能把上表校准成贴合业务的版本。

七、停止规则与失败重试:长时间运行的纪律

长时间运行的智能体,最大的风险不是失败,而是"看起来还在工作"的无限循环——反复重试、反复自我修正,预算被一点点磨掉。持久执行把任务生命周期拉长了,停止纪律就要更严格。我的规则清单:

text
任务启动 ── 登记三类预算
   |
   v
执行一步 ──失败──> 可重试? ──否──> 上报并保留现场
   |        |
   |        是
   |        v
   |   退避重试(上限 3 次)
   |        |
   +<──成功──+
   |
   v
到达检查点 ── 落状态、写摘要
   |
   v
预算触顶? ──是──> 熔断,输出已完成部分与现场引用

这张图的重点是"分类发生在重试之前"。可重试的失败交给退避策略,不可重试的失败直接进人工通道。两者混在一起处理,是自建系统里最常见的反模式——要么把不该重试的错误重试到熔断,要么把该重试的错误一次就放弃。持久执行把检查点变成平台能力之后,这套纪律里真正需要自己守住的,只剩预算口径和幂等设计两件事。

八、单任务 token 构成测算(估算口径)

拿上面订单异常处理任务为例,按托管侧的运行方式拆一笔账。以下均为估算口径,具体以中转后台与平台账单为准:

构成项tokens(估算)占比备注
system 与任务描述3,0006%一次性注入
主循环轮次(12 轮)30,00058%历史随轮次累积,最大头
工具结果回填8,00015%裁剪后回填
子智能体两轮任务9,00017%独立上下文
最终输出2,0004%结论与建议
合计52,000100%熔断线 100k,留有余量

两个结论从这张表里读出来。第一,主循环轮次占了近六成,这正是托管上下文管理的主战场——用阶段性摘要替代全量重放,占比能明显压下来;自建系统如果没做摘要策略,同样的任务实测通常更高。第二,子智能体虽然自带独立上下文,看起来多花了一份,但换回来的是主上下文不被分析明细撑爆,主循环轮次的增量成本反而更低。这笔账要合在一起算,不能只看单项。

成本金额不给出具体数字,因为不同渠道、不同模型的实时单价差异很大,折算方式也随中转计费口径变化。可操作的做法是:跑十个真实任务取平均构成,按账单实际价折算出单任务成本基线,之后再做优化就有对照。测算的意义不在精确,而在让"省 token"从一句口号变成可复核的差值。

九、风险与合规提示

托管省下来的人力和 token,对应的是控制权的部分让渡,三件事要在接入前想清楚。

数据出域。任务内容、文件、工具结果都会进入平台基础设施。涉及客户隐私或商业敏感数据的任务,先做数据分级:能脱敏的脱敏后进任务,不能出域的留在本地处理。共享智能体这类可分享的能力尤其要注意授权范围,别让内部数据通过分享链路流出去。

审计留存。日志与审计记录转由平台侧留存后,留存期限、导出方式、字段粒度都要提前确认。自建时代"日志在自己手里"的掌控力会部分让渡,对留存有明确要求的团队,这一项要作为硬条件评估,谈不拢就自建。

供应商依赖。六件套的能力边界和字段会随版本演进,业务代码里保留一层自己的抽象,不把流程硬编码在平台特有字段上。接入方式以官方文档与中转服务条款为准,只做合法接入与架构设计上的讨论,不碰绕过限制的方案——这一条既是合规要求,也是工程上避免脆弱依赖的常识。

十、上线前检查清单

接入教程跑通之后、正式放量之前,按这份清单过一遍:

  1. 最小链路验证:单工具、无子智能体的任务先跑通,确认中转、托管、模型三层的报错能明确区分;
  2. 熔断演练:故意把 token 预算调到极低,确认超限时任务真的停下来,而不是静默继续;
  3. 恢复演练:任务运行中主动杀掉进程,按 run id 恢复,确认带幂等键的写操作不会重复执行;
  4. 分账核对:从账单后台核对每个子智能体的用量,确认归因粒度满足排查需要;
  5. 敏感数据演练:把含手机号等信息的样本送进任务,确认日志与输出符合内部脱敏规范;
  6. 限流退避验证:模拟限流响应,确认退避节奏与重试上限符合第七节的规则;
  7. 退出方案评审:写下未来更换托管方时需要重写哪些部分,避免依赖在无感知中越积越深。

清单前四项对应功能与成本,后三项对应风险。全部通过再放量,比出事故之后补课便宜得多。

十一、总结

这一期把 OpenAI Agents API 的 public beta 捋了一遍:托管范围是六件套——上下文管理、工具调用、子智能体、持久执行、文件、代码环境,定位支撑可长时间运行的智能体;对照自建 harness 的三类隐性成本,给出了四层架构图、托管与自建的对比表、通过中转接入的 Python 示例、token 预算分账与单任务构成测算(估算口径),以及停止重试纪律和上线检查清单。行业侧 Meta 的共享智能体与这套托管能力指向同一个趋势:harness 正在从项目里的脚手架变成平台中间层,自建的灵活性没有消失,只是从默认选项变成了需要论证的选项。我后续会把部分生产任务迁到托管 harness 上,把省下的人力和 token 记录成对照数据;接入与账单管理继续通过 4sapi(https://4sapi.com)完成,所有渠道用量集中在一个后台。关于托管与自建的取舍,或者迁移途中踩过的坑,欢迎在评论区聊聊。

标签:OpenAI Agents API托管Harness省Token成本优化接入实测

推荐阅读

探索更多前沿洞察与行业干货。