Hermes-Agent——(四)Prompt分层构建与缓存
上篇聊了工具执行策略这篇聊一个更现实的问题——钱。每次调大模型 API对话历史里的 System Prompt 都要原封不动发一遍。一轮长对话跑下来光 System Prompt 重复传输的 token 量就很可观——全价。但 Anthropic 有个 Prompt Caching 机制如果请求前缀跟上次一样模型直接读缓存不用重新算。缓存命中时输入 token 费用降 90%。规则很直白请求前缀System Prompt 历史消息越稳定 越省钱 响应越快。问题是 Agent 的运行需要动态内容。用户记忆、插件上下文、当前时间、Session ID——这些每轮都在变。你要 System Prompt 不变这些动态信息往哪放这就是 hermes-agent 的分层架构要解决的核心矛盾既要 prompt 稳定不变给缓存省钱又要注入动态信息让 Agent 正常工作。三层架构解法是把内容拆成三层分界线只有一个标准放这里会不会让缓存失效。第一层缓存 System Prompt稳定层Agent 身份、工具使用规则、长期记忆快照、Skills 索引、项目上下文文件——这些在一次会话里基本不变。构建一次存到 SQLite多轮复用。只有两个触发点会重建上下文压缩、模型切换。这层占请求前缀的绝对大头也是 Prompt Caching 省钱的核心。只要它不变缓存前缀就能匹配上被缓存的那部分 token 费用降 90%。第二层ephemeral_system_prompt追加层预加载的 Skill 全文、子 Agent 任务描述、API Server 的 instructions——这些也是 system 级别的指令享有 system role 的高指令遵循权重但每轮可能不同。拼在缓存层之后。代价很明显内容变了缓存就失效。但 hermes-agent 赌的是大多数场景下 ephemeral 在一次会话内是稳定的。CLI 配置不变Gateway context 不变预加载的 Skill 在构造时确定。赌赢了省钱赌输了全价——跟没做分层一样。源码的注释说得明白# Note: ephemeral_system_prompt is NOT included here. Its injected at# API-call time only so it stays out of the cached/stored system prompt.ephemeral_system_prompt 不参与这里的构建。它只在 API 调用时刻注入因此不会进入缓存或持久化的 system prompt。第三层User Message 动态注入动态层外部记忆检索结果、插件上下文——每轮必变。直接拼到当前 user message 末尾彻底不碰 system 消息。缓存前缀纹丝不动。三层的关系一句代码就说清楚了effective_systemself._cached_system_promptor# 先拿缓存层ifself.ephemeral_system_prompt:# 如果有追加层effective_system(effective_system\n\n# 用两个换行拼在后面self.ephemeral_system_prompt).strip()cached ephemeral 拼成最终的 system 消息。动态内容走另一条路注入到 user message。缓存层里到底拼了什么缓存层的构建逻辑按顺序逐层拼接最后用空行连起来。源码注释说是 7 层但实际 append 操作有十几个。按逻辑归成四组身份与行为规则。Agent 身份优先读 SOUL.md没有就用硬编码的默认身份。然后根据已加载的工具动态追加行为指导——有 memory 工具就拼记忆使用说明有搜索聊天记录就拼历史搜索说明。强制工具调用禁止光说不练Google 和 OpenAI 模型各自有专属操作指令。记忆与知识。内置 MemoryStore 的快照——用户偏好、项目约定——在构建时从磁盘加载后冻结。外部记忆系统的工具声明——给了搜索外部记忆的工具但声明不是数据本身。项目上下文文件HERMES.md → AGENTS.md → CLAUDE.md → .cursorrules 按优先级只加载第一个找到的单文件超 2 万字符会头尾保留截断。能力清单。Skills 索引——不是 SKILL.md 全文是名称一行描述的目录模型根据目录决定调哪个查看详情的工具。付费功能的可用状态清单。环境与元信息。当前时间、Session ID、模型名——冻结在构建时刻。平台格式规则Telegram/Discord/WhatsApp 各有要求。阿里云 API 的身份修正workaround阿里云总是返回错误的模型名。WSL/Termux 等特殊环境的路径提示。构建完就冻结。源码注释里有个关键表述Rebuilding would pick up memory changes from disk that the model already knows about (it wrote them!), producing a different system prompt and breaking the Anthropic prefix cache.翻译过来如果每轮都重新从磁盘读 memory模型刚写进去的新记忆会立刻出现在 system prompt 里——缓存前缀变了缓存失效。而且这是死循环模型写记忆 → 下一轮 system prompt 多了新内容 → 缓存失效 → 全价。所以构建时拍快照冻结除非压缩或换模型绝不重建。追加层的取舍ephemeral_system_prompt 的通路不止一条CLI 的--skills参数启动时读 SKILL.md 全文拼进 ephemeral子 Agent任务委派工具创建子 Agent 时任务目标写进子 Agent 的 ephemeralAPI Server外部系统通过 API 调用时传入的指令它跟缓存层的核心权衡就一句话方案Cache 稳定性指令遵循度ephemeral 放 systemhermes 选变就失效高system role 权重大ephemeral 放 user永远稳定低混在用户闲聊里这不是一个正确答案的选择是看你更在意省钱还是更在意指令执行精度。hermes-agent 选了 ephemeral 放 system代价是内容变了缓存从头废。为什么动态内容走 User Message两个原因第一个是钱第二个是正确性。钱外部记忆检索结果和插件上下文每轮必变。放 system prompt → 前缀每轮不同 → 缓存每轮失效 → 全价。放 user message 末尾前缀完全不变。对 LLM 来说 system 和 user 都是上下文效果基本等价成本天差地别。正确性System Prompt 存在 SQLite 里跨 Gateway 实例共享。如果每轮改存哪个版本重建会重新读磁盘上的 memory 文件可能拿到模型刚写的内容——“用户喜欢 Python记住了”——这条记忆出现在下一轮 system prompt 里而且跟上一轮的 prompt 不一样。不一致。User Message 注入的实现也干净操作的是api_messagesAPI 发送时的临时副本不碰messages持久化到 SQLite 的原始消息。源码注释写得很清楚API-call-time only — the original message inmessagesis never mutated, so nothing leaks into session persistence.数据库存的是干净历史API 发的是带注入的版本。两层分离。另外 Memory Prefetch 在主循环外只调一次源码注释写得很清楚Reuse the cached result on every iteration to avoid re-calling prefetch_all() on each tool call (10 tool calls 10x latency cost).缓存保护策略三个缓存逐级兜底内存缓存有→ 直接用 没有 → SQLite 里有→ 恢复Gateway 跨实例复用 没有 → 全新构建 → 同时存内存和 SQLite两个触发点会让缓存失效但行为不一样上下文压缩对话太长压缩历史 → 缓存失效从磁盘重新加载 memory → 重建。压缩后 memory 是新读的包含对话中写入的内容。模型切换用户换模型 → 直接清空缓存 → 下一轮重建。但不重新读 memory用的是已有的记忆数据。两个触发点的 memory 行为不一致——压缩后刷新换模型不刷新。这不一定是 bug但说明缓存失效是个敏感操作什么该重建什么该保留需要分清楚。Gateway 场景下 SQLite 持久化尤其关键。Gateway 为每条消息创建新的 Agent 实例没有 SQLite 的话每次都重新构建 prompt缓存永远命中不了。有 SQLite 之后消息1→ 新 Agent → 全新构建 → 存 SQLite → 缓存未命中 消息2→ 新 Agent → 从 SQLite 读到跟上次完全一致的 prompt → 缓存可能命中总结第一分层的标准不是内容类型是缓存稳定性。什么放哪一层不取决于它是什么内容而取决于它会让缓存失效吗。稳定层塞不变的东西追加层塞偶尔变的东西动态层塞每轮变的东西。每一步都在算成本。第二冻结快照。构建时的状态冻结运行时不回流。Agent 对话中写了新记忆 → 不反哺到当前会话的 system prompt → 等压缩重建时才重新加载。不是所有系统都需要这个但如果你的 Agent 会自我修改知识你得想清楚回流时机。第三追加层是显式赌博。system role 的权威性 vs cache 的稳定性。hermes-agent 选了权威性代价是 ephemeral 变的时候缓存从头废。你的场景可能反过来。关键是别装不知道这个 trade-off。第四注入不持久化。messages 表存干净历史临时消息副本是带注入的临时数据。动态内容在 API 时刻拼用完就丢。

相关新闻

终极指南:如何用本地图片搜索引擎快速找到相似图片

终极指南:如何用本地图片搜索引擎快速找到相似图片

终极指南:如何用本地图片搜索引擎快速找到相似图片 【免费下载链接】ImageSearch 基于.NET10的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 你是否曾经在成千上万的图片文件中…

2026/10/25 13:53:29 阅读更多 →
从单体 Agent 到 Agent 平台:一次架构迁移的技术方案和组织挑战

从单体 Agent 到 Agent 平台:一次架构迁移的技术方案和组织挑战

从单体 Agent 到 Agent 平台:一次架构迁移的技术方案和组织挑战 一、深度引言与场景痛点 2024 年初我们的 AI 应用还只有一个 Agent — 一个智能客服机器人。用了大半年反响不错,业务部门开始来提需求:法务要一个合同审查 Agent、HR 要一个简…

2026/10/27 13:13:52 阅读更多 →
HarmonyOS7 串联动画实战:用 setTimeout 编排动画序列

HarmonyOS7 串联动画实战:用 setTimeout 编排动画序列

文章目录前言效果预览布局思路逐步实现定义独立的动画状态方块渲染与动画绑定核心:setTimeout 串联动画波浪效果的嵌套 setTimeout关键代码踩坑记录坑1:延迟时间太短会导致动画"吞掉"坑2:快速连续点击会出bug坑3:animat…

2026/10/29 15:38:21 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/31 10:20:19 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/31 10:20:23 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/31 10:30:19 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/31 9:29:43 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 18:03:41 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 11:00:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →