Hermes 三层记忆系统(下):技能记忆------AI 自己生成 Skill 的秘密
会话记忆让 Hermes 记住"刚才聊了什么"。持久记忆让 Hermes 记住"你是谁"。但 Hermes 最独特的能力是第三种记忆------技能记忆。当它观察到你反复纠正同一类问题,它会自己生成一个 Skill,以后自动按那个 Skill 执行。这是"自进化"的核心引擎。
技能记忆是什么
技能记忆不是"你教 AI 怎么做"------是"AI 观察你,然后自己总结了一套规则"。
普通 AI 的学习路径(你在教):
👤 "记住,以后 for 都改成 map"
🤖 "好的,记住了"
→ 这是一条规则,存在某处
Hermes 的学习路径(它在学):
👤 "用 map 吧"(第 1 次)
👤 "改成 map"(第 2 次)
👤 "说了用 map"(第 3 次)
🤖 [后台分析]
"检测到模式:用户连续 3 次将 for 循环改为 map。
提取规则:'生成数组遍历代码时使用 map/filter/reduce 而非 for/while'。
关联:[user] code_style: 函数式
置信度:0.85
生成 Skill: auto-code-style-functional"
→ 下次自动用 map,不再需要你纠正
技能记忆 = 持久记忆中的 feedback 类型条目 + 自动触发 Skill 生成引擎。
技能记忆的生成过程:五步详解
第一步:触发------什么时候开始"注意"
触发条件(三个条件全部满足):
① 同一类型的纠正 ≥ min_corrections 次(config.yml 默认 3 次)
② 纠正发生在不同的会话中(不是同一场对话里反复说)
③ 每次纠正的模式一致("改成 map"、"用 map 吧"、"说了用 map" → 同一意图)
不会触发的情况:
→ 同一场对话里纠正了 3 次(可能只是你当时心情不好)
→ 纠正模式不统一(一次说"用 map",一次说"用列表推导",一次说"用 filter")
→ 时间跨度太短(30 分钟内纠正 3 次 → 可能只是在调试)
第二步:分析------提取可执行的规则
Hermes 不只是记录"用户偏好 map",而是尝试把它变成一个可执行、可验证的规则:
原始观察:
纠正 1: for item in items: result.append(process(item))
→ 改成: result = [process(item) for item in items]
纠正 2: for user in users: active.append(user)
→ 改成: active = [u for u in users if u.is_active]
纠正 3: for log in logs: print(log.level)
→ 改成: [print(log.level) for log in logs]
分析输出:
规则名称: "遍历优先用推导式或 map"
触发条件: 代码中出现 for 循环对可迭代对象做遍历+聚合操作
正确做法: 使用列表推导式(简单情况)或 map/filter(复杂情况)
反例代码: [三个原始 for 循环的代码]
正例代码: [三个纠正后的代码]
检查清单:
- [ ] 代码中是否有 for 循环仅做遍历+收集操作
- [ ] 如果是 → 替换为列表推导式或 map/filter
- [ ] 替换后代码是否比原来更短
第三步:生成------创建一个 SKILL.md
markdown
# Auto-Generated Skill: code-style-functional
**来源**: 自动生成
**置信度**: 0.85
**生成时间**: 2026-06-04
**触发纠正次数**: 3
**关联记忆**: [[user: code_style: 函数式]]
## 规则
当生成 Python 代码涉及数组遍历和转换时,优先使用以下方式(按优先级排序):
1. 列表推导式(简单映射/过滤)
2. map() + filter()(需要函数引用时)
3. for 循环(其他情况,如需要 break/continue/副作用)
## 示例
❌ 不要:
```python
result = []
for item in items:
result.append(process(item))
✅ 应该:
python
result = [process(item) for item in items]
检查清单
-
代码中是否有 for 循环仅做遍历+收集操作
-
替换后代码是否可读
-
不适用于有副作用的遍历(如写文件、发网络请求)
这个 SKILL.md 会保存在
~/.hermes/skills/auto/目录下,下次对话时自动加载。第四步:应用------自动注入到上下文
下次你说:
👤 "帮我写一个函数,把用户列表里所有 email 转成小写"
Hermes 的处理流程:
- 加载 auto-code-style-functional SKILL.md
- 检查清单触发:"有 for 循环仅做遍历+收集操作?"
- 生成代码时直接使用列表推导式:
user.email.lower() for user in users
- 不再使用 for 循环
你不需要再纠正。甚至不需要知道这个 Skill 的存在。
### 第五步:迭代------持续优化
Skill 不是一成不变的。你的后续行为会继续影响它:
场景一:你认可了这个 Skill
→ 连续 5 次你没纠正 → 置信度 0.85 → 0.95
→ Skill 更"稳固",应用更果断
场景二:你部分纠正了
👤 "list comprehension 没问题,但 filter 的时候还是用 for 吧,可读性更好"
→ Hermes 更新 Skill,添加例外规则
→ 置信度微降 0.85 → 0.80(因为发现了不适用的情况)
场景三:你完全否定了
👤 "不用 map,全部改回 for"
→ 置信度 0.85 → 0.3
→ 低于阈值(min_confidence: 0.7)→ Skill 自动停用
→ 如果你继续纠正,Skill 不会被重新激活(因为已经被明确否定)
---
## 查看和管理自动生成的 Skill
### 查看
```bash
# 列出所有自动生成的 Skill
hermes skills list --source auto
# 输出示例:
# 🤖 auto code-style-functional 置信度 0.85 应用次数 12 生成 2026-06-04
# 🤖 auto error-message-lang-zh 置信度 0.92 应用次数 8 生成 2026-05-28
# 🤖 auto db-try-except-pattern 置信度 0.78 应用次数 5 生成 2026-05-20
# ✍️ manual project-api-format 置信度 1.00 应用次数 25 创建 2026-05-15
# 查看一个 Skill 的完整内容
hermes skills show code-style-functional
# 查看 Skill 的应用历史
hermes skills history code-style-functional
# 输出:
# 2026-06-04 15:30 应用 ✅ 生成代码时使用列表推导式
# 2026-06-04 10:15 应用 ✅ 生成代码时使用列表推导式
# 2026-06-03 18:00 应用 ⚠️ 但用户纠正了一次(filter 时用 for 更好)
批准/拒绝/修改
当 review_before_apply: true 时(默认),自动生成的 Skill 需要你确认才生效:
bash
# 查看待确认的 Skill
hermes skills pending
# 输出:
# 🤖 auto prefer-pydantic-v2-syntax (置信度 0.82, 4 次纠正)
# 触发规则:你在纠正中将 Pydantic v1 语法改为 v2 语法
# 影响范围:所有涉及数据模型的代码生成
# [A] 批准 [R] 拒绝 [E] 编辑 [I] 忽略本次
# 批准
hermes skills approve prefer-pydantic-v2-syntax
# 拒绝(并说明原因)
hermes skills reject prefer-pydantic-v2-syntax --reason "项目还在用 v1,暂不升级"
# 编辑后再批准
hermes skills edit prefer-pydantic-v2-syntax
# 打开编辑器 → 修改规则 → 保存 → 自动批准
停用和删除
bash
# 暂时停用一个 Skill(保留但不再自动加载)
hermes skills disable code-style-functional
# 重新启用
hermes skills enable code-style-functional
# 完全删除
hermes skills delete some-bad-skill
一个两周的技能演进案例
以 code-style-functional 这个自动生成的 Skill 为例:
Day 1-3(观察期):
对话 1: 纠正了 for → map
对话 2: 纠正了 for → 列表推导式
触发条件未达到(< 3 次),只是记录为 feedback 条目
Day 4(触发):
对话 3: 纠正了 for → 列表推导式
→ 第 3 次同类纠正!
→ 触发分析:用户偏好函数式遍历
→ 生成 Skill v0.1(置信度 0.70)
→ 进入 pending 状态,等待确认
Day 5(批准生效):
你批准了 Skill
→ 开始自动应用
→ 但应用策略比较保守:只在"明显应该用推导式"时应用
Day 8(第一次迭代):
对话 5: 👤 "这个 filter 逻辑用 for 吧,可读性更好"
→ Hermes 记录例外:filter 场景用 for
→ 更新 Skill v0.2(添加例外规则,置信度 0.78)
Day 12(第二次迭代):
对话 7: 连续 3 次生成代码你都没纠正
→ Hermes 提升置信度:0.78 → 0.88
→ 应用策略变得更果断
Day 14(稳定):
对话 9: 生成代码完全符合你的风格
你完全不需要纠正
Skill 置信度:0.92,应用次数:15
→ 从"待确认"变成"稳定规则"
当自学习学错了
最需要警惕的情况------Hermes 把一次"特殊情况"错当成了"通用规则":
错误案例:
Day 1: 你在写一个性能敏感的模块
👤 "这个地方别用 map,用 for 循环快一点"
(理由:这个特定场景下 for 比 map 少一次函数调用)
Day 2-5: Hermes 注意到了另一个 for 循环的使用
→ 关联了 Day 1 的纠正
→ 错误推断:"用户似乎偏好 for 循环而非 map"
→ 生成 Skill: prefer-for-loop
Day 6: 出问题了
👤 "为什么你一直用 for?之前不是都用 map 的吗?"
→ Skill 和实际的用户偏好完全相反!
如何排查和修复
bash
# 1. 发现可疑的 Skill
hermes skills list --source auto --sort confidence
# prefer-for-loop 置信度 0.55 ← 很低的置信度但已经生效了
# 2. 看它的生成历史
hermes skills history prefer-for-loop
# 触发来源:2026-05-20,单次纠正
# (问题:为什么单次纠正触发了?因为被另一个相关记忆"强化"了)
# 3. 看它最近的应用
hermes skills history prefer-for-loop --recent 5
# 每次应用都收到了纠正 ← 说明 Skill 是错的
# 4. 关闭 + 回滚
hermes skills disable prefer-for-loop
hermes skills delete prefer-for-loop
# 5. 手动纠正相关记忆
hermes memory edit mem_xyz --content "仅在性能敏感的循环中使用 for,日常用 map/filter"
# 6. 防止再次生成
# 在配置中提高阈值:
# memory.skill.min_corrections: 5(从 3 提高到 5)
# memory.skill.min_confidence: 0.90(从 0.85 提高到 0.90)
防止学错的配置策略
yaml
memory:
skill:
auto_generate: true
min_corrections: 3 # 推荐 3-5
review_before_apply: true # 初期永远 true
min_confidence: 0.85 # 初期可以设高一点(0.90)
skills:
autogen:
enabled: true
min_confidence: 0.85
max_per_day: 5 # 限制每天自动生成数
max_total: 50 # 限制总量
require_multiple_sessions: true # 必须在多个会话中都出现(防止单次对话误判)
手动创建 Skill vs 自动生成 Skill
手动创建(你写的 SKILL.md):
优势:
→ 一步到位,不需要等待观察期
→ 100% 准确(你明确知道规则是什么)
→ 可以写复杂的条件逻辑
劣势:
→ 需要你主动意识到"这个规则应该存在"
→ 维护负担在你身上
自动生成(Hermes 自己写的 SKILL.md):
优势:
→ 发现你没意识到的模式("原来我 8 次纠正了同一个东西")
→ 零维护------生成、更新、过期全自动
→ 随你的偏好变化而变化
劣势:
→ 需要观察期(3-5 次纠正)
→ 可能学错(置信度低时需要你审核)
→ 对复杂的、条件性的规则提取不准确
最佳实践:
→ 核心规则、安全规则 → 手动创建(一步到位,不出错)
→ 代码风格、个人偏好 → 让 Hermes 自动学(你未必意识到自己的模式)
手动创建 Skill 的格式
bash
# 创建自定义 Skill
hermes skills create my-coding-rules
# 自动打开编辑器,填入:
markdown
# my-coding-rules
## 适用范围
所有 Python 后端代码生成
## 规则
1. 所有函数类型标注完整(参数 + 返回值)
2. 数据库操作使用 async/await
3. 配置文件从环境变量读取,不硬编码
4. 日志使用 structlog,不直接用 print
## 示例
❌
```python
def get_user(id):
return db.query(User).filter(User.id == id).first()
✅
python
async def get_user(user_id: int) -> User | None:
async with get_db_session() as db:
return await db.query(User).filter(User.id == user_id).first()
检查清单
- 所有函数有完整类型标注
- 数据库操作是异步的
- 配置从环境变量读取
- 使用 structlog 而非 print
这篇文章的要点
-
技能记忆 ≠ 持久记忆中的一条规则
→ 它是规则 + 触发条件 + 示例 + 检查清单 + 自动应用引擎
-
五步生成过程:
触发(3+ 次同类纠正)→ 分析(提取可执行规则)→ 生成(写 SKILL.md)
→ 应用(下次自动加载)→ 迭代(持续优化置信度)
-
review_before_apply: true 是最重要的安全阀
→ 自动生成的 Skill 需要你确认后才生效
→ 初期永远保持 true
-
手动 Skill(核心规则)+ 自动 Skill(个人偏好)= 最佳组合
-
学错了怎么办:
hermes skills history → 排查 → disable → delete → 调整阈值