06 - 提示缓存与组装策略
学习目标
本章聚焦 Hermes Agent 的系统提示构建与前缀缓存保护策略。你将了解:
- 系统提示如何只构建一次并 SQLite 持久化
- 三种异常状态如何诊断前缀缓存失效
- 技能/插件内容为何注入用户消息而非系统提示
- 缓存感知 slash 命令的设计
前置知识
本章涉及系统提示组装的通用原理,建议先阅读:
下文直接聚焦 Hermes 的具体实现。
项目实践
一次性构建 + SQLite 持久化
Hermes 的系统提示在首次 turn 时完整构建,然后持久化到 SQLite 会话数据库:
# 首次 turn:构建 + 持久化agent._cached_system_prompt = agent._build_system_prompt(system_message)agent._session_db.update_system_prompt(agent.session_id, agent._cached_system_prompt)
# 后续 turn:从 SQLite 读取,逐字节复用stored_prompt = agent._session_db.get_session(agent.session_id)["system_prompt"]agent._cached_system_prompt = stored_prompt核心优势:_build_system_prompt() 是一个重操作(需要聚合 bootstrap 文件、技能描述、插件上下文、工具 schema),只执行一次即可跨 turn 复用。SQLite 读取比每次重建快得多。
前缀缓存保护:一切动态内容注入用户消息
Hermes 严格区分系统提示(稳定前缀)和动态上下文(可变后缀):
| 内容 | 注入位置 | 原因 |
|---|---|---|
| 工具 schema | 系统提示 | 同一 session 内不变 |
| 技能描述 | 用户消息 | 按需加载,变化频繁 |
| 记忆 prefetch | 用户消息 | 每轮可能不同 |
插件 pre_llm_call 上下文 | 用户消息 | 每轮动态 |
| 用户输入 | 用户消息 | 每轮必变 |
设计原则:所有可能变化的内容都不进入系统提示。系统提示保持跨轮次字节级稳定 → Anthropic prefix cache 前缀匹配 → 只有变化的用户消息部分消耗新 token。
三种异常状态诊断
Hermes 对系统提示的 SQLite 持久化设置了三种诊断状态:
| 状态 | 含义 | 行为 |
|---|---|---|
missing | 无会话记录 | 正常首次构建,新建记录 |
null | 记录存在但值为 NULL | 旧版本遗留,WARNING 日志,重建 |
empty | 记录存在但为空串 | 持久化 bug,WARNING 日志,重建 |
当 SQLite 写入失败时,Hermes 降级为每次重建系统提示。这会持续导致前缀缓存 miss,成本飙升。运维人员可通过 hermes logs 监控 WARNING 级别的 null 和 empty 状态。
缓存感知 Slash 命令
Hermes 的 slash 命令设计了 --now 标志来控制缓存失效策略:
- 无
--now:slash 命令内容注入用户消息,下一轮 API 调用时自然生效,不破坏前缀缓存 - 带
--now:立即触发缓存失效(如/reset --now),强制重建系统提示
这使得用户可以在”常规操作不破坏缓存”和”特殊情况立即生效”之间做出选择。
问题与规避
系统提示重建导致的缓存失效
问题:如果 SQLite 写入失败,每轮都重建系统提示,前缀缓存持续 miss。
对策:三种异常状态以 WARNING 级别记录日志。降级重建虽然成本高,但保证了功能可用性。建议定期备份 SQLite 数据库。
技能内容膨胀导致用户消息过长
问题:当加载多个技能时,技能内容注入用户消息可能导致该消息 token 数过大。
对策:技能描述有 60 字符硬限制(见技能系统),确保注入的技能摘要紧凑。详细使用说明在 SKILL.md 正文中,模型按需读取。
设计取舍
系统提示注入 vs 用户消息注入
| 方案 | 优势 | 代价 |
|---|---|---|
| 用户消息注入(Hermes) | 系统提示字节级稳定,前缀缓存命中率高 | 动态内容作为用户消息消耗新 token |
| 系统提示注入 | 动态内容在系统提示中,模型可能更重视 | 每轮系统提示变化,前缀缓存持续 miss |
Hermes 选择将所有动态内容注入用户消息,牺牲的是动态内容的 token 成本(用户消息本就会每轮变化),保护的是系统提示的前缀缓存命中率。对于 Anthropic 模型,前缀缓存命中可节省约 50-90% 的 prompt token 成本。
参考来源
- 源码验证:
agent/prompt_caching.py、agent/prompt_builder.py、agent/system_prompt.py