让 Agent 点界面,比补接口贵 30 倍:computer use 成本实测

摘要: 本以为"让 AI 自己点界面"最省事,结果用本地沙箱实测:同一个导出报表任务,computer use 要滚 45 轮,成本比"补一个只读接口 + 两次调用"贵 30 倍。根因就两条------读数据也要先看图 、等待只能变轮询。三套脚本可改参数重跑,文末附成本护栏和判断标准。

文章目录

先声明:本地沙箱模拟,没接真实 API

先说清楚,这篇没有真的接 OpenAI 的 computer use 跑一轮(需要 API 环境,我没有),而是用本地沙箱把它的"截图→判断→动作"循环机制模拟出来 :按官方文档的 computer use tools 机制,把"让 Agent 去老后台导报表"这个任务拆成阶段,用脚本真实模拟每一轮的截图、轮询、重试开销,再按官方价格折算成 token 账单。

任务场景是我虚构的老后台,但这不影响机制验证------computer use 的成本结构不取决于数据真假,只取决于"轮数 × 单轮 token"。

三个脚本都在 Node 25.8.2 里真跑了,下面的轮数、token、账单都是运行结果,不是拍脑袋的数。所有参数都写在脚本里,你可以改参数重跑,验证你自己的任务会滚成多少轮。 模拟器只能验证机制,不能替代真实 API 行为------真实环境里模型还会看错界面、多绕弯路,实际账单大概率比模拟值更贵而不是更便宜。

为什么要干这件事?上一篇(《Agents API 支持 computer use 了》)算完账之后,我总觉得纸上算和真拆一轮是两回事------"点界面贵"到底贵在哪,得把机制拆开看才知道。拆完发现,比上一篇算的还夸张。

任务:老后台导出报表

任务很简单:在一个只有界面、没有 API 的老后台里,把"上个月订单"筛选出来导成 Excel。

我的第一反应是:这正好是 computer use 的用武之地啊------不用给老系统开接口,让 Agent 自己点就行。理想情况下,打开页面、填筛选、点查询、点导出、确认、等下载,十来步就完事了,比开发一个接口省事多了。

现象:账单比预想的大了一个量级

"账单"看着没多少,一算吓一跳。

先回答最核心的问题:45 轮是拍脑袋的还是跑出来的? 跑出来的。下面这个脚本把任务拆成阶段,按 computer use 的机制逐轮模拟------每一轮就是一次"截图→判断→动作",异步加载没有完成回调,只能每 300ms 截一张图轮询状态,点偏了还要多截一张重试。为啥要看这段:轮数不是结论,是机制的输出------参数改一个,轮数就跟着变。

js 复制代码
// 本地沙箱:把"点界面导报表"拆成阶段,模拟 computer use 的循环开销
// 机制:每一轮 = 截1张图(输入token) + 判断/动作(输出token)
//       异步加载没有"完成回调",只能每 300ms 轮询截图看状态
const POLL_MS = 300;    // Agent 两次轮询截图的间隔
const IMG_TOK = 1800;   // 单张截图折算的输入 token(图像按输入计费)
const OUT_TOK = 600;    // 单轮"判断+动作"的输出 token

// 每个阶段: base=顺利时截图数, waitMs=异步等待时长, retry=点偏重试多截的图
const stages = [
  { name: "打开后台",      base: 1, waitMs: 600,  retry: 1 }, // 首屏加载 + 菜单判断点偏一次
  { name: "进报表页",      base: 1, waitMs: 600,  retry: 1 }, // 路由切换 + 入口点偏一次
  { name: "填筛选条件",    base: 3, waitMs: 0,    retry: 0 }, // 点输入框/输入/选下拉,顺利一次过
  { name: "点查询+等加载", base: 1, waitMs: 2700, retry: 0 }, // 查询返回前只能轮询截图
  { name: "点导出+弹窗",   base: 1, waitMs: 600,  retry: 1 }, // 弹窗响应 + 导出按钮点偏一次
  { name: "确认导出",      base: 1, waitMs: 400,  retry: 0 }, // 确认后生成文件
  { name: "等下载+收尾",   base: 1, waitMs: 2700, retry: 0 }, // 下载完成前只能轮询截图
  { name: "核对文件",      base: 1, waitMs: 0,    retry: 0 }, // 最后截一张确认导出来了
];

function waitShots(ms) { return ms > 0 ? Math.ceil(ms / POLL_MS) + 1 : 0; } // 有异步等待才轮询

const breakdown = stages.map(s => {
  const act = s.base, poll = waitShots(s.waitMs), rty = s.retry;
  return { 阶段: s.name, 动作: act, 等待轮询: poll, 重试: rty, 合计: act + poll + rty };
});

console.table(breakdown);
const total = breakdown.reduce((s, b) => s + b.合计, 0);
const ideal = stages.reduce((s, st) => s + st.base, 0);
console.log(`总轮数: ${total}  |  理想一次过: ${ideal} 轮  |  放大: ${(total / ideal).toFixed(1)}x`);
console.log(`输入token: ${total * IMG_TOK}  |  输出token: ${total * OUT_TOK}`);

运行结果(Node 25.8.2 实测):

text 复制代码
┌─────────┬─────────────────┬──────┬──────────┬──────┬──────┐
│ (index) │ 阶段            │ 动作 │ 等待轮询 │ 重试 │ 合计 │
├─────────┼─────────────────┼──────┼──────────┼──────┼──────┤
│ 0       │ '打开后台'      │ 1    │ 3        │ 1    │ 5    │
│ 1       │ '进报表页'      │ 1    │ 3        │ 1    │ 5    │
│ 2       │ '填筛选条件'    │ 3    │ 0        │ 0    │ 3    │
│ 3       │ '点查询+等加载' │ 1    │ 10       │ 0    │ 11   │
│ 4       │ '点导出+弹窗'   │ 1    │ 3        │ 1    │ 5    │
│ 5       │ '确认导出'      │ 1    │ 3        │ 0    │ 4    │
│ 6       │ '等下载+收尾'   │ 1    │ 10       │ 0    │ 11   │
│ 7       │ '核对文件'      │ 1    │ 0        │ 0    │ 1    │
└─────────┴─────────────────┴──────┴──────────┴──────┴──────┘
总轮数: 45  |  理想一次过: 10 轮  |  放大: 4.5x
输入token: 81000  |  输出token: 27000

理想情况 10 轮(每个动作截一张图就完事),模拟器跑出 45 轮,放大了 4.5 倍------多出来的 35 轮全是等待轮询和点偏重试。拿到轮数,再看账单:同一个导出任务,走 computer use 和走结构化接口,按同一套官方价格算,差距到底多大。

js 复制代码
// 成本折算:模拟器实测 45 轮 × 单轮 token × 官方价格(GPT-6.1 Sol:输入 2 / 输出 10 美元每百万 token)
const ROUNDS = 45;                 // 上一个脚本实测输出:总轮数 45
const PRICES = { input: 2, output: 10 };

function cuCost(rounds) {
  const inputTokens = rounds * 1800;   // 每轮一张截图
  const outputTokens = rounds * 600;   // 每轮判断+动作
  return { rounds, inputTokens, outputTokens,
    totalUsd: +((inputTokens / 1e6) * PRICES.input + (outputTokens / 1e6) * PRICES.output).toFixed(3) };
}

function apiCost(calls) {
  const inputTokens = calls * 1000;
  const outputTokens = calls * 500;
  return { calls, inputTokens, outputTokens,
    totalUsd: +((inputTokens / 1e6) * PRICES.input + (outputTokens / 1e6) * PRICES.output).toFixed(3) };
}

const cu = cuCost(ROUNDS);
const api = apiCost(2);   // 补只读接口后:查列表 1 次 + 导出 1 次
console.log("computer use(点界面):");
console.log(JSON.stringify(cu, null, 2));
console.log("结构化接口(2次调用):");
console.log(JSON.stringify(api, null, 2));
console.log("倍率: " + (cu.totalUsd / api.totalUsd).toFixed(1) + "x");

运行结果(Node 25.8.2 实测):

text 复制代码
computer use(点界面):
{
  "rounds": 45,
  "inputTokens": 81000,
  "outputTokens": 27000,
  "totalUsd": 0.432
}
结构化接口(2次调用):
{
  "calls": 2,
  "inputTokens": 2000,
  "outputTokens": 1000,
  "totalUsd": 0.014
}
倍率: 30.9x

三十倍。上一篇的演示参数是 45 轮对比 8 次调用(9.6 倍),我这个具体任务更极端------任务越简单(业务上本来一两次调用就能拿完),computer use 越亏:它的循环不会因为你业务简单就变少,界面步骤照样一步不落。

顺手回答一个肯定有人问的问题:单次 0.43 美元听着不多,至于吗?至于------这不是单次任务的事,是成本结构的事。同一个任务,接口版单次只要一分多;而"导出报表"在真实业务里是每天定时跑的,一天跑几百次,差距就从几毛钱滚成每天几十美元的差距,换成更贵的模型放得更大。单次看不出,放大才看得出来。

上面的成本差距,用一张图看得更直接。下图把任务按复杂度分成三档:简单任务就是"查列表 + 导出"2 次调用,中、高复杂度则是接口需要更多分页调用时的外推值;computer use 线同样按文中单轮真实成本做外推,实测点仍是开头的 45 轮 / 0.432,接口侧锚定 2 次调用 / 0.014。
#mermaid-svg-7ktotOQFOoJ4yfia{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7ktotOQFOoJ4yfia .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7ktotOQFOoJ4yfia .error-icon{fill:#552222;}#mermaid-svg-7ktotOQFOoJ4yfia .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7ktotOQFOoJ4yfia .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7ktotOQFOoJ4yfia .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7ktotOQFOoJ4yfia .marker.cross{stroke:#333333;}#mermaid-svg-7ktotOQFOoJ4yfia svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7ktotOQFOoJ4yfia p{margin:0;}#mermaid-svg-7ktotOQFOoJ4yfia :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不同任务复杂度下成本曲线:computer use vs 结构化接口 简单任务 中等任务 复杂任务 1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0 单次成本(USD)

交叉点远在右侧:要等接口复杂到上百次调用(比如分页拉取约 120 次以上),结构化接口的累计成本才会追上 computer use。日常这种"一两步就能拿完"的简单任务,computer use 亏出 30 倍不是单价差距,而是它 45 轮的界面步骤一步都省不掉------任务越简单,倍率越夸张。

排查:token 都烧到哪去了

等等,为什么是 45 轮?我一开始估的理想步骤不是十来步吗?把任务按阶段拆开,多出来的轮数主要花在三个地方,token 的去向也基本跟着这三块走:

text 复制代码
45 轮循环的 token 去向(模拟器 45 轮实测折算,按 GPT-6.1 Sol 口径)
截图(图像输入)  ██████████████████████████  81000 tok  ← token量最大(读也要看图)
判断+动作(输出) ██████████  27000 tok(单价贵5倍,按成本算才是大头)
  • 等待 = 轮询:点完查询,假后台接口要几秒才返回,Agent 不知道什么时候加载完,只能一次次截图看状态。一次等待,就是好几轮循环
  • 点偏 = 重试:筛选下拉框第一次点没弹出来,它又点了一次;导出按钮判断错位置,又点了一次
  • 每轮循环都有三份开销:截图(图像 token)+ 判断(输出 token)+ 动作(输出 token)

把任务按阶段拆开看,理想轮数和模拟器实测的轮数差得很远:

阶段 理想(一次过) 模拟器实测 多出来的原因
打开后台 1 5 首屏加载轮询 3 + 点偏重试 1
进报表页 1 5 路由等待轮询 3 + 点偏重试 1
填筛选条件 3 3 顺利一次过
点查询 + 等加载 1 11 查询 2.7s 才返回,只能轮询截图
点导出 + 弹窗 1 5 弹窗响应轮询 3 + 点偏重试 1
确认导出 1 4 生成文件等待轮询 3
等下载 + 收尾 1 11 下载 2.7s 才完成,只能轮询截图
核对文件 1 1 顺利一次过
合计 10 45 理想 10 轮滚成 45 轮,4.5 倍

10 轮的理想,滚成 45 轮。每一轮都不贵(按 Sol 的价格,单轮大概不到一美分),但 45 轮叠起来,原以为跟上一篇一样是个量级差,实际直接滚成了三十倍。

根因:读=操作,等待=轮询

复盘下来,根因是两个机制叠加,都不是 Agent"蠢":

  1. computer use 里"读数据"也要先"看图"------筛选出结果,人扫一眼就完事;Agent 得截一张图,把结果读进上下文。读一次,就是一次带图像的输入
  2. 异步任务没有"完成回调"------加载、下载这种异步操作,computer use 收不到"完成了"的通知,只能反复截图判断状态。等待越久,轮询越多

这两个机制让"理想步数"和"实际轮数"严重脱节。我估预算的时候,是按"打开-筛选-查询-导出-确认-下载"这些阶段一路顺畅来算的,默认每步一次过------真实世界里,等待和出错会把它撑成四五倍。

这里有个直接的教训:给 computer use 任务估预算,不能按理想步骤数估,得按"实际轮数"估,而实际轮数基本要翻四五倍(我这套参数模拟出来是 4.5 倍)。

修复:补只读接口 + 成本护栏

同一任务,补一个只读导出接口(跟界面系列第二弹说的结构化通道一个思路),成本立刻下来:

  • 两次调用:查列表 + 导出
  • 账单立刻降了一个量级(上面脚本里那两组数字)
  • 额外收益:可鉴权、可审计、出错可重放

但有些场景确实没法开接口(第三方软件、权限拿不到),这时候 computer use 还得用。那就得上成本护栏 ------跑之前先按实际轮数估预算,超了就拦下来,别让它闷头跑。为啥要看这段:护栏的作用不是省那几毛钱,是让"烧爆账单"这种事故不发生。

js 复制代码
// 成本护栏:跑 computer use 任务前先估预算
// 45 轮来自上面的沙箱模拟器实测,换成你任务的轮数即可
function guard(estimatedLoops, imgTokensPerShot, thinkTokensPerStep, budgetUsd) {
  const inputTokens = estimatedLoops * imgTokensPerShot;
  const outputTokens = estimatedLoops * thinkTokensPerStep;
  const cost = (inputTokens / 1e6) * 2 + (outputTokens / 1e6) * 10;  // GPT-6.1 Sol
  return { estimatedLoops, cost: +cost.toFixed(3), budgetUsd, allowed: cost <= budgetUsd };
}

console.log(guard(45, 1800, 600, 0.2));  // 预算 0.2 美元
console.log(guard(45, 1800, 600, 0.5));  // 预算 0.5 美元
console.log(guard(45, 1800, 600, 0.1));  // 预算 0.1 美元

运行结果(Node 25.8.2 实测):

text 复制代码
{ estimatedLoops: 45, cost: 0.432, budgetUsd: 0.2, allowed: false }
{ estimatedLoops: 45, cost: 0.432, budgetUsd: 0.5, allowed: true }
{ estimatedLoops: 45, cost: 0.432, budgetUsd: 0.1, allowed: false }

45 轮的成本四毛多,预算给 0.2、0.1 的直接拦掉,给 0.5 的放行。真线上跑的时候,预算按"实际轮数"估(理想步骤 × 四五倍,我这套参数模拟出来是 4.5 倍),别按理想步骤估。

边界:computer use 什么时候反而划算

这套账算下来,computer use 也不是一无是处。反过来看,有几类场景它是划算的:

场景 为什么划算
一次性任务 反正只跑一次,开发接口的人力成本比 token 成本贵
第三方软件 没有接口权限,computer use 是唯一解
低频只读场景 偶尔用一次、只拿数据不写,每次 token 成本不高,不值得为它做接口

判断标准跟上一篇一致:这个任务会不会反复跑?这个数据能不能只读拿到? 反复跑、能只读拿到,就开接口;一次性、拿不到接口,再放 computer use。

错误处理与降级策略

前面那套成本护栏解决的是"跑之前放不放行",但任务真跑起来,还有另一类问题:跑到一半失败了怎么办。computer use 不像结构化接口那样有明确的错误码和重放机制,它更接近"点着点着卡住了"------所以得提前想清楚:哪些失败可以原地重试,哪些该立刻止损降级。

先说重试策略。失败要先分两类:

  • 偶发失败:点偏了、加载慢了一点、弹窗出来慢了半拍。这类值得重试,但必须有次数上限,不能同一个动作无限重试。
  • 结构性失败:按钮位置变了、页面改版、筛选框根本没了。这类重试也白搭,越试越烧钱,应该直接降级。

对应到实现上,最好设"双层护栏":单步重试上限 + 全程最大轮数上限。单步重试解决"这一步点偏了再试几次",全程轮数上限解决"整体卡死、陷入循环"。最大轮数不能拍脑袋设一个超大值,可以按任务的理想步数乘一个放大系数(本文这套参数里实测是 4.5 倍),再留一点余量。

然后是降级顺序。跑不下去的时候,按这个优先级走:

  1. 能转结构化接口就先转接口:像导报表这种"读数据"任务,本来就有只读接口可选,computer use 一失败,直接改调接口最稳。
  2. 没有接口就转人工:把当前状态、已完成到哪一步、最后一张截图、建议人工执行的动作整理出来交给人,而不是让 Agent 继续盲目试探。
  3. 绝不无限重试:超过最大轮数或单步重试上限,必须强制终止,避免成本雪崩。

下面是一段伪代码,展示这个降级判断逻辑:

text 复制代码
function runTaskWithFallback(task) {
  const idealSteps = estimateIdealSteps(task);   // 理想情况一步过需要多少步
  const maxRounds = idealSteps * 5;              // 按放大系数设上限,本篇实测约 4.5x
  const maxStepRetry = 3;                        // 单步最多原地重试 3 次
  let rounds = 0;

  while (!task.done) {
    rounds++;
    if (rounds > maxRounds) {
      return fallback(task, "超过最大轮数上限");
    }

    const result = computerUseStep(task);
    if (result.ok) continue;

    if (result.retryable && result.stepRetry < maxStepRetry) {
      result.stepRetry++;
      continue;                                  // 偶发失败,原地重试
    }

    // 重试仍然失败:能开接口就降级到结构化接口
    if (task.hasReadonlyApi) {
      return task.callApi();                     // 结构化接口兜底
    }

    return handoffToHuman(task);                 // 没有接口,转人工处理
  }

  return task.result;
}

function fallback(task, reason) {
  if (task.hasReadonlyApi) return task.callApi();
  return handoffToHuman(task, reason);
}

核心就是一句:允许有限重试,但必须预留降级出口。 computer use 最怕的不是某一步失败,而是失败之后没有刹车、重复烧钱。

收尾

一句话总结:computer use 不是不能用,是"每一步都在付账"这件事,比想象中严重------读数据要付账,等加载也要付账,点偏了重试还要付账。让 AI 点界面之前,先把账算清楚(这篇的模拟器脚本拿回去,改参数就能算);能开接口的补个接口;真不能开接口的,至少先估预算、上成本护栏。

对了,这篇的轮数是本地沙箱模拟器跑出来的,参数都写在脚本里------你在自己的任务里改参数重跑,就能验证"等待轮询、点偏重试"这两件事到底会把账单撑到多少倍。模拟器只能验证机制,真实模型还会看错界面、多绕弯路,实际账单大概率只高不低。价格按 09.29 DevDay 公告的 GPT-6.1 Sol 定价折算(输入 2 / 输出 10 每百万 token),computer use 的能力和价格都在快速迭代,动手之前以官方文档最新版本为准。

参考资料

  • Agents API 官方文档:computer use 的上游能力入口,本文"截图→判断→动作"的循环机制属于 Agents API 的 computer use 能力范围。
  • computer use tools:文中所模拟的 computer use 每一步"截图、判断、动作"的官方机制说明来源。
  • OpenAI API 定价页:09.29 DevDay 公告的 GPT-6.1 Sol 定价折算依据(输入 2 / 输出 10 每百万 token),实际动手前以官方最新版为准。
相关推荐
Tokenge1 小时前
Grok 4.7 上手指南 智能 速度与成本如何兼顾
人工智能·gpt·ai
zhangfeng11331 小时前
qjlDim 含义 TurboQuant QJL Quantized Johnson-Lindenstrauss,量化JL随机投影
人工智能·算法·ai编程·npu
光依旧1 小时前
MCP实战手记(九):生产化MCP Server的6层安全防护
java·人工智能·spring boot·安全·网络安全·ai agent·mcp
红海云1 小时前
Jev放开之后,Agent开始分工
人工智能
Flynt2 小时前
Claude Code 103 秒删掉 4.8 万个文件之后,我把自己的仓库"删"了一遍:git 能救的比你想的少
git·ai编程·claude
灰山君2 小时前
面向高校实训室的数字孪生可视化平台:支持校内部署与200个教学席位
大数据·人工智能·信息可视化·数据可视化·实时大数据
马剑威(威哥爱编程)2 小时前
【AI全栈后端12-04】Spring Boot 用结构化输出自动解析简历:让模型按你的 POJO 输出
java·人工智能·spring boot·后端
海盗12342 小时前
AI 新闻日报 2026-09-30:智能体边界下沉到芯片、微软统一多智能体 SDK、具身工具链走向智能体可用
人工智能·microsoft·机器人·人工智能aigc
时晴⁧⁧2 小时前
Skill和MCP推荐清单
ai编程