Hermes Agent: Self-Improving AI Agent with Closed Learning Loop

code NousResearch-hermes-agent
agentself-improvingskillsmemorymulti-platformMCP

Hermes Agent: Self-Improving AI Agent with Closed Learning Loop #

Nous Research, Teknium | 2026-04 | https://github.com/NousResearch/hermes-agent Category: code | Tags: agent, self-improving, skills, memory, multi-platform, MCP, tool-calling, RL-training Read: 2026-04-16

Core Contribution #

开源的自我进化 AI Agent 框架,具备闭环学习能力(技能自动创建与改进、持久记忆、用户建模),支持 20+ 平台网关和 6 种终端后端,从 5 美元 VPS 到 GPU 集群均可运行。

Summary #

Hermes Agent 是 Nous Research 构建的开源 AI Agent,核心特点是「自我改进闭环」:Agent 在完成复杂任务后自动创建技能(Skill),后续使用中持续改进技能,并通过持久记忆和用户画像实现跨会话的个性化。

架构上,项目以 run_agent.py(10K 行)中的 AIAgent.run_conversation 为核心循环,实现了多 Provider 适配(OpenAI/Anthropic/OpenRouter/200+ 模型)、流式响应、工具调用(40+ 内置工具)、上下文压缩、会话持久化(JSONL + SQLite FTS5)、子代理委托等。Gateway 系统支持 Telegram/Discord/Slack/WhatsApp/Signal/飞书/钉钉等 20+ 平台,统一通过 BasePlatformAdapter 抽象层适配。

项目还包含面向研究的批量轨迹生成(batch_runner.py)、轨迹压缩(trajectory_compressor.py)和 Atropos RL 环境集成,用于训练下一代工具调用模型。v0.8.0 版本已实现 MCP 双向集成(既是 MCP 客户端也是 MCP 服务端)、ACP 适配器、cron 调度等企业级功能。

核心三问 #

逻辑故事还原 #

时代定位 #

2025-2026 年,AI Agent 从概念验证进入实用化竞赛。Claude Code、Cursor Agent、Devin、OpenHands 等产品密集发布。但多数 Agent 存在两个根本缺陷:(1) 无记忆——每次对话从零开始,不会从过去的成功/失败中学习;(2) 平台绑定——只能在特定 IDE 或终端中使用。Hermes Agent 试图在开源领域建立一个「持久存在、持续进化」的 Agent 范式。

背景 #

Claude Code 等商业产品虽然强大,但闭源且绑定特定 Provider。OpenHands 等开源方案侧重沙箱执行,缺乏学习闭环。Cursor 有 Skills 但不开源。市场上没有一个开源的、自带学习闭环的、平台无关的 Agent 框架。

约束推导 #

为何不可每次重新生成技能? 因为技能的价值在于累积经验——一个经过 10 次使用改进的技能比新生成的要好得多,重新生成等于丢弃了所有实践反馈。

为何不可把记忆放在上下文中? 因为上下文窗口有限(128K-1M tokens),而用户画像和项目知识会持续增长。必须持久化到文件/DB,按需注入。

为何不可统一所有平台的 API? 因为 Telegram 支持 Markdown、Discord 有 embed、Slack 用 Block Kit、WhatsApp 只有纯文本——渲染差异太大。解决方案是 BasePlatformAdapter 抽象 + PLATFORM_HINTS 让 Agent 根据平台调整输出格式。

破局 #

核心 insight 是:Agent 的价值不在单次执行能力,而在于跨会话的知识积累。Hermes 把 Agent 从「工具」变成「助手」——它认识你、记得你的偏好、能从错误中学习、随时间变得更好。这就像一个新员工 vs 一个跟了你三年的助理的区别。

核心技术壁垒 #

run_agent.pyAIAgent.run_conversation双轨消息设计是整个系统能稳定工作的关键:messages(持久化真相源)与 api_messages(每轮构造的请求视图)分离。这使得 ephemeral 插件注入(memory prefetch、context engine)不会污染持久化历史,同时 Anthropic prefix cache 的前缀可以保持稳定。没有这个设计,多轮对话中的缓存命中率会骤降,推理成本翻倍。

设计绑定批判 #

Key Findings #

Limitations #

Infrastructure Impact #


Deep Analysis (code) #

1. Project Identity #

2. Architecture & Module Map #

2a. Directory Structure #


hermes-agent/
├── run_agent.py           # 核心 Agent 循环(10K 行,AIAgent 类)
├── cli.py                 # 交互式 TUI(prompt_toolkit,9.7K 行)
├── model_tools.py         # 工具系统门面:发现、定义、分发
├── toolsets.py             # 工具集配置与解析
├── hermes_state.py         # SQLite (WAL) 会话/消息持久化 + FTS5
├── hermes_constants.py     # 全局常量
├── hermes_logging.py       # 分组件日志
├── hermes_time.py          # 时间工具
├── agent/                  # Agent 内部模块
│   ├── prompt_builder.py   #   系统提示组装
│   ├── context_compressor.py #  上下文压缩引擎
│   ├── anthropic_adapter.py #  Anthropic API 适配
│   ├── auxiliary_client.py  #  辅助 LLM 调用
│   ├── memory_manager.py    #  记忆插件编排
│   ├── error_classifier.py  #  API 错误分类与恢复策略
│   ├── skill_utils.py       #  技能索引与加载
│   └── ...                  #  credential_pool, rate_limit, display 等
├── tools/                  # 40+ 工具实现
│   ├── registry.py         #   工具注册中心
│   ├── terminal_tool.py    #   终端执行
│   ├── file_tools.py       #   文件读写搜索
│   ├── browser_tool.py     #   浏览器自动化
│   ├── mcp_tool.py         #   MCP 客户端
│   └── ...
├── gateway/                # 多平台消息网关
│   ├── run.py              #   GatewayRunner 主入口(8.6K 行)
│   ├── config.py           #   平台配置与枚举
│   └── platforms/          #   20+ 平台适配器
│       ├── base.py         #     BasePlatformAdapter 抽象
│       ├── telegram.py
│       ├── discord.py
│       ├── feishu.py
│       └── ...
├── hermes_cli/             # CLI 子命令
│   ├── main.py             #   `hermes` 入口
│   ├── commands.py         #   斜杠命令注册表
│   └── ...
├── skills/                 # 内置技能(YAML+Markdown)
├── plugins/                # 插件(记忆 provider 等)
├── cron/                   # 定时任务调度
├── mcp_serve.py            # MCP 服务端(暴露 Hermes 给 Cursor/Claude Code)
├── batch_runner.py         # 批量轨迹生成
├── trajectory_compressor.py # 离线轨迹压缩
├── tests/                  # 测试套件
└── website/                # 文档站

2b. Core Modules #

ModuleDirectoryLOCResponsibility
Agent Looprun_agent.py~10,500对话编排、工具执行、流式、重试、压缩、持久化
CLI TUIcli.py~9,800prompt_toolkit 交互界面、快捷键、slash 命令
Gatewaygateway/~22,00020+ 平台消息网关、授权、会话管理
Toolstools/~12,00040+ 内置工具注册与实现
Agent Internalsagent/~8,000提示词、压缩、错误分类、记忆、技能
Statehermes_state.py~1,200SQLite WAL + FTS5 会话持久化
Model Toolsmodel_tools.py~700工具发现、定义生成、分发
Batch/RLbatch_runner.py + trajectory_compressor.py~3,500轨迹生成与压缩

2c. Architecture Diagram #


┌─────────────────────────────────────────────────────────────────┐
│                        User Interfaces                          │
│  ┌──────────┐  ┌───────────┐  ┌──────────┐  ┌───────────────┐  │
│  │  CLI TUI │  │  Telegram │  │  Discord │  │ Slack/飞书/...│  │
│  │ (cli.py) │  │ (gateway) │  │ (gateway)│  │  (gateway)    │  │
│  └────┬─────┘  └─────┬─────┘  └────┬─────┘  └──────┬────────┘  │
│       │               │             │               │            │
│       └───────────────┴──────┬──────┴───────────────┘            │
│                              │                                    │
│                    ┌─────────▼──────────┐                        │
│                    │   AIAgent Loop     │                        │
│                    │ (run_agent.py)     │                        │
│                    │                    │                        │
│                    │ ┌───────────────┐  │                        │
│                    │ │ messages      │  │ ← 持久化历史           │
│                    │ │ (真相源)      │  │                        │
│                    │ └───────┬───────┘  │                        │
│                    │         │          │                        │
│                    │ ┌───────▼───────┐  │                        │
│                    │ │ api_messages  │  │ ← 每轮构造(ephemeral)  │
│                    │ │ (请求视图)    │  │                        │
│                    │ └───────┬───────┘  │                        │
│                    │         │          │                        │
│                    │    ┌────▼────┐     │                        │
│                    │    │ LLM API │     │                        │
│                    │    │ (stream)│     │                        │
│                    │    └────┬────┘     │                        │
│                    │         │          │                        │
│                    │    tool_calls?     │                        │
│                    │    ┌────▼────┐     │                        │
│                    │    │ Execute │     │                        │
│                    │    │ Tools   │     │                        │
│                    │    └────┬────┘     │                        │
│                    │         │          │                        │
│                    │    continue/break  │                        │
│                    └────────────────────┘                        │
│                              │                                    │
│              ┌───────────────┼───────────────┐                   │
│              │               │               │                    │
│     ┌────────▼──────┐ ┌─────▼──────┐ ┌──────▼──────┐            │
│     │ Tool Registry │ │ Memory     │ │ Skills      │            │
│     │ (40+ tools)   │ │ (MD+Honcho)│ │ (YAML+MD)   │            │
│     └───────────────┘ └────────────┘ └─────────────┘            │
│                              │                                    │
│                    ┌─────────▼──────────┐                        │
│                    │   SessionDB        │                        │
│                    │ (SQLite WAL+FTS5)  │                        │
│                    └────────────────────┘                        │
└─────────────────────────────────────────────────────────────────┘

2d. Key Design Decisions #

  1. 双轨消息而非单一消息列表——messages 用于持久化,api_messages 每轮构造用于请求。好处:prefix cache 稳定、ephemeral 注入不污染历史。代价:复杂度显著增加(两套消息需要同步字段映射)。
    1. 工具内联执行而非全走 registry——todo/memory/session_search/delegate 等「有状态工具」在 Agent 循环内直接执行,不经过 registry.dispatch。好处:避免向 registry 传递 Agent 内部状态(TodoStore, SessionDB 等)。代价:工具执行逻辑有两份实现,增加了维护负担。
      1. 多 Provider 适配内置于 Agent 而非抽象层——OpenAI/Anthropic/Codex 三种 API 模式在 run_conversation 内用 api_mode 分支处理。好处:紧密控制每种 API 的边界情况。代价:run_agent.py 膨胀到 10K 行。
        1. 技能用文件系统而非数据库——Skills 存储为 ~/.hermes/skills///SKILL.md。好处:人类可读可编辑,git 友好。代价:多实例需要共享文件系统。
          1. 网关共享 Agent 代码——CLI 和 Gateway 都实例化 AIAgent,共享完全相同的循环。好处:一致的行为。代价:网关需要处理 Agent 的非线程安全假设。
          2. 3. Entry Points & API Surface #

            
            Entry: hermes (hermes_cli/main.py:main)
              Input: CLI subcommands (chat, gateway, model, tools, config, doctor, ...)
              Output: Interactive TUI or subcommand result
              Side effects: Reads/writes ~/.hermes/ config and state
            
            Entry: hermes-agent (run_agent.py:main)
              Input: --model, --toolset, --query, conversation_history
              Output: AIAgent.run_conversation result dict
              Side effects: Tool execution (file/terminal/web), session persistence
            
            Entry: hermes-acp (acp_adapter/entry.py:main)
              Input: ACP protocol messages
              Output: ACP responses
              Side effects: Delegates to AIAgent
            
            Entry: hermes mcp serve (mcp_serve.py)
              Input: MCP stdio protocol (from Cursor/Claude Code)
              Output: conversations, messages, events
              Side effects: Reads session state, can send messages
            

            4. Core Data Structures #

            StructureFilePurposeLifetimeThread Safety
            AIAgentrun_agent.py对话编排器,持有所有状态Per conversation (CLI) / Per message (Gateway)非线程安全,单线程使用
            messages: List[Dict]run_agent.py持久化对话历史(user/assistant/tool)Per conversation主线程独占
            api_messages: List[Dict]run_agent.py每轮构造的 API 请求视图Per API call局部变量
            IterationBudgetrun_agent.py线程安全迭代预算计数器Per conversationthreading.Lock
            SessionDBhermes_state.pySQLite WAL 会话/消息数据库SingletonBEGIN IMMEDIATE + 随机退避
            MemoryStoretools/memory_tool.pyMEMORY.md + USER.md 读写Per AIAgent主线程独占
            ContextCompressoragent/context_compressor.py上下文压缩引擎Per AIAgent主线程独占
            TodoStoretools/todo_tool.py任务列表管理Per conversation主线程独占
            GatewayRunnergateway/run.py网关主进程,持有所有平台 adapterSingleton各平台在独立线程/协程
            BasePlatformAdaptergateway/platforms/base.py平台抽象基类Per platform平台内单线程

            5. Critical Path: User Message → Response #

            
            [User Input]
              → cli.py: _on_enter() / gateway: _handle_message()
                → AIAgent.run_conversation(user_message, conversation_history)
                  → _build_system_prompt() [if not cached]                     ~10ms
                  → _compress_context() [if tokens > threshold]                ~2-5s (LLM call)
                  → while iteration_budget.remaining > 0:
                    → _build_api_kwargs(api_messages, tools)                   ~1ms
                    → _interruptible_streaming_api_call()                      ~1-30s (LLM)
                      → stream deltas → stream_callback (TUI/platform)
                    → if tool_calls:
                      → _execute_tool_calls()                                  ~0.1-60s
                        → handle_function_call() / _invoke_tool()
                      → append tool results to messages
                      → continue
                    → else:
                      → final_response = content
                      → break
                  → _persist_session() → JSONL + SQLite                        ~10ms
                  → synthesis (memory sync, skill nudge)                       ~100ms
                ← result dict with final_response
              ← Display to user / Send to platform
            

            6. Concurrency Model #

            • 主线程:Agent 循环(run_conversation)在单线程中执行,包括 LLM API 调用和工具执行。
            • 工具并行_should_parallelize_tool_batch 判断后可用 ThreadPoolExecutor(最多 8 worker)并行执行工具,前提是工具路径不冲突且都在安全集合中。
            • 流式:API 流式响应在独立线程中消费(chat completions)或异步事件驱动(Anthropic),有 stale stream 超时检测。
            • Gateway:每个平台 adapter 可能在独立线程或 asyncio loop 中运行(Telegram 用 python-telegram-bot 的 Application,Discord 用 discord.py 等)。GatewayRunner 的 _handle_message 在各平台的回调中执行。
            • SQLiteBEGIN IMMEDIATE 防止并发写冲突,有随机退避重试。
            • 已知风险AIAgent 本身不是线程安全的。Gateway 中如果同一用户在短时间内发送多条消息,需要靠 _active_conversations 锁来排队。

            7. Tech Debt & Code Quality #

            IssueLocationSeverityImpact
            巨型单文件run_agent.py (10K 行)High传输层/编排/恢复耦合,难以独立测试和修改
            工具执行双路径_execute_tool_calls_sequential vs _invoke_toolMedium逻辑重复,新工具需要在两处都加
            Dict 代替 dataclassmessages, result, api_kwargsMedium无类型检查,字段名拼写错误不会报错
            字符串拼接 system prompt_build_system_promptLow可读性差,但功能正确
            魔术数字各种阈值(85%, 50%, 8 workers, 3 retries)Low散落各处,缺乏集中配置

            8. Comparison with Alternatives #

            FeatureHermes AgentClaude CodeCursor AgentOpenHands
            开源✅ MIT✅ MIT
            自我改进技能✅ 创建+patch✅ Skills
            持久记忆✅ MD+Honcho
            多平台✅ 20+❌ CLI only❌ IDE only❌ Web only
            模型无关✅ 200+❌ Claude only✅ 多模型✅ 多模型
            MCP 集成✅ 双向✅ 客户端✅ 客户端
            RL 训练管线✅ Atropos
            上下文压缩✅ 两层✅ 内置✅ 内置✅ 基础
            子代理委托
            定时任务✅ Cron

            9. Verdict & Recommendations #

            Should you use it?

            • 如果你需要一个可以 7x24 运行、从 Telegram/Discord 远程操控、随时间变得更聪明的 AI 助手——Hermes 是目前开源领域的最佳选择
            • 如果你需要面向特定 IDE 的编码助手——Claude Code 或 Cursor 更合适
            • 如果你需要 GPU 推理优化——这不是正确的项目

            Top 3 architectural improvements:

            1. 拆分 run_agent.py——用状态机或 strategy pattern 将 API 模式(OpenAI/Anthropic/Codex)、工具执行、错误恢复拆成独立模块
            2. 统一工具执行路径——用依赖注入替代当前的 registry + agent 内联双路径,所有工具通过统一接口执行
            3. 引入类型系统——用 dataclass/Pydantic 替代 Dict 传递核心数据结构(messages, result, tool definitions)
            4. 10. Ecosystem Influence #

              • 技能标准:兼容 agentskills.io 开放标准,推动了 Agent 技能的标准化
              • MCP 双向集成:既作为 MCP 客户端调用外部工具,又作为 MCP 服务端被 Cursor/Claude Code 调用——这种双向模式可能成为 Agent 互操作的范式
              • RL 训练管线:Atropos 集成为工具调用模型的强化学习训练提供了完整的数据生成和评估管线
              • 从 OpenClaw 演化:项目的前身是 OpenClaw,通过快速迭代(v0.2→v0.8)验证了开源 Agent 框架的可行性