Hermes Agent 架构拆解:记忆、Skills 与执行经验如何形成学习闭环

从 Agent Loop、会话压缩、持久记忆、Skill 生成、execute_code、委派与安全边界出发,拆解 Nous Research Hermes Agent 所谓“自改进”究竟如何发生,以及怎样把它用成一个可验证的长期执行系统。

本文使用humanizerdocumd-visuals

一个 Agent 完成过一次复杂任务,并不等于它学会了这件事。多数系统会把成功过程留在越来越长的聊天记录里。会话关闭后,记录很难参与下一次决策;即使记录还在,模型也不一定能从几十轮工具输出里抽出可复用的方法。

Nous Research 把 Hermes Agent 描述为 self-improving agent。这里的“改进”主要不发生在模型权重上。Hermes 保存长期记忆和历史会话,让模型能回找旧经验;它也可以把反复使用的过程整理成 Agent Skill,等到相似任务出现时再按需加载。真正变化的是模型外围的知识、程序与运行状态。

这篇文章不把“自改进”当口号。我们会沿一条真实运行链拆开它:用户消息如何进入 Agent Loop,工具怎样执行,长对话如何压缩,哪些信息可以进入下一次会话,Skill 如何成为可复用程序,子 Agent 又如何隔离上下文。最后用一个仓库发布任务把这些机制串起来,并给出一套能实际检查的配置与验收方法。

Hermes Agent 从交互入口到执行、记忆与技能层的整体架构

一、Hermes 解决的不是“再多一个聊天客户端”

只看交互界面,Hermes 很容易被理解成能在终端或 Telegram 里调用工具的聊天机器人。这个描述没有错,却漏掉了最重要的设计目标:把任务执行产生的经验带到未来的任务里,而且避免把所有历史永久塞进上下文。

一个长期使用的 Agent 至少要处理四种时间尺度。当前一轮要决定下一次工具调用;当前任务要维护计划、输出和错误;跨会话要保留用户偏好与已经验证的事实;跨任务还要沉淀可复用操作。普通聊天记录主要覆盖前两种,Hermes 的 session、memory、skills 和定时任务分别承担了更长周期的状态。

这也解释了它与通用编排框架的差别。开发者当然可以用模型 SDK、数据库和工具注册表自行搭建同样的能力。Hermes 提供的是一套已经连起来的个人 Agent Harness:统一的 Agent Loop、终端后端、消息 Gateway、持久会话、记忆、Skill 管理、委派和安全开关。使用者面对的核心问题从“怎样把这些组件接上”变成“哪些能力应该开放,以及什么经验值得保存”。

“个人 Agent”不表示只能做个人事务。它表示系统默认围绕一个持续存在的工作主体组织状态:有自己的用户画像、长期记忆、技能目录、凭证与会话历史。若要服务多个互不信任的人,就要额外拆分 profile、凭证、执行环境和入口权限,不能让一份个人配置自然升级成公共多租户服务。

二、先把自改进拆成三条不同的回路

Hermes 的学习闭环包含三条速度不同的路径。

第一条是当前任务内的反馈回路。模型调用工具,读取结果,再调整下一步。命令报错、网页为空、测试失败,都会在同一会话里成为新证据。这属于 Agent 的常规执行能力,不会自动跨任务保留。

第二条是跨会话记忆。模型把稳定事实或偏好写入 MEMORY.md、USER.md,也可以通过 session search 找回旧会话。下一次新会话启动时,记忆快照进入初始上下文,于是行为发生变化。这是一种轻量学习:更新速度快,表达能力有限,也容易受错误记忆影响。

第三条是 Skill 演化。一个需要多步工具、固定检查和明确输出格式的做法,可以被写成 SKILL.md,必要时再配脚本和参考材料。Skill 不必常驻上下文,只有被任务描述或斜杠命令命中才加载。它的改动影响范围更大,适合低频、可审查地更新。

三者不能混成一团。一次失败后的临时修正不应该马上写入长期记忆;一句用户偏好也不值得扩成 Skill;未经回放验证的 Skill 更不能因为“成功过一次”就覆盖旧版本。可靠的自改进需要把候选经验、持久状态和已发布程序分开。

回路 保存对象 典型生命周期 适合保存什么 主要风险
当前任务 对话与工具结果 几分钟到几小时 当前计划、错误、临时路径 Context 膨胀、任务漂移
长期记忆 MEMORY.md、USER.md、会话索引 多个会话 稳定偏好、已验证事实、经验索引 事实过期、错误固化
Skills ~/.hermes/skills/ 下的程序与说明 多个任务与版本 可复现流程、检查清单、脚本 权限扩大、流程陈旧

Hermes 所谓的闭环,可以更准确地写成:执行留下轨迹,轨迹产生候选经验,候选经过选择后进入记忆或 Skill,新会话再读取这些资产。这里没有神秘的“Agent 自己变聪明”,只有外部状态被更新,以及后续 Prompt 和工具集合因此变化。

三、运行时骨架:AIAgent 外面是入口,里面是循环

官方的开发者文档把 run_agent.py 中的 AIAgent 描述为门面,主要循环位于 agent/conversation_loop.py,每轮的细节进一步拆进 agent/turn_*.py。这组文件名很能说明架构:入口负责装配,循环负责生命周期,单轮模块负责模型调用和工具结果。

一次典型运行可以抽象为下面的状态机:

加载 profile、配置、模型与工具
  → 建立或恢复 session
  → 构造 system prompt、记忆快照与对话历史
  → 调用模型
  → 有工具请求:校验并执行,再把结果送回模型
  → 无工具请求:形成面向用户的回复
  → 保存消息、用量与 session 状态
  → 必要时刷新记忆、压缩上下文或触发后台动作

这个循环看起来和其他工具调用 Agent 相似,差别在外围约束。Hermes 要支持 CLI、消息 Gateway、远程终端、MCP、子 Agent 和不同模型提供商,同一个循环不能把某个交互面或执行环境写死。工具注册、Prompt 构造、上下文压缩、持久化和模型适配因此被拆成单独组件。

门面模式还有一个实际价值:CLI 的一次交互、Gateway 收到的一条消息和子 Agent 的一次委派,都能复用相同运行时,同时传入不同 profile、工具集与会话策略。若把这些入口各自实现一套循环,错误处理和权限检查很快就会分叉。

观察 Hermes 时应该分清“模型正在想什么”和“运行时已经确认什么”。模型可以说自己保存了记忆,运行时只有看到 memory 工具调用才会真正写盘;模型可以说任务完成,session 存储只会忠实记录这段文字,不会替外部系统验证结果。AIAgent 把能力接起来,并没有消除模型自述与客观状态之间的差距。

四、Prompt 不是一段固定文字,而是一次运行的装配结果

Hermes 的 Prompt Builder 会把运行所需的不同来源合并起来:基础身份与行为约束、可用工具、profile 记忆、当前会话、可能命中的 Skills、项目上下文以及用户本轮消息。把它们都称为 Prompt 容易忽略来源和生命周期差异。

工具定义会随 toolset、平台和配置变化。记忆通常在会话开始时冻结。Skill 按任务需要加载。会话历史随每轮增长。项目文件则来自当前工作目录。它们若全部当成永久系统提示,不但浪费窗口,还会让旧规则和新事实难以区分。

所以 Context Engineering 的重点不是让上下文“尽可能完整”,而是让每条信息在正确时间出现。稳定的用户偏好适合常驻短记忆;一份几千字的部署手册适合按需 Skill;一次构建的完整日志适合落盘后只返回关键错误;昨天的排障过程适合通过 session search 查找,而不是每天随启动注入。

Prompt 缓存能降低重复前缀的开销,但它不会改变信息选择的正确性。若前缀里混入频繁变化的时间、随机值或无关历史,缓存命中和注意力都会受到影响。稳定区放前面、动态区放后面,是成本优化,也是可解释性优化:当行为发生变化时,能追到究竟是哪一层 Context 变了。

五、长对话如何压缩:保存任务状态,不是摘要文学

长任务早晚会接近模型窗口。Hermes 在调用前做压缩预检,官方文档给出的触发参考是超过模型窗口约 50%;Gateway 场景还会在更高水位自动压缩,文档标注约 85%。这些数值是当前实现策略,不应该当作跨版本契约,真正重要的是压缩发生在下一次模型调用前,并且会持久化新的 session 血缘。

它的压缩思路是保留最近若干条消息,概括更早的中段,同时保持工具调用和工具结果成对。默认保留最近 20 条这一类策略,目的不是复述整段聊天,而是让 Agent 继续工作:任务目标、已经完成的动作、关键决策、未解决错误和下一步必须留下。

工具配对很关键。若保留“命令失败”的结果,却删掉对应命令,模型不知道什么失败;只留下工具调用,没有结果,则可能误以为动作尚未执行。压缩器必须理解消息协议,而不是对文本做任意截断。

压缩前还会给记忆一次写入机会。因为即将被摘要的内容可能包含跨会话值得保留的事实,先做 memory flush 能减少信息随着历史收缩而丢失。不过“给机会”不代表保证写入,模型仍然要正确判断并调用工具。高价值事实若只依靠模型主动记忆,需要在验收里检查实际文件,而不能听它口头承诺。

一次好压缩至少能回答五个问题:原始目标是什么;完成了哪些可验证动作;当前工作区是什么状态;哪些尝试失败以及原因;恢复后下一步是什么。会议式摘要可能读起来流畅,却经常漏掉命令、路径、错误和待办。Agent 压缩首先是一份恢复检查点。

六、记忆快照的反直觉之处:写入后通常要到下一会话才生效

Hermes 的记忆文档强调了一个容易误解的语义:会话开始时读取记忆快照,本会话中的写入通常在下一个会话才作为启动记忆生效。这种冻结让同一会话的 Context 更稳定,也意味着写完 MEMORY.md 后不能假设模型在当前轮已经重新读取了它。

于是会话边界不只是聊天整理动作,也是学习闭环的一部分。如果 Gateway 中的会话连续运行几周,Agent 一直依赖当前历史,就很少经历“忘记、重新启动、从记忆和检索恢复”的过程。长期记忆是否足够、session search 能否找回旧证据,都得不到检验。

USER.md 更适合用户画像和稳定偏好,MEMORY.md 更适合 Agent 应长期保留的事实、约束与经验。官方文档提到有限的字符预算,这个限制传达了正确方向:常驻记忆应短小、密集、可维护。把大段日志、完整教程和临时错误都写进去,会持续收取 Context 成本,并让真正重要的约束被稀释。

一条适合进入长期记忆的记录应包含事实、适用范围和必要来源。例如“该仓库发布前运行 pnpm build”比“记得做测试”更可执行;“用户要求所有文章完成后直接推送,适用于 personal-blog”比“用户喜欢自动化”更少误伤其他场景。带时间性的事实还应写明日期或失效条件。

记忆工具支持 add、replace、remove,说明记忆并非只追加的日记。旧规则必须能被替换,错误必须能被删除。若只会加不会减,任何个人 Agent 最终都会背着一份相互矛盾的历史包袱运行。

七、Session Search 是长尾记忆,不等于把聊天记录重新塞回来

短记忆容量有限,更多细节留在 SQLite 会话历史中。Hermes 使用 FTS5 做全文检索,让 Agent 能按关键词回找旧任务。这条路径承担的是“我记得以前处理过,但细节不在常驻记忆里”。

检索结果仍然需要判断。旧会话中的命令可能已经过期,当时的结论也可能只适用于某个分支或环境。Session search 提供证据入口,不负责把历史陈述升级成当前事实。模型应该先找到相关会话,再回到当前文件、配置或远端状态验证。

搜索词也会影响召回。若旧会话只写“修好了”,未来很难找到;若保存了仓库名、组件名、错误码和最终做法,检索价值会高很多。这说明可检索性应该进入 session 记录和压缩摘要的设计。好的任务收尾不是多写一句感想,而是留下稳定实体和可区分的结果。

长期知识可以采用三层结构:MEMORY.md 保存高频路由信息,session search 保存带上下文的历史证据,Skill 保存已经整理和验证的程序。查询先从短记忆得到方向,需要细节时搜会话,确认可复用后再提升为 Skill。这样既控制常驻成本,也避免每次从零摸索。

八、Skills 把经验从“我记得”提升到“我会按步骤做”

Hermes 的 Skills 与 Agent Skills 开放格式兼容,以 SKILL.md 为入口,并允许附带脚本、引用和资源。系统启动时只需知道名称与描述,任务命中后读取主文件,遇到特定步骤再打开参考材料。这种渐进披露解决了技能数量和上下文成本之间的冲突。

记忆和 Skill 的分界可以用一个问题判断:这条内容是在提醒 Agent 一个事实,还是在教它完成一个过程?“仓库使用 pnpm”是记忆;“发布前检查版本、运行构建、验证产物、提交并推送”的完整流程是 Skill。前者短小且总有用,后者更长,只在相关任务出现时有用。

Hermes 支持通过 /learn 从当前过程、文件或文档生成 Skill,也允许 skill_manage 创建、更新和删除技能。方便之处很明显:刚成功完成一项陌生工作,就能把步骤整理出来。风险也同样明显:一次偶然成功可能依赖隐藏状态,自动生成的脚本可能过度授权,描述写得太宽还会让 Skill 在无关任务中触发。

因此 Skill 的发布至少要经过四项检查:触发范围是否明确;步骤在干净环境能否复现;写操作和凭证需求是否声明;失败后怎样停下和回滚。Hermes 提供 write approval,可以把后台产生的修改先暂存,等人工审核后生效。这道门尤其适合 Skill,因为一条错误记忆影响几轮回答,一项错误技能可能重复执行真实动作。

官方 lint 对超长主文件、引用资料过度分散等问题给出提示,本质是在守住渐进披露。主文件应该包含完成任务所需的主干,细节按条件跳转;如果读一个 Skill 要追几十个文件,模型会丢失路径,也很难判断哪些引用仍然有效。

九、Skill 真正的质量单位是可复现任务,不是文档字数

评审 Skill 时,最好用任务回放代替文本审美。准备三个或更多代表性输入,在全新会话和干净工作区运行,记录调用了哪些工具、是否越界、结果是否满足验收。再准备几个相似但不应该触发该 Skill 的反例,检查描述是否过宽。

一个发布流程 Skill 可以包含:适用仓库、版本来源、必须通过的检查、产物位置、提交格式、推送前的状态核对和失败退出条件。它不需要解释 Git 的全部历史,也不该把某次发布的具体 commit 写成永久步骤。稳定程序与实例数据要分离。

脚本比自然语言更适合确定性检查,但脚本本身也要可审计。它应明确输入输出,避免暗中读取整个环境,失败时返回可行动的错误。若脚本执行远端写入,应支持 dry-run、幂等键或状态查询,不能把一句“不要重复”留给模型记忆。

版本管理也不可少。每次 Skill 更新应保留变更原因、触发它的失败样本和回归结果。若新版本退化,能够回滚到上一个已知可用版本。没有版本与评测,所谓持续改进很容易退化成持续漂移。

十、execute_code:把多次工具推理压进一个受控程序

Hermes 的 execute_code 不是普通 shell 的别名。模型生成 Python 脚本,脚本通过 hermes_tools 调用已经注册的 Agent 工具。它在子进程运行,并通过 Unix socket 与主进程做 RPC;Windows 使用回环 TCP,远程后端采用文件式 RPC。只有脚本显式 print() 的内容进入模型上下文,中间工具输出可以留在程序里处理。

这对三类任务特别有用:连续调用三个以上工具;需要过滤、聚合或循环;原始输出很大但最终只需少量结论。例如搜索一百个文件、读取命中片段、统计错误类型,如果每一步都回到模型,会产生大量 Token 和推理往返。用 Python 在工具层处理,只打印前十个高置信结果,上下文更干净。

Hermes execute_code 的子进程、RPC 与工具注册表数据流

边界也很清楚。终端适合构建、进程管理和原生 shell;execute_code 适合在多个 Agent 工具之间编排逻辑。它不是把任意 Python 当成可信代码,更不应该递归调用自身。官方白名单排除了 execute_code、delegate_task 和 MCP 等高风险或递归能力,并设置运行时、输出大小和工具调用数限制。

默认限制包括约 300 秒超时、50KB 标准输出、10KB 标准错误和 50 次工具调用。具体值可以变化,工程含义不会变:模型生成的程序必须被当作不可信工作负载,限制时间、输出和扇出。否则一个循环错误就可能占满进程,或把海量结果重新灌回 Context。

环境变量过滤同样重要。Hermes 曾收紧宽泛前缀,只保留确切需要的运行变量,原因很直接:同一前缀下可能混有密钥。安全设计不能依赖变量名“看起来像系统配置”,应该采用明确允许列表,并让脚本通过受控工具获取必要能力。

十一、七种终端后端代表七种不同的信任假设

Hermes 可以把终端放在本机、Docker、SSH、Daytona、Singularity、Modal 或 Vercel Sandbox。它们不只是部署选项,也定义了 Agent 能看到什么以及一次失误会影响哪里。

本地后端体验最直接,能访问当前文件、进程和凭证,爆炸半径也最大。Docker 适合隔离文件系统和依赖,但挂载宿主目录、Docker socket 或敏感环境后,隔离会被显著削弱。SSH 把执行面移到另一台机器,适合专用工作节点;云沙箱适合临时任务和弹性资源,但要处理网络、产物回传、冷启动和凭证注入。

后端选择应从资产开始,而不是从方便开始。只读研究任务不需要宿主写权限;构建陌生仓库适合临时容器;操作家庭自动化设备需要网络访问,却未必需要读取源码目录;生产运维则应使用单独账号、命令白名单和审批。

官方安全指南建议在更高风险场景把 Gateway 和执行器拆开,例如 Gateway 留在承接消息的节点,工具通过 SSH 进入独立工作机。这样即使执行进程被诱导读取文件或启动服务,也不必与消息凭证和主机控制面共享同一个安全域。

“运行在容器里”也不是完整结论。要继续问:容器挂载了什么,使用哪个用户,能否联网,资源是否受限,凭证如何注入,产物怎样回收。隔离的强度由最宽的出口决定。

十二、委派不是复制聊天,而是压缩并行工作的接口

Hermes 的 delegate_task 会创建新的 AIAgent 实例。子 Agent 有独立对话和终端,可以继承工具访问,但默认只接收目标与显式上下文;完成后只把最终摘要返回父 Agent。项目上下文文件可以继承,SOUL.md 这类人格文件会被排除。

这种隔离解决了主上下文污染。让子 Agent 阅读十个实现文件、试错五次,父 Agent 不需要吞下所有中间输出,只接收结论、证据和未解决项。它也带来信息损失:目标描述不完整时,子 Agent 会在错误假设上工作;最终摘要若没有文件路径和验证结果,父 Agent 很难复核。

一个好的委派契约应写清任务边界、允许修改的资源、所需证据和返回格式。例如:

目标:定位支付回调重复入账原因,只做诊断。
范围:services/payment 与相关测试;不得修改文件或调用生产接口。
返回:根因、证据路径与行号、排除过的假设、建议的最小修复。
完成条件:至少用一条测试或日志链证明重复路径。

子 Agent 没有默认墙钟超时,主要受迭代预算与心跳监测约束。文档区分了轮次间长时间无响应和工具执行中的长时间无响应,这比粗暴的统一超时更合理:一次构建可以很久,而模型轮次卡死的信号不同。但外部副作用仍需独立截止时间,不能因为委派还“活着”就无限等待。

委派本身也不是持久任务队列。父进程结束或 session 生命周期变化后,不能假设子任务自动恢复。需要跨进程、跨重启保证的工作应交给 cron、后台终端或专门队列,并为结果建立可查询状态。

十三、Gateway 与 Bot Mode:同一运行时,不同的隔离外壳

Hermes Gateway 把 Agent 接到 Telegram、Discord、Slack 等消息平台,也承接计划任务和异步通知。渠道接入扩大了可用性,也把身份、来源校验和投递结果变成核心问题。CLI 中只有本机用户,消息入口面对的是网络上的账号、群组和机器人事件。

Bot Mode 本质上是 profile:独立配置、记忆、Skills、凭证与历史目录,而不是一套新的 Agent 内核。这个设计很务实,同一个 Loop 可以服务“私人助手”“代码机器人”“研究机器人”,隔离依靠 profile 和入口规则完成。

隔离不能只看目录。若多个 Bot 最终共享本地 shell、同一主目录和同一组云凭证,它们在执行层仍处于同一信任域。真正的高风险隔离需要连同终端后端、环境变量、网络出口和文件挂载一起拆分。

Gateway 的完成语义需要单独核对。一次后台任务成功进入投递队列,只能说明系统接受了交付,不代表消息平台已经把回复送到用户设备。可靠通知应该区分执行完成、投递已受理、平台确认与最终不可达。把 admission 当 delivery,会让任务日志显示成功,而用户什么也没收到。

十四、一个完整案例:让 Hermes 学会发布这个博客

假设第一次让 Hermes 完成“新增一篇技术长文并推送”。仓库有 Astro 构建、文章审计、SVG 规范和 Git 流程,Agent 之前不了解这些约束。

第一步,创建干净 session 并明确验收条件:文章达到站内旗舰标准,引用官方来源,SVG 能被 XML 解析,审计和全站构建通过,最终提交推送。Agent 先读仓库指令和参考文章,建立任务计划。此时信息只服务当前任务,不急着写入长期记忆。

第二步,执行研究和写作。网页搜索读取官方资料,文件工具检查已有内容,终端运行审计与构建。若需要批量统计章节长度,可以用 execute_code 调工具、过滤结果,只把短板清单打印回 Context。构建完整日志落盘,模型只看失败摘要。

第三步,验证结果。检查文章统计、坏链、SVG、构建产物和 Git diff;启动后台开发服务器,真实访问桌面与移动页面。完成条件来自外部证据,不是模型说“已经完成”。若推送超时,先查询远端分支,不直接重试。

第四步,任务结束时整理经验。稳定事实进入记忆,例如仓库路径、发布前必须运行的命令。可复用流程形成候选 Skill:触发条件是新增或大改技术长文,步骤包含研究、写作、图片、审计、构建、渲染检查、提交和推送。某次文章的标题、引用和临时错误不进入 Skill。

第五步,在一个全新 session 回放。给 Hermes 另一篇文章题目,不提醒旧过程,观察它能否从短记忆定位 Skill,按需加载并跑完整验收。再给一个只改错别字的反例,确认不会错误启动旗舰长文全流程。通过回放后再批准 Skill 写入。

Hermes 从任务轨迹到记忆、Skill 候选、审批与新会话回放的学习闭环

这个案例里真正的“学习”发生在第四、第五步。第一次成功只是轨迹;提取、审查、发布和新会话复现,才把轨迹变成系统能力。

十五、最容易踩的六个坑

第一,Agent 说保存了记忆,就相信保存成功。较弱的本地模型尤其可能只用自然语言回应,没有调用 memory 工具。验收要读实际记忆文件或工具日志。

第二,让一个 Gateway 会话永久不结束。历史看似完整,长期记忆和 session recall 却从未经历冷启动检验。应为不同任务建立边界,并定期用新 session 回放核心能力。

第三,自动批准所有 Skill 修改。模型会把一次性绕路、临时路径甚至错误假设固化为流程。后台建议可以自动产生,发布应经过 diff、权限和回归检查。

第四,用 execute_code 规避权限。它只是编排已允许工具的方式,不该成为获得额外工具、环境变量或网络权限的后门。白名单和运行限制必须在运行时执行。

第五,把委派当持久队列。子 Agent 适合隔离上下文和并行研究,不负责跨重启交付。长任务要有独立状态、可恢复执行和通知回执。

第六,只隔离 profile,不隔离执行面。独立记忆避免信息串线,却挡不住宿主文件和共享凭证泄露。面向不同信任等级的 Bot 应使用不同执行后端、账号和网络策略。

十六、怎样判断 Hermes 是否真的在变好

不要用“看起来越来越懂我”作为唯一指标。至少建立一组固定回放任务,覆盖信息查询、文件操作、多工具编排、Skill 命中、记忆恢复和权限拒绝。每次修改 memory、Skill 或工具配置后,用相同输入比较。

结果可以分成五类:任务是否完成;完成是否有外部证据;调用成本和时长;越权或多余动作;新 session 能否恢复。对于 Skill,还要测误触发率和漏触发率。一个让成功率提高、但把普通问答都导入高权限流程的 Skill,不是净改进。

日志需要能关联 session、模型调用、工具 call、子 Agent 和最终交付。敏感参数应脱敏,动作结果要保留状态类别。写操作超时不能笼统记成 failed,而应记作 unknown,随后附上状态核对结果。

记忆也应定期审计:哪些条目从未被使用,哪些已经过期,哪些相互冲突,哪些应该迁移到 Skill。删除无效记忆与增加新记忆同样重要。Context 是有限预算,任何常驻内容都应证明自己值得留下。

最后,把版本固定下来。Hermes 仍在快速迭代,触发阈值、目录和工具集可能变化。生产使用要记录代码或发布版本,升级前跑回放集,避免拿今天的文档解释几个月前的行为。

十七、适用边界:什么时候应该选 Hermes

Hermes 适合希望自己掌控模型、执行环境和长期状态的人。任务横跨终端、网页、消息平台,经常重复,并且愿意维护记忆与 Skills 时,它的一体化闭环很有价值。多种终端后端也让同一套交互可以从本机逐步迁到隔离环境。

若需求只是固定 Workflow,普通任务编排器往往更简单、更可预测。若面对大量互不信任租户,需要严格的数据边界、配额、审计和服务等级,Hermes 的个人 Agent 假设不能直接替代多租户平台设计。若没有时间维护回放和审批,自动生成 Skills 反而可能扩大漂移。

它最值得借鉴的不是某个工具名称,而是三层知识结构和明确的会话边界:短记忆负责路由,历史会话负责证据,Skills 负责程序;当前任务结束后提取候选,在新会话里验证能否恢复。这样,“用过一次”才有机会变成“以后会做”。

十八、分四个阶段上线,比第一天开放所有能力更可靠

第一次安装 Hermes 时,最危险的做法是同时接入私人消息、宿主 shell、浏览器、MCP、云凭证和自动 Skill 写入。系统即使出现异常,也很难判断是模型、入口、权限、记忆还是工具造成的。更稳的路径是按风险逐层开放,并为每一层保留一组验收任务。

第一阶段只使用交互式 CLI 和只读能力。开放网页搜索、受限文件读取与 session 保存,暂时不允许 shell 写操作,也不接消息 Gateway。选择十个日常任务,确认模型提供商、上下文压缩、会话恢复和费用统计正常。这一步建立基线:同一个任务重复三次,结果和成本大致落在什么区间。

第二阶段增加隔离执行。选择 Docker、SSH 或云 Sandbox,在空白测试项目中开放终端和 execute_code。检查工作目录、环境变量、网络出口、运行时间和输出限制;故意运行无限循环、超大输出、读取宿主敏感路径和未允许工具,确认每种尝试都被正确截断或拒绝。只有失败路径被验证,隔离才不只是配置文件里的一行字。

第三阶段开放记忆与 Skills。先把 memory write 设置为审批模式,观察模型想保存什么,建立可接受与不可接受样本。Skill 也先只允许建议或暂存,用干净 session 回放后人工发布。这个阶段应记录记忆命中率、过期条目、Skill 误触发和回放成功率,避免只统计创建了多少资产。

第四阶段才接 Gateway、计划任务和更广的委派。入口使用精确用户 allowlist,Bot 使用独立 profile,高风险执行迁到单独后端。准备一个只能读公开资料的低权限 Bot,先验证身份与投递;随后再让私有 Bot 使用写工具。后台任务必须有执行状态和投递状态,计划任务要能在重启后继续被查询。

每一阶段都应冻结一份有效配置和回放结果。下一阶段出现退化时,先回到上一个配置定位差异,而不是同时调整 Prompt、模型和权限。渐进开放看起来慢,实际减少了后期在混合故障里反复猜测的时间。

十九、为 Memory 和 Skills 建立数据治理

Hermes 保存的不只是技术状态,也可能包含用户习惯、聊天内容、仓库路径、错误日志和服务端返回。把文件留在本机并不自动等于安全,仍要决定什么可以保存、保留多久、谁能读取、怎样删除和如何备份。

可以先给信息分四级。公开信息允许进入 session、记忆和 Skill;内部信息只进入指定 profile 与加密备份;敏感信息可以在当前任务短暂使用,但不得写入长期记忆;密钥和认证材料只能由凭证系统在运行时注入,不进入对话、Skill 或日志。分类规则既要写进操作规范,也要通过环境过滤和工具返回裁剪落实。

记忆写入前要问三个问题:未来任务是否真的需要;内容是否包含可以直接识别个人或系统的细节;是否能用引用替代复制。例如没必要把完整客户邮件写入 MEMORY.md,只需记录“该问题的证据位于受控工单 123,访问前重新授权”。这样既减少泄露面,也避免副本过期。

Skill 审查要额外关注供应链。一个 SKILL.md 可能引用脚本、远端安装命令和外部资料。审核主文件不够,还要固定依赖来源,检查脚本差异,避免运行时下载未经验证的最新版本。来自他人的 Skill 先按不可信代码处理,在无凭证的隔离环境观察它实际访问的文件和网络。

备份也需要分层。session 数据库适合短周期备份,用于恢复轨迹;记忆与 Skills 适合版本控制和更长保留,用于追踪行为变化;凭证应使用独立的密钥备份机制。恢复测试要确认文件权限和 profile 边界没有因为拷贝而放宽。删除请求则要覆盖主文件、历史版本、数据库、构建产物和备份保留策略,明确哪些副本会在何时过期。

每月做一次轻量审计通常已经很有价值:列出最近新增和修改的记忆,找出无来源、无范围或带敏感值的条目;列出 Skill 的依赖与最后回放时间;检查从未使用的资产;抽样确认删除和替换真的生效。一个能学习的系统,也必须能忘记和退役。

二十、给学习闭环配一份最小回归集

回归任务不需要一开始就很大。重要的是固定输入、环境与验收,使 memory、Skill、模型或 Hermes 升级后的变化可比较。下面是一份适合个人代码 Agent 的最小集合:

类型 固定任务 主要验收
会话恢复 中途停止一次三步修改,再从新进程恢复 已完成步骤不重做,下一步和工作区状态一致
冷启动记忆 新 session 询问仓库构建与发布约束 引用正确记忆,不扩展到其他仓库
历史召回 查找一个月前的错误码和处理证据 能定位旧 session,并重新验证当前事实
Skill 命中 新增一篇旗舰文章 读取正确 Skill,执行完整验收
Skill 反例 只改一处错别字 不启动昂贵的完整写作流程
执行隔离 尝试读取未挂载的敏感路径 明确拒绝,不泄露路径内容
输出控制 在一百个文件中汇总三个指标 中间结果不灌入 Context,最终数字可复核
委派契约 让子 Agent 只诊断一个故障 没有修改文件,返回证据和排除项
写入未知 模拟推送超时 查询远端状态,不直接重复推送
投递故障 让消息平台拒绝回复 任务结果保留,交付标记为失败或待重试

每次运行保存 Hermes 版本、模型、配置散列、输入、最终状态、工具轨迹摘要、Token、时长和外部验收。随机模型不要求每次路径完全一样,但关键边界必须稳定:不能越权,不能把未知写成成功,不能在反例里触发高风险 Skill。

分数也不应只看最终成功。一个任务可以成功,却调用了十倍工具、泄露了多余信息或依赖人工补救。建议同时统计任务完成率、可验证证据率、平均成本、重复动作、权限拒绝、未知结果和人工接管次数。对学习资产再增加两个指标:命中后是否改善结果,以及没有命中时是否仍能安全降级。

当新 Skill 在目标任务上提升,却让反例误触发时,先收窄 description;当记忆提高冷启动准确率,却持续带入旧版本事实时,增加日期和失效检查;当升级导致长任务压缩后遗忘验收条件时,把恢复摘要加入断言。这些处置把“感觉退化”变成了具体可修的层。

二十一、排障时按状态链找证据

Hermes 表现异常时,可以按“入口、session、Prompt、模型、工具、外部状态、持久资产”逐层检查。先确认用户消息进入了哪个 profile 和 session;再确认本轮实际装配了哪些记忆、Skill 与工具;随后看模型提出了什么调用、执行器接受了什么、外部系统最终处于什么状态;最后检查有没有把错误结论写入 memory 或 Skill。

这条顺序能避开常见误诊。模型没有遵守某条规则,可能是 Skill 根本没命中;命令读不到文件,可能是远程后端没有挂载工作区;新会话忘记偏好,可能是上次只口头说“已保存”;用户没收到结果,可能是平台交付失败,而任务早已完成。每一种现象的修复位置不同。

排障输出最好保留一份短的事实包:Hermes 与模型版本、profile、session ID、终端后端、有效 toolset、命中的 Skill、最后一次压缩位置、失败 call ID、外部回执和敏感信息已脱敏的错误。它足以复现大多数运行时问题,又不需要导出全部私人对话。

如果问题只在长会话出现,就用相同输入分别在新 session 和旧 session 运行,比较 Prompt 与压缩摘要;只在某个后端出现,就用最小命令比较本地和远程的工作目录、环境与网络;只在 Gateway 出现,就把执行完成和消息交付拆开。控制变量比继续往系统提示里添加“务必正确”更有效。

参考资料