详情

首页手游攻略 Hermes Agent 源码探秘 (7):记忆与技能 — Agent 的学习能力

Hermes Agent 源码探秘 (7):记忆与技能 — Agent 的学习能力

佚名 2026-07-07 09:05:51

前面的文章里,Agent 每次启动都是"一张白纸"。它不知道你是谁,不记得上次聊了什么,每次都是全新的开始。

但现实中的助理——不管是人类还是数字的——都需要记忆和学习能力。

Hermes 有两套机制来解决这个问题:

机制作用类比人类
Memory(记忆)记住用户偏好、事实信息长期记忆
Skills(技能)学会完成特定任务的流程肌肉记忆/操作规程

这篇就来拆这两个系统。

一、记忆系统(Memory)

1.1 记忆解决什么问题?

每次 Agent 会话都是独立的。如果没有记忆:

第一次对话:你:我喜欢简洁的回答Agent:好的,记住了!第二天:你:帮我查一下资料Agent:好的!(又变成啰嗦模式了)——它忘了你的偏好

有了记忆,Agent 就能跨会话记住信息:

第一次对话:你:我喜欢简洁的回答记忆:存储在数据库中第二天:你:帮我查一下资料Agent:加载记忆 → "用户喜欢简洁" → 简洁回答

1.2 记忆系统的架构

记忆系统的实现在 agent/memory_manager.py

class MemoryManager:def __init__(self, provider):self.provider = provider# 存储后端def get_relevant_memories(self, query, limit=5):"""根据当前对话获取相关记忆"""return self.provider.search(query, limit)def save_memory(self, content, metadata=None):"""保存新记忆"""return self.provider.save(content, metadata)def update_memory(self, memory_id, content):"""更新已有记忆"""return self.provider.update(memory_id, content)

它不自己存储数据,而是委托给存储提供者(provider)。支持多种后端:

# 不同存储后端class BuiltinMemoryProvider:"""使用本地 SQLite 存储(默认)"""def search(self, query, limit):# 简单的关键词匹配...def save(self, content, metadata):# 写入 SQLite...class HonchoMemoryProvider:"""使用 Honcho(一个专门的记忆服务)"""def search(self, query, limit):# 向量相似度搜索...class Mem0MemoryProvider:"""使用 Mem0 记忆服务"""def search(self, query, limit):# Mem0 的语义搜索...

1.3 记忆在对话中的注入流程

当用户发起对话时,记忆系统的执行流程:

用户发消息│▼build_memory_context_block()│ 从记忆库中搜索与当前话题相关的记忆│ 比如用户问"帮我写个Python脚本"│ 记忆:用户是Python开发者,喜欢Type hints▼搜索到的记忆注入到 System Prompt│▼Agent 看到记忆 → 据此调整回答风格

关键代码在 agent/memory_manager.pybuild_memory_context_block()

def build_memory_context_block(memory_manager, user_message, user_profile=None):context_parts = []# 1. 加载用户画像(偏好、风格等)if user_profile:context_parts.append(f"## 用户信息n{user_profile}")# 2. 搜索相关记忆memories = memory_manager.get_relevant_memories(user_message)if memories:memory_text = "n".join([f"- {m.content}" for m in memories])context_parts.append(f"## 相关记忆n{memory_text}")return "nn".join(context_parts)

注入后的 System Prompt 看起来像这样:

...【用户信息】用户是全栈开发者,擅长Python和JavaScript喜欢简洁的回答风格偏好FastAPI而非Flask【相关记忆】- 用户之前在做一个炒股小工具- 用户对AI Agent源码感兴趣,在写一个拆解系列...

1.4 记忆的保存时机

记忆不会自动保存每一句话——那样会存太多噪声。Hermes 在特定的时机保存记忆:

  1. 用户主动要求:"记住我喜欢简洁的回答" → memory_tool 工具被调用
  2. Agent 判断有价值的信息:在对话结束时,Agent 会自动总结有价值的记忆点
  3. 明确的偏好更正:当用户纠正 Agent 的行为时

memory_tool 的实现:

# tools/memory_tool.pydef save_memory(content: str, target: str = "memory", task_id: str = None) -> str:"""保存一段记忆到持久存储"""memory_manager.save(content=content,metadata={"target": target, # "memory" 或 "user""timestamp": time.time(),"source": "user_request"})return json.dumps({"status": "saved"})

二、技能系统(Skills)

如果说记忆是"记住事实",那技能就是"学会做事"。

2.1 什么是"技能"?

技能是一个 Markdown 文件,描述如何完成某个特定任务:

~/.hermes/skills/├── writing-plans/│ └── SKILL.md← 技能文件├── test-driven-development/│ └── SKILL.md├── systematic-debugging/│ └── SKILL.md└── ...

每个技能的核心文件是 SKILL.md,包含两部分:

  1. YAML 前置元数据(frontmatter)
  2. Markdown 正文(指令内容)

2.2 技能文件结构

---name: test-driven-developmentdescription: TDD 工作流:先写测试,再写代码,然后重构version: 1.0.0---# TDD 工作流当你需要实现一个新功能时,按以下步骤执行:## Step 1:写测试(RED)- 先写一个会失败的测试用例- 明确输入和期望输出- 运行测试,确认是红色(失败)## Step 2:写实现(GREEN)- 写刚好能让测试通过的代码- 不要过度设计- 运行测试,确认是绿色(通过)## Step 3:重构(REFACTOR)- 在测试保护下优化代码- 提高可读性和性能- 确保测试仍然通过## 注意事项- ❌ 不要跳过测试先写实现- ❌ 不要一次写太多代码- ✅ 每次只做一个功能点

2.3 技能的加载流程

# agent/skill_utils.pydef get_all_skills_dirs():"""扫描所有技能目录"""skills_dir = get_skills_dir()return [d for d in skills_dir.iterdir() if d.is_dir()]def load_skill(skill_dir):"""加载一个技能"""skill_file = skill_dir / "SKILL.md"if not skill_file.exists():return Nonewith open(skill_file, "r") as f:content = f.read()# 解析 frontmatter 和正文frontmatter, body = parse_frontmatter(content)return {"name": frontmatter.get("name", skill_dir.name),"description": frontmatter.get("description", ""),"content": body,"path": skill_dir}

2.4 技能注入 System Prompt

当 Agent 加载了一个技能,这个技能的内容就会被注入到 System Prompt 中:

# agent/system_prompt.pydef build_skills_section(enabled_skills):"""构建技能部分的 system prompt"""parts = []for skill_name in enabled_skills:skill = load_skill(skill_name)if skill:parts.append(f"""## 技能:{skill['name']}{skill['description']}{skill['content']}""")if parts:return "以下是你需要遵循的技能指南:n" + "n---n".join(parts)return ""

所以"教 Agent 新技能"本质上就是往 System Prompt 里塞了一段 Markdown 文本。 LLM 看到了这段指令,就会按照其中的步骤执行任务。

2.5 技能的生命周期管理

Hermes 还有个 Curator(策展人) 系统,自动管理技能的整个生命周期:

hermes curator status # 查看技能状态hermes curator run# 手动执行一次维护hermes curator pin name # 固定技能(不被自动清理)hermes curator unpin name # 解锁

Curator 会:

  • 跟踪技能使用频率:不常用的技能标记为"空闲"
  • 自动归档:长时间不用的技能自动归档
  • 备份:定期打包备份所有技能,防止丢失

# agent/curator.pyclass Curator:def __init__(self, skills_dir):self.skills_dir = skills_dirself.usage_db = UsageTracker()# SQLite 记录使用情况def run_maintenance(self):"""执行维护任务"""for skill in self._get_all_skills():stats = self.usage_db.get_stats(skill.name)# 判断技能是否应该归档if stats.is_idle():self._archive_skill(skill)# 判断技能是否应该标记为过期if stats.is_stale():self._mark_stale(skill)def _archive_skill(self, skill):"""将技能移入归档目录"""shutil.move(skill.path, ARCHIVE_DIR / skill.name)self.usage_db.set_state(skill.name, "archived")

三、记忆 vs 技能:对比与协同

维度记忆(Memory)技能(Skills)
存储内容事实、偏好、用户信息操作流程、步骤、规范
存储格式键值对/向量Markdown 文件
检索方式语义搜索(相关度)精确匹配(按名称加载)
生命周期永久保存由 Curator 管理
修改方式memory_tool 工具直接编辑 SKILL.md
适用场景"用户喜欢什么""怎么完成某任务"

它们怎么协同工作?

用户说:"写个Python脚本处理CSV"1. Memory 系统介入: → 搜索记忆 → "用户是Python开发者" → 搜索记忆 → "用户之前做过类似的数据处理" → 注入到 System Prompt2. 如果已加载 "python-best-practices" 技能: → 技能内容注入到 System Prompt → "使用类型注解、写docstring、用pathlib"3. Agent 开始工作 → "用户是Python开发者" → 代码风格符合 → "有最佳实践技能" → 结构规范 → 输出质量更高

记忆提供了"上下文",技能提供了"能力"。两者结合,Agent 才能越来越懂你、越来越能干。

四、这个设计好在哪里?

1. 记忆即插即用

多种存储后端可选(内置 SQLite、Honcho、Mem0),从小项目到大规模都可以。

2. 技能即文档

用 Markdown 教 Agent 做事。门槛极低——写文档就是在训练 AI。

3. 自动化的生命周期管理

Curator 自动管理技能的"生老病死",不用手动清理。

4. 零代码扩展

添加记忆不需要改代码,添加技能只需要创建 Markdown 文件。这让非技术人员也能参与 Agent 的"训练"。

五、下一篇预告

Agent 有手(工具系统),有脑(核心循环),有记忆(Memory & Skills),还能服务多平台(Gateway)。但有时候,一个 Agent 不够用怎么办?

一个复杂的任务需要多个人协作完成。

第八篇我们拆 子袋里系统(Delegation) — "Agent 生 Agent"的机制。看一个 Hermes 怎么派出多个"子 Hermes"并行干活,然后把结果汇总回来。

元思未来 · 行稳致远,进而有为

相关资讯
点击查看更多
游戏推荐
推荐专题
热门阅读
推荐下载