三个月前我往 API 账户里充了一笔预算,本想着能撑过整个迭代周期,结果一个下午的重构任务就把余额烧掉一大截。那种看着 Token 消耗曲线往上飙又不知道砍哪儿的感觉,用 OpenClaw 的朋友应该都懂。
后来我把 OpenClaw 从模型配置到工具调用策略整体捋了一遍,没换更便宜的底层模型,也没降低任务复杂度,单纯靠配置调整就让同样强度的活省了差不多一半 Token。这篇文章把我实际验证过的配置和思路写出来,给正在被 Token 账单追着跑的朋友一个参考。内容不涉及玄学,全部是可复现的配置项和操作路径。
1. 摸清“隐形账单”到底在哪产生
1.1 上下文是重复计费的重灾区
很多人以为 Agent 烧 Token 是因为模型“想得太多”,实际上大头在上下文的重发。OpenClaw 这类 Agent 框架每执行一步工具调用,都要把系统提示、工具定义、历史消息、最新结果重新发给模型算一遍。只要会话没有压缩,历史内容就一遍又一遍地重复计费。
举个具体例子。假设某个任务触发 30 次工具调用,系统提示加工具定义约 4000 Token,平均每轮新增 1000 Token。那么第 30 轮请求的输入长度大约在 4000 + 29×1000 = 33000 Token。这轮请求本身不夸张,但问题在于前 29 轮也在发生类似请求,整个会话累计发送的输入 Token 大约为 30×4000 + (0+1+2+...+29)×1000 = 555000 Token。而模型真正输出的 Token 可能只有不到 3 万。输入侧和输出侧的差距就是隐形账单的来源。
所以省钱逻辑的第一步不是压输出,而是让输入侧的重复计算降下来。
1.2 工具回传和失败重试是第二桶金
OpenClaw 执行 shell 命令后会把 stdout、stderr、退出码全部拿回来。如果命令输出的是几百行编译日志或超长目录树,这些内容会被原封不动塞进上下文,成为后续所有轮次都要携带的“历史包袱”。我见过最长的一次,光一个 find 命令的输出就贡献了 1.8 万 Token,而且后面每轮请求都会重新算一次这些内容。
失败重试同样隐蔽。工具调用如果报错,Agent 会尝试换一种方式重新执行,有时连续四五次都在同一个问题上打转。每一次尝试都是完整的新请求,每次请求都会把已膨胀的上下文再送一遍。配置部分我会重点讲怎么限制工具回传体积、怎么减少无意义的失败循环。
为了更直观地理解成本构成,我把常见消耗点整理成了表格:
| 消耗场景 | 是否可优化 | 优化空间 | 说明 |
|---|---|---|---|
| 历史消息重复发送 | 可优化 | 大 | 开启缓存、及时压缩或分段会话 |
| 系统提示和工具定义 | 可优化 | 中 | 精简 skill 和 MCP 数量 |
| 工具命令输出回传 | 可优化 | 大 | 设置截断阈值或忽略噪声目录 |
| 失败重试导致的额外请求 | 可优化 | 中 | 控制重试次数,收敛任务边界 |
| 模型长文本思考/推理 | 可优化 | 中 | 根据任务难度调整思考预算 |
| 最终长输出 | 较少优化 | 小 | 设置合理的 max_tokens |
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 第一刀:模型与请求级配置
2.1 给不同类型的任务挂不同的模型
在 OpenClaw 的配置里,模型不一定是全局固定的。很多版本支持配置多个模型档位,不同的任务类型走不同的模型。这个能力看着不起眼,实际却能省下非常可观的开销。
我的策略是:琐碎操作、文件读取、日志定位这类“跑腿型”任务,走便宜模型或响应更快的模型;只有方案设计、多文件重构、复杂 bug 分析这类“动脑型”任务,才让顶级模型上。
举个例子。我让 OpenClaw 批量重命名几十个文件并同步修改引用,这种任务根本不需要动用复杂推理,用便宜模型就能完成。要是全局绑定最强模型,相当于开着跑车去取快递,油钱全花在跑腿上了。
2.2 max_tokens、temperature、思考预算
三个参数值得单独说。
max_tokens 决定模型单次输出上限。我见过不少人在配置里把 max_tokens 设得特别高,结果 Agent 在简单任务上也会啰嗦地输出一长串解释。对我来说,命令行交互场景下普通操作设 1024 或 2048 足够,只有大段代码生成或长文档撰写才需要 4096 以上。把上限压到任务实际需要的区间,能阻止模型“自我发挥”。
temperature 影响随机性。不少 Agent 框架默认在 0.7 或 1.0,但对代码生成和确定性任务来说这个值偏高,模型容易反复尝试不同写法。调到 0.2 左右,输出更稳定,重试次数也会下降。重试少了,Token 自然省。
还有一类消耗容易被忽略:具备思维链能力的模型在每次工具调用前都可能产生大量内部思考 Token。部分服务商把这段思考也计入费用。OpenClaw 配置里如果有 thinking 或 reasoning_effort 参数,日常任务直接设 low 或关掉,只在真正需要复杂推理的任务里调高。
2.3 一份可以直接抄的 settings 片段
下面这段配置是我当前在用的核心模型参数,基本可以照抄后按自己的服务商微调:
json复制{
"model": {
"default": "fast-model-id",
"profiles": {
"fast": {
"provider": "provider-name",
"model": "fast-model-id",
"max_tokens": 2048,
"temperature": 0.2,
"thinking": "disabled"
},
"deep": {
"provider": "provider-name",
"model": "strong-model-id",
"max_tokens": 8192,
"temperature": 0.2,
"thinking": "enabled"
}
}
},
"request": {
"timeout_seconds": 120,
"max_retries": 2
},
"output": {
"default_response_tokens": 1024
}
}
这里的 model 字段填的是服务商接口里能识别的精确模型 ID,不是产品展示名。填错了会出现类似 “unknown model” 的报错,后面的排查章节会专门讲。
max_retries 设成 2 就够了。我之前用默认的重试次数,服务端偶发超时后 Agent 会反复提交同一请求,Token 白白消耗。限制重试次数后,偶发失败宁愿让整个任务中断重来,也比在同一个请求上多次重试省钱。
3. 第二刀:上下文和会话压缩策略
3.1 开启缓存,不是玄学是实打实的便宜
很多大模型服务商支持提示词缓存机制,相同的前缀内容在有效期内再次发送,输入侧价格能降到很低。这个机制对 Agent 场景特别友好,因为 OpenClaw 的每次请求都会带着同样的系统提示和已固定的历史内容。
我在 OpenClaw 里做的第一件事就是把缓存开关打开。配置类似这样:
json复制{
"context": {
"cache_control": true,
"cache_min_tokens": 4096,
"compact_threshold": 60000,
"max_context_tokens": 90000
}
}
cache_min_tokens 是触发缓存的最低长度。如果一段前缀低于几千 Token,缓存的意义不大,可能直接按普通输入计费。调高一点能避免频繁切换缓存位点。
想验证缓存是否生效,可以跑一个长会话任务,观察服务商侧返回的 usage 明细里有没有缓存命中的 Token 数量。只有看到 cache read / cache hit 数据明显增加,才说明配置真的起作用了。
这里有个容易踩的坑:缓存命中有时效性,热门服务商一般在 5 分钟到 1 小时之间。如果两个工具调用之间间隔太久,缓存会过期,下轮请求又按全价计算。所以长任务尽量一口气跑完,中间不要停太久。
3.2 别等整场会话挤爆窗口再压缩
OpenClaw 默认会在上下文接近模型窗口上限时自动压缩历史。但自动触发的那一下往往已经太晚了,因为膨胀的中段内容已经按全价发了许多轮。
我建议把 compact_threshold 设在模型窗口的 40% 到 60% 之间。假设模型上下文窗口是 200K Token,阈值可以设在 80K 到 120K。当 OpenClaw 发现已用 Token 超过阈值,会触发摘要压缩,把早期对话浓缩成一小段摘要,后续请求不再携带完整历史。
这个值需要根据任务平衡。阈值调太低,Agent 容易丢失早期细节,遇到复杂任务会反复重新理解问题;调太高,省 Token 效果不明显。我自己的习惯是:复杂代码任务阈值设窗口的 60%,批量处理和简单问答设 40%。
3.3 用“会话分段”替代“一个会话干到底”
这个习惯帮我省下的 Token 可能比压缩阈值还多。
以前我喜欢一个会话从早干到晚,中途切换多个任务。后来发现,OpenClaw 为了让模型理解当前状态,会把之前的任务讨论也保留在上下文里,哪怕它们已经完全不相关。一次会话累积了七八个子任务后,上下文里一大半是陈年旧事,每次请求都在为这些旧事付费。
现在我的做法是强行分段:一个任务开一个新会话,完成一个阶段就结束当前会话。比如需要改一个前端页面和调整一份后端接口,我会拆成两个独立会话。它们之间如果有依赖,用文档或明文描述传递即可,没必要让模型记住所有中间细节。
会话越短,历史上重复发送的代价越低,也越不容易触发模型因为上下文相互干扰导致的错误重试。
4. 第三刀:工具层瘦身和文件访问收敛
4.1 让 ignore 规则挡住不该读的文件
OpenClaw 在任务过程中会扫描工作区、读取相关文件。如果你的项目目录里有 node_modules、dist、.git、.next、target 这类目录,Agent 很容易在探索阶段读入大量无用内容。
我最初没配 ignore 规则时,一次扫描就能让上下文多出几万 Token,还都是对任务毫无帮助的依赖包和构建产物。后来我给项目加了类似下面内容的 ignore 文件:
gitignore复制node_modules/
dist/
build/
.target/
.angular/
*.log
.cache/
coverage/
.git/
OpenClaw 不少版本会自动读取工作区的 ignore 规则。配置后,扫描文件时直接跳过这些目录。这招的效果立竿见影,尤其是在大仓库里做小改动时,Token 消耗能降一个量级。
4.2 限制工具回传内容,避免日志刷屏
即使 ignore 规则做好了,Agent 主动执行命令时仍可能带回大量输出。像 cat 一个几千行的配置文件,或者执行返回超长列表的命令,工具输出会全部进入上下文。
OpenClaw 工具层通常有输出截断相关的控制项。我在配置里增加了对工具结果的限制:
json复制{
"tools": {
"max_output_tokens": 2000,
"truncate_large_outputs": true
}
}
max_output_tokens 设成 2000 意味着超过这个体积的工具输出会被截断,模型只看到摘要部分,不会读取完整的上万行内容。这个配置对日志排查任务尤其有帮助,Agent 只需要看报错开头和结尾就能定位问题,没必要把整段日志逐字读一遍。
4.3 精简 skills 与 MCP,别让无关能力占据每次请求
OpenClaw 支持通过 skills 和 MCP 扩展能力,这本身很强大,但技能装多了有个隐性成本:模型每次请求都要携带工具定义和技能说明。几十个技能全挂着,光工具定义就可能占几千 Token。而且技能太多之后,模型可能选错工具,来回试好几次才发现走不通,重试成本更高。
我的建议是:只保留当前任务真正会用到的技能。日常代码开发,挂两三个核心技能就够了;做网页自动化那几天,再单独加相关能力,用完就卸载。
MCP 服务同理。每接入一个 MCP 服务器,工具定义都会进入模型上下文。如果某个 MCP 服务暂时用不到,直接停掉比让它待机更省钱。控制在“够用且不冗余”的状态。
4.4 exec-approvals 的自动化边界
OpenClaw 在需要执行敏感命令时会弹出审批请求,批准记录保存在 exec-approvals.json 文件里。
有的朋友为了省事,把所有命令都加入白名单,让 Agent 随便跑。这对稍微危险的操作来说隐患很大,而且不一定省 Token。真正浪费 Token 的往往不是审批流程,而是命令执行失败后的反复尝试。
我采取的原则是:只把高频、低风险、可重复的命令加入自动批准列表,比如 ls、cat、grep 这些读取类命令和明确的格式化命令。涉及删除、覆盖文件、大范围改动目录的命令,仍然走人工审批。这样既不需要每次都停下确认,也不会让 Agent 在错误方向上乱试。
5. 实测:我把三类任务的 Token 消耗拉出来对比
5.1 代码重构类:差点吃空预算的任务
我做过一次老模块的接口重构,涉及项目里 6 个文件的结构调整。优化前,OpenClaw 在一个会话里从头干到尾。任务结束后我查看消耗记录,输入 Token 逼近 120 万,输出 Token 大概十几万。原因是会话中途不断有工具返回的长文件内容进入历史,后面每轮都要带着这些历史重新发送。
优化后用新配置重跑了一遍同样的需求。开了缓存,设置了压缩阈值 60K,加了 ignore 规则让 Agent 不读取无关目录,任务拆成了“分析现状”和“执行修改”两个会话。最终输入 Token 降到 45 万左右,整体消耗大约只有之前的 38%。
5.2 日志排查类:工具输出截断贡献最大
有一次排查线上接口超时问题,OpenClaw 需要反复查看服务日志。优化前跑一次完整排查,日志文件被完整读了好几遍,每次读取的内容都进入上下文,消耗非常大。
调整配置后,我把 max_output_tokens 设成了 1500,并让 Agent 优先用 grep 和 tail 定位关键词,而不是直接读整份文件。同样的排查流程,Token 用量降了接近一半。这个任务里最大的功臣不是模型参数,而是工具输出限制。
5.3 文档批量处理类:换模型最有性价比
批量处理几十个 Markdown 文档,比如统一格式、补充缺失的前置说明,这类任务重复性高、逻辑链短。以前用强模型跑,效果没问题但没什么必要。后来切到便宜模型档位,输出质量几乎没差别,Token 单价下来了,总费用直接砍半。
这个对比说明一件事:配置省钱不能只盯某一个开关,模型选型、上下文管理、工具收敛三个方向都要照顾到。
5.4 配置项汇总表
下面是我整理过的一份速查表,可以直接作为日常配置的参照:
| 优化方向 | 关键配置/操作 | 预期效果 |
|---|---|---|
| 模型选型 | 简单任务切便宜模型档位 | 单价降低 40% 甚至更多 |
| 输出控制 | max_tokens 按需设置 | 避免模型输出废话 |
| 稳定性 | temperature 设为 0.1-0.3 | 减少重试次数 |
| 上下文缓存 | 开启 cache_control | 重复前缀计费降至 10% |
| 自动压缩 | compact_threshold 设在窗口 40%-60% | 避免历史无限膨胀 |
| 会话管理 | 一任务一会话 | 消除无关历史累计 |
| 文件访问 | ignore 依赖和构建目录 | 阻断无用大文件进上下文 |
| 工具输出 | max_output_tokens 2000 左右 | 防止日志刷爆上下文 |
| 技能精简 | 只保留当前任务所需 skills | 降低工具定义占比 |
| 失败控制 | max_retries 设为 2 | 减少无效重试请求 |
6. 我不会忽略的常见报错与处理
6.1 token exchange failed / 403
“sign-in could not be completed token exchange failed”这个报错不少人都遇到过。它发生在登录或 token 刷新阶段,本质是本地持有的凭证没有换到服务端的新凭证。
403 的情况通常是账户或密钥权限不对齐,比如 API Key 没有开通对应模型的使用权限,或者服务商在账户层面有区域白名单策略。处理思路很简单:先检查本地配置里的 API Key 和账户是否匹配,去服务商控制台重新生成一次密钥;再确认账户有没有开通目标模型的权限;如果配置里有自定义的 API 地址,确认地址和端口跟密钥对得上。
这类问题有时候会被本地时间和真实时间差太多触发。JWT 类凭证对时间偏差很敏感,系统时间和服务端差几分钟就可能验证失败。我在排查这类问题时,第一步就是先看系统时钟是否同步到正确时间。
6.2 unknown model 到底是什么意思
报错里出现 “unknown model: deepsee-xxx” 这类信息时,最直接的原因是配置里的 model 字段填错了。OpenClaw 不会帮你做模糊匹配,字段必须和服务商接口模型列表里的精确定 ID 一致。
比如展示名是“DeepSeek Chat”,接口模型 ID 可能完全不是这个写法。建议不要凭记忆填,去服务商模型文档里复制准确的 ID。另外要看清当前 OpenClaw 的模型走的是哪个服务商端点,不同服务商对模型 ID 的命名体系不一样。
如果模型 ID 确认无误仍报错,检查模型是否配置在正确的 provider 下。多 provider 混用时,很容易把 A 服务商的模型填到 B 服务商的配置块里。
6.3 legacy exec approvals 的提示要不要处理
启动时看到类似 “legacy exec approvals exist at /root/.openclaw/exec-approvals.json” 的提示,说明当前版本升级后发现了旧版审批文件。
最好的处理方式是按提示运行迁移命令,让旧版批准记录自动转换到新格式。如果你直接无视,某些旧批准记录可能无法被新版本识别,执行敏感命令时反而会多出额外的审批循环,任务中断次数变多,Token 也在无形中消耗。
如果迁移过程中报错,先备份原文件再删除它,重新生成一份新的审批文件即可。审批文件本身很小,不影响成本,但不要让旧格式导致 Agent 反复卡在执行环节。
6.4 配置改完仍然高消耗?先看这三点
配置看起来都改了,消耗依然很高的话,我一般会做三件事。
第一,确认配置真的被加载了。经常有人改了 settings.json 却忘了重启 OpenClaw,或者改的文件根本不是我正在用的一份。启动后打印当前配置,确认所有关键项已经生效。
第二,看单次请求的 usage 明细。如果每次请求的输入 Token 数依旧很高,说明上下文没有按预期压缩,或者某个工具还在回传大段内容。用 OpenClaw 的会话状态命令查看当前上下文构成,删除占用最多的历史消息节点。
第三,检查是不是任务本身的提示词写得太“开放”。提示词里没有明确交付边界时,Agent 会反复探索无关方案。我通常在任务开始时加一句“只处理 xxx,不扫描和修改其他内容”,这能显著降低无效工具调用次数。
最后分享一个我现在养成的习惯
我接手任何一个新任务前,会先花几分钟想清楚这件事值不值得让 Agent 全程跑长会话。多数任务在动手前已经能判断出大致的 Token 消耗规模。
日常的琐碎批量操作,我会用“快速档位 + 小上下文 + 关闭思考”的方式跑;只有真正需要理解业务逻辑、跨多个文件做判断的任务,才配得上“完整档位 + 大窗口 + 思考能力”的配置。模型不是要省着不用,而是让每一分 Token 都花在它该花的位置上。
另外,建议每次调完配置都记一笔当时的 Token 消耗数据。我第一次做重构优化时凭感觉以为压缩阈值越低越好,后来对比数据才发现 40% 的阈值组合效果最好。没有数据支撑的省钱方案很容易变成另一种浪费。希望这篇配置记录能帮你少走几步弯路,把省下来的预算留给真正有价值的任务。
