拆解 Hermes Agent 的动态 Prompt 和 learning loop 架构
什么是 Hermes AgentHermes Agent 是 Nous Research 开源的自托管 AI Agent 项目。官方定位为一个会“随着你一起成长”的自改进 Agent它不只是执行一次性问答而是内置 learning loop会从任务经验中创建技能在使用过程中改进技能定期提示自己保存重要知识搜索过去会话并逐步形成对用户的跨会话理解。从形态上看Hermes Agent 不是单一聊天机器人而是一个 Agent 运行环境。它包含交互式 CLI、消息平台 gateway、工具系统、记忆系统、技能系统、任务调度、子 Agent 委派、多终端后端和项目上下文加载能力。功能上 Hermes 的核心能力拆成几类Tools Toolsets工具系统可按平台启用或禁用 Skills System按需加载的技能文档用来保存可复用工作流 Persistent Memory跨会话持久记忆保存用户偏好、项目、环境和经验 Context Files自动加载项目上下文文件让 Agent 遵守当前项目规则 Messaging Gateway把同一个 Agent 接入多个消息平台 Cron Scheduling用自然语言创建定时任务 MCP Integration连接外部 MCP server 扩展工具能力其中最关键的是 memory 和 skills。Hermes 的内置记忆由两个文件组成MEMORY.mdAgent 的个人笔记用来保存环境事实、约定、经验和教训 USER.md用户画像用来保存用户偏好、沟通风格和期待这些记忆会在新会话开始时作为 frozen snapshot 注入 system prompt。同一会话中它通常不会每一轮重新加载而是保持 system prompt 稳定以保护 prompt cache。Skills 则更像过程性记忆。它不是简单的工具列表而是 Agent 可以按需加载的工作流说明。比如 GitHub PR 流程、系统化调试、代码审查、MCP 使用、文档处理、YouTube 内容提取等都可以沉淀成 skill。Hermes 的 learning loop 会在任务完成后判断是否需要保存或更新技能让 Agent 的经验可以跨会话复用。这也是 Hermes Agent 和普通聊天助手最大的区别之一普通聊天助手主要依赖当前上下文。 Hermes Agent 会把长期事实写入 memory把可复用方法写入 skills把项目规则写入 context files并在未来会话中重新注入这些内容。所以Hermes 的“自我进化”不是模型参数训练也不是神秘能力。它更像一个工程化的外部记忆与技能维护系统通过 memory、skills、session search、context files 和 learning loop让同一个 Agent 在长期使用中越来越贴合用户和项目。这篇文章不讨论模型本身能力而是拆解 Hermes Agent 的一个核心设计一个可长期运行、可记忆、可沉淀经验的 Agent它的系统提示词应该如何被组织很多人理解的 system prompt是一段写死的角色设定。比如你是一个有帮助的 AI 助手。但真正做 Agent 系统时这种理解很快就不够用了。一个长期可用的 Agent不只是“会回答问题”。它需要知道自己是谁用户是谁当前在哪个项目里能用哪些工具应该遵守哪些项目规则过去学到了什么以及哪些经验应该沉淀到未来。Hermes Agent 的系统提示词设计正好体现了这一点。它的 system prompt 不是单个静态文本文件而是一个运行时组装出来的上下文结构。它把人格、记忆、用户画像、技能、项目规则、工具纪律、平台提示和运行时信息组合起来形成当前会话里的 Agent 身份。这篇文章会拆解 Hermes Agent 的系统提示词是如何构成的以及它背后的 learning loop 如何让 Agent 逐渐积累经验。1. System Prompt 不是静态文本而是运行时组装结果在 Hermes 里系统提示词由AIAgent._build_system_prompt()组装。它大致按下面的顺序拼接1. Agent 身份优先来自 SOUL.md不存在时使用默认身份 2. 工具相关行为指南根据当前可用工具动态注入 3. Nous subscription 相关提示根据当前工具和订阅/环境状态按需加入 4. 工具使用强制规则根据模型、工具和配置按需加入 5. 用户或 gateway 传入的 system message 6. 持久记忆 MEMORY 7. 用户画像 USER PROFILE 8. 外部 memory provider 的系统提示块 9. skills 系统提示和技能索引 10. 项目上下文文件 11. 会话开始时间、Session ID、模型和 provider 12. 特定 provider 的模型身份修正例如 Alibaba provider 13. 环境提示例如 WSL、Termux 等 14. 平台特定提示例如 CLI、Telegram、微信、Slack 等此外还有一类ephemeral_system_prompt。它不会存入 cached system prompt也不会写入 SessionDB而是在每次 API 调用时临时拼到最终 system prompt 后面。这样既能临时影响模型行为又不会破坏稳定的缓存前缀。所以 Hermes 的 system prompt 更像一个“上下文操作系统”。它不是一段 prompt而是一组动态层。不同用户、不同项目、不同平台、不同模型、不同工具集最终生成的 system prompt 都可能不一样。这也解释了为什么现代 Agent 的 prompt 设计不应该只讨论“写一句什么话效果最好”。更重要的是这些信息如何分层、如何注入、什么时候刷新、什么时候缓存、哪些内容允许长期保存。2. 第一层SOUL.md 定义 Agent 的长期人格Hermes 的身份层优先来自~/.hermes/SOUL.md这个文件不是代码里写死的。它是用户可编辑的 Agent 人格文件。在当前版本里SOUL.md的核心思想大概是你不是一个普通聊天机器人而是在形成一个持续存在的工作身份。 你要真正帮上忙而不是用客套话表现得很有帮助。 你可以有判断、有偏好也可以直接指出问题。 在向用户提问前先自己查文件、查上下文、查资料。 用户给了你访问文件、消息和工具的权限你要用能力赢得信任。 涉及外部动作时要谨慎涉及内部探索时要主动。 私人内容必须保持私密。 每次新会话开始时你都要依靠这些文件和记忆恢复连续性。这和传统 assistant prompt 很不一样。传统 prompt 通常会写你是一个有帮助、友好的 AI 助手。Hermes 的方式则是把 Agent 的人格抽成一个可编辑文件。这带来几个好处。第一用户可以直接调整 Agent 的长期风格而不需要改源码。第二人格可以跨会话稳定存在不会因为新对话而丢失。第三它为 Agent 的“自我进化”留下了入口。如果未来用户希望 Agent 改变沟通方式、边界或行为习惯这些都可以落到可持久化的文件里。如果SOUL.md不存在Hermes 才会回退到源码里的默认身份提示。这说明一个设计原则Agent 的人格不应该只能写死在代码中。它应该是可配置、可迁移、可演化的。3. 第二层工具相关行为指南按能力动态注入Hermes 不会无条件注入所有工具相关规则。它会根据当前可用工具决定是否加入某些行为指南。例如如果 memory 工具可用就加入“如何保存长期记忆”的规则。 如果 session_search 工具可用就加入“如何回忆历史会话”的规则。 如果 skill_manage 工具可用就加入“如何保存和更新技能”的规则。这是一点很重要的工程细节。很多 Agent 系统会在 prompt 里写你可以使用浏览器搜索。 你可以写入记忆。 你可以调用某某工具。但实际运行时这些工具未必可用。工具可能被用户禁用也可能缺 API key也可能在某个平台不支持。如果 prompt 里长期提到不可用工具模型就容易幻觉调用不存在的工具。Hermes 的做法更稳健工具存在才注入对应规则。这让 prompt 和工具系统保持一致。在当前 Hermes prompt 里memory、session_search、skill_manage 都可用所以系统会提示 Agent你拥有跨会话的持久记忆。 只保存未来仍然重要的稳定事实比如用户偏好、环境细节、工具使用习惯和长期约定。 不要把临时任务进度、一次性 TODO 或完成日志写入长期记忆。 当用户提到过去对话或者你怀疑历史会话里有相关信息时先用 session_search 查找。 完成复杂任务、修复棘手错误或发现可复用流程后用 skill_manage 保存成技能。 如果已有技能过时、不完整或错误要主动修补它。这说明 Hermes 不只是给模型一组工具而是同时告诉模型这些工具应该在什么语境下使用。4. 第三层Memory 和 User Profile 让 Agent 不再每次从零开始Hermes 的系统提示词会动态注入两类长期信息MEMORY USER PROFILEMemory 更像 Agent 的个人笔记用来保存长期稳定事实。例如用户偏好 环境细节 工具使用惯例 稳定约定 反复出现的问题 能减少未来重复解释的信息User Profile 则更偏向“用户是谁”。例如用户叫什么 用户所在时区 用户关心什么项目 用户喜欢什么沟通方式 用户不喜欢什么行为这两个东西的区别很关键。Memory 记录事实和经验。User Profile 记录用户画像。但 Hermes 也明确要求不是所有内容都应该保存到 memory。比如下面这些就不适合进入长期记忆临时任务进度 已完成工作的流水账 一次性 TODO 本轮会话中的短期状态原因很简单memory 会进入新会话首次构建的 system prompt 快照。如果把所有短期内容都塞进去prompt 会越来越脏成本越来越高模型也会被无关历史干扰。需要注意的是memory 并不是在同一会话里每一轮都实时重新注入。Hermes 会在会话开始时构建 system prompt并在同一会话内复用这个 prompt 快照。继续旧会话时也会优先复用 SessionDB 中保存的旧 system prompt以保持 prompt cache 稳定。Hermes 更合理的划分是长期偏好进入 memory 用户身份信息进入 user profile 历史对话细节通过 session_search 查询 可复用流程沉淀为 skill这是一套比较清晰的长期上下文治理策略。它把“记住用户”从一个模糊能力拆成了不同类型的信息管理。5. 第四层Skills 把经验沉淀成可复用能力Hermes 的 skills 系统是它最重要的设计之一。系统提示词中会动态注入当前可用技能列表例如GitHub 工作流 系统化调试 测试驱动开发 MCP 使用 macOS 自动化 文档处理 YouTube 内容提取 代码审查 多 Agent 协作这不是简单的工具列表。Skill 更像是“可复用工作流”。一个 skill 里可以写什么时候应该使用这个技能 使用前需要检查什么 应该调用哪些命令 常见坑点是什么 用户偏好的做法是什么 完成后如何验证Hermes 的系统提示词会明确要求回复前先检查可用技能列表。 只要某个技能和当前任务相关哪怕只是部分相关也应该先加载该技能。 加载后按照技能中的步骤执行。 如果技能内容有问题要主动修补。 如果本次任务形成了新的可复用经验要考虑保存为技能。这带来一个非常实际的好处Agent 不需要每次都重新摸索。如果过去已经沉淀过“如何在这个项目里做代码审查”下一次就应该直接加载对应 skill而不是从通用经验重新开始。更进一步如果 Agent 在使用某个 skill 时发现它已经过时、不完整或错误系统提示词会要求它立即 patch。也就是说skills 不是静态文档而是一套可维护的过程记忆。这就是 Hermes 自我进化机制的第二个基础memory 记录长期事实 skills 记录可复用方法6. Learning Loop后台复盘如何让 Agent 自我进化Hermes 的自我进化不是模型参数训练也不是神秘的“自我意识”。它更像一个后台复盘系统。当 memory 或 skill 的复盘阈值被触发时Hermes 会在主回复完成后后台 fork 一个临时 Agent让它回顾刚才的对话判断是否有内容值得保存到 memory或者是否应该创建/更新 skill。这个过程不会阻塞主回复也不会把普通对话回复发给用户。SkillsMemory后台 Review AgentSessionDB主 Agent用户SkillsMemory后台 Review AgentSessionDB主 Agent用户alt[达到 memory / skill 复盘阈值][没达到阈值或无价值内容]发起任务调用工具并完成任务返回主回复保存会话历史fork 临时 Agent 并传入对话快照判断是否有长期价值写入用户偏好或长期事实创建或更新可复用工作流可选返回简短保存结果跳过在源码里这个机制叫Background memory/skill review它有三类 review prompt。6.1 Memory Review Prompt当 Hermes 判断可能需要更新 memory 时后台 Agent 会收到这样的指令回顾上面的对话判断是否有适合保存到长期记忆中的内容。 重点关注两类信息 第一用户是否透露了关于自己的稳定信息比如性格、愿望、偏好或值得以后记住的个人细节。 第二用户是否表达了对你行为方式的期待比如希望你如何工作、如何沟通、采用什么工作风格。 如果发现有价值的信息就使用 memory 工具保存。 如果没有值得保存的内容就回答“Nothing to save.”并停止。这段 prompt 的目的不是总结对话而是筛选长期有价值的信息。它关注的问题包括用户是否透露了偏好 用户是否表达了希望 Agent 如何工作 用户是否给出了稳定的个人信息 用户是否反复纠正了某种行为如果有后台 Agent 就会用 memory 工具保存。如果没有它就只说Nothing to save.然后停止。这很重要。一个好的 memory 系统不应该什么都记。它应该有过滤器。6.2 Skill Review Prompt如果一次任务中出现了可复用方法Hermes 会考虑保存或更新 skill。后台 Agent 会收到这样的指令回顾上面的对话判断是否应该保存一个新技能或者更新已有技能。 重点关注这次任务是否使用了非平凡的方法是否经历了试错是否因为过程中发现的新情况而改变策略用户是否期待另一种方法或结果 如果已经存在相关技能就把这次学到的内容更新进去。 如果没有相关技能但这个方法未来可以复用就创建一个新技能。 如果没有值得保存的内容就回答“Nothing to save.”并停止。这段 prompt 关注的不是用户是谁而是“这次解决问题的方法是否值得复用”。例如某个项目的启动流程 某个服务的排错路径 某个 API 的正确调用方式 某个测试失败的修复经验 某个工具的坑点 用户偏好的代码提交流程如果这些经验未来还能用就应该进入 skill。如果已有相关 skill则更新它。如果没有则创建新 skill。这就是 Agent 的过程性学习。6.3 Combined Review Prompt有些对话同时包含用户偏好和可复用流程。这时 Hermes 会让后台 Agent 同时检查 memory 和 skill回顾上面的对话同时考虑两件事。 第一是否有值得保存到 memory 的信息 用户是否透露了关于自己的稳定信息 用户是否表达了对你行为方式、工作风格或沟通方式的期待 如果有就使用 memory 工具保存。 第二是否有值得保存为 skill 的方法 本次任务是否使用了非平凡方法 是否经历了试错 是否根据实践发现改变了方向 用户是否期待不同的方法或结果 如果已有相关技能就更新它。 如果没有相关技能但方法可复用就创建一个新技能。 只有在确实有内容值得保存时才行动。 如果没有明显值得保存的内容就回答“Nothing to save.”并停止。这里最重要的是最后这条约束只有在确实有内容值得保存时才行动。这说明 Hermes 的 learning loop 不是无脑记录。它强调真正有长期价值才保存。 没有价值就停止。这避免了长期记忆污染。7. Learning Loop 是异步后台机制Hermes 的 learning loop 默认不会干扰主任务。它的触发方式大致是memory review 默认每 10 个用户 turn 触发一次 skill review 默认每 10 次工具调用迭代后触发一次 review 在主回复完成之后运行 后台 review agent 最多运行 8 次迭代 review agent 静默执行不产生普通对话回复 它直接使用 memory 和 skill_manage 工具写入结果 它不会修改主对话历史更精确地说memory review 的触发需要同时满足memory.nudge_interval 0 当前工具集中包含 memory 内置 memory store 已启用并加载 用户 turn 计数达到阈值默认是 10skill review 的触发需要同时满足skills.creation_nudge_interval 0 当前工具集中包含 skill_manage 工具调用迭代计数达到阈值默认是 10后台 review agent 不会输出普通对话回复。但如果它确实成功创建或更新了 memory / skillHermes 可能会显示一条很短的保存结果提示例如 memory 已更新或 skill 已创建。这说明 Hermes 把“完成任务”和“沉淀经验”拆开了。主 Agent 负责当下任务。后台 review Agent 负责复盘和保存经验。这是一种很好的架构分离。如果把学习动作放进主对话可能会干扰用户任务。用户只是想让 Agent 修一个 bug结果 Agent 花半天讨论要不要写 memory就很糟糕。Hermes 的做法是先把用户任务完成。 达到阈值后后台异步复盘。 有价值就保存。 没价值就跳过。这更符合真实产品体验。8. Pre-reset Flush会话清空前的最后一次整理除了周期性 learning loopHermes 在 gateway 会话即将因为空闲或每日重置而清空时还会触发一次 pre-reset flush。这个机制会让临时 Agent 执行这样的任务当前会话即将因为长时间不活跃或定时重置而自动清空。 这一轮之后对话上下文会被清除。 请回顾上面的对话并完成以下检查 1. 如果其中有未来会话仍然有用的重要事实、用户偏好或决定请保存到 memory 或 user profile。 2. 如果你发现了可复用工作流或者解决了一个非平凡问题请考虑保存为 skill。 3. 如果没有值得保存的内容可以直接跳过。 不要回复用户。 只在需要时使用 memory 和 skill_manage 工具然后停止。这相当于会话上下文清空前的一次“临终整理”。它解决的问题是gateway 场景下用户可能在 Telegram、微信、Slack 等平台里进行长时间对话。如果会话因为空闲或定时重置被清空里面可能有一些有价值的信息还没来得及沉淀。Pre-reset flush 就是在上下文丢失前最后检查一次有没有用户偏好需要记 有没有重要决定需要记 有没有可复用流程应该保存成 skill为了避免旧会话覆盖新记忆flush 前还会读取当前 live memory 状态也就是MEMORY.md和USER.md。临时 Agent 会被明确要求不要覆盖或删除已有 memory除非当前对话确实证明旧内容已经被取代只添加尚未被记录的新信息。这进一步增强了 Hermes 的长期连续性同时降低多会话、cron job 或用户手动更新 memory 后被旧上下文覆盖的风险。9. Project Context让 Agent 自动遵守当前项目规则Hermes 还会根据当前工作目录自动加载项目上下文。优先级是1. .hermes.md / HERMES.md从当前目录向上查找到 git root 2. AGENTS.md / agents.md只查当前工作目录 3. CLAUDE.md / claude.md只查当前工作目录 4. .cursorrules / .cursor/rules/*.mdc只查当前工作目录注意这里是“first found wins”只加载第一个命中的项目上下文类型不会把所有类型全部叠加进去。在当前项目中命中的是/Users/mac/Documents/hermes-agent/AGENTS.md这类项目上下文会告诉 Agent项目结构是什么 运行 Python 前必须激活 venv 如何新增工具 如何新增 slash command 如何处理 profile-safe 路径 不要硬编码 ~/.hermes 测试应该怎么跑 已知坑点是什么这对 coding agent 非常重要。因为每个项目都有自己的工程约定。没有项目上下文的 Agent很容易犯低级错误忘记激活虚拟环境 跑错测试命令 硬编码用户目录 忽略项目已有架构 修改不该修改的文件自动加载AGENTS.md这类文件相当于让 Agent 每次进入项目时先阅读项目手册。这也是为什么现在很多 Agent 工程都会支持类似文件AGENTS.md CLAUDE.md .cursor/rules .cursorrules它们本质上都是项目级系统提示词。10. 工具执行纪律防止 Agent 只说不做Hermes 的 prompt 中还有一层非常关键的规则工具使用强制要求。核心思想是如果你说要做就必须立刻调用工具做。比如 Agent 不能说我会检查这个文件。然后停在那里。它必须马上调用文件读取或搜索工具。这类约束对 coding agent 尤其重要因为编码任务中最常见的问题不是模型不会写而是模型不够踏实不查文件就猜 不看日志就判断原因 不跑测试就说完成 工具返回空结果就放弃 没有验证就总结所以 Hermes 会对 GPT/Codex 类模型注入更强的执行纪律只要工具能提高正确性、完整性或依据性就使用工具。 如果进一步调用工具能改善结果不要过早停止。 如果工具返回空结果或部分结果先换查询方式或策略重试。 算术、哈希、当前时间、系统状态、文件内容、git diff 等都必须通过工具确认。 缺少上下文时优先用工具查找不要猜测。 最终回复前检查结果是否满足要求、是否有依据、格式是否正确、是否存在副作用风险。这是一种非常实用的 prompt 设计。它不是在教模型“更聪明”而是在约束模型“更像工程师”。11. 为什么系统提示词要缓存Hermes 的系统提示词虽然有很多动态内容但它不是每一轮都重新生成。它会在会话开始时构建一次并保存到 SessionDB 中。继续同一个会话时Hermes 会优先复用已经保存的 system prompt。原因是 prompt cache。如果系统提示词每一轮都变化比如当前时间每轮更新 memory 每轮重新读取 skills 列表顺序变化 项目上下文重新扫描 provider 信息变化那么模型的前缀缓存就会失效。这会带来两个问题成本上升 延迟增加所以 Hermes 的策略是新会话构建一次系统提示词 同一会话复用已保存的 system prompt 继续旧会话优先从 SessionDB 读取旧 system prompt 上下文压缩等特殊情况才重建 ephemeral_system_prompt只在 API 调用时临时拼接不写入缓存快照这说明“动态注入”并不等于“每轮都动态变化”。更准确地说系统提示词在会话创建时动态生成。 生成后在同一会话内保持稳定。这是一个非常重要的工程取舍。它既允许不同会话拥有不同上下文又保证单个会话内 prompt cache 稳定。12. 这个设计对 Agent 开发有什么启发Hermes 的系统提示词设计有几个值得借鉴的点。第一system prompt 应该分层而不是堆成一整段。人格、工具规则、记忆、技能、项目上下文、平台提示、模型特定约束都应该是独立层。这样才方便维护、调试和扩展。第二动态内容应该有清晰来源。例如SOUL.md 来自用户可编辑文件 Memory 来自持久记忆 Skills 来自技能索引 Project Context 来自当前项目文件 Model/Provider 来自运行时配置只有来源清晰才能解释 Agent 为什么这样行为。第三prompt 要和工具系统联动。不要在 prompt 里要求模型调用不存在的工具。当前启用了什么工具就注入什么行为规则。第四长期记忆要克制。不是所有历史都应该进入 memory。否则长期上下文会被污染。更合理的分工是长期偏好进 memory 用户画像进 user profile 可复用流程进 skill 历史细节进 session search 临时状态不保存第五自我进化应该落到外部状态上。Hermes 的“学习”不是更新模型参数而是维护外部知识结构memory user profile skills project context session database这反而更可控、更可解释也更容易调试。第六learning loop 应该后台运行。用户要的是任务结果不是看 Agent 自我反思。后台异步复盘可以把体验和学习解耦。第七缓存不是优化细节而是 Agent 架构的一部分。当 system prompt 包含 memory、skills、项目上下文这些动态内容时如果不控制刷新时机成本和延迟都会变得不可控。Hermes 选择“新会话动态生成同一会话稳定复用”这是一个很实用的工程取舍。13. 总结Hermes Agent 的系统提示词不是一句“你是一个有帮助的助手”。它更像一个动态上下文架构。它由多个层级组成SOUL.md 定义人格 Memory 保存长期事实 User Profile 记录用户画像 Skills 保存可复用流程 Learning Loop 后台沉淀经验 Project Context 注入项目规则 Tool Discipline 约束执行方式 Prompt Cache 保持会话稳定这套设计的关键不在于某一句 prompt 写得多漂亮而在于它把 Agent 的长期行为拆成了可维护的系统。Hermes 的自我进化也不是神秘能力。它实际做的是从对话中提取值得长期保存的信息 把用户偏好写入 memory 把可复用流程写入 skill 在未来新会话中重新注入这些内容 必要时通过 session_search 找回历史细节这是一种非常工程化的 Agent 学习方式。它不会改变模型本身但会改变模型每次运行时看到的上下文。而对 Agent 来说上下文就是能力的一部分。所以如果要构建一个长期可用的 Agent问题不只是“prompt 怎么写”而是哪些信息应该长期保存 哪些经验应该沉淀成技能 哪些上下文应该自动加载 哪些规则应该按工具和平台动态注入 什么时候该学习 什么时候该保持沉默 什么时候该缓存Hermes 给出的答案是把 system prompt 当成架构而不是文案。