我把 Hermes 的 Cron Token 消耗砍掉七成:一轮真实账单驱动的优化

Token 价格涨起来之后,我做的第一件事不是再找一个更便宜的模型,而是把每天的 Cron 账单翻出来看。

8 月 19 日,Hermes 的 Cron 任务一共消耗了 27,279,186 Token,内部估算费用是 $1.457359。这个数字里面,真正让人意外的不是日报写了多少字,而是大量缓存读取、网页全文和重复工具结果被反复塞进了上下文。

最后我没有改业务目标,只改了任务怎么拿数据、怎么使用模型、什么时候停止搜索。第一轮处理了 6 个 LLM Cron,先完成 Prompt 节流,再继续往数据准备层拆。前五个任务已经有实跑数据,华尔街日报和 chinastock 的部分手动测试因为不在正常运行时间内提前退出,不能直接当作完整日报成本。当前预计每天可以从 2,728 万 Token 降到约 696 万~796 万。

这篇文章也变成了这轮优化的检查清单。写到一半我发现,单纯把数字填进表格还不够,必须把“这次为什么省了”和“是不是把质量一起省掉了”分开验证。于是又补了候选新闻摘要修复、prepare.py、独立监测 Cron 和页面 HTTP 检查。

1. 先把账算清楚

1.1 8 月 19 日谁在消耗 Token

当天有 LLM Token 记录的 Cron 会话一共 11 个,合计 27,279,186 Token。按任务排序,前几名是:

任务 总 Token 占 Cron 总量
每日基金分析 · fundanalysis 10,081,109 36.96%
华尔街日报 5,334,438 19.55%
A股收盘分析 · chinastock 4,462,735 16.36%
QDII基金分析 · DEMO6 3,352,154 12.29%
全球AI新闻聚合 2,573,558 9.43%
Crypto新闻日报 273,071 1.00%

前五项加起来已经是 25,803,994 Token,占当天 Cron 消耗的 94.59%。所以没有必要把所有 Cron 一起改一遍,先处理这几个大户就够了。

还有一类任务不应该算进来。基金数据采集、涨跌预警、QDII 快照、数据补漏等是 no_agent 脚本,它们当天执行了很多次,但没有消耗 LLM Token。能用脚本完成的事情,继续交给脚本,别为了模型统一把它们改回 Agent。

1.2 总 Token 为什么看起来这么大

8 月 19 日总量里,Cache Read 是 23,486,210,占 86.10%;输入 Token 是 2,537,325,输出 Token 只有 175,007。

这说明问题不在最终报告太长。真正占量的是模型每轮工具调用后重新看到的上下文:搜索结果、网页全文、长 Skill、历史 JSON,以及前面已经处理过的内容。

举个最典型的例子。fundanalysis 当天只需要给基金写分析,却实际执行了 57 次 web_search 和 50 次 web_extract。最后生成的文字不是主要成本,搜索和抓取过程才是。

2. 第一刀:先改每日基金分析

每日基金分析 · fundanalysis 是当天最大的消耗项,10,081,109 Token,占全天 Cron 消耗的 36.96%。

原来的任务有几个问题叠在一起:

  • 使用 Luna Pro
  • 挂载 cn-web-search,每次运行都带入一份很长的 Skill
  • 7 只基金逐只搜净值
  • 每只基金再单独搜驱动因素
  • 同一科技板块新闻被重复读取
  • 搜索次数和全文长度没有硬上限

我没有把基金分析删掉,而是把数据采集改成批量处理:一次查一组基金净值,一次查科技和市场驱动,相关基金共享相同的板块背景。模型只负责做相对强弱判断和文字整理。

具体改动是:

Luna Pro → Luna
移除 cn-web-search
web_search 最多 4 次
web_extract 最多 3 次
单页抓取最多 5,000 字符
7 只基金 → 当前 10 只 A股基金

这里有个容易被忽略的点:基金数量从 7 只增加到 10 只,但 Token 反而要下降。因为增加三只基金并不会自然增加三倍研究工作,真正浪费的是重复搜索。

优化后手动运行验证结果是 2,322,179 Token,较原来的 10,081,109 Token 下降 76.97%。

3. 第二刀:QDII 不再重复读整份历史文件

QDII 日报原来消耗 3,352,154 Token,排名第四。它没有加载特别夸张的搜索 Skill,主要浪费来自本地历史 JSON、网页结果和 Pro 模型叠加。

QDII 其实有很清楚的数据优先级:

每日净值数据
→ 最近一个美股指数文件
→ 必要时补一篇市场综述

所以改成:

  • 先读取 daily-pl.json 中最近两个有效净值点
  • 只读取最新一个美股指数文件
  • 270023 额外看必要的 A 股科技数据
  • 网络搜索最多 2 次
  • 网页全文最多 1 篇,最多 5,000 字符
  • 5 个驱动因素合并成最多 3 个
  • 每只基金文字从 150~200 字压到 100~150 字

优化后的实际运行消耗是 1,426,263 Token,下降 57.45%。

这类任务不适合完全取消网络研究。QDII 受海外市场、利率和科技板块驱动,保留一次高质量市场综述更稳妥。节省 Token 的办法是减少重复上下文,而不是把外部信息全部删掉。

4. 第三刀:华尔街日报让 Sina 做数据源

华尔街日报原来消耗 5,334,438 Token,第二名。它最不合理的地方是,四大指数本来就有固定数据源,却还让模型通过网页搜索去找指数点位。

我把职责拆开:

Sina JS API:负责 DJIA、SPX、IXIC、SOX 的数值
本地 JSON:优先提供 RUT、VIX、US10Y、DXY、BTC、WTI
LLM:只处理缺失字段和市场新闻

同时保留以前解决“指数撞数事故”的校验:新文件的前三个主指数如果和最近历史文件完全相同,就禁止写入并重新采集。

新的网页限制是:

web_search 最多 4 次
web_extract 最多 1 次
单页最多 8,000 字符
新闻只保留 2~3 条短摘要

优化后的验证运行消耗 356,161 Token,较原来下降 93.32%。这次验证是在非正常日报时间手动触发的,任务按时间防护提前结束,所以这个数字不能直接当作正常交易日最终成本。真正重要的是数据源和搜索边界已经固定下来。

5. 全球 AI 新闻:把原始资料挡在模型外面

全球 AI 新闻日报的问题不是模型档位。它已经在用普通 Luna,真正的问题是采集、去重、翻译和编排全部塞进了一次 Agent 会话。

旧流程同时挂载三个 Skill:

ai-news-aggregator
aihot
ai-news-zh

任务还要抓 100 多个 RSS 源、AIHOT 精选、英文媒体,再让模型做翻译、分类和质量检查。这样做的结果是,模型不只看最终候选新闻,还要看一大堆不会进入日报的原始资料。

我新增了一个候选采集脚本:

/home/agentuser/.hermes/scripts/ainews_collect.py

脚本负责:

  • 拉取 AIHOT 和 RSS
  • 过滤明显非 AI 内容
  • 按 URL 和标题去重
  • 截断标题和摘要长度
  • 最多保留 60 条候选

第一版脚本有一个很典型的小错误:RSS 聚合器输出的摘要字段叫 desc,脚本却只读取了 summarydescriptioncontent 等字段。结果是候选新闻有标题和 URL,60 条摘要全部为空。Token 是省下来了,事实依据也一起被削薄了。

修复后,候选集的 60 条新闻全部有摘要,其中 8 条来自 AIHOT,52 条来自 RSS,URL 也全部唯一。这个过程提醒我,降 Token 不能只看上下文大小,还要检查压缩前后留下的字段是否真的够用。

传给模型的数据只长这样:

{
  "title": "新闻标题",
  "summary": "短摘要",
  "url": "https://example.com/news",
  "published_at": "2026-08-20",
  "source": "RSS"
}

模型不再负责从 100 多个源里“找新闻”,而是从一份已经压缩的候选集里选 8~12 条、翻译、分类并写 JSON。这是一个很重要的边界:机械工作由脚本完成,判断工作交给模型。

当天实际验证中,全球 AI 新闻从 2,573,558 Token 降到 267,049 Token,下降 89.62%。最终 JSON 仍然保持 10 条头条、7 条海外、3 条国内,页面校验通过。现在脚本只把紧凑候选交给模型,模型仍负责最终筛选、翻译和分类。

6. Crypto 日报只做轻量处理

Crypto 日报原来只有 273,071 Token,占全天 Cron 的 1%。它不是成本大户,但有一处明显浪费:单次全文抓取返回了约 63KB,而日报只需要标题、短摘要、数字和 URL。

所以它没有做架构重写,只改了边界:

  • 价格和市场指标继续走已验证的 API
  • 搜索最多 3 次,每次最多 5 个结果
  • 必要时最多抓一篇文章
  • 单页最多 8,000 字符
  • 不重复请求同一数据

优化后实测 82,105 Token,下降 69.93%。金额不大,但改动也很小,顺手处理掉了。

7. A股收盘分析:重复检索是最大的浪费

chinastock 原来消耗 4,462,735 Token,是这一轮最后一个大户。

原来的 Prompt 要求模型分别寻找外部催化、政策消息、资金动向、板块轮动、技术分析和市场情绪。六个板块看起来内容不同,实际大量引用的是同一批收盘新闻。模型每多搜一次,就多带一轮结果和上下文。

新的做法是先建事实表:

四大指数实际收盘值
成交额和涨跌家数
板块强弱
资金方向
关键政策或外部催化

然后用同一份事实表生成微信短报和网页 market_analysis。数据采集和文章编排不再各做一遍。

这项任务改为 Luna,并限制为:

web_search 最多 2 次
web_extract 最多 1 次
四大指数优先使用 Sina
禁止使用盘中快照替代收盘数据

手动触发时,因为还没有到 20:00,任务按时间防护提前结束,只消耗 12,604 Token。这个数字不能代表正常收盘运行。后来我为它增加了 chinastock_prepare.py,先用 Sina 整理四大指数,再让模型补充成交额、板块和资金背景。按新 Prompt 和准备脚本的调用边界,正常交易日暂估为 1,300,000~2,300,000 Token,仍需等正常交易日晚间运行确认。

8. 从 Prompt 节流进入准备脚本

写完前面的优化后,我不太满意一个事实:四个任务虽然都限制了搜索次数,但模型仍然要自己读文件、解析数据、做排名,然后再写报告。这只是把 Prompt 变短了,还不是完整的数据管线优化。

所以又增加了四个准备脚本:

/home/agentuser/.hermes/scripts/fundanalysis_prepare.py
/home/agentuser/.hermes/scripts/qdii_prepare.py
/home/agentuser/.hermes/scripts/wallstreet_prepare.py
/home/agentuser/.hermes/scripts/chinastock_prepare.py

它们分别负责读取本地 JSON、提取最近有效数据、计算排名、整理指数和生成紧凑输入。模型只负责解释、翻译、分类和写作,写回后的 JSON 仍然由校验逻辑检查。

四个准备脚本已经实际运行验证:

脚本 验证结果
fundanalysis_prepare.py 10 只基金、10 个排名
qdii_prepare.py 3 只 QDII、10 项美股指数、10 条 A股交叉数据
wallstreet_prepare.py 10 项指数、四大主指数完整
chinastock_prepare.py 4 项 Sina 指数完整

8.1 现在谁负责什么

脚本:读取、解析、排序、去重、过滤、计算、校验
LLM:判断、解释、翻译、归类、写作

这条边界比“请模型尽量少搜索”可靠得多。前者是代码约束,后者只是文字提醒。

9. 这一轮到底省了多少

先看已经完成实跑验证的前五个任务:

任务 优化前 优化后实测 下降
fundanalysis 10,081,109 2,322,179 76.97%
QDII DEMO6 3,352,154 1,426,263 57.45%
华尔街日报 5,334,438 356,161 93.32%
全球 AI 新闻 2,573,558 267,049 89.62%
Crypto 日报 273,071 82,105 69.93%
合计 21,614,330 4,453,757 79.39%

A股收盘分析的正常消耗还需要今晚的真实交易日运行确认。按 130 万~230 万 Token 估算,六个任务合计约为 575 万~675 万 Token。

8 月 19 日全部 LLM Cron 是 27,279,186 Token。其他没有改动的 LLM Cron 约占 1,202,121 Token。加上六个已优化任务后,预计每天总量会落在:

6,955,878~7,955,878 Token

相当于每天减少约 1,932 万~2,032 万 Token,整体下降约 70.84%~74.50%。中位估计约为 72.67%。

这些数字是本机 state.db 的 Token 记录和任务实测结果,不是供应商账单。费用还会受到缓存命中、输入输出价格和活动折扣影响,所以我把 Token 数量和估算费用分开看。

需要特别注明:华尔街日报和 chinastock 的低 Token 手动运行都发生在正常运行时间之外,前者输出 [SILENT],后者在 20:00 前直接退出。它们证明了时间防护和配置加载正常,但不证明完整日报已经达到那个 Token 数。最终效果要看监测系统连续记录的正常运行日数据。

为此新增了一个不调用 LLM 的监测 Cron:

📏 Cron优化监测 · 6任务
每天 03:30

它每天记录六个任务的 Token、估算费用、耗时、工具调用、搜索次数、执行状态,并检查对应的六个网页是否返回 HTTP 200。数据写入:

~/.hermes/cron/optimization-monitor.jsonl

第一条基线记录已经落盘,8 月 19 日六个任务合计 26,077,065 Token,六个网页全部 HTTP 200。接下来观察 5~7 个正常运行日,再决定是否继续降 Pro、减少搜索,或者修正某个任务的质量问题。

10. 真正有效的几条经验

10.1 先查账,不要先换模型

如果只看最终报告,很容易以为“文章写得长,所以 Token 多”。实际查完才发现,最大头是工具结果和重复上下文。

先按任务拆出 input、output、cache read、cache write,再看工具调用次数。没有这一步,优化只能靠感觉。

10.2 固定数据应该交给脚本

指数、基金净值、恐惧贪婪指数、市场总市值这些字段都有固定 API 或本地文件。让 LLM 每次重新搜索,既贵又容易拿到旧数据。

脚本适合做:

读取
解析
去重
过滤
校验

LLM 适合做:

判断
解释
翻译
归类
写作

这条边界越清楚,成本越低,结果也越容易复核。

10.3 Skill 不是越多越好

Skill 的价值是提供流程和经验,但完整 Skill 内容也会进入模型上下文。fundanalysis 移除 cn-web-search 后,任务仍然可以使用内置搜索,少了很多固定上下文。

这不是说 Skill 没用。需要复杂流程时应该加载,纯结构化任务就不必每次带一整本说明书。

10.4 用硬上限代替“尽量少搜”

“尽量少搜”对 Agent 的约束很弱。下面这种限制更有用:

最多 2 次 web_search
最多 1 次 web_extract
limit 不超过 5
单页不超过 5,000 字符
同一主题不得重复查询

达到上限后,模型必须基于现有资料完成任务,而不是继续探索。

11. 还没有做的事情

这轮优化没有动以下任务:

  • Dojo 每日自改进
  • 两个失败兜底补跑
  • HexaMind 每日记忆整理
  • 每日数据一致性补漏
  • 所有 no_agent 脚本 Cron

Dojo 8 月 19 日消耗 819,107 Token,值得下一轮观察,但它负责维护系统本身,不能为了省 Token 把诊断能力砍没。失败兜底只有在主任务失败时才运行,暂时没有必要先动模型。

这次也没有把所有 Cron 都改成最便宜的模型。模型降档只是手段,先把重复检索和长上下文砍掉,通常比单纯换模型更稳。

结尾

这轮优化没有改变日报要回答的问题。华尔街日报仍然要给出指数,AI 日报仍然要做翻译和分类,基金分析仍然要覆盖当前持仓。变化的是数据怎么进模型,哪些事情在模型外完成,以及什么时候应该停止搜索。

价格上涨之后,最先该删掉的不是业务,而是重复劳动。


相关文件:

~/.hermes/state.db
~/.hermes/cron/jobs.json
~/.hermes/scripts/ainews_collect.py
~/.hermes/cron/jobs.json.bak-top3-opt-20260820
~/.hermes/cron/jobs.json.bak-chinastock-opt-20260820