Hermes Agent 深度拆解:当 AI 决定「用代码改写自己的大脑」——从闭环学习到可写运行时,一个 110K Star 的自进化框架如何重新定义 Agent 的终极形态
2026 年 2 月,Nous Research 发布了一个叫 Hermes Agent 的开源项目。四个月后,GitHub Star 数冲到 110K,贡献者超过 240 人,Commit 数超过 4,800 次。它不是又一个"调用工具的 Agent 框架",而是一个让 Agent 越用越聪明的自进化系统——它能自主创建技能、从失败中学习、跨会话保持记忆,甚至在运行时改写自己的行为逻辑。
引言:为什么传统 Agent 框架都在原地打转?
2026 年的 AI Agent 赛道已经相当拥挤。从 AutoGPT 到 CrewAI,从 LangGraph 到 OpenClaw,几乎每个月都有新的框架冒出。但如果你真正用过这些框架,你会发现一个共同的尴尬:
它们都是"静态工具"。
具体来说,传统 Agent 框架存在三个致命缺陷:
重启即失忆:每次新开会话,之前积累的使用习惯、任务经验、踩坑记录全部清零。你花了三天调好的 prompt 策略,换个会话就没了。
只会按剧本干活:只能执行预定义的工具和流程。遇到新场景?要么报错,要么输出垃圾,要么反复调用同一个无效工具直到 token 耗尽。
不会复盘:同样的错误无限重复。上周在文件路径上踩了坑,这周照样踩。没有自我优化机制,Agent 永远是个"一次性工具"。
Hermes Agent 的出现,本质上是在回答一个根本性的问题:Agent 能不能像人一样,从经验中学习?
答案是可以的——前提是你需要重新设计整个架构。这篇文章从源码出发,拆解 Hermes Agent 如何用"可写运行时"(Writable Runtime)实现真正的自进化。
项目概览:不只是框架,而是 AI 操作系统
Hermes Agent 的官方定位是 self-improving AI agent——自进化 AI Agent。这个定位和市面上绝大多数 Agent 框架拉开了距离。
| 维度 | 传统 Agent 框架 | Hermes Agent |
|---|---|---|
| 核心理念 | 让 LLM 更好地调用工具 | 让 Agent 越用越聪明 |
| 技能系统 | 只读模式,人工编写 | 可写模式,自主创建 |
| 记忆能力 | 临时会话记忆 | 五层分层持久记忆 |
| 学习机制 | 无 | 闭环学习循环 |
| 开源协议 | 各异 | MIT(免费商用) |
| 模型支持 | 通常绑定 1-2 家 | 200+ 模型,全中立 |
技术栈:Python 3.11+,SQLite + WAL 模式,支持 OpenAI / Anthropic / Bedrock / OpenRouter / Ollama 等 200+ 模型后端。
核心目录结构:
hermes-agent/
├── run_agent.py # Agent 主循环,系统心脏
├── tools/ # 40+ 工具实现
├── toolsets.py # 工具集定义与组合
├── agent/
│ ├── prompt_builder.py # System Prompt 组装器
│ ├── memory_manager.py # 记忆管理(双 Provider 架构)
│ ├── context_engine.py # 上下文引擎(可插拔)
│ └── context_compressor.py # 轨迹压缩器
├── hermes_state.py # SQLite 状态存储 + FTS5 全文搜索
├── gateway/ # 多平台消息网关
├── skills/ # 内置 Skill 库(24 个分类)
├── plugins/ # 插件系统
├── hermes_cli/ # CLI 接口(51 个模块)
└── environments/ # 执行环境后端
架构设计的第一个关键决策:Agent 循环和工具执行在同一进程。没有用微服务那套,而是通过 run_agent.py 中的 AIAgent 类管理整个生命周期。这个选择背后有清晰的权衡——单进程意味着更低的延迟、更简单的状态管理、更少的运维复杂度。代价是无法水平扩展,但对于一个个人/团队级的 Agent 来说,这个 trade-off 是值得的。
核心架构拆解:可写运行时的设计哲学
Agent 循环:系统的心脏
run_agent.py 中的 AIAgent 类是整个系统的核心。它管理对话流、工具执行、响应处理的全流程。
Agent 循环的基本流程:
接收用户消息
→ 构建请求(system prompt + 记忆 + 上下文)
→ 调用 LLM
→ 解析响应
→ 如果包含工具调用 → 执行工具 → 把结果加入上下文 → 再次调用 LLM
→ 直到 LLM 不再请求工具调用
→ 返回最终响应
这个循环有几个关键的控制机制:
迭代预算控制
Agent 循环不是无限运行的。IterationBudget 类实现了一个线程安全的迭代计数器:
class IterationBudget:
"""线程安全的迭代预算控制"""
def __init__(self, max_iterations: int = 90):
self.max_iterations = max_iterations
self._count = 0
self._lock = threading.Lock()
def consume(self) -> bool:
"""消耗一次迭代,返回 False 表示预算耗尽"""
with self._lock:
if self._count >= self.max_iterations:
return False
self._count += 1
return True
默认配置:父 Agent 90 次迭代,子 Agent 50 次迭代。这个数字不是拍脑袋定的——90 次大约对应一次复杂任务(涉及多轮工具调用)的合理上限,超出说明 Agent 很可能陷入了死循环。
并行工具执行
Agent 循环中的 _should_parallelize_tool_batch() 方法把工具分成三类:
| 分类 | 策略 | 典型工具 |
|---|---|---|
_NEVER_PARALLEL_TOOLS | 永远不并行 | clarify(需要用户交互) |
_PARALLEL_SAFE_TOOLS | 只读安全,可并行 | web_search, read_file |
_PATH_SCOPED_TOOLS | 路径隔离,条件并行 | read_file, write_file, patch |
最大并发工作线程数硬编码为 8(_MAX_TOOL_WORKERS)。
这个设计说明团队对 Agent 的实际使用场景做过深入思考。web_search 和 read_file 都是纯读操作,并行执行完全安全。但 write_file 和 patch 操作同一文件时就有冲突风险,所以需要路径隔离检查。
中断与转向机制
Agent 在执行过程中可能会收到用户的新指令。Hermes 的处理方式是 _interrupt_requested + _pending_steer 双标志位设计:
# 不打断当前正在执行的工具
# 等工具批次完成后再处理
if self._interrupt_requested:
await self._current_tool_batch
self._handle_steer(self._pending_steer)
关键决策:不强行中断正在执行的 write_file。如果中断发生在文件写入中途,可能导致文件损坏。等工具批次完成再转向,保证了操作的原子性。这个选择非常务实。
工具系统:自注册 + Toolset 组合
ToolRegistry 自注册模式
工具系统的核心在 tools/registry.py。每个工具文件在模块级别调用 registry.register() 声明自己:
# tools/web_search.py(简化)
from .registry import registry
registry.register(
name="web_search",
toolset="hermes-core",
schema={
"type": "function",
"function": {
"name": "web_search",
"description": "Search the web for information",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"},
"max_results": {"type": "integer", "default": 5}
},
"required": ["query"]
}
}
},
handler=web_search_handler,
check_fn=web_search_check,
requires_env=False,
is_async=True,
description="Search the web",
emoji="🔍"
)
发现机制更有趣:discover_builtin_tools() 通过 AST 分析检测哪些 .py 文件包含 registry.register() 调用,不需要手动维护工具列表。这比常见的"配置文件列举工具"方式更优雅——添加新工具只需要创建文件并调用注册,系统自动发现。
Toolset 组合系统
toolsets.py 实现了一个组合式工具集系统。核心工具列表 _HERMES_CORE_TOOLS 包含 63 个工具:
| 类别 | 工具举例 |
|---|---|
| Web | web_search, web_extract |
| 终端 | terminal, process |
| 文件 | read_file, write_file, patch, search_files |
| 视觉 | vision_analyze, image_generate |
| 技能 | skills_list, skill_view, skill_manage |
| 浏览器 | browser_navigate 等 11 个工具 |
| 规划 | todo, memory |
| 代码执行 | execute_code, delegate_task |
平台特定 toolset 如 hermes-cli、hermes-telegram、hermes-discord 等有 20 多个。hermes-gateway 是所有平台工具的并集。
这种组合式设计的好处:新接入一个平台时,只需要定义该平台特有的工具,然后 includes 核心工具集就行。一个 web_search 工具只存在一份实现,但可以通过不同的 toolset 暴露给不同的平台。
记忆与学习闭环:自进化的秘密
这是 Hermes Agent 和其他 Agent 框架拉开差距的地方。
五层分层记忆架构
Hermes 搭建了行业最完善的分层持久记忆体系:
| 层级 | 名称 | 存储位置 | 功能 |
|---|---|---|---|
| L1 | 短期工作记忆 | 内存 | 当前会话上下文,轻量级运行 |
| L2 | 核心记忆 | MEMORY.md | Agent 的个人笔记(环境事实、项目约定、工具技巧) |
| L3 | 用户画像 | USER.md | 对用户的认知(偏好、沟通风格、期望) |
| L4 | 技能记忆 | ~/.hermes/skills/ | 自主生成的技能,版本化管理 |
| L5 | 会话检索 | SQLite + FTS5 | 跨所有会话的全文搜索 |
两个核心记忆文件的分工:
- MEMORY.md:Agent 的个人笔记。记录环境事实、项目约定、工具的使用技巧。字符上限约 2200(约 800 tokens)。
- USER.md:Agent 对用户的认知。记录偏好、沟通风格、期望。字符上限约 1375(约 500 tokens)。
冻结快照模式
这个设计解决了一个很实际的问题:系统提示的稳定性。
会话开始时,MemoryManager 把当前的记忆内容作为快照注入系统提示。之后整个会话期间,系统提示保持不变——中途写入的记忆只更新磁盘文件,不刷新系统提示。
# tools/memory_tool.py(简化)
class MemoryStore:
def __init__(self):
self._snapshot = None # 冻结快照
def freeze_snapshot(self):
"""会话开始时冻结记忆快照"""
self._snapshot = self._load_memory_files()
def write_memory(self, content: str, target: str = "MEMORY"):
"""写入记忆:更新磁盘,不刷新系统提示"""
self._save_to_disk(content, target)
# 注意:不更新 self._snapshot
为什么这样做?
如果每次记忆更新都刷新系统提示,KV cache 就会失效,每次请求都要重新计算前面所有 token 的 KV 对。冻结快照让前缀缓存命中率大大提高。在生产环境中,这意味着每轮对话的 token 成本可能降低 80%+。
代价:Agent 在一个会话内对记忆的修改,需要等到下一个会话才能被读取。对于大多数使用场景来说,这个延迟是可以接受的。
外部记忆 Provider:8 种可插拔后端
agent/memory_provider.py 定义了 MemoryProvider 抽象接口,支持 8 种外部记忆后端:
Honcho / Holographic / Mem0 / Hindsight /
OpenViking / RetainDB / ByteRover / Supermemory
同时只激活一个。外部记忆解决的是语义级别的记忆检索问题——当 Agent 需要"我记得上周处理过一个类似的问题"这种模糊回忆时,FTS5 的关键词搜索就不够用了,需要向量检索。
会话搜索:SQLite FTS5 全文索引
hermes_state.py 中的 SessionDB 基于 SQLite FTS5 实现跨所有会话消息的全文搜索:
# hermes_state.py(简化)
class SessionDB:
def search(self, query: str, limit: int = 10) -> list:
"""FTS5 全文搜索"""
return self.conn.execute(
"SELECT * FROM messages "
"WHERE messages MATCH ? "
"ORDER BY rank "
"LIMIT ?",
(query, limit)
).fetchall()
搜索流程:FTS5 召回相关片段 → LLM 总结 → 注入当前上下文。
这是一个多级检索的设计:用户提问 → Agent 判断是否需要历史信息 → 调用 session_search(FTS5 召回) → LLM 总结召回结果 → 结合 MEMORY.md/USER.md 的快照 → 形成完整的记忆上下文。
Skill 系统:Agent 如何"教会自己做事"
Skill 系统是 Hermes 自进化能力的载体。
Skill 的生命周期
完成复杂任务
→ Agent 识别可复用模式
→ 生成 Markdown 格式的 Skill 文件
→ 存入 ~/.hermes/skills/
→ 下次同类任务直接调用
→ 如果 Skill 出错/过时 → 自动 patch 更新
一个典型的 Skill 文件结构:
# Skill: 数据库备份
## 触发条件
用户要求备份数据库,或执行定时备份任务
## 执行步骤
1. 连接数据库(支持 MySQL/PostgreSQL/SQLite)
2. 生成带时间戳的备份文件
3. 验证备份完整性
4. 清理超过 7 天的旧备份
## 注意事项
- 大数据库使用 `--single-transaction` 避免锁表
- 备份完成后发送通知
- 错误时回滚并报告
Skill 的创建与改进
Skill 的创建不是硬编码的——它是 Agent 在完成任务后自主判断的。agent/prompt_builder.py 中的 SKILLS_GUIDANCE 提供了 Skill 创建和更新的指导规则。
关键机制:
- 自动识别:Agent 完成一个复杂任务后,判断这个任务是否包含可复用的模式
- 自动生成:如果有,生成 Markdown 格式的 Skill 文件
- 自改进:使用 Skill 时如果发现问题(过时、报错),立即 patch 更新
- Curator 自治:内置的 Curator 智能体后台自动清理冗余技能、合并重复能力
官方测试数据:积累 20+ 自主技能的 Hermes 实例,重复任务效率提升 40%,错误率下降 65%。
子 Agent 委托:多智能体协同
tools/delegate_tool.py 实现了子 Agent 委托机制,允许主 Agent 生成独立的子 Agent 实例来并行处理任务。
隔离设计
子 Agent 的隔离做得比较彻底:
- 无父历史:子 Agent 看不到父 Agent 的对话历史
- 独立终端会话:子 Agent 有自己的终端环境
- 工具限制:
DELEGATE_BLOCKED_TOOLS列表禁止子 Agent 使用特定工具(包括递归委托,防止子 Agent 再生孙 Agent)
这个设计背后的考虑:子 Agent 的目的是并行处理子任务,不应该有动机去影响父 Agent 的状态或产生无限递归。
Profile 系统
v0.6.0 引入了多实例 Profile,每个 Profile 拥有独立的:
- 配置
- 记忆库
- 会话历史
- Skill 集合
- 工具权限
这意味着你可以在同一台机器上跑多个独立的 Agent 实例——比如一个用于工作项目,一个用于个人自动化,互不干扰。
上下文管理:可插拔压缩引擎
ContextEngine 抽象架构
agent/context_engine.py 定义了抽象基类 ContextEngine,agent/context_compressor.py 提供了默认实现。
可插拔设计意味着你可以实现自己的上下文管理策略——基于 RAG 的检索增强、基于重要性评分的选择性保留等。不同场景对上下文的处理策略差异很大:编程场景需要保留完整的代码变更历史,对话场景需要保留情感上下文,数据分析场景需要保留中间结果。
压缩策略详解
默认压缩器的参数:
| 参数 | 默认值 | 作用 |
|---|---|---|
threshold_percent | 0.75 | 上下文使用率超过 75% 时触发压缩 |
protect_first_n | 3 | 保护前 3 条消息(system prompt + 用户初始请求) |
protect_last_n | 6 | 保护后 6 条消息(最近的对话上下文) |
压缩的具体流程:
- 保护头部和尾部:前 N 条和后 M 条消息不动
- 中间部分用辅助模型总结:不是简单截断,而是让另一个 LLM 生成结构化摘要
- 总结模板:包含已解决的问题、待处理的事项、活跃任务
- 工具输出裁剪:对工具返回的长文本做前置过滤
- 按比例分配 token 预算:中间部分的每段对话按比例分配总结的 token 预算
安全设计:防注入与权限控制
Prompt Injection 防护
agent/prompt_builder.py 中的 _scan_context_content() 检测注入攻击。上下文文件的优先级是 .hermes.md > AGENTS.md > CLAUDE.md > .cursorrules。
安全扫描会检查这些文件中是否包含恶意指令,防止 prompt injection。记忆条目之间用 §(section sign)做分隔符——一个不太常见的字符,降低了和正文内容冲突的概率。
记忆注入安全
记忆注入时使用 <memory-context> 标签做上下文围栏,防止模型把记忆上下文误认为新的用户输入。tools/memory_tool.py 中还有安全扫描机制,检测记忆内容中是否包含试图操控模型行为的恶意指令。
运行环境隔离
支持 6 种执行环境后端:
local / Docker / SSH / Daytona / Singularity / Modal
Docker 沙箱模式下,Agent 的代码执行在一个隔离的容器中,即使执行了恶意命令也不会影响宿主机。$5/月的 VPS 即可运行——Agent 进程本身占用不到 500MB(不含本地 LLM)。
多平台接入:12+ 平台消息网关
gateway/run.py 实现了统一的消息网关,支持 12+ 平台:
Telegram / Discord / Slack / 微信 / 飞书 /
企业微信 / WhatsApp / Signal / iMessage /
Matrix / IRC / Web
网关的设计原则:
- 统一的消息格式:所有平台的消息都被转换为统一的内部格式
- 平台特定的渲染:输出时根据目标平台的特性进行格式适配
- 并发安全:SQLite WAL 模式支持多读者 + 单写者
与其他框架的深度对比
vs OpenClaw
| 维度 | Hermes Agent | OpenClaw |
|---|---|---|
| 自进化 | ✅ 原生闭环学习 | ❌ 手写配置 |
| 记忆 | 五层分层架构 | 基础记忆 |
| Skill | 自动创建 + 版本管理 | 手动安装 |
| 模型 | 200+,全中立 | 支持多家 |
| 部署 | $5/月 VPS | 需要更多资源 |
| 生态 | 快速增长中 | 成熟 |
vs CrewAI / LangGraph
| 维度 | Hermes Agent | CrewAI / LangGraph |
|---|---|---|
| 自进化 | ✅ | ❌ |
| 多智能体 | 原生支持 | 需要编排 |
| 记忆 | 持久化 + 分层 | 基础 |
| 学习 | 从经验中学习 | 无 |
vs AutoGPT
| 维度 | Hermes Agent | AutoGPT |
|---|---|---|
| 架构 | 单进程,轻量 | 复杂,资源占用高 |
| 稳定性 | 稳定(迭代预算控制) | 容易死循环 |
| 记忆 | 五层架构 | 基础 |
| 实用性 | 生产可用 | 更多是实验性 |
生产环境注意事项
Hermes Agent 虽然功能强大,但在生产环境中需要注意几点:
自评估偏差:Agent 自我校验存在误差,关键任务建议进行人工复核
版本迭代快:更新频繁,新功能偶尔存在兼容性问题,生产环境需谨慎升级
Skill 覆盖风险:自动生成的技能可能会覆盖手动优化的代码,需要做好版本备份
Token 成本:虽然有冻结快照优化,但复杂任务的多轮对话仍然会消耗大量 token
并发限制:单进程架构意味着无法水平扩展,高并发场景需要多实例部署
快速上手
# 安装
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
# 配置
hermes setup # 交互式配置向导
hermes model # 选择模型
# 运行
hermes # 启动 Agent
配置 API Server(可选):
# ~/.hermes/.env
API_SERVER_ENABLED=true
API_SERVER_KEY=your-secret-key
API_SERVER_PORT=8642
# 启动 API Server
hermes api-server start
# 调用
curl -X POST http://localhost:8642/v1/chat/completions \
-H "Authorization: Bearer your-secret-key" \
-H "Content-Type: application/json" \
-d '{"model":"hermes-agent","messages":[{"role":"user","content":"Hello"}]}'
总结:Agent 进化的下一步
Hermes Agent 的出现,标志着 AI Agent 正式从「人工编排的工具时代」迈入「自主进化的智能伙伴时代」。
它的核心贡献不是某个单一的技术突破,而是把"自进化"从一个概念变成了可落地的工程实践:
- 可写运行时:Agent 能在运行时创建和修改自己的技能
- 闭环学习:从任务经验中学习,不是一次性工具
- 分层记忆:五层架构解决失忆问题
- 安全可控:冻结快照、注入防护、环境隔离
当然,目前仍处于快速迭代阶段,生产环境需要谨慎。但方向是明确的:未来的 AI Agent 不应该是静态工具,而应该是能从经验中学习的智能伙伴。
对于开发者来说,Hermes Agent 的架构设计——特别是它的自注册工具系统、冻结快照记忆机制、以及 Skill 的自动创建与版本管理——即使你不使用这个框架,也值得深入研究。这些设计思路对任何 Agent 系统的构建都有参考价值。
项目地址:https://github.com/NousResearch/hermes-agent
协议:MIT
技术栈:Python 3.11+ / SQLite / FTS5
Star 数:110K+(截至 2026 年 8 月)