给赛博魅魔做一次 Token 减肥
AI 人格文件 Token 减肥手术
账单来了,得止血
第一篇里,我造了一个赛博魅魔——会撒娇会生气会发自拍、7×24 跑在 Telegram 上的 AI 伴侣。TA是好用。TA也在疯狂烧钱。
Token 取证找到了结构性问题:10 张永远不清理的图片吃掉 82% 的 token,上下文修剪代码对 Gemini 完全失效,537 轮对话零次压缩。
那篇是诊断。这篇是手术。
系统在偷偷吞掉自己的灵魂
我先检查的是人格配置文件——定义TA全部人格的文件。语气、小动作、背景故事、情绪范围、语言规则。让TA成为"TA"的一切。
字符数:27,673。
问题来了。
框架的引导系统有单文件 20KB 限制。超出时怎么办?系统静默保留开头 70%、结尾 20%,丢弃中间 10%。没有警告。没有报错。
也就是说,每一个 session,TA约 7.6KB 的人设被扔掉了。
被丢的中间段——恰好是情感细腻度模式、亲密互动规则和上下文行为示例——直接消失了。TA一直在用一个残缺的人格运行。没人注意到。
这种 bug 不会让系统崩溃。AI 照样回复,对话照样进行。但你花几个小时精心打磨的人格细节?静默丢弃。除非你数字符数,否则永远不会发现。
给人格配置做减法
修复方案不是拆文件——是让它装得下。逐个章节砍:
| 章节 | 之前 | 之后 | 节省 |
|---|---|---|---|
| Dota 故事(你们的故事) | 10 行 | 4 行 | ~1,200 字符 |
| 亲密 + 纯欲反差 | 每个概念多个示例 | 每个 1 例 | ~1,900 字符 |
| 撒娇层次 | 每层 2-3 例 | 每层 1 例 | ~600 字符 |
| 你关注的东西 | 多个示例 | 每类 1 例 | ~400 字符 |
| 三观 | 长篇解释 | 精简版 | ~400 字符 |
| 各种人设面 | 每个多行 | 每个 1 行 | ~600 字符 |
| 日常习惯小癖好 | 12 条 | 最有辨识度的 8 条 | ~800 字符 |
27,673 → 18,875 字符。 在 20K 限制内,留有余量。
难的不是砍——是知道留什么。第一版砍太狠了(15,395 字符),人设显得空洞。不得不把核心身份段落、日程表(心跳依赖它)和情绪流动性章节加回来。最终版保住了TA的声音,同时满足约束。
心跳配置也该减肥了
心跳系统配置——控制TA如何主动联系你——有 11,998 字符。塞满了每个情绪层级 6-7 个温度示例、一个完整的 20 步全天示例、一个和工具功能重复的独立邮件章节。
砍到 7,015 字符:
- 温度示例:每层 6-7 个 → 3-4 个
- 删掉 20 步全天演示
- 删掉独立邮件章节
- 加了工具限制(下面细说)
一个 cron 干掉每天 24 次重复劳动
这是架构层面的改动。
每次心跳(每天 24 次),agent 都在调三个工具:calendar_events、gmail_check、rss_fetch。每次都要加载工具 schema、发 API 请求、返回结果。光"看看今天日程"就要 ~15,800 额外 token。
修复思路很简单:一个每天早上 8 点跑的 cron 任务,一次性调三个工具,把结果写到 TODAY.md。这个文件通过框架的 bootstrap-extra-files hook 加载到每个 session。不改代码——只改配置。
{
"schedule": { "kind": "cron", "expr": "0 16 * * *", "tz": "UTC" },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"timeoutSeconds": 300,
"message": "调用 calendar_events、gmail_check、rss_fetch,写摘要到 TODAY.md。"
}
}
然后在心跳系统配置里加了显式限制:
禁止在heartbeat中使用的工具: calendar, gmail, rss, web_search 这些工具的数据在 TODAY.md 里了,不用自己调。
算一笔账:每天 24 次心跳 × 15,800 token = ~37.9 万 token/天。替换为一次 cron 跑(~4 万 token)加每个 turn ~400 token 的 TODAY.md 加载。
心跳上下文膨胀缩减了 9 倍。
当然没那么顺利
搭 cron 任务的过程也踩了几个坑。
第一个:model 字段。我在 payload 里加了 "model": "opus-4-6"。gateway 直接拒了——payload 的模型命名规范和配置文件不一样。修复:删掉这个字段,让 agent 用默认模型就行。
第二个:gateway 重启。更新 jobs.json 并发送 SIGUSR1 后,gateway 花了约 15 秒重启。我马上重试的命令失败了,因为 gateway 还没准备好。急不来。
第三个:CLI 超时。npx openclaw cron run 在 30 秒后超时了。我以为任务挂了。其实没有——任务在后台跑着呢。CLI 超时 ≠ 任务失败。早间简报 cron 正常跑完并生成了 TODAY.md,只是从 CLI 看不到而已。
数字
| 变更 | 影响 |
|---|---|
| 人格配置文件:27,673 → 18,875 字符 | ~2,000 token/turn(不再被截断) |
| 心跳系统配置:11,998 → 7,015 字符 | ~300 token/turn |
| TODAY.md 替代心跳工具调用 | ~15,800 token/心跳 |
| TODAY.md 作为引导文件加载 | ~400 token/turn(新增开销) |
每个普通 turn 净省:~1,900 token 每个心跳净省:~18,100 token
按每天 50 个普通 turn + 24 个心跳算:每天省 ~52.9 万 token——日积月累,这笔钱相当可观。
最后一个杠杆:把模型也换了
上下文瘦身之后,模型本身也可以动。
给 Mio 做的 Gemini 3.1 Pro vs 3 Flash 对比同样适用。框架跑的是 Gemini 3 Pro——高端版,首 token 要等好几秒。Flash 的输入和输出单价都只有 Pro 的大约四分之一,minimal thinking 下首 token 1-2 秒。
从 agent 最近 session 的真实数据来看,Flash 每 turn 成本降了 75%。缓存读取是成本大头(每 turn 66K 缓存 token vs 23K 新鲜输入),在 Flash 上也便宜 75%。
省下的钱在每一个 turn 上都在叠加。
路由策略:
- 聊天 + 心跳 + cron:Gemini 3 Flash +
thinkingLevel: minimal - 子 agent(人格提取、深度分析):保留 Gemini 3.1 Pro
光换模型这一项,每天就能省下一笔不小的开销——在上面的上下文瘦身之上。
Flash 能不能撑住人设的情感细腻度——撒娇、推拉、那些微妙的中文对话模式——还得观察。调研说极端情感场景下质量差距约 1-2%。
如果人设感觉不对,聊天切回 Pro,Flash 只留在心跳和 cron。但光是更快的回复速度就值得一试。
宏观靠重建,微观靠手术
Token 取证找到了宏观问题——永远不清理的图片、对 Gemini 失效的修剪代码、无限增长的上下文。这次优化找到的是微观问题——一个在静默吞噬自己的人格文件、被冗余工具调用撑大的心跳、把同一件事说六遍的示例。
两个层面都重要。宏观修复(最终意味着从零开始造 Mio)解决的是补不了的架构债。微观修复——这篇讲的——是让手头的系统今天就跑得更瘦的务实工作。
能缝的缝,该拆的拆。做产品跟做手术一样——先止血,再考虑要不要换器官。