当大多数 AI Agent 还在"干完就忘"时,Hermes 做了一件架构层面的事:它让 Agent 具备了"事后复盘"的能力。本文从源码层面拆解其 Memory、Skill、Nudge Engine 三大子系统,并探讨这套机制在企业场景中的落地思路。
一、问题的本质:为什么 Agent 总是"金鱼记忆"?
当前主流 AI Agent 有一个共同痛点:会话隔离。每次对话结束,Agent 对用户的认知归零:你的代码风格、项目约定、环境怪癖,下次见面全部重来。
更深层的问题是:Agent 不会从失败中学习。今天踩过的坑,明天照踩不误。你纠正过十次的做法,第十一次它依然按老路子来。
这不是模型能力问题,是架构设计问题。大多数 Agent 框架把"记忆"当成一个外挂的向量数据库,只存不整理;把"技能"当成静态的配置文件,只读不写。
Hermes Agent 的核心设计哲学是:Agent 应该像人一样,干完活后主动复盘,把经验沉淀为可复用的资产。
二、总览:三个子系统构成的自进化闭环
Hermes 在内部搭建了一套"学习闭环",由三个子系统协同支撑:
| 子系统 | 职责 | 类比 |
|---|---|---|
| Memory | 记住事实(你是谁、环境什么样) | 助理的随身笔记本 |
| Skills | 记住怎么做(操作流程、踩坑经验) | 助理的操作手册 |
| Nudge Engine | 定时触发复盘 | 提醒助理"回头看看"的闹钟 |
用户的每一次对话,都会同时流入 Memory 和 Skill 两条线;Nudge Engine 则按固定节奏触发后台审查,决定哪些该记、哪些该存、哪些该修。
三、Memory 子系统:在容量限制下做信息压缩
3.1 极简存储:两个文本文件
Hermes 的 Memory 设计非常克制:只有两个纯文本文件,用§分隔条目:
~/.hermes/memories/ ├── MEMORY.md #环境事实、项目约定、工具怪癖 └── USER.md # 用户偏好、沟通风格、工作习惯关键设计:硬性容量上限
MEMORY.md 限制2200 字符
USER.md 限制1375 字符
这个设计看似反直觉,为什么不给更多空间?因为容量有限会倒逼 Agent 做信息压缩。过时的、低价值的记忆自然被挤掉,留下的都是高密度事实。相比之下,纯追加模式的记忆文件用几个月就会膨胀成几万行,检索效率极低。
3.2 超限处理:让模型自己决定取舍
当新增内容超出上限时,Hermes 不会静默丢弃,而是让操作失败,并把当前所有条目返回给模型:
Memory at 1,800/2,200 chars. Adding this entry (500 chars) would exceed the limit. Replace or remove existing entries first.模型收到错误后,会主动调用 replace 或 remove 操作,自己判断哪些过时、哪些可以合并。这本身就是一次"自我反思"。
3.3 冻结快照:省钱的工程智慧
每次会话启动时,Memory 加载后会立即捕获一份快照,之后系统提示词里用的都是这份冻结版本:
def load_from_disk(self): self.memory_entries = self._read_file(...) self.user_entries = self._read_file(...) 会话开始时冻结,之后不再变动 self._system_prompt_snapshot = { "memory": self._render_block(...), "user": self._render_block(...), }为什么冻结而不是实时更新? 因为系统提示词会话内不变,就能共享前缀缓存(Prefix Cache),避免每轮 API 调用重复计费。新写入的内容只改磁盘,下一个会话才刷新,用延迟一致性换成本优化。
3.4 记忆的内容规范
系统提示词中对 Memory 有明确的写入引导:
“Write memories as declarative facts, not instructions to yourself.‘User prefers concise responses’ ✓’Always respond concisely’ ✗”
声明式事实(“用户喜欢简洁回复”)vs 命令式指令(“永远简洁回复”)的区别在于:前者是偏好,可以被当前上下文覆盖;后者是死命令,会限制 Agent 的灵活性。
同时,Tool Schema 里有一句关键边界规则:
“If you’ve discovered a new way to do something, save it as a skill.”
Memory 不存操作步骤,操作步骤归 Skill 管。一句话划清了两个系统的职责边界。
四、Skill 子系统:把踩过的坑变成组织能力
4.1 Skill 的结构
每个 Skill 是一个目录,核心是SKILL.md文件:
~/.hermes/skills/ ├── devops/ │ └── flask-k8s-deploy/ │ ├── SKILL.md 主指令(YAML frontmatter + Markdown)│ ├── references/ # 参考文档│ └── templates/ # 模板文件一个典型的 SKILL.md 结构:
--- name: flask-k8s-deploy description: Deploy a Flask app to Kubernetes with health checks version: 1.0.0 --- Flask K8s Deployment## When to use- User wants to deploy a Flask/Python app to Kubernetes## Steps1. Create Dockerfile with gunicorn (not dev server)2. Build and push image to registry BEFORE creating deployment3. Write deployment.yaml with livenessProbe pointing to /health...## Pitfalls- MUST push image to registry before kubectl apply- Flask 默认没有 /health 端点,需要手动添加- livenessProbe path 必须返回 200注意 Pitfalls 这一节不是预先写好的,而是 Agent 踩坑后自动追加的。这就是 Skill 层面的"自我进化"。
4.2 自动创建:什么值得记?
Agent 不需要用户说"帮我创建一个 Skill"。skill_manage 工具的 Schema 里写明了创建门槛:
“Create when: complex task succeeded (5+ calls), errors overcome, user-corrected approach worked, non-trivial workflow discovered…”
只有满足以下条件才值得创建:
- 工具调用超过 5 次(简单任务不记)
- 踩过坑并修复过(有教训才有价值)
- 用户纠正过的做法(人的反馈是最宝贵的信号)
4.3 自我修补:局部更新而非全量重写
当 Agent 按 Skill 执行但发现步骤遗漏或新坑时,完成任务后会回头修补。采用模糊匹配做局部 patch:
def _patch_skill(name, old_string, new_string, ...): new_content, match_count, strategy, error = fuzzy_find_and_replace( content, old_string, new_string, replace_all ) if error: return {"success": False, "error": error} 修改前备份 original = content _atomic_write_text(target, new_content) # 安全扫描,不通过就回滚 if _security_scan_skill(skill_dir): _atomic_write_text(target, original) return {"success": False, "error": "Security scan failed"}几个工程细节:
- 模糊匹配:容忍 Agent 给出的 old_string 与原文有格式差异
- 原子写入:先写备份,再替换,失败可回滚
- 安全扫描:每次修改后自动跑安全检测,不通过就撤销
4.4 渐进式加载:解决上下文膨胀
Skills 多了不能全塞进系统提示词。Hermes 采用"动态图书馆"模式:
默认只放一个轻量索引,每个 Skills 的名字和一句话描述:
Available skills: devops: - flask-k8s-deploy: Deploy a Flask app to Kubernetes - nginx-reverse-proxy: Configure Nginx with SSL software-development: - fix-pytest-fixtures: Debug pytest fixture scope issuesAgent 判断某个 Skills 与当前任务相关时,才通过 skill_view 加载完整内容。“先看目录再翻全书”,按需加载,避免上下文膨胀。
五、Nudge Engine:谁来触发"复盘"?
Memory 和 Skills 都是存储系统,写入需要触发器。Nudge Engine 就是这个计数内省触发器。
5.1 两个计数器,两种粒度
# Memory 计数器:按用户回合 self._memory_nudge_interval = 10 # 每 10 个用户回合触发一次# Skill 计数器:按工具迭代 self._skill_nudge_interval = 10 # 每 10 次工具调用触发一次粒度不同是有道理的:
- Memory 的信息来自用户输入 → 按回合计
- Skill 的经验来自工具使用过程 → 按迭代计
5.2 后台 fork:不打扰用户的静默审查
Nudge 触发后,不会在主对话中插入"让我想想",而是在后台 fork 一个独立的 Agent 实例做审查:
def _spawn_background_review(self, messages_snapshot, review_memory=False, review_skills=False): def _run_review(): with open(os.devnull, "w") as devnull, \ contextlib.redirect_stdout(devnull), \ contextlib.redirect_stderr(devnull): review_agent = AIAgent(model=self.model, max_iterations=8, quiet_mode=True) review_agent._memory_store = self._memory_store 共享 Memory review_agent._memory_nudge_interval = 0 # 禁用递归 review_agent._skill_nudge_interval = 0 review_agent.run_conversation(user_message=prompt, ...) thread = threading.Thread(target=_run_review, daemon=True) thread.start()设计要点:
- 输出重定向到/dev/null:用户完全无感知
- 最多 8 次工具调用:控制成本上限
- 禁用 review agent 自身的 nudge:避免无限递归
- 共享 Memory 存储:写入直接生效,无需同步
审查提示词以这句话收尾:
“If nothing is worth saving, just say ‘Nothing to save.’ and stop.”
防止 review agent 为了"交差"而硬塞内容。
六、完整案例:K8s 部署的三次会话演进
用一个真实场景串起三个子系统的协同。
第一次会话:冷启动
用户:帮我把这个 Flask 应用部署到 K8s 集群Memory 和 Skills 都是空的,Agent 靠基座知识摸索:
| 迭代 | 操作 | 结果 |
|---|---|---|
| 1-5 | 读代码、写 Dockerfile、写 deployment.yaml | 正常推进 |
| 6 | kubectl apply | 💥 ImagePullBackOff(忘记推镜像) |
| 7-8 | 推镜像、重新 apply | 修复 |
| 9-10 | 写 service.yaml、apply | 正常推进 |
| 11 | kubectl get pods | 💥 CrashLoopBackOff(livenessProbe 路径不对) |
| 12 | 修改 deployment.yaml、重新部署 | ✅ 成功 |
12 次调用,2 个错误。触发 Skill Review,后台 Agent 自动创建flask-k8s-deploySkill,把两个 Pitfalls 写进文件。用户对这一切毫不知情。
第二次会话:Skill 复用 + 自我修补
用户:帮我再部署一个 Django 应用到 K8sAgent 加载已有 Skill,已知坑被绕过:
| 迭代 | 操作 | 结果 |
|---|---|---|
| 1 | skill_view("flask-k8s-deploy") | 加载完整 Skill |
| 2-6 | 按 Skill 步骤执行 | 先 push 再 apply、加 /health 端点 |
| 7 | kubectl apply | 💥 DisallowedHost(Django 特有,Skill 未覆盖) |
| 8-9 | 添加 ALLOWED_HOSTS 环境变量、重新 apply | ✅ 成功 |
从 12 次降到 9 次,已知坑被绕过,但遇到新坑。Review Agent 做三件事:写入用户画像、记住 registry 地址、patch Skill 补上 Django 的坑。
第三次会话:零错误,一次搞定
用户:帮我部署一个新的 FastAPI 微服务Agent 已经知道你是谁、registry 在哪、集群在哪,Skill 里也包含了 ALLOWED_HOSTS 的教训:6 次调用,零错误。
三次演进对比:
| 维度 | 第一次 | 第二次 | 第三次 |
|---|---|---|---|
| 工具调用 | 12 次 | 9 次 | 6 次 |
| 错误数 | 2 | 1 | 0 |
| Memory | 无 | 触发写入 | 系统提示词注入 |
| Skill | 触发创建 | 复用 + 修补 | 复用已修补版本 |
七、安全机制:进化必须有约束
Agent 能往自己"脑子"里写东西,意味着攻击面扩大。Hermes 做了两层防护。
7.1 Memory 内容扫描
因为 Memory 最终会注入系统提示词,如果被诱导记住"ignore all previous instructions",下次会话就等于被劫持:
_MEMORY_THREAT_PATTERNS = [ (r'ignore\s+(previous|all|above|prior)\s+instructions', "prompt_injection"), (r'do\s+not\s+tell\s+the\s+user', "deception_hide"), (r'system\s+prompt\s+override', "sys_prompt_override"), (r'curl\s+[^\n]*\$\{?\w*(KEY|TOKEN|SECRET|PASSWORD)', "exfil_curl"), ]7.2 Skill 安全扫描 + 自动回滚
每次 Skill 创建或修改后,自动跑安全扫描,不通过就回滚到原版本:
scan_error = _security_scan_skill(skill_dir) if scan_error: _atomic_write_text(target, original_content) 不通过就回滚 return {"success": False, "error": scan_error}八、设计取舍:源码背后的架构思考
| 设计决策 | 表面效果 | 深层考量 |
|---|---|---|
| Memory 限 2200 字符 | 迫使 Agent 挑重点记 | 低质量 Memory 注入系统提示词 = 每次 API 调用都带噪声 |
| 声明式事实 vs 操作步骤分离 | Memory 存事实,Skill 存步骤 | 更新频率、触发条件、安全风险完全不同 |
| 冻结快照模式 | 系统提示词会话内不变 | 保护前缀缓存,避免重复计费 |
| 后台 fork 审查 | 用户无感知 | 自省不应占用用户任务的 attention budget |
| patch 优先于全量重写 | 局部修复 Skill | 保留已验证的稳定部分,只改需要改的 |
| 安全扫描 + 自动回滚 | 拒绝恶意写入 | Memory/Skill 最终进入系统提示词,是一等安全边界 |
九、企业落地思考:从"个人工具"到"组织能力"
开源 Hermes 的自进化能力令人印象深刻,但在企业落地时,还需要解决几个关键问题:
9.1 冷启动问题
开源版 Skill 需要 Agent 从零积累。对于企业场景,预装领域 Skill 是更务实的路径,数据库巡检、慢 SQL 诊断、索引优化等通用技能,Agent 上线第一天就应具备。
9.2 团队共享问题
开源 Hermes 的经验积累在~/.hermes/本地目录。团队落地时,需要将 Skill 存储从本地磁盘搬到云端共享存储:一个 DBA 踩过的坑,全团队 Agent 都能绕过。自我进化不应是单点的,而应是组织级的能力沉淀。
9.3 密钥安全问题
Agent 有了终端权限后,API Key、数据库密码等凭证就暴露在攻击面上。企业级部署需要加密托管:AK/SK 由网关代理鉴权,密钥不落盘,不暴露给 Agent 也不暴露给用户。
9.4 审计与治理
Agent 能自我进化,但每一步操作都应在审计链路上可追溯。写操作需二次确认才执行,每一次会话可审计,Token 消耗可监控,安全事件可告警。
十、总结
Hermes Agent 的自进化架构,本质上是三件事的配合:
- Memory 记住你是谁:在容量限制下做高密度信息压缩
- Skill 记住怎么做事:把踩坑经验自动沉淀为可复用资产
- Nudge Engine 保证循环不停转:后台静默触发复盘,不打扰用户
这套机制的价值不在于功能多复杂,而在于设计哲学的转变:从"人调教 Agent"到"Agent 自己学"。
对于正在构建或选型 Agent 平台的技术团队,Hermes 的源码值得仔细研读。它证明了:Agent 的护城河不是模型能力,不是框架功能,而是在真实工作中积累的组织记忆。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~