Hermes 接 LiteLLM 缓存不生效踩坑记录

最近在深度使用Hermes Agent中发现一个怪事:我的 Hermes Agent 和 Claude Code 都接的同一个 LiteLLM 网关,底下是 AWS Bedrock 的 Claude 模型。Hermes 用 Sonnet 4.6,Claude Code 用 Opus 4.7,按定价 Opus 比 Sonnet 贵 67%,但 4 天账单下来,Hermes 每次请求比 Claude Code 贵了将近一倍

直觉告诉我不对,决定认真查一下。

先看数据

从 LiteLLM spend logs 里拉了两个 key 的数据,统计区间是 2026-04-25 到 04-26:

指标 hermess-agent claude-code
使用模型 Claude Sonnet 4.6 Claude Opus 4.7
总请求数 1,043 次 156 次
平均单次费用 $0.1490 $0.0818
平均输入 token 47,378 94,108
平均输出 token 457 361
缓存读取 token 0 89,613
缓存命中率 0% 95.1%

Hermes 的输入 token 比 Claude Code 少一半,但单次费用贵了近一倍。缓存命中率:0% vs 95%。一眼就看出来问题在哪了。

为什么命中率是 0%

看 LiteLLM 日志里的 request_tags

json 复制代码
// Hermes
"request_tags": [
  "Credential: AWS-AK/SK",
  "User-Agent: OpenAI",
  "User-Agent: OpenAI/Python 2.32.0"
]

// Claude Code
"request_tags": [
  "Credential: AWS-AK/SK",
  "User-Agent: claude-cli",
  "User-Agent: claude-cli/2.1.114 (external, claude-vscode, agent-sdk/0.2.114)"
]

Hermes 用的是 OpenAI Python SDK 在发请求。走 OpenAI 兼容格式(/v1/chat/completions),请求里根本没有 cache_control 字段,缓存从来没有触发过。

但 Hermes 明明支持 Prompt Cache------翻它的源码 run_agent.py,有一个 _anthropic_prompt_cache_policy 方法,专门决定是否对这次请求启用缓存。问题是它的判断前提:它必须先"认出"对面是 Anthropic 协议,才会走缓存分支。

根因:api_mode 没配

我当时的配置是这样的:

yaml 复制代码
# ~/.hermes/config.yaml
model:
  default: claude-sonnet-4-6
  provider: custom
  base_url: https://api.huancode.com/v1
  api_key: ${HUNCODE_API_KEY}

provider: custom 加上普通的 base_url,Hermes 内部的 determine_api_mode 方法拿到这个 URL,不命中任何特殊规则,返回 chat_completions------OpenAI 兼容模式。后续缓存逻辑判断 is_anthropic_wire = False,直接返回 (False, False)cache_control 从未被加到请求里。

LiteLLM 那边其实完整支持 /v1/messages(Anthropic 原生格式),但 Hermes 压根没用这个端点。

解决方法:加一行 api_mode

yaml 复制代码
# ~/.hermes/config.yaml
model:
  default: claude-sonnet-4-6
  provider: custom
  base_url: https://api.huancode.com
  api_key: ${HUNCODE_API_KEY}
  api_mode: anthropic_messages   # ← 这一行

两处变化:base_url 去掉了末尾的 /v1,以及显式加了 api_mode: anthropic_messages

从日志里可以验证效果。修复前,LiteLLM 收到的 request_tags 是:

json 复制代码
["Credential: AWS-AK/SK", "User-Agent: OpenAI", "User-Agent: OpenAI/Python 2.32.0"]

修复后变成:

json 复制代码
["Credential: AWS-AK/SK", "User-Agent: Anthropic", "User-Agent: Anthropic/Python 0.96.0"]

协议切换之后,缓存开始命中。以下是一次完整会话的连续请求记录:

ini 复制代码
14:51:38  cache_read=     0  cache_write=23,686  ← 第一轮,写入缓存
14:51:40  cache_read=23,686  cache_write= 4,031
14:51:45  cache_read=27,717  cache_write=10,721
14:52:13  cache_read=38,438  cache_write=   822
14:52:17  cache_read=39,260  cache_write= 1,162
14:52:20  cache_read=40,422  cache_write=   292
14:52:28  cache_read=40,714  cache_write=   853

每轮对话的历史内容持续命中缓存,只有新增部分触发少量写入,和 Claude Code 的命中模式完全一致。

api_mode 是什么

api_mode 是 Hermes 决定用哪种 wire protocol 跟 API 通信的配置项。有四个合法值:

chat_completions(默认) 走 OpenAI /v1/chat/completions 格式。几乎所有第三方 API 都兼容,是 Hermes 的默认值。适用于 OpenAI、大多数国产模型、OpenRouter 等。

anthropic_messages 走 Anthropic /v1/messages 格式。使用原生 Anthropic SDK 发请求,支持 cache_control(prompt caching)、thinking block、extended output 等 Anthropic 专有特性。适用于:

  • api.anthropic.com(官方)
  • 兼容 Anthropic 协议的第三方网关(如本例中的 LiteLLM)

codex_responses 走 OpenAI /v1/responses 格式(Responses API)。用于 OpenAI Codex、xAI Grok 等支持 Responses API 的端点。

bedrock_converse 走 AWS Bedrock Converse API 格式。直接对接 AWS Bedrock,不走任何兼容层。

自动推断逻辑

如果不写 api_mode,Hermes 会根据 base_url 自动推断:

base_url 包含 自动推断为
api.anthropic.com anthropic_messages
openai.com/v1/responses codex_responses
其他 chat_completions

provider: custom 的情况不在自动推断范围内,所以即使 LiteLLM 完整支持 /v1/messages,Hermes 也不知道------必须手动写 api_mode: anthropic_messages

这是文档里没有特别强调的一个坑:custom provider 时,api_mode 的默认行为是 chat_completions,不会自动探测对端协议能力

成本影响有多大

把缓存打开之后按同等命中率估算,每次请求从 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.149 降到大约 0.149 降到大约 </math>0.149降到大约0.039,整体节省约 73%。

两天的 1043 次请求,如果缓存一直是生效的,总费用从实际的 <math xmlns="http://www.w3.org/1998/Math/MathML"> 153 降到约 153 降到约 </math>153降到约42,差了 $111。

用框架接模型时,协议模式的选择比框架选型本身更重要。Hermes 支持缓存,但只对它"认识的" Anthropic 协议生效。默认配置走了 OpenAI 兼容模式,缓存悄悄关掉了,账单悄悄涨上去,不认真看日志根本发现不了。


数据来源:LiteLLM spend logs,统计区间 2026-04-25 至 2026-04-26,基础设施:Bedrock (us-east-1)。

相关推荐
齿轮2 小时前
Agent 管理范式演进:从管一句话到管整个系统
人工智能·后端
AIGCmagic社区2 小时前
AI多模态理论基础高频考点
人工智能
珹洺2 小时前
C++AI多模型聊天系统(三)AI多模型(豆包/Kimi/千问)接入与实现
开发语言·c++·人工智能
啷咯哩咯啷2 小时前
纯本地运行的私人文档知识库
前端·人工智能·后端
FrontAI2 小时前
深入浅出 LangGraph —— 第7章:持久化与检查点机制
人工智能·langchain·ai agent·langgraph
探物 AI2 小时前
【感知·车道线检测】UFLDv2车道线检测与车道偏离预警(LDWS)实战
人工智能·算法·目标检测·计算机视觉
Swilderrr2 小时前
学术研读报告:MEM1面向长视距智能体的记忆 - 推理协同框架
人工智能
aLTttY2 小时前
Spring Boot整合AI大模型实现智能问答系统实战
人工智能·spring boot·后端
easy_coder2 小时前
《工程化视角下的Prompt设计与迭代:云诊断与CICD变更风控中的实践》
人工智能·云计算·prompt