芥末
发布于 2026-02-01 / 0 阅读
0
0

Clawdbot 高 Token 消耗的架构原因与降本方案

Clawdbot 后来更名为 OpenClaw,是一个面向自动化任务的开源 AI Agent。它能调用浏览器、Shell、文件系统、记忆检索、接口请求等工具,把一个自然语言任务拆成多个步骤执行。

这种能力的代价也很明显:Token 消耗很容易失控。简单问候可能就要一万多 Token;一旦进入多轮工具调用、错误重试和反思修正,单个任务突破几十万 Token 并不罕见。极端情况下,一周消耗上亿 Token 也不是架构上不可能发生的事。

问题不只是“模型贵”,而是 Agent 的执行方式决定了它会反复携带大量上下文。理解这一点,才能知道钱花在了哪里,也才能知道哪些优化真的有用。

Token 成本为什么会突然变大

Clawdbot/OpenClaw 的成本主要来自四类开销:

flowchart TD
    A[一次用户任务] --> B[系统提示词固定开销]
    A --> C[ReAct 多轮推理循环]
    A --> D[工具执行结果回灌]
    A --> E[错误后的反射重试]

    B --> B1[身份定义]
    B --> B2[工具 JSON Schema]
    B --> B3[Skills 和引导文件]
    B --> B4[运行时元数据]

    C --> C1[每一轮都携带历史上下文]
    D --> D1[网页 HTML]
    D --> D2[文件内容]
    D --> D3[命令输出]
    D --> D4[API JSON 响应]

    E --> E1[失败分析]
    E --> E2[重新规划]
    E --> E3[再次调用工具]

这些开销叠加在一起后,会形成一种近似二次方增长的成本曲线。任务轮次越多,每一轮携带的历史越长,下一轮请求就越贵。

一个大致的消耗量级如下:

场景Token 消耗量级费用量级特点
基础对话初始化约 14,5000.04 - 0.05主要花在系统提示词和工具定义
简单查询,无缓存约 15,000约 $0.055用户输入很短,固定开销占主导
多轮工具调用任务100,000 - 500,0000.30 - 1.50每轮都带历史和工具结果
复杂工作流,含反射循环1,000,000+3 - 10错误重试会快速放大上下文
失控任务10,000,000+数百美元缺少预算上限时容易发生

费用会随模型、输入输出比例、缓存命中率而变化,但增长机制是一样的:固定提示词很大,历史上下文不断累积,工具结果又经常很长。

固定系统提示词:一次问候也要背上完整装备

AI Agent 和普通聊天机器人最大的区别,是它通常不只回答问题,还要决定是否调用工具、调用哪个工具、工具参数怎么填、失败后怎么恢复。为了让模型知道这些能力,系统提示词里需要塞入大量说明。

Clawdbot/OpenClaw 的一次请求通常会包含类似结构:

System Prompt
├── 核心身份与行为规范
│   └── 说明 Agent 的角色、能力边界、回复风格
├── 工具定义列表
│   ├── bash
│   ├── browser
│   ├── file_system
│   ├── memory_search
│   └── 其他工具
├── Skills 元数据
│   └── 可用技能、触发条件、描述信息
├── 引导文件
│   ├── AGENTS.md
│   ├── SOUL.md
│   ├── TOOLS.md
│   └── USER.md
├── 运行时元数据
│   ├── 当前时间
│   ├── 时区
│   ├── 主机信息
│   └── 模型配置
└── 回复格式与安全约束

其中最重的一部分通常是工具定义。Clawdbot/OpenClaw 使用 MCP(Model Context Protocol,模型上下文协议)描述工具。每个工具都要告诉模型:工具叫什么、能做什么、参数有哪些、每个参数是什么类型、哪些字段必填。

一个简化后的 bash 工具定义类似这样:

{
  "name": "bash",
  "description": "Execute shell commands in a controlled environment.",
  "input_schema": {
    "type": "object",
    "properties": {
      "command": {
        "type": "string",
        "description": "The shell command to execute."
      },
      "timeout": {
        "type": "integer",
        "description": "Maximum execution time in seconds."
      }
    },
    "required": ["command"]
  }
}

单个工具定义看起来不长,但 20 多个工具一起放进系统提示词后,很容易达到数千 Token。再加上身份说明、技能元数据、引导文件和格式约束,基础系统提示词可能接近 14,000 Token。

这意味着用户只输入“你好”,请求里也可能要带上完整工具手册。用户输入越短,固定开销占比越夸张。

ReAct 循环:每一轮都要重新携带历史

Clawdbot/OpenClaw 这类 Agent 常用 ReAct(Reasoning and Acting,推理与行动)模式。模型不是一次性给答案,而是反复执行:

  1. 思考当前任务应该怎么做;
  2. 选择一个工具;
  3. 调用工具;
  4. 观察工具结果;
  5. 基于结果继续推理或结束任务。

调用过程可以表示成这样:

sequenceDiagram
    participant U as 用户
    participant A as Agent/LLM
    participant T as 工具系统

    U->>A: 提交任务
    A->>A: 读取系统提示词与历史上下文
    A->>T: 调用工具 Action
    T-->>A: 返回 Observation
    A->>A: 基于结果继续推理
    A->>T: 再次调用工具
    T-->>A: 返回新的 Observation
    A-->>U: 输出结果

关键点在于:当前主流 LLM(Large Language Model,大语言模型)API 通常要求每次请求都发送完整上下文。第二轮请求不是只发送“上一轮工具结果”,而是要把系统提示词、用户任务、前面的推理、前面的工具结果一起带上。

假设:

  • S:系统提示词大小;
  • U:用户任务大小;
  • A:每轮模型输出大小;
  • R:每轮工具返回结果大小;
  • N:任务执行轮数。

k 轮输入大约是:

S + U + (k - 1) × (A + R)

整个任务的总消耗大约是:

总输入 ≈ N × (S + U) + (A + R) × N × (N - 1) / 2
总输出 ≈ N × A

总 Token ≈ N × (S + U) + (A + R) × N × (N - 1) / 2 + N × A

这个公式说明了一个重要事实:轮数增加时,成本不是简单线性增长。只要每轮都保留完整历史,累积输入就会出现二次方级别的增长。

举个简化例子:

S = 14,000   # 系统提示词
U = 50       # 用户任务
A = 400      # 每轮模型输出
R = 2,500    # 每轮工具结果
N = 10       # 10 轮推理/工具调用

总输入 ≈ 10 × 14,050 + 2,900 × 45
       ≈ 140,500 + 130,500
       ≈ 271,000

总输出 ≈ 4,000

这还只是中等大小的工具结果。如果工具返回网页 HTML、日志文件或大段 JSON,R 会明显变大,成本也会继续放大。

工具结果回灌:真正容易被忽略的 Token 黑洞

很多 Agent 任务贵,不是因为模型“想得太多”,而是因为工具返回得太多。

常见工具输出规模如下:

工具类型典型返回内容Token 量级
浏览器抓取页面正文、DOM、HTML、链接、脚本片段5,000 - 20,000
文件读取代码文件、配置文件、日志文件1,000 - 10,000
数据库查询多行结果集、字段名、嵌套结构2,000 - 15,000
Shell 命令stdout、stderr、堆栈信息500 - 5,000
API 调用JSON 响应、分页数据、错误详情1,000 - 8,000
搜索工具多条结果标题、摘要、URL2,000 - 10,000

浏览器工具尤其容易制造大上下文。用户可能只需要网页中的一句航班价格信息,但工具返回的是整个页面结构。模型下一轮请求又会携带这段页面内容,后续每一轮都继续背着它走。

一个典型任务流程可能是:

flowchart LR
    A[用户: 帮我比较航班] --> B[浏览器搜索]
    B --> C[返回搜索页 HTML]
    C --> D[模型分析]
    D --> E[打开航司页面]
    E --> F[返回页面 HTML/表单信息]
    F --> G[模型继续分析]
    G --> H[调用价格比较或代码工具]
    H --> I[返回结果]
    I --> J[生成答案或继续操作]

如果每一步都把完整结果放进上下文,Token 增长速度会非常快。

更合理的做法是让工具返回“模型真正需要的内容”,而不是原始结果全集。例如:

{
  "results": [
    {
      "airline": "Example Air",
      "price": 320,
      "departure": "09:30",
      "arrival": "12:40",
      "url": "https://example.com/flight/123"
    }
  ],
  "omitted": {
    "raw_html": true,
    "reason": "HTML content is too large and not needed for comparison."
  }
}

Agent 框架如果默认把原始结果完整回灌,成本会非常难控。工具层做字段筛选、截断、摘要和分页,是控制 Token 的关键手段。

反射循环:错误会把成本继续放大

Agent 执行任务时不可避免会遇到错误,例如网页元素定位失败、命令执行失败、接口返回异常、文件路径不存在。Clawdbot/OpenClaw 这类系统通常会通过反射循环恢复,也就是让模型分析失败原因,然后重新规划下一步。

普通路径是:

Plan → Act → Observe → Done

出错路径会变成:

Plan → Act → Error → Reflect → Retry → Error → Reflect → Retry → ...

反射本身要消耗 Token,因为模型需要读取错误信息、分析原因、提出修复方案。更麻烦的是,每一次错误和反思都会进入历史上下文,导致下一次请求更长。

AgentBench 一类评测中的数据能体现这个趋势:

反射轮数平均 Token/任务相对无反射
0 轮约 12,8001x
3 轮约 45,000约 3.5x
5 轮约 136,000约 10.6x
7 轮约 172,000约 13.4x

反射不是坏机制。没有它,Agent 很多复杂任务根本无法完成。问题在于反射不能无限重试,否则会出现“越失败,上下文越大;上下文越大,模型越难抓住重点;模型越容易继续失败”的循环。

合理的 Agent 应该给反射设置预算,例如:

限制项建议
单个工具最大重试次数2 - 3 次
单个任务最大反射次数3 - 5 次
单次工具结果最大 Token按工具类型设置上限
单个任务最大 Token达到阈值后暂停并询问用户
错误摘要策略保留关键错误,丢弃重复堆栈

为什么这些成本很难完全避免

Clawdbot/OpenClaw 的高 Token 消耗并不是某一个 bug 造成的,而是 Agentic 系统的常见代价。

API 上下文通常是“全量发送”

很多 LLM API 的请求模型是无状态的。服务端不会默认记住上一轮完整上下文,客户端必须在每次请求里重新提交历史消息。

这带来几个结果:

情况成本影响
只追问一句话仍然要携带前面的对话历史
只改一个工具参数仍然要携带系统提示词和工具定义
只需要工具结果的一小段如果没有裁剪,完整结果会进入上下文
多轮任务持续执行每一轮请求都会越来越大

Prompt Caching 可以降低重复前缀的计费,但它不等于“上下文不存在”。缓存内容通常仍然占用上下文窗口,也需要满足缓存命中条件。

Agent 为“能力最大化”设计时,成本会自然升高

很多通用 Agent 默认追求“什么都能做”,于是会启用大量工具、加载完整技能库、保留详细历史、使用能力最强的模型。

这种设计适合探索性任务,但不适合成本敏感场景。

设计选择好处成本问题
默认加载 20+ 工具模型随时能调用多种能力工具 Schema 进入系统提示词
保留完整历史模型不容易丢上下文每轮输入持续变大
工具返回完整结果信息不丢失大量无关内容进入上下文
默认强模型复杂推理更稳单价更高
自动反射重试失败后可恢复错误会不断堆积

缺少硬预算时,任务容易跑飞

如果系统没有任务级预算,Agent 可能一直尝试“再试一次”。从用户体验看,它是在努力完成任务;从账单看,它是在持续消耗 Token。

预算控制至少应该覆盖三层:

flowchart TD
    A[成本控制] --> B[请求级预算]
    A --> C[任务级预算]
    A --> D[会话级预算]

    B --> B1[单次输入 Token 上限]
    B --> B2[单次输出 Token 上限]

    C --> C1[最大工具调用次数]
    C --> C2[最大反射次数]
    C --> C3[最大总 Token]

    D --> D1[用户每日额度]
    D --> D2[项目级费用上限]

没有这些限制,复杂网页任务、自动化表单任务、长日志分析任务都可能产生远高于预期的账单。

降低 Token 成本的几种有效办法

控制 Clawdbot/OpenClaw 的成本,不应该只靠“少用”。更实际的做法是减少重复上下文、减少无关工具、减少不必要的 ReAct 决策,并给任务设置边界。

启用 Prompt Caching,降低固定提示词成本

Prompt Caching 适合缓存稳定、重复出现的系统提示词和工具定义。对于 Clawdbot/OpenClaw 这种固定提示词很大的 Agent,缓存命中后可以显著降低重复前缀的费用。

示例配置:

agents:
  defaults:
    model:
      params:
        cacheControlTtl: "1h"
    heartbeat:
      every: "55m"

缓存的典型效果:

请求类型成本特点
首次请求需要写入缓存,可能比普通输入略贵
后续命中缓存前缀按更低价格计费
长会话固定系统提示词重复出现,节省更明显
提示词频繁变化容易缓存失效,收益下降

使用缓存时要注意几个细节:

  • 系统提示词前缀要稳定,工具顺序和内容频繁变化会导致缓存命中率下降;
  • 缓存降低费用,不一定减少上下文窗口占用;
  • 如果每次都动态注入大量不同文件,缓存收益会被稀释;
  • 缓存 TTL 到期后需要重新写入。

用确定性工作流替代部分 ReAct 循环

有些任务不需要模型每一步都重新思考。例如固定的航班查询、价格比较、报表生成、接口同步,本质上是确定流程,只是输入参数不同。

这类任务可以用 Lobster 工作流引擎或类似机制,把多轮 LLM 决策改成预定义工具链:

workflow:
  name: flight_booking
  steps:
    - tool: browser.search
      input: "flights NYC to LAX {{date}}"

    - tool: code.compare_prices
      input: "{{previous_result}}"

    - tool: api.book
      input: "{{best_option}}"

ReAct 和确定性工作流的差异:

方式决策者适合场景成本特点
ReAct 循环LLM 每轮决定下一步开放任务、路径不确定、需要复杂判断成本随轮数快速增长
确定性工作流配置好的流程决定下一步流程稳定、步骤明确、输入结构化工具链成本更可控
混合模式关键节点由 LLM 判断部分步骤固定,部分步骤需要推理成本和灵活性折中

工作流不是为了替代所有 Agent 能力,而是把“本来就确定”的步骤从 LLM 编排里拿出来。只在真正需要判断的地方调用模型,Token 消耗会明显下降。

做上下文压缩,把历史变成摘要

长会话和多轮任务不能无限保留原始历史。上下文压缩的思路是:把已经完成的中间过程总结成关键状态,只保留后续任务还需要的信息。

示例配置:

agents:
  defaults:
    memory:
      autoCompaction:
        enabled: true
        tokenThreshold: 50000
        interval: 1800

也可以手动触发:

/compact

压缩前的上下文可能是:

用户任务
系统提示词
第 1 轮推理
第 1 次工具返回的完整 HTML
第 2 轮推理
第 2 次工具返回的完整 JSON
第 3 轮错误堆栈
第 4 轮反射分析
...

压缩后应该变成:

任务目标:比较指定日期从 NYC 到 LAX 的航班。
已知条件:
- 用户偏好:价格优先,直飞优先。
- 已排除:ExampleAir 09:30 航班,价格过高。
- 当前候选:DemoAir 12:10,$320;SampleAir 15:00,$350。
- 待完成:确认行李政策和退改签规则。

压缩会丢弃细节,所以不能把所有历史都粗暴摘要掉。适合保留的信息包括:

信息类型是否保留
用户明确约束保留
当前任务目标保留
已经做出的关键选择保留
工具返回的原始大文本通常摘要
重复错误堆栈只保留关键错误
临时推理草稿大多可丢弃

精简工具集,减少系统提示词体积

如果一次任务只需要文件读取和 Shell,就没有必要把浏览器、数据库、邮件、日历、API 调用等工具全部暴露给模型。

示例配置:

agents:
  defaults:
    tools:
      enabled:
        - bash
        - file_read
        - memory_search
      disabled:
        - browser
        - api_call

工具裁剪的收益很直接:工具越少,系统提示词里的 JSON Schema 越少,模型选择工具时的干扰也越少。

常见工具配置策略:

场景推荐工具
代码仓库分析file_readgrepbash
网页信息检索browser.searchbrowser.extract
数据处理file_readpythonbash
知识库问答memory_searchfile_read
自动化业务流程业务 API 工具、少量浏览器工具

更进一步的做法是延迟加载工具:默认只给模型核心工具,等模型判断需要某类能力时,再加载对应工具包。这样可以避免每次请求都带上完整工具宇宙。

对工具返回结果做裁剪

工具返回结果应该服务于下一步决策,而不是把原始数据完整塞给模型。不同工具可以设置不同的返回策略。

工具推荐处理
浏览器提取正文、标题、表格、关键链接,避免返回完整 HTML
文件读取支持按行号读取、按函数读取、按关键词截取
Shell限制输出行数,长输出写入文件并返回摘要
数据库限制行数,返回 schema 和样例,避免一次吐出大结果集
API过滤字段,只返回业务相关字段
搜索控制结果数量,返回标题、摘要、URL 即可

例如 Shell 工具可以做输出限制:

tools:
  bash:
    maxOutputTokens: 2000
    truncateStrategy: tail

日志分析时通常更需要尾部错误信息,而不是完整日志。让工具层按场景裁剪,比让模型在几万 Token 的原始输出里自己找重点更省钱,也更稳定。

使用模型路由,不要所有任务都上强模型

不同任务对模型能力要求不同。简单查询、格式转换、工具参数生成,不一定需要最贵模型;复杂规划、长上下文推理、关键决策,才更适合强模型。

示例配置:

agents:
  defaults:
    model:
      routing:
        simple_queries: "claude-sonnet-4"
        tool_execution: "claude-sonnet-4"
        complex_reasoning: "claude-opus-4-5"

模型路由可以按任务类型划分:

任务类型推荐模型策略
简单问答便宜模型
工具参数生成中等模型
代码解释中等或强模型,视代码复杂度而定
长链路规划强模型
失败反射中等模型起步,多次失败再升级
最终用户回复润色便宜模型或中等模型

如果强模型和中等模型之间有 5 倍价差,正确路由就能明显降低账单。更稳妥的策略是“默认便宜,必要时升级”,而不是所有请求都走最高规格。

一套更稳的成本控制组合

单个优化手段有用,但组合起来效果更明显。一个成本敏感的 Clawdbot/OpenClaw 配置可以遵循这样的思路:

flowchart TD
    A[用户任务进入] --> B{任务是否有固定流程}
    B -- 是 --> C[走工作流引擎]
    B -- 否 --> D[走 ReAct Agent]

    C --> E[只在关键节点调用 LLM]
    D --> F[加载最小工具集]

    F --> G[工具返回结果裁剪]
    G --> H{上下文是否超过阈值}
    H -- 是 --> I[压缩历史上下文]
    H -- 否 --> J[继续执行]

    I --> J
    J --> K{是否超过任务预算}
    K -- 是 --> L[暂停并请求用户确认]
    K -- 否 --> M[输出结果]

推荐的组合策略:

优化项解决的问题预期收益
Prompt Caching系统提示词重复计费固定前缀成本大幅下降
工具裁剪工具 Schema 过大系统提示词变短
工具结果裁剪HTML、日志、JSON 过长历史上下文膨胀变慢
上下文压缩多轮历史越来越长长任务更可控
工作流引擎固定流程被 LLM 反复决策避免不必要的 ReAct 循环
模型路由简单任务使用昂贵模型降低平均单价
任务预算反射和重试失控防止账单意外扩大

使用 Clawdbot/OpenClaw 时的实践检查清单

上线或长时间运行前,至少检查这些配置:

  • 系统提示词是否启用了缓存;
  • 默认工具数量是否控制在任务真正需要的范围内;
  • 浏览器、文件、Shell、API 工具是否有输出上限;
  • 是否设置了自动上下文压缩阈值;
  • 是否限制了单任务最大工具调用次数;
  • 是否限制了反射重试次数;
  • 是否按任务复杂度做模型路由;
  • 是否给用户、会话、任务设置了 Token 或费用预算;
  • 是否在预算耗尽前暂停,而不是继续自动重试。

Clawdbot/OpenClaw 的高 Token 消耗,本质上是通用 Agent 架构的成本体现:它把工具说明、历史上下文、工具结果和错误恢复都交给大模型处理。能力越通用,默认携带的信息越多;执行链路越长,重复发送的上下文越大。

真正的降本方向不是简单限制模型回答长度,而是减少不必要的上下文进入模型:稳定内容走缓存,固定流程走工作流,大工具集按需加载,长工具结果先裁剪,多轮历史及时压缩,错误重试必须有预算。这样才能在保留 Agent 自动化能力的同时,把 Token 消耗控制在可预期范围内。


评论