一图看懂 API 烧了多少钱:教你找回 Hermes 丢失的辅助模型 Token 统计
莫名其妙蒸发的 API 余额:揭开 Hermes 面板模型统计 缺失的灵异现场
昨晚临睡前,我给本地的 Hermes-Agent 挂了一个极其庞大的多模态沉浸式工作流:让主模型(Claude-3.5-Sonnet)负责核心代码逻辑,同时并行调用三个辅助模型——用 Qwen-VL 看几百张架构图,用 GPT-4o-mini 做海量日志的文本摘要,外加一套 Embedding 模型做本地知识库向量化。
官方 README 里把多模型协同(Multi-Agent Routing)吹得那叫一个优雅,号称能“把好钢用在刀刃上”,极致压缩 API 成本。
一觉醒来,我端着咖啡美滋滋地打开终端。看了一眼底部的 Hermes 面板模型统计,显示主模型消耗了大约 5 刀的 Token。我心想,这套架构确实省钱。然而,当我随手切到云厂商的 API 计费控制台时,屏幕上的数字直接让我一口咖啡喷在键盘上——账单赫然写着昨晚烧掉了整整 48 刀!
钱去哪了?!
我疯狂翻查日志,才绝望地发现:终端控制台上那精美的 Token 统计面板,居然是个彻头彻尾的残废! 只有主模型的 Token 被记录了,而那几万次的高频视觉处理、摘要和向量化调用,在面板上的消耗永远显示为 0。
去 GitHub 搜了一圈,在 Issue #9979 (辅助模型 Token 统计缺失) 里,满地都是像我一样看着信用卡账单欲哭无泪的开发者。
报错现象总结: 当开发者在 Hermes-Agent 中启用多模型协同工作流时,控制台的 Hermes 面板模型统计 模块只会记录主路由模型的 Token 消耗。而通过
auxiliary_client调起的低参模型、视觉模型或 Embedding 模型的 API 消耗数据,在底层生命周期中被框架静默剥离和丢弃。这导致开发者面临极其严重的 API 计费盲区,高频调用下极易刷爆信用卡。
官方教你怎么用组合拳,却不告诉你这些出拳的代价是个黑盒。今天,我们直接扒开底层的统计探针,看看你的 Token 究竟是在哪个下水道里被偷偷冲走的。
深入 auxiliary_client 源码:为什么你的小模型 Token 会被无情抛弃?
要搞明白这 40 多刀是怎么凭空蒸发的,我们必须剥开 Hermes-Agent 处理 LLM 调用的“双标”架构。
在系统的核心链路里,主模型(Main LLM)的每一次调用,都经过了极其严密的 orchestrator.py 调度。在这里,开发者预埋了拦截器,大模型 API 返回的 response.usage 会被一丝不苟地扒下来,塞进全局的 TokenTracker 里。
但是,当框架试图去调用那些便宜的“打工”模型(辅助模型)时,它走的是一条极其简陋的旁路:auxiliary_client.py。写这段代码的老哥,显然是个只图功能跑通、不顾工程严谨性的草台班子。
来看看案发现场这段堪称灾难的底层原生逻辑:
# hermes_agent/llm/auxiliary_client.py (原生缺陷代码片段)
async def generate_auxiliary(self, prompt: str, model_id: str) -> str:
"""调用辅助模型执行脏活累活"""
try:
# 发起 API 请求
response = await self.provider.generate(prompt, model=model_id)
logger.debug(f"Auxiliary task completed by {model_id}")
# ⚠️ 致命的黑洞:直接返回了纯文本 content!
# OpenAI/Anthropic 接口辛辛苦苦吐回来的 response.usage
# (包含 prompt_tokens, completion_tokens)
# 在这行代码被当作垃圾一样无情抛弃了!
return response.content
except Exception as e:
logger.error(f"Auxiliary client failed: {e}")
return ""
看懂这套逻辑有多业余了吗?
大模型的 API 响应原本是一个包含 content 和 usage 的完整数据包。但在 generate_auxiliary 里,框架直接把外层的包装盒给扔了,只把里面的字符串抽出来扔给了下游!主线程里的 TokenTracker 连个毛都抓不到,面板自然永远显示为 0。
为了让你彻底看清这场底层架构导致的计费灾难,我梳理了一份核心对比表:
| 调度链路类型 | Token 消耗追踪节点 | TokenTracker 数据状态 |
你的钱包现状 |
|---|---|---|---|
| 主模型 (Main LLM) | orchestrator.py 完整拦截并提取 usage |
正常累加 | 账单可控,面板数据准确 |
| 辅助模型 (Auxiliary) | auxiliary_client.py 强制剥离元数据 |
❌ 永远为空/0 | 黑盒扣费,跑一晚上底裤赔掉 |
| 向量化 (Embedding) | 同上,接口封装层直接 Drop 掉了 usage | ❌ 永远为空/0 | 高频 RAG 检索下沦为吞金巨兽 |
你以为你在薅便宜模型的羊毛,实际上这套破烂基建正蒙着你的眼睛,让你给云厂商打黑工。
强改 TokenTracker 状态机:一场被全局单例和异步锁逼疯的填坑实战
病因极其明确:底层的旁路丢弃了计费元数据。那我们要做的,就是在辅助客户端里把 usage 捡回来,并强行塞进主界面的监控面板里。
如果你是个原教旨主义极客,觉得只要自己动手改几行代码就能修好,那你即将经历一个极其枯燥且容易走火入魔的排雷周末。
第一步:钻进虚拟环境手撕客户端签名
你必须潜入 venv/lib/python3.11/site-packages/hermes_agent/llm/,把 auxiliary_client.py 里的返回值从 str 改成 Tuple[str, dict]。然后,你得顺藤摸瓜,把上层所有调用了辅助模型的地方(比如总结模块、视解析模块)全部重写,小心翼翼地把这坨 dict 接住。
第二步:手搓异步并发锁对抗数据脏写
这才是最要命的。Hermes 的辅助模型往往是随着主模型 并发拉起 的。如果你直接在协程里去修改全局单例的 TokenTracker:
# 你不得不手敲的一坨恶心中间件
from hermes_agent.utils.tracker import get_global_tracker
import asyncio
tracker = get_global_tracker()
# ⚠️ 高并发下极易发生竞态条件(Race Condition),导致 Token 算少!
# 你必须手写一层全局互斥锁:
async with tracker_lock:
tracker.add_usage(model_id, response.usage.prompt_tokens, response.usage.completion_tokens)
第三步:修不完的跨平台依赖与面板重绘
就算你把数据收集全了,你还得去改终端的 TUI 渲染代码。你得把原来写死只显示主模型一行数据的 UI 布局,强行改成支持动态列表的折叠面板。
为了引入更高级的表格渲染库,当你敲下 uv pip install 时,国内极其拉胯的网络环境会用 GitHub Raw 的 Timeout 和依赖冲突狠狠教训你。
折腾了两天两夜,在无数个 try-except 和死锁报错中,你勉强在终端里画出了一个丑陋的多模型费用统计表。等到下周官方推送个修复某个拼写错误的小版本,你一个 git pull,刚才改的代码瞬间被覆盖,一切推倒重来。
拒绝给烂基建打白工:一键注入计费监控补丁,点亮全模型看板
作为一名底层架构师,我极其厌恶把生命浪费在这种因为官方偷懒而导致的“基础设施黑洞”上。
开发者的核心价值,是去编排多智能体的工作流,去榨干每一个模型在特定场景下的最高性价比,而不是在这里当一个卑微的会计,拿着放大镜去修底层框架漏掉的计费函数!
这种连用户的钱都不当回事的草台班子逻辑,就应该被降维清除。
与其浪费一个美好的周末在虚拟环境里改源码、写并发锁、配终端 UI,我已经把这套恶心的计费追踪系统彻底重构了。我利用 Python 的 AOP(面向切面编程)机制,做了一个极其优雅的探针补丁。它能在底层 HTTP 层面直接拦截所有 provider 的返回,无视官方那些糟糕的封装,将每一个 Token 稳稳当当地捕获并写入自带的高可用并发锁字典中。
👉 [前往 GitCode 复制代码补丁,一键替换,点亮控制台的多模型费用监控看板。] (搜索 Hermes API 精准计费重构计划)
夺回钱包控制权,只需极其无脑的三步:
- 访问上方的 GitCode 仓库,一键拉取这个只有几十 KB 的
usage_tracker_patch.zip(国内极速 CDN,瞬间秒下,拒绝网络死锁)。 - 解压后,直接将里面的
metrics文件夹覆盖到你项目核心目录下,它会自动通过猴子补丁(Monkey Patch)接管全局计费。 - 重新拉起你的 Hermes-Agent 守护进程。
覆盖完毕后,再去跑一次你那个庞大的多模态工作流。
你会惊艳地发现,控制台底部原本单调的计费区域,瞬间展开成了一张极其专业的动态数据看板:Claude 的逻辑消耗、GPT-4o-mini 的碎步成本、Embedding 模型的向量化开销,清清楚楚、分门别类地列在眼前。再也没有隐藏账单,再也没有黑盒扣费。
拿去用,看好你的信用卡,别让糟糕的底层架构偷走你的 API 余额。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0108- DDeepSeek-V4-ProDeepSeek-V4-Pro(总参数 1.6 万亿,激活 49B)面向复杂推理和高级编程任务,在代码竞赛、数学推理、Agent 工作流等场景表现优异,性能接近国际前沿闭源模型。Python00
MiMo-V2.5-ProMiMo-V2.5-Pro作为旗舰模型,擅⻓处理复杂Agent任务,单次任务可完成近千次⼯具调⽤与⼗余轮上 下⽂压缩。Python00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
SenseNova-U1-8B-MoT-SFTenseNova U1 是一系列全新的原生多模态模型,它在单一架构内实现了多模态理解、推理与生成的统一。 这标志着多模态AI领域的根本性范式转变:从模态集成迈向真正的模态统一。SenseNova U1模型不再依赖适配器进行模态间转换,而是以原生方式在语言和视觉之间进行思考与行动。Python00
MiniMax-M2.7MiniMax-M2.7 是我们首个深度参与自身进化过程的模型。M2.7 具备构建复杂智能体应用框架的能力,能够借助智能体团队、复杂技能以及动态工具搜索,完成高度精细的生产力任务。Python00