Hermes Agent 架构深度解析:自进化的AI代理框架
Hermes Agent - Self-Improving AI Agent Framework
本文深度解析Nous Research开源的Hermes Agent项目,揭示其作为自进化AI代理框架的核心设计理念。文章系统分析了从AIAgent核心循环到多平台网关的完整架构,重点探讨了其独特的技能学习系统、记忆管理机制和子代理委托模式。
一、项目概述:不止是一个聊天机器人
Hermes Agent 是由 Nous Research 构建的开源AI代理框架,其核心定位远超过一个普通的LLM包装器。项目的 README 中有一句话精准地概括了它的特色:
"The only agent with a built-in learning loop — it creates skills from experience, improves them during use, nudges itself to persist knowledge, searches its own past conversations, and builds a deepening model of who you are across sessions."
这句话揭示了 Hermes 的三个核心差异化特征:
- 自进化的技能系统 - 从经验中提取可复用的程序化知识
- 跨会话记忆机制 - 不只是简单存储,而是主动检索和建模
- 多平台网关架构 - 统一的入口,分布式的交互
本文将深入分析这些设计选择背后的架构考量。
二、核心架构:分层设计哲学

Hermes 的架构可以清晰地划分为五个层次:
1. 核心AI层 (Core AI Layer)
这一层由三个核心文件构成:
- run_agent.py -
AIAgent类,包含完整的对话循环逻辑 - model_tools.py - 工具注册和调用的编排层
- hermes_state.py - SQLite 会话存储 (支持 FTS5 全文搜索)
关键设计决策:AIAgent 是一个完全同步的类。不同于许多基于异步/事件循环的代理框架,Hermes 选择同步架构来简化推理流程和调试。
# run_agent.py 中的核心循环
while api_call_count < self.max_iterations and self.iteration_budget.remaining > 0:
response = client.chat.completions.create(...)
if response.tool_calls:
for tool_call in response.tool_calls:
result = handle_function_call(tool_call.name, tool_call.args, task_id)
messages.append(tool_result_message(result))
else:
return response.content2. Agent 内部组件层
位于 agent/ 目录下的模块化组件:
| 组件 | 职责 | 关键文件 |
|---|---|---|
| Prompt Builder | 系统提示组装 | prompt_builder.py |
| Memory Manager | 记忆提供者编排 | memory_manager.py |
| Context Compressor | 自动上下文压缩 | context_compressor.py |
| Skill Utils | 技能索引和匹配 | skill_utils.py |
| Model Metadata | 模型上下文长度管理 | model_metadata.py |
3. 工具层 (Tool Registry)
Hermes 采用自注册模式:每个工具文件在导入时调用 registry.register() 完成注册。这种设计实现了工具与注册中心的解耦。
工具分为几个类别:
- 基础工具:
read_file,write_file,terminal,web_search - 高级工具:
browser_navigate,vision_analyze,delegate_task - 元工具:
memory,skill_manage,session_search - MCP 工具: 外部 MCP 服务器集成的动态工具
4. 网关层 (Gateway Layer)
位于 gateway/ 目录,支持多平台消息接入:
- Telegram, Discord, Slack
- WhatsApp, Signal
- Home Assistant
架构亮点: 网关通过 SessionStore 实现跨平台会话连续性,用户可以在 Telegram 开始对话,在 Discord 继续。
5. 终端后端层 (Terminal Backends)
位于 tools/environments/,支持六种执行环境:
| 后端 | 用途 | 特点 |
|---|---|---|
| Local | 本地执行 | 直接访问宿主机 |
| Docker | 容器化 | 隔离、可复现 |
| SSH | 远程执行 | 连接远程服务器 |
| Daytona | 云端开发环境 | 协作、持久化 |
| Modal | Serverless | 按需计费、自动休眠 |
| Singularity | HPC 环境 | 高性能计算场景 |
三、核心循环:AIAgent 的执行流程

3.1 初始化阶段
每次对话开始时,系统会构建一个复杂的系统提示:
系统提示 = 身份定义 + 记忆上下文 + 技能索引 + 平台适配 + 工具使用规范记忆预取 (MemoryManager.prefetch_all()) 是一个关键步骤,它会根据用户查询从多个记忆提供者中检索相关上下文。
3.2 主循环结构
用户输入 → 记忆预取 → 上下文压缩检查 → LLM 调用 → [工具执行循环] → 响应用户 → 记忆同步迭代预算 (Iteration Budget) 是 Hermes 的一个重要安全机制:
- 父代理: 默认 90 次迭代
- 子代理: 默认 50 次迭代
execute_code调用的迭代会被退还(refund),鼓励程序化工具使用
3.3 并行工具执行
Hermes 支持工具并行执行,但有明确的安全策略:
# run_agent.py 中的并行策略
_PARALLEL_SAFE_TOOLS = frozenset({
"read_file", "search_files", "web_search", "web_extract",
"vision_analyze", "skills_list", "session_search", ...
})
_NEVER_PARALLEL_TOOLS = frozenset({"clarify"}) # 交互式工具必须串行
_MAX_TOOL_WORKERS = 8四、自进化系统:技能与记忆
4.1 技能系统 (Skills)
设计哲学: 技能是程序化记忆——可复用、可版本控制、可分享的显性知识。
自动技能创建的触发条件:
# agent/skill_utils.py 中的启发式规则
SKILLS_GUIDANCE = """
After completing a complex task (5+ tool calls), fixing a tricky error,
or discovering a non-trivial workflow, save the approach as a skill...
"""技能存储在 ~/.hermes/skills/ 目录,支持:
- Markdown 格式的前置条件匹配
- 自动版本更新 (
skill_manage action='patch') - 跨项目分享 (兼容 agentskills.io 标准)
4.2 记忆管理架构
MemoryManager 采用提供者模式,支持内置和外部记忆系统的组合:
class MemoryManager:
"""Orchestrates the built-in provider plus at most one external provider."""
def prefetch_all(self, query: str, session_id: str) -> str:
"""Collect prefetch context from all providers."""
def sync_all(self, user_content: str, assistant_content: str, session_id: str) -> None:
"""Sync a completed turn to all providers."""关键限制: 只能有一个外部记忆提供者,防止工具模式膨胀和冲突。
4.3 会话搜索 (FTS5)
Hermes 使用 SQLite FTS5 实现全文搜索,这是一个轻量但强大的设计:
-- hermes_state.py 中的 FTS5 表定义
CREATE VIRTUAL TABLE messages_fts USING fts5(
content,
content=messages,
content_rowid=id
);搜索触发采用启发式而非强制:当用户提及过去的内容时,Agent 会自动调用 session_search。
五、上下文压缩:聪明的资源管理
ContextCompressor 是 Hermes 应对长对话的创新方案:
5.1 压缩策略
采用三段式压缩策略:
- 头保护 - 保留系统提示和前 N 条消息
- 尾保护 - 保留最近的 token 预算(默认 20K tokens)
- 中间压缩 - 用辅助模型生成结构化摘要
5.2 结构化摘要模板
[CONTEXT COMPACTION] Earlier turns were compacted to save space.
GOAL: {original task goal}
PROGRESS: {what has been accomplished}
DECISIONS: {key decisions made}
FILES: {files created/modified}
NEXT STEPS: {what remains}迭代更新: 多次压缩时,新摘要会合并到旧摘要,而非完全替换,保持历史连续性。
六、子代理系统:委托与并行
delegate_task 工具实现了 Hermes 的层级代理架构:
6.1 隔离原则
每个子代理获得:
- 隔离的上下文 - 不继承父代理历史
- 独立的 task_id - 独立的终端会话和文件缓存
- 受限的工具集 - 移除了危险工具(如
delegate_task,memory,clarify) - 聚焦的系统提示 - 基于委托目标定制的提示
6.2 并发控制
# tools/delegate_tool.py
MAX_CONCURRENT_CHILDREN = 3
MAX_DEPTH = 2 # 防止无限递归
DELEGATE_BLOCKED_TOOLS = frozenset([
"delegate_task", # 禁止递归
"clarify", # 禁止交互
"memory", # 禁止共享记忆写入
"send_message", # 禁止跨平台副作用
])6.3 进度回调
子代理的执行进度通过树形视图实时反馈给父代理的显示层:
├─ 🔀 [1] read_file "pyproject.toml"
├─ 🔀 [1] ├─ web_search "dependency versions"
├─ 🔀 [2] read_file "src/main.py"七、多平台网关:统一的接入层
7.1 会话管理
SessionStore 实现了真正的跨平台连续性:
# gateway/session.py
class SessionStore:
"""SQLite-backed session storage with cross-platform lookup."""
def get_or_create_session(self, user_id: str, platform: str) -> Session:
"""Retrieve existing or create new, maintaining continuity."""密钥设计: 使用归一化的用户标识符(去除平台特定格式)作为会话键,实现跨平台识别。
7.2 平台适配器模式
每个平台实现 BasePlatformAdapter 接口:
class BasePlatformAdapter(ABC):
async def send_message(self, chat_id: str, text: str, ...): ...
async def handle_message(self, event: MessageEvent): ...7.3 环境桥接
网关启动时会将 config.yaml 的配置桥接到环境变量,确保工具层可以访问配置:
# gateway/run.py
# Bridge terminal config to TERMINAL_* env vars
_terminal_env_map = {
"backend": "TERMINAL_ENV",
"cwd": "TERMINAL_CWD",
"timeout": "TERMINAL_TIMEOUT",
# ...
}八、关键设计决策分析
8.1 同步 vs 异步
Hermes 选择同步架构,这在一众异步代理框架中显得独特。利弊权衡:
| 方面 | 同步优势 | 异步代价 |
|---|---|---|
| 调试 | 堆栈清晰,易于跟踪 | 回调地狱,难以调试 |
| 推理 | 线性思维,符合直觉 | 需要心智模型转换 |
| 工具执行 | 简单顺序控制 | 需要复杂的并发协调 |
| 性能 | 牺牲部分并发性 | 更好的资源利用 |
设计洞察: 对于以 LLM 调用为瓶颈的代理系统,同步架构的"性能损失"几乎可以忽略,而可维护性的提升是实实在在的。
8.2 工具自注册模式
Hermes 的工具系统采用自注册而非集中配置:
# tools/example_tool.py
registry.register(
name="example_tool",
toolset="example",
schema={...},
handler=lambda args, **kw: example_tool(...),
)优势:
- 新工具只需创建文件,无需修改注册中心
- 工具实现与注册元数据同处一地,减少遗忘
- 支持运行时动态发现 (MCP, Plugins)
8.3 记忆提供者的单例限制
限制只能有一个外部记忆提供者,这看似限制了灵活性,实则是一种防御性设计:
- 防止工具模式数量爆炸
- 避免多个记忆系统之间的冲突
- 强制清晰的架构选择
九、对系统设计的启示
9.1 渐进式复杂度
Hermes 展示了如何按需引入复杂度:
- 基础场景: 简单同步循环即可工作
- 长对话: 自动触发上下文压缩
- 复杂任务: 启发式触发子代理委托
- 跨会话: 显式的记忆工具调用
这种"pay-as-you-go"的哲学让每个用户只承担其使用场景对应的复杂度。
9.2 显式优于隐式
Hermes 的设计偏向显式控制:
- 技能不会自动创建,需要满足条件并调用工具
- 记忆不会自动检索,需要调用
session_search - 上下文不会自动压缩,需要触发阈值
这与一些"全自动"的代理框架形成对比,显式控制带来了可预测性和调试友好性。
9.3 人机协作的边界
从 clarify 工具的设计可以看出 Hermes 对人机协作的理解:
_NEVER_PARALLEL_TOOLS = frozenset({"clarify"})交互式工具必须串行执行,因为人类是顺序处理者。这个细节体现了对用户体验的深入思考。
十、结语
Hermes Agent 是一个务实的架构设计典范。它没有追求最前沿的技术栈,而是在成熟的同步 Python 基础上,通过精心的分层和模块化,构建了一个可维护、可扩展的代理框架。
其核心贡献不在于任何单一技术,而在于系统的集成:
- 技能系统提供了知识积累的能力
- 记忆系统实现了跨会话连续性
- 子代理支持任务分解和并行
- 网关层实现了多平台统一接入
- 上下文压缩解决了长对话的资源限制
这些组件协同工作,形成了一个自进化的代理生态系统——这正是 Nous Research 所追求的"唯一内置学习循环的代理"。
对于希望构建生产级代理系统的开发者,Hermes 提供了一个经过验证的参考架构。
参考资源
- GitHub: https://github.com/NousResearch/hermes-agent
- 文档: https://hermes-agent.nousresearch.com/docs/
- Skills Hub: https://agentskills.io
- 论文/报告: 本文基于代码版本 v0.8.x 分析