乐于分享
好东西不私藏

如何降低 OpenClaw 在使用过程中的 token 消耗

如何降低 OpenClaw 在使用过程中的 token 消耗

最近折腾 OpenClaw,越用越有一个朴素感受:Agent 这东西是真好用,但如果不管住它,token 消耗也是真的有点凶。

我一开始其实没太在意这个问题。刚开始玩 OpenClaw 的时候,注意力都放在那些“看起来很酷”的能力上:能不能调工具?能不能开 sub-agent?能不能长期运行?能不能记住我的偏好?能不能自动检查任务?能不能像一个半自动员工一样,自己往前推事情?

这些当然都很香。但香归香,跑多了之后,另一个问题就慢慢冒出来了:怎么感觉每次调用都不便宜?尤其是连续用一阵以后,就会发现,token 消耗并不是只来自模型回答的那几段话。很多时候,真正贵的是输入,是上下文,是每次它给模型塞进去的那一大包东西。系统提示词要带着,历史消息要带着,工具说明要带着,技能列表要带着,memory 要带着,文件片段要带着,工具结果要带着,有时候 heartbeat 和 sub-agent 还会再来一波。层层叠叠。说白了,有时候你只是想让它帮你看个小问题,它却像是背着一整套工具箱、资料库、会议纪要和工作日志上场。这当然就贵了。

所以,OpenClaw 降 token,我觉得核心不是一句“让模型简洁回答”就能解决的。那太表面了。真正要降,得从使用习惯、上下文结构、memory、工具、heartbeat、sub-agent 这些地方一起下手。

我下面就按我自己的理解,聊聊怎么把 OpenClaw 用得轻一点。

先说第一个,也是最容易忽略的:不要什么都塞进长期记忆。我以前做 Agent 的时候,也很容易犯这个毛病。总觉得记忆越多越好。用户说过什么、工具返回了什么、中间推理过程、临时判断、今天查到的资料啥的都会记下来。刚开始看起来很爽,像是这个 Agent 很勤快,什么都没忘。但时间一长,就开始不对劲了。memory 越来越大,里面什么都有。真正有用的长期信息反而被淹没在一堆临时材料里。等模型需要用的时候,它不是在“调用记忆”,更像是在垃圾桶里翻东西。这就很浪费!所以我现在更倾向于把 OpenClaw 的 memory 当成一个“高密度笔记”,而不是聊天记录仓库。

长期记忆里应该放什么?放那些以后还会反复用到的东西。比如用户的长期偏好、项目方向、稳定身份、固定写作风格、长期决策、反复出现的工作方式。比如用户关注 AI Agent、工业智能化、电力场景、OpenClaw、Agent OS 等方向,偏好“技术原理 + 工程落地 + 公众号表达”的写法。这句话不完整,也不优雅,但够用,它比把几千字历史对话塞进去轻多了。而那些临时性的东西,比如某次工具输出、某段网页内容、某天讨论到一半的想法、某个还没确认的判断,就别急着往长期 memory 里放。它们可以存在,但更适合放在 daily memory 或任务记录里。简单理解就是:长期记忆不是垃圾桶。越想省 token,越要克制记忆。

第二个点,记忆可以有,但不要每轮都拿出来。这个地方我之前也有误区。我以前会觉得,既然 Agent 记住了,那模型每次就应该能看到。否则不就等于没记吗?后来发现,不是这么回事。记住,不等于每次都注入上下文。你写文章的时候,不会把过去所有笔记都摊在桌面上;你做项目的时候,也不会每次都把历史会议纪要重新读一遍。大多数时候,是遇到某个问题,才回头去找对应资料,Agent 也应该这样。OpenClaw 的 memory 更适合做成资料库,而不是背景音乐。它在那里,但不应该一直响。比如当前只是让 Agent 改一段代码变量名,那以前关于公众号选题、工业智能体、封面风格的记忆,完全没必要出现。或者当前是在分析 token 消耗,那和 context、memory、tool result、heartbeat、sub-agent 相关的记忆才值得召回。这就是按需召回。

很多 token 消耗,其实就是因为系统太爱“翻旧账”。明明当前任务用不到,它也要把一些历史偏好、旧项目、旧讨论带出来。看起来很贴心,实际很败家。所以,如果想降低 OpenClaw 的 token 消耗,第一步不是删记忆,而是让记忆不要每次都出现。该搜的时候搜,该读的时候读,不该出现的时候就安静待着。

再说工具说明。这个东西看起来不大,但累起来也很吓人。OpenClaw 这类 Agent 系统通常会有很多工具和技能。浏览器、文件系统、Shell、数据库、邮件、日历、任务管理、sub-agent,各种各样的能力都可以挂上去。这当然很强。但问题是,每个工具都有说明,每个技能也有规则。工具越多,schema 越多,描述越多,模型每次读的东西也越多。如果只是两三个工具,没什么感觉。但如果你把所有工具都打开,再把所有技能说明都塞给模型,那基础 token 成本就上去了。用户只是问一句“帮我优化下这段话”,结果模型还得顺便知道 shell 怎么用、浏览器怎么开、邮件怎么发、日历怎么查,这不是很离谱吗?所以我觉得,OpenClaw 使用过程中,一个很实在的降 token 方法就是:能少开就少开,能按需加载就按需加载。不要因为系统支持某个工具,就一定要让当前 Agent 看到它。写作 Agent 就主要保留写作、搜索、文件相关能力;代码 Agent 就保留代码、shell、git、文件相关能力;办公 Agent 再去接日历、邮件、任务这些东西。

不要让一个 Agent 背着所有工具上场。很多人喜欢全能 Agent,我以前也喜欢。但现在我越来越觉得,全能 Agent 很适合演示,不一定适合长期使用。长期使用时,专业 Agent 更省,因为它轻。

工具说明是一部分,工具结果更可怕。这个我自己感受很明显。工具说明至少是固定的,你大概知道它有多长。但工具结果不是。工具结果可能突然非常大。网页一抓就是几万字;日志一跑就是几千行;数据库一查就是一堆记录;文件一读就是整篇内容。如果这些东西原封不动塞给模型,token 不爆才怪。而且很多时候,模型根本不需要全部内容。比如看日志,真正有用的可能就是 error、exception、traceback 附近那几十行;读网页,有用的是正文核心段落,不是导航栏、广告、脚本、页脚;看代码,有用的是相关文件、相关函数,不是整个仓库。所以 OpenClaw 在使用过程中,一定要控制工具结果。不要让工具拿到什么就返回什么,更好的方式是:先摘要,再展开;先定位,再读取;先看目录,再看文件;先看错误附近,再决定是否继续拉日志。我甚至觉得,很多时候 OpenClaw 贵不贵,不取决于模型回答多长,而取决于工具返回有没有节制,工具要能拿信息,但不能像水管爆了一样往上下文里灌

还有一个很现实的点:别动不动让 sub-agent 带全量上下文。sub-agent 很好用,它能帮你拆任务,能并行处理,能把一部分复杂工作隔离出去。比如让一个子 Agent 去查文档,一个去看代码,一个去整理 memory,一个去总结结论。最后主 Agent 只拿结果。但问题是,很多人用 sub-agent 的时候,会很自然地把主会话完整复制过去。这就比较麻烦,如果主上下文本来已经很重,再 fork 给三个子 Agent,那不是省 token,是把成本乘了几倍。其实子 Agent 不需要知道全部历史,它只需要知道任务目标、必要背景、输入材料和输出格式。比如你让子 Agent 去查 OpenClaw 的 heartbeat,它不需要知道你之前写过哪些公众号标题,也不需要知道你和用户聊过哪些工业场景。它只需要知道:去看 heartbeat 相关内容,整理它怎么影响 token 消耗,最后给出三点结论。这样就够了。我比较喜欢一句话:子 Agent 要带着问题出去,不要背着整个世界出去。

再说心跳机制(heartbeat。OpenClaw 里的 heartbeat 是个挺有代表性的机制。它让 Agent 可以周期性运行,检查任务、提醒事项、外部状态。这个能力看起来很像常驻助手。但常驻助手后台运行不是免费的。如果 heartbeat 每隔一段时间自动醒来一次,每次又带完整上下文、完整历史、完整 memory、完整工具说明,那用户就算什么都不干,系统也在默默烧 token。这个成本在演示里看不出来,因为演示可能只跑几分钟。但如果你真把 OpenClaw 挂一天、挂一周、挂一个月,后台消耗就会慢慢变成真实成本。所以 heartbeat 一定要轻,它不应该每次都像重新启动一个完整 Agent,也不应该把所有历史重新读一遍。很多 heartbeat 场景,其实只需要知道几件事:有没有待办,是否需要提醒,有没有异常,要不要通知用户。所以如果你在使用 OpenClaw 时启用了 heartbeat,我建议重点看三个东西:频率是不是太高,上下文是不是太重,会不会在任务忙的时候继续触发。如果只是普通个人使用,heartbeat 没必要太频繁。后台检查不是越勤快越好,太勤快就是烧钱。这话说得现实一点:常驻能力越强,越要抠成本。不然表面上是智能助手,实际上是一个定时醒来花钱的闹钟

还有一个很容易被忽略的地方:不要让历史会话无限滚。Agent 做长任务时,很容易出现一个情况:历史越来越长,工具结果越来越多,中间讨论越来越多。每一轮都带一点旧内容,每一轮又新增一点新内容。最后上下文就像滚雪球。你可能感觉它只是在继续任务,但模型那边看到的是越来越长的历史包袱。所以长任务一定要阶段性总结。不要一直让原始历史滚下去。比如完成一个阶段后,可以把过程压成一个简短状态:当前目标是什么、已经完成什么、还剩什么、关键结论是什么、哪些材料后面可能还要用等等。这样下一轮就不需要带着所有原始过程继续跑。这个其实很像写项目周报,不会把每天所有聊天记录发给领导,你会整理成进展、问题、风险、下一步。Agent 也是这样,上下文不能一直流水账,必须阶段性归档。否则跑着跑着就会变成:前面一大堆过程,后面一点点任务。模型要先穿过一堆旧信息,才能看到当前问题。太浪费。

再往下说,就是不同场景最好拆不同 Agent。我以前对“万能 Agent”也挺上头,一个 Agent 什么都会:写代码、写文章、查资料、发邮件、管日程、跑脚本、开子任务。听起来很像电影里的 AI 管家。但实际用起来,万能 Agent 往往很重,因为它要带更多工具、更多技能、更多规则、更多记忆。哪怕当前只是一个小任务,它也可能要背着一整套能力包。从 token 成本看,这并不划算。更合理的方式是拆角色:写作就用 writing-agent、代码就用 coding-agent、资料研究就用 research-agent、办公管理就用 work-agent等。每个 Agent 只带自己需要的工具、技能和 memory。这就像公司分工。不是说财务不能懂一点研发,研发不能懂一点市场,而是如果所有人都处理所有事,组织就会变乱。Agent 系统也是一样。边界越清楚,越容易轻。万能 Agent 看着漂亮,专业 Agent 用起来更耐用。

还有一点,prompt 本身也要克制。虽然我一直说,OpenClaw 降 token 不能只靠 Prompt,但这不代表 Prompt 不重要。多人写系统提示词,喜欢越写越长,安全规则写一段,输出风格写一段,工具使用写一段,角色设定写一段,异常处理再写一段。最后系统提示词自己就变成一个小作文。这也会贵。而且长 prompt 不一定更好。很多时候,它只是给模型增加负担。真正稳定的规则,可以放进系统层;具体任务规则,放进当前任务;长期偏好,放 memory;工具说明,按需加载。不要把所有要求都塞到一个 prompt 里。我自己比较喜欢一个原则:系统 prompt 只放最稳定、最底层、最不该频繁变化的东西。临时任务要求、某一次写作风格、某个项目的细节等都不用写进去。否则 prompt 会越长越长,最后变成另一个 memory 垃圾桶。

还有输出也可以控制一下。虽然我前面说,大头常常在输入,但输出也不能完全不管。有些 Agent 很喜欢长篇解释,尤其是技术任务,一解释就停不下来。每次都把背景、原因、原理、建议、注意事项全说一遍。如果只是阶段性沟通,没必要。可以在任务里明确要求:先给结论,需要展开时再展开,不重复已确认内容,只返回本轮新增信息。这不是为了让文章变短,而是为了让交互变轻。尤其是多轮任务里,用户可能已经知道前面结论了。模型没必要每次都重新铺垫。这个地方也容易被忽略。输入太重会贵,输出啰嗦也会贵。不过我还是觉得,OpenClaw 里更该优先处理的是输入,因为输入上下文一旦膨胀,每一轮都会跟着贵。

如果把这些东西放在一起看,我觉得降低 OpenClaw token 消耗,大概可以总结成几个习惯。不是那种特别高深的优化,就是一些用起来要克制的地方。

  • 长期 memory 要短

  • 短期状态要及时归档

  • 旧记忆不要每轮都召回

  • 工具不要全开

  • 技能说明不要全量注入

  • 工具结果先摘要再展开

  • sub-agent 不要默认 fork 全量上下文

  • heartbeat 要轻,不要太勤快

  • 文件先定位再读取

  • 长任务要阶段性总结

  • 不同场景拆不同 Agent

  • 输出尽量只说新增内容

这些看起来都挺碎的,但长期用下来,差别很大。因为 token 消耗往往不是一次性爆掉的。它更像灰尘。每次多带一点历史,多返回一点日志,多注入一点工具说明,多塞一点 memory。一天看不出来,一周之后就很明显。所以 OpenClaw 的降 token,本质上不是某一个开关,而是一套使用习惯。它不是让模型少思考,而是让模型少读无关信息。不是让 Agent 少做事,而是让 Agent 别背着一堆不该背的东西做事。


最后,提供一个大模型token消耗的查询方式,可以使用OpenAI Python SDK,快速便捷:

from openai import OpenAIclient = OpenAI(api_key="你的 API KEY")response = client.chat.completions.create(    model="gpt-4o-mini",    messages=[        {"role""system""content""你是一个技术助手。"},        {"role""user""content""解释一下 OpenClaw 如何降低 token 消耗"}    ])print(response.choices[0].message.content)# 查看 token 消耗print("prompt_tokens:", response.usage.prompt_tokens)print("completion_tokens:", response.usage.completion_tokens)print("total_tokens:", response.usage.total_tokens)

调用前可以用 tiktoken 估算。OpenAI Cookbook 也推荐用 tiktoken 来理解和计算 token。不过它也提醒,聊天消息的 token 计算会受模型和消息格式影响,所以调用前计算更适合当“估算”,最终还是以 API 返回的 usage 为准。

先安装:

pip install tiktoken

简单文本统计:

import tiktokendef count_text_tokens(text: str, model: str = "gpt-4o-mini") -> int:    encoding = tiktoken.encoding_for_model(model)    return len(encoding.encode(text))text = "OpenClaw 降低 token 消耗的核心,是减少无效上下文。"print(count_text_tokens(text))

如果你传的是 Chat messages,可以这样粗略估算:

import tiktokenfrom typing import ListDictdef count_messages_tokens(    messages: List[Dict[strstr]],    model: str = "gpt-4o-mini") -> int:    encoding = tiktoken.encoding_for_model(model)    # 这是一个近似值,不同模型的 message 包装开销可能不同    tokens_per_message = 3    tokens_per_name = 1    total_tokens = 0    for message in messages:        total_tokens += tokens_per_message        for key, value in message.items():            total_tokens += len(encoding.encode(value))            if key == "name":                total_tokens += tokens_per_name    # assistant 回复起始也有少量开销    total_tokens += 3    return total_tokensmessages = [    {"role""system""content""你是一个技术助手。"},    {"role""user""content""解释一下 OpenClaw 如何降低 token 消耗"}]print("estimated prompt tokens:", count_messages_tokens(messages))