前言
如果你在用 Hermes Agent(由 Nous Research 开发的开源 AI 智能体),尤其是在飞书、Telegram 等平台通过 Gateway 模式使用,很可能遇到过这个问题:
发一条消息,等 10-15 秒才收到回复。
这不是你的网络问题,也不是 Hermes 本身有 bug。这是 Hermes 的架构设计带来的代价------它要加载大量工具定义、技能描述、记忆系统,每轮对话发送给 LLM 的 prompt 高达 18 万 tokens。
本文记录了我今天对一个生产环境 Hermes 实例进行速度优化的完整过程,包含每一步的实测数据和决策依据。最终效果:从 15 秒降到 2.6 秒,快了 5 倍。
环境说明
- 硬件:Linux 服务器
- Hermes Agent:v2026.5.x(最新版)
- 连接方式:飞书消息(Feishu Gateway)
- 记忆系统:Hindsight(Docker 部署)
- 初始 LLM :MiMo v2.5(Xiaomi token-plan 套餐)
- 替代 LLM :DeepSeek V4 Flash
一、慢在哪里?先诊断
1.1 每轮对话的时间线
ruby
用户发消息 → 飞书 Webhook → Gateway → 组装 Prompt → LLM 推理 → 返回结果
200ms 50ms 50ms ????ms 200ms
用 tail -f ~/.hermes/logs/agent.log 可以看到每条消息的延迟分布:
r
# MiMo v2.5 的日志
API call #10: model=mimo-v2.5 provider=xiaomi in=185K out=94 latency=13.5s cache=100%
API call #11: model=mimo-v2.5 provider=xiaomi in=180K out=716 latency=15.4s cache=99%
结论:90% 的时间都花在 LLM 推理上,其他环节加起来不到 1 秒。
1.2 每轮发了多少 token?
通过 ~/.hermes/state.db 查询:
less
每轮平均:
新 Input(需处理): 5,645 tokens
Cache(跳过): 107,735 tokens
总 Input: 113,380 tokens
缓存率: 95.0%
即使 95% 缓存命中,那 5% 新 token(~5,600)加上 MiMo 自身的推理延迟,导致了 13-15 秒的响应时间。
1.3 System Prompt 里到底有什么?
深入分析 Hermes 的 agent/system_prompt.py,发现每轮发给 LLM 的 system prompt 由三层组成:
javascript
Stable 层(跨轮不变):
SOUL.md(人格身份) ~2,000 tokens
HERMES_AGENT_HELP_GUIDANCE ~200
MEMORY_GUIDANCE ~500
SESSION_SEARCH_GUIDANCE ~300
SKILLS_GUIDANCE ~200
TOOL_USE_ENFORCEMENT ~400
Skills 清单(66个技能描述) ~3,000
Environment hints ~100
Platform hints(飞书) ~300
Context 层:
AGENTS.md(Hermes 开发指南) ~17,000 ← 最大浪费!
system_message ~0
Volatile 层(每轮变化):
MEMORY 快照 ~350
USER profile ~25
Hindsight recall 注入 ~2,048
时间戳+Session信息 ~30
工具 JSON Schema(79个工具定义) ~23,000 ← 第二大
─────────────────────────────────
静态开销总计 ~50,000 tokens
关键发现:
- AGENTS.md(~17K tokens) :这是一个 50KB 的 Hermes 开发指南,记录项目结构、如何添加工具等,跟日常聊天完全无关,却被自动注入每一轮对话。
- 工具 JSON Schema(~23K tokens) :79 个工具文件的 JSON 定义,但大部分(browser、video、spotify 等)在飞书场景根本用不到。
- 这两项加起来占了 40,000 tokens,是最大的浪费。
二、优化一:移除 AGENTS.md
做了什么
AGENTS.md 是 Hermes 的 prompt_builder.py 自动扫描当前工作目录加载的。它位于 ~/.hermes/hermes-agent/AGENTS.md。
bash
# 备份并重命名,不再被自动扫描
cp AGENTS.md AGENTS.dev.md
rm AGENTS.md
影响
- 效果:每轮减少 ~17,000 个新 token
- 日常聊天:零影响,因为开发指南跟聊天无关
- 开发 Hermes :需要时
mv AGENTS.dev.md AGENTS.md恢复即可
核心代码片段
Hermes 的 prompt_builder.py 中这样扫描:
python
def _load_agents_md(cwd_path: Path) -> str:
"""AGENTS.md --- top-level only (no recursive walk)."""
for name in ["AGENTS.md", "agents.md"]:
candidate = cwd_path / name
if candidate.exists():
content = candidate.read_text(encoding="utf-8").strip()
return _truncate_content(result, "AGENTS.md")
return ""
所以只要文件不叫 AGENTS.md 就不会被加载。
三、优化二:禁用不需要的工具集
做了什么
在 ~/.hermes/config.yaml 中:
markdown
agent:
disabled_toolsets:
- browser
- video
- video_gen
- spotify
- tts
- discord
- discord_admin
- computer_use
这些工具在飞书文字聊天场景完全用不到。
影响
- 工具 Schema 从 ~23K 减少到 ~15K
- 需要时随时在 config 里删掉对应项恢复
四、优化三:更换底层 LLM 模型
这是最关键的一步。
实测对比
在完全相同的 prompt(~185K tokens)下进行对比:
| 模型 | 调用次数 | 延迟 | 缓存率 |
|---|---|---|---|
| MiMo v2.5 | 13 次 | 13-15 秒 | 99-100% |
| DeepSeek V4 Flash | 首次 | 4.7 秒 | 80% |
| DeepSeek V4 Flash | 第 3 次 | 2.6 秒 | 98% |
| DeepSeek V4 Flash | 第 9 次 | 2.6 秒 | 98% |
为什么 DeepSeek 更快?
| 对比维度 | MiMo v2.5 | DeepSeek V4 Flash |
|---|---|---|
| 模型定位 | 推理型模型,擅长复杂推理 | Flash 模型,优化推理速度 |
| 首 token 延迟 | 高(需要思考链) | 低(直接输出) |
| 缓存机制 | 内存级缓存,TTL 5 分钟 | 硬盘级缓存,持久数小时到数天 |
| 缓存命中价格 | 套餐内 1x 计费 | ¥0.02/M tokens |
| 网络延迟 | token-plan-cn 约 143ms | api.deepseek.com 约 143ms |
DeepSeek 的缓存机制特别值得一提
根据 DeepSeek 官方文档:
"Each user request will trigger the construction of a hard disk cache. Once the cache is no longer in use, it will be automatically cleared, usually within a few hours to a few days."
这意味着:
- 缓存存储在磁盘上,不是内存
- 没有固定 TTL,只要在用就一直保留
- 你白天用 Hermes,隔天回来缓存大概率还在
- 跨平台切换(飞书 ↔ Web UI),system prompt 部分继续命中缓存
如何配置
arduino
# ~/.hermes/config.yaml
model:
default: "deepseek-v4-flash"
provider: "deepseek"
同时确保 .env 中有 DeepSeek API Key:
ini
DEEPSEEK_API_KEY=sk-your-key-here
五、优化四:优化 Prompt Caching 策略
背景
GitHub Issue #20880 揭示了一个关键问题:
"Tool-heavy agents pay ~70% input-token overhead ---
system_and_3caching skips tools schema."
Hermes 默认的 system_and_3 策略只在 system prompt + 最后 3 条消息上设置缓存断点,工具的 JSON Schema(~12K tokens)每次调用都不缓存。
做了什么
yaml
# ~/.hermes/config.yaml
prompt_caching:
strategy: system_tools_and_2 # 缓存 system + 工具定义 + 最后 2 条消息
cache_ttl: "5m"
效果
工具定义部分也从缓存提供服务,进一步减少每轮需要处理的新 token。
六、完整效果对比
Token 维度
| 指标 | 优化前 | 优化后 | 变化 |
|---|---|---|---|
| 每轮新 Input token | 5,645 | ~1,926 | ↓ 66% |
| 每轮 Cache token | 107,735 | ~138,794 | ↑ |
| 缓存命中率 | 95.0% | 98% | ↑ |
时间维度
| 场景 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 简单问答 | 13-15 秒 | 2-3 秒 | 5 倍 |
| 多工具调用 | 15-20 秒 | 3-5 秒 | 4-5 倍 |
日志对比
优化前(MiMo v2.5):
ini
API call #10: model=mimo-v2.5 provider=xiaomi
in=178,977 out=692 total=179,669 latency=13.5s cache=98%
API call #13: model=mimo-v2.5 provider=xiaomi
in=180,951 out=403 total=181,354 latency=15.4s cache=99%
优化后(DeepSeek V4 Flash):
ini
API call #3: model=deepseek-v4-flash provider=deepseek
in=180,659 out=118 total=180,777 latency=2.6s cache=98%
API call #9: model=deepseek-v4-flash provider=deepseek
in=185,232 out=109 total=185,341 latency=2.6s cache=98%
七、费用影响
DeepSeek 定价
| 项目 | 价格 |
|---|---|
| 缓存命中 | ¥0.02 / M tokens |
| 输入(未命中) | ¥1 / M tokens |
| 输出 | ¥2 / M tokens |
实际成本
每轮对话:~185K input tokens,98% 缓存命中
ini
缓存命中: 181K × ¥0.02/M = ¥0.0036
未命中: 4K × ¥1/M = ¥0.004
输出: 120 × ¥2/M = ¥0.00024
────────────────────────────
每轮成本: ¥0.008
每天 500 轮对话:约 ¥4/天,远低于 MiMo 套餐 ¥411/月。
八、总结与建议
优化清单(按效果排序)
| 优先级 | 优化 | 难度 | 效果 |
|---|---|---|---|
| ⭐⭐⭐ | 更换更快的 LLM 模型 | 低 | 5 倍提升 |
| ⭐⭐ | 移除 AGENTS.md | 低 | 减少 ~17K token |
| ⭐⭐ | 禁用不用的工具集 | 低 | 减少 ~8K token |
| ⭐ | 优化 prompt_caching 策略 | 低 | 工具定义也缓存 |
其他可参考的优化
- 用
/compress命令压缩长对话:Hermes 内置了上下文压缩,长对话后手动运行,可减少历史 token - Hindsight recall tokens 调低:默认 4096,可改为 1024
- 对话压缩更激进 :
compression.target_ratio: 0.15
排错指南
如果你遇到类似问题,第一步是看日志:
bash
tail -f ~/.hermes/logs/agent.log | grep -E 'latency|model'
根据输出判断:
- 延迟集中在 LLM 调用 → 换模型/优化 prompt
- 缓存率低(<80%)→ 检查 prompt_caching 策略和 cache_ttl
- 工具调用多 → 考虑禁用不用的工具集
- 前几轮慢后面快 → 缓存正在预热,正常