2.4. Prompt Builder 实现了一套轻量级 RAG 管理系统
Prompt Builder 实现了一套轻量级 RAG 管理系统
现象与背景:为什么上下文管理成了 Agent 的“隐形天花板”
如果你在 2025 年底问 Agent 开发者最头疼的问题是什么,多数人会给出同一个答案:上下文窗口。长对话中,推理链、工具调用记录、中间摘要不断累积,很快就能把一个 200K token 的窗口撑爆。更糟糕的是,简单的截断(truncation)经常导致模型“放弃”复杂任务——因为承载长期目标的记忆片段恰好落在了被丢弃的窗口之外。
Hermes Agent 的开发者很早就意识到,这个问题无法通过无限扩展窗口容量来解决,而必须靠一套精巧的上下文压缩与缓存机制。截至 2026 年 4 月,Hermes 在 0.x 系列版本(如 v0.16.0) 中已经形成了完整的上下文管理方案:Prompt Builder 内部实现了一套轻量级 RAG(检索增强生成)管理系统,它不同于传统基于向量数据库的 RAG,而是通过对历史消息做摘要、缓存稳定前缀、按需检索相关记忆,来在有限的上下文窗口内维持长期对话的连贯性。
这套 RAG 管理系统有三个核心维度:
- 摘要压缩:从简单滑动窗口进化为层次化摘要,动态决定哪些历史要保留原始文本,哪些压缩为摘要。
- 上下文缓存与模板实例化:通过缓存稳定前缀(系统提示、工具定义)和已渲染的模板,大幅减少重复推理计算。
- 历史消息的按需检索:避免全量注入,而是通过
memory_tool根据当前任务动态查询相关历史片段。
下面我们逐一拆解这三个维度。
核心维度分析
1. 摘要压缩:从滑动窗口到层次化摘要
传统的滑动窗口(Sliding Window)只保留最近 N 轮对话,其余全部丢弃。这种做法的最大问题是:一旦窗口滚动,早期的重要决策(比如“用户要求最终生成一份 PDF”)就再也找不回来。模型会在对话中途突然忘记目标,表现得像是在执行一个独立的新任务。
Hermes 的做法是引入双层压缩系统,模拟了经典 RAG 中的“检索 + 压缩”流程:
- 第一层:修剪(Truncation) —— 当 prompt 的 token 总数达到预设阈值(默认为窗口容量的 50%)时,自动触发。这一层会移除重复的工具调用日志、中间推理片段以及已完成的系统动作,只保留决策路径的关键节点。它就像 RAG 中的粗筛,丢掉明显的噪音。
- 第二层:摘要(Summarization) —— 当修剪后仍然超出安全水位,压缩器会将早期对话轮次转换为精炼的摘要文本,并插入到当前上下文的开头,代替原始消息。摘要中刻意保留了任务目标、已完成步骤、未决待办三项结构化信息,确保模型在任何阶段都能“捡回”长期上下文。
下面这张对比表展示了不同上下文压缩策略对推理质量的影响:
| 策略 | 机制 | 长期记忆保持 | 计算开销 | 适用场景 | 作者的结论 |
|---|---|---|---|---|---|
| 滑动窗口 | 只保留最近 k 轮 | 差 | 极低 | 简单问答、无状态对话 | 不适用于任何需要多步规划的 Agent 任务 |
| 全量摘要 | 将所有旧消息总结为一段文本 | 中等,但信息容易模糊 | 中等 | 摘要模型质量极高的情况 | 实践中容易丢失细节,且摘要自身的计算成本不可忽略 |
| 层次化摘要(Hermes 默认) | 混合修剪与摘要,按优先级压缩 | 强,关键节点保留原始文本 | 可控,通过阈值触发 | 多步推理、工具调用密集的任务 | 当前最优解,平衡了上下文占用与细节保留 |
从当前调研资料看,Hermes 的双层压缩触发条件可通过
compression.threshold调整,默认 50% 是一个经过实际场景验证的平衡点——过低会频繁触发压缩,影响响应速度;过高则可能来不及在窗口溢出前完成压缩,导致 API 报错。
2. 上下文缓存与模板实例化
很多 Agent 框架都有“Prompt Builder”模块,但 Hermes 的 Prompt Builder 不止是拼接字符串,它还内建了缓存热机的思维:将一次 prompt 构建拆分为稳定部分和可变部分,对稳定部分进行缓存复用。
在 Hermes 的实现中,每一次 LLM 调用的最终 prompt 由以下片段按序拼接而成:
- 系统提示(System Prompt) —— 描述 Agent 角色、约束、输出格式等,在整个会话中保持不变。
- 工具定义(Tool Definitions) —— JSON schema 列表,多数情况下在一次会话中不变。
- 注入的上下文块(Injected Context Blocks) —— 来自各种插件、记忆检索结果等,随使用场景变化。
- 历史消息窗口(History Window) —— 经过压缩处理后的最近消息,每个轮次都会变化。
稳定前缀(1 和 2)被单独缓存,Hermes 会利用底层模型(如 Anthropic Claude)提供的 Prompt Caching API,设置 cache_control 断点。具体的缓存策略采用了官方推荐的 system_and_3 模式:
- 断点 1:系统提示末尾。
- 断点 2:工具定义末尾。
- 断点 3:从下往上数第 3 条非系统历史消息的末尾。
这个策略的巧妙之处在于:它不仅缓存了系统级信息,还在历史消息中“锁定”了一个相对稳定的前缀(越靠前的历史被压缩后重新生成的频率越低),从而在每次请求中都能命中大量缓存 token,将推理成本和延迟降低 30%–80%(具体收益取决于会话长度和消息结构)。
缓存与压缩的协同:压缩减少了历史消息的体积,使“可变窗口”更短,间接提高了历史前缀的缓存命中率。因此 Hermes 的 Prompt Builder 并不是两个独立功能的堆砌,而是一个反馈闭环。
缓存策略对比
| 缓存策略 | 断点设置 | 缓存命中率 | 复杂度 | 作者的结论 |
|---|---|---|---|---|
| 全动态(无缓存) | 无 | 0% | 低 | 仅适用于一次性调用 |
| 仅系统提示 | 1 个断点 | ~20% | 极低 | 收益有限 |
system_and_3(Hermes 默认) |
3 个断点 | 50%–70% | 中等,但实现一次即可复用 | 投入产出比最高,推荐所有长对话场景使用 |
3. 历史消息的按需检索
轻量级 RAG 管理系统的“Retrieval”部分并不仅体现在压缩和缓存上,更核心地体现在:Agent 不会将全部历史消息平铺进 prompt,而是像真正的 RAG 架构一样,由记忆模块根据当前任务“检索”出最相关的片段。
Hermes 中负责这一机制的是 memory_tool。当一个新的用户请求到来,Prompt Builder 会调用记忆工具,工具内部运行一个轻量级的嵌入检索(基于文本相似度),从持久化存储中返回符合 query 的历史信息。只有这些检索结果(而非整个对话日志)才会被注入到上下文中。
这样做有三个直接好处:
- 避免上下文污染:无关的历史消息不会占用宝贵的 token 位。
- 节能降本:每次 LLM 调用处理的 token 数减少,API 成本线性下降。
- 支持跨会话记忆:存储可以在会话结束后保留,Agent 重启后仍能“记住”之前的用户偏好。
从调研资料中可以看到,Hermes 的配置项 prompt_caching.enabled 和 context_compression.enabled 均可以独立开关,而记忆检索通过 memory_tool 的注册来实现。用户可以通过简单的命令行配置将其全部开启:
# 启用上下文压缩(自动摘要旧消息)
hermes config set context_compression.enabled true
# 启用 prompt 缓存(减少重复推理计算)
hermes config set prompt_caching.enabled true
这样一套最小化 RAG 系统,不必引入额外的向量数据库依赖,而是将检索能力直接内建于 Prompt Builder 的组装流程中,保持了 Agent 运行时的轻量化。
先给结论:轻量 RAG 管理系统是长对话 Agent 的必需品
综合以上三个维度,我们得出一个清晰结论:对于任何需要处理多轮复杂任务的 Agent,单纯依赖大上下文窗口是不可靠的,必须在 Prompt Builder 层面引入轻量级 RAG 机制——摘要压缩负责“写”,缓存负责“省”,按需检索负责“读”——三者在工程上组合起来,才能将上下文窗口的物理限制转化为可控的管理策略。
整体方案对比
| 方案 | 压缩 | 缓存 | 检索 | 复杂度 | 综合收益 | 作者的结论 |
|---|---|---|---|---|---|---|
| 原始上下文全量注入 | ✗ | ✗ | ✗ | 低 | 极低,极易溢出 | 只适合玩具 demo |
| 仅滑动窗口截断 | 半 | ✗ | ✗ | 低 | 低,长期记忆丢失 | 不适用于 Agent |
| 仅摘要压缩 | ✓ | ✗ | ✗ | 中 | 中,仍可能占用过多 token | 缺乏缓存配合,成本偏高 |
| Hermes 轻量 RAG 系统 | ✓(双层) | ✓(前缀缓存) | ✓(按需检索) | 中 | 高,最大化窗口利用率 | 当前工程最佳实践 |
按场景的推荐
根据不同的应用场景,你可以调整 Hermes 上下文管理的策略组合:
-
对话式 FAQ Bot
上下文长度天然较短,任务无状态。可以选择关闭压缩和检索,仅保留缓存来降低重复询问的成本。 -
多步数据分析 Agent
需要跟踪中间计算结果,建议开启全部压缩与缓存功能,并将压缩阈值调高至 60%–70%,避免在计算密集阶段频繁压缩导致核心中间数据丢失。 -
个人助理 / 长期陪伴 Agent
必须开启按需检索功能,并定期将重要偏好写入持久化记忆。缓存和压缩可以沿用默认配置,重点是保证跨会话记忆的连续性。 -
成本敏感的生产环境
建议同时开启缓存和压缩,并密切关注缓存命中率指标。如果使用 Anthropic Claude,可考虑将系统提示进一步精炼,使其更稳定,以提高缓存利用率。
在下一章《工具调度机制让同一个 Agent 服务于多个前端》中,我们将看到这些经由 Prompt Builder 精心编织的上下文,是如何被分发到不同调用方、工具和插件中去执行的。 Tool Dispatch 的设计目标正是把 Agent 的“大脑”与“手脚”彻底解耦,让同一套推理逻辑可以无缝服务于命令行、Web 界面、聊天 API 等多种交互方式。
Hermes Agent 系统设计与工程落地
关于 LearnKu