logo

操作型智能体的模型分层选型与成本权衡

作者:JC2026.11.10 19:55浏览量:0

简介:本文围绕屏幕操作类智能体的模型选型,说明如何按任务复杂度、调用频率和容错要求做分层路由。文中给出单任务成本与端到端时长的核算方法、自建评测集的步骤,以及带升级策略的代码示例,帮助团队在质量和成本之间找到平衡点。

一、问题背景

智能体执行界面操作时,任务大致分成两类。第一类是高频、短链路的操作,例如点击按钮、填写表单、读取页面状态、核对订单字段。这类任务步骤少,每一步的判断相对明确,但每天的调用量可能达到数万次。第二类是低频、长链路的任务,例如跨多个页面整理信息、根据规则判断异常并给出处理方案、修改复杂的业务流程。这类任务单次调用的推理量大,错误代价也高。

如果所有任务都交给同一个模型处理,会出现两种典型问题。第一种是成本随调用量线性增长,高频任务把预算吃光。第二种是能力不足导致返工,操作失败后需要人工介入或重新执行,总成本反而更高。分层选型的思路是:先把任务按复杂度、频率和容错要求分组,再为每组匹配合适的模型档位,而不是只挑一个“最好”的模型。

二、选型的四个维度

1. 任务复杂度

复杂度看的是完成任务所需的规划步数和判断难度。单步可判定的任务,例如“点击某个确认按钮”,对模型的要求是准确识别界面元素。多步规划的任务,例如“找到三个月内未结算的订单并逐条核对退款状态”,要求模型记住上下文、维护计划、处理分支情况。复杂度越高,越需要强模型,但强模型并非在所有环节都必要。

2. 调用频率与单次成本

频率决定了成本的总量。一个单次成本只有几分钱的任务,如果每天执行十万次,月度账单可能超过一个单次成本高但每天只执行几十次的任务。选型时应同时计算“单次成本”和“月度总成本”,两个数字的排序可能完全不同。

3. 视觉与界面理解需求

很多操作任务依赖截图或页面结构来理解界面。若界面元素密集、改版频繁、弹窗形式多样,模型的视觉定位能力会直接影响成功率。若任务只需读取结构化数据,例如接口返回的 JSON,视觉能力的权重就可以降低。

4. 容错与复核成本

操作类任务的错误分为两类。一类是失败后可以重试,代价只是时间和少量费用。另一类是有副作用的错误,例如误提交表单、误删除记录、重复发送通知。后一类错误的代价远高于推理费用。对于有副作用的操作,选型时应把“误操作率”作为首要指标,而不是只看平均成本。

三、成本核算的正确方法

1. 单价不等于任务成本

模型服务通常按每百万输入 token 和每百万输出 token 分别计价。单次任务的成本应该按实际消耗计算:

任务成本 = 输入 token 数 × 输入单价 + 输出 token 数 × 输出单价 + 重试带来的额外消耗

智能体任务的输入通常远大于输出。系统提示词、工具描述、历史页面状态和多轮对话都会计入输入。因此,只比较输入单价或只比较输出单价,都可能得出错误结论。

2. 按输入输出比加权

如果业务的输入输出比接近固定值,可以用加权单价做快速比较。设输入与输出的 token 比为 r:1,加权单价为:

加权单价 = (r × 输入单价 + 输出单价) / (r + 1)

当输入输出比为 3:1 时,r 取 3。这个公式适合在初步筛选候选模型时使用,最终决策仍应以实际日志中的 token 统计为准。

3. 缓存命中的影响

智能体每一步都会重复携带相同的系统提示词和工具定义。部分服务支持对重复前缀做缓存,缓存命中的输入单价通常明显低于普通输入。计算成本时应把缓存命中率纳入模型,否则会高估重复前缀较多的场景的成本。

4. 端到端时长与单 token 速度

单 token 的生成速度和任务完成时间是两个不同的指标。一个任务通常包含多次模型调用、页面加载、元素等待和工具执行。端到端时长可以拆解为:

端到端时长 = 模型调用次数 × 单次推理延迟 + 工具执行时间 + 页面等待时间 + 重试时间

如果某个模型的单 token 速度更快,但需要更多步骤才能完成任务,它的端到端时长未必更短。评估速度时应直接测量任务完成时间。

5. 核算示例代码

下面的代码只演示计算方法,价格参数为占位值,使用时应替换为实际计费标准和日志统计数据。

  1. from dataclasses import dataclass
  2. @dataclass
  3. class ModelPrice:
  4. input_per_m: float # 每百万输入 token 的单价
  5. output_per_m: float # 每百万输出 token 的单价
  6. cached_per_m: float # 每百万缓存命中输入 token 的单价
  7. def task_cost(price: ModelPrice,
  8. in_tok: int,
  9. out_tok: int,
  10. cached_tok: int = 0,
  11. retries: int = 0) -> float:
  12. """计算单个任务的总成本(含重试)。"""
  13. attempts = 1 + retries
  14. fresh_in = max(in_tok - cached_tok, 0)
  15. per_attempt = (
  16. fresh_in * price.input_per_m
  17. + cached_tok * price.cached_per_m
  18. + out_tok * price.output_per_m
  19. ) / 1_000_000
  20. return per_attempt * attempts
  21. def blended_price(price: ModelPrice, ratio: float = 3.0) -> float:
  22. """按输入输出比加权的单价,用于快速筛选。"""
  23. return (ratio * price.input_per_m + price.output_per_m) / (ratio + 1)
  24. def monthly_cost(price: ModelPrice,
  25. avg_in: int,
  26. avg_out: int,
  27. tasks_per_day: int,
  28. cache_hit_rate: float = 0.0,
  29. retry_rate: float = 0.0,
  30. days: int = 30) -> float:
  31. """按日志统计估算月度总成本。"""
  32. cached = int(avg_in * cache_hit_rate)
  33. per_task = task_cost(price, avg_in, avg_out,
  34. cached_tok=cached,
  35. retries=0)
  36. return per_task * (1 + retry_rate) * tasks_per_day * days

四、能力评估:不要只看综合分数

公开的综合榜单分数是多类任务的加权平均,它反映的是模型的一般能力。具体业务是否需要这种能力,需要通过自有数据验证。综合分数相近的两个模型,在界面操作类任务上可能表现差异很大。

1. 构建自有评测集

评测集应从真实业务日志中抽取,覆盖以下几类情况:

  • 正常路径:界面结构与训练时常见的情况一致。
  • 异常分支:弹窗、验证码、加载失败、按钮位置变化。
  • 长页面:需要滚动或翻页才能找到目标信息。
  • 界面改版:同一功能的页面结构发生变化。
  • 歧义指令:用户描述模糊,需要模型做合理推断或主动询问。

样本数量应足以覆盖主要异常类型。每类任务若只有几条样本,结论的可信度很低。

2. 指标体系

建议至少记录以下指标:

指标 含义 关注点
任务成功率 最终结果符合预期的比例 质量底线
误操作率 产生有副作用错误的比例 有副作用场景的首要指标
平均步数 完成任务的平均操作次数 影响成本与时长
人工介入率 需要人工接管的比例 隐性成本
单任务成本 含重试的实际费用 预算约束
端到端时长 从下达指令到完成的时间 用户体验与吞吐

3. 成本与质量的权衡曲线

很多模型支持调节推理强度,即在更多思考与更快响应之间选择。把不同档位的成功率和单任务成本画成散点图,可以找到曲线的拐点。拐点之前,提高档位能明显提升成功率;拐点之后,额外成本带来的收益很小。多数业务的最优点位于中低档位,而不是最高档位。

五、分层路由设计

1. 三种常见策略

规则路由:根据任务类型、涉及页面或指令关键词直接分配模型。实现简单,行为可预测,适合任务类型清晰的场景。

分类器路由:用轻量模型或规则对任务复杂度打分,再决定分配给哪一档模型。适合任务类型多样、难以手工枚举的场景。分类器本身也有成本,需要在评测中一并计算。

升级策略:先用低成本模型执行,验证结果是否合格,不合格时再交给强模型处理。这种策略能把大部分简单任务留在低成本档位,但前提是验证环节足够可靠。

2. 升级策略示例

  1. from typing import Callable, Tuple, Any
  2. def run_with_escalation(
  3. task: dict,
  4. light_model: Callable[[dict], Any],
  5. strong_model: Callable[[dict, Any], Any],
  6. verify: Callable[[Any], bool],
  7. ) -> Tuple[Any, str]:
  8. """先用轻量模型执行,验证失败后升级到强模型。"""
  9. result = light_model(task)
  10. if verify(result):
  11. return result, "light"
  12. # 将轻量模型的执行轨迹作为提示,帮助强模型定位问题
  13. result = strong_model(task, getattr(result, "trace", None))
  14. return result, "strong"

3. 升级策略的注意点

升级策略的收益取决于验证函数的质量。若验证只检查模型是否返回了“完成”,而没有核对页面的真实状态,错误结果会被误判为成功。验证应基于可观测的结果,例如页面上出现的确认文本、数据库中的记录变化或接口返回的状态码。

验证本身也有成本。若验证需要再次调用模型,它的费用应计入总成本。对于有副作用的操作,验证应在动作执行之前完成,或在执行之后立即回滚。

升级比例是需要监控的关键指标。若升级比例持续升高,说明轻量模型已不适合当前任务分布,应重新评估分层规则。

六、操作类任务的工程要点

模型选型只是系统设计的一部分。以下工程措施与模型档位无关,但直接影响操作的安全性。

1. 高风险动作需要确认

提交订单、删除数据、发送外部通知、修改权限等动作,应在执行前经过明确确认。确认可以是人工审批,也可以是基于规则的二次校验,例如金额超过阈值时强制人工复核。

2. 每步操作后校验状态

点击之后,应检查页面是否进入预期状态,而不是假设操作已成功。可以比较操作前后的截图差异,或读取页面中的关键文本与元素属性。状态不符时应停止执行,而不是继续下一步。

3. 限制动作空间

智能体可执行的操作应有明确边界。常见做法包括:限定可访问的域名列表,对只读任务启用只读模式,禁止在未授权页面输入凭证。动作空间越小,误操作的可能性越低。

4. 操作幂等

同一个指令重复执行时,结果应保持一致。例如“创建工单”的操作应先检查是否已存在相同工单,避免因网络超时重试而产生重复记录。

5. 日志与隐私

操作过程中的截图和页面内容可能包含个人信息或业务数据。日志应加密存储,设定保留期限,并对敏感字段做脱敏处理。访问日志的权限也应遵循最小授权原则。

七、落地步骤

  1. 梳理任务清单:列出所有操作类任务,并为每类任务标注复杂度、频率、视觉需求和容错要求。
  2. 构建评测集:从日志中抽取样本,覆盖正常路径和异常分支,标注期望结果。
  3. 批量评测候选模型:在同一评测集上运行各候选模型,记录成功率、误操作率、步数、单任务成本和端到端时长。
  4. 设定路由规则:根据评测结果确定每类任务的模型档位,或设定升级阈值。
  5. 灰度上线:先让一小部分流量走新路由,对比旧方案的成功率与成本。
  6. 持续监控与复测:关注成功率、成本、升级比例的变化。界面改版、模型版本更新或业务规则调整后,应重新运行评测。

八、常见误区

**误

发表评论

活动