Hermes Agent 综合调研报告

·
AIagent
Contents · 19

基于 hermes-agent v0.7.x 主线(run_agent.py 9439 行)和 hermes-agent-self-evolution(截至 2026-04 末,7 次 commit)。官方文档:hermes-agent.nousresearch.com/docs

TL;DR

本报告 1400+ 行,本节是全篇导航。每条结论后标注对应章节,采访前可按兴趣跳读。措辞尽量沿用原文描述,推论性判断会显式标出。

一句话概括

Hermes 是 Nous Research(AI 研究机构)开发的 agent 框架,自述为 “Evolutionary self-improvement for Hermes Agent”(README.md:3)。报告分两部分:上篇盘点 Hermes 相对其他四个框架(Claude Code / Codex CLI / OpenClaw / Pi)的独特做法(7 项独有命名 + 10 条设计独走 + 12 条工程手法);下篇深入分析独立仓库 hermes-agent-self-evolution 的 GEPA 优化管道,并对照代码审计 PLAN.md 的实现落差。

核心事实(对采访准备最相关,严格引用原文)

关于主仓库 Hermes:

  • run_agent.py 9439 行,AIAgent 类独占 472-9223 行(即单个类 8752 行)[§4.4]
  • 支持 17 个 IM/平台适配器,包括 Discord、Slack、Telegram、Feishu、Signal、WhatsApp 等 [§2.1]
  • 同时原生支持三种 LLM API:OpenAI Chat Completions、OpenAI Codex Responses、Anthropic Messages(architecture.md:30-37:“3 API Modes: chat_compl. / codex_resp. / anthropic”)[§2.7]
  • 文档列出可插拔的 7 个外部 memory provider:Honcho、OpenViking、Mem0、Hindsight、Holographic、RetainDB、ByteRover(overview.md:42)[§2.5]

关于独立仓库 Self-Evolution:

  • 自述采用 DSPy + GEPA (Genetic-Pareto Prompt Evolution),“ICLR 2026 Oral, MIT licensed”(README.md:26)[§6]
  • 成本自述:”~$2-10 per optimization run”、“No GPU training required”(README.md:7)[§7.3]
  • 定位自述:“Lives in its own repo (NousResearch/hermes-agent-self-evolution), operates ON hermes-agent — not part of it”(PLAN.md:5)[§7.1]
  • 三条硬限定(PLAN.md 原文):不训练权重(PLAN.md:17)、“No evolved content is ever hot-swapped into an active conversation”(PLAN.md:694)、“All evolved changes go through a pull request”(PLAN.md:705-706)[§6]
  • 仓库实际规模(截至 2026-04 末):3762 行 Python、7 次 git commit、2 个测试文件共 190 行、1 份 14.5KB 的 Phase 1 validation PDF [§11.1]

独特做法速览(想 drill down 就跳到对应章节)

7 项独有命名(上篇 §1):

Hermes 用词一句话含义章节
Procedural MemorySkills 是记忆的一种,和 MEMORY.md 事实记忆对偶§1.1
MEMORY.md + USER.md事实记忆拆成环境(2200 字符)+ 用户画像(1375 字符)两份§1.2
Durable Identity (SOUL.md)身份绑实例不绑项目,占 system prompt 第 1 槽§1.3
Frozen Snapshot Pattern显式命名 prompt cache 取舍:session 内记忆变更不进 prompt§1.4
Input vs Output Guardrails拦外部进 + 拦自己出,双向安全边界§1.5
Subagents Know Nothing子 agent 零知识契约(父需显式传 context)§1.6
Shadow Git Checkpoint~/.hermes/checkpoints/ 独立 git,用户项目 .git 不碰§1.7

10 条设计独走(上篇 §2):常驻多平台 Agent / Skills Hub 联邦生态 / Fallback Skill 条件激活 / Skill 即 Slash Command / Memory Provider 插件化 / RL 数据导出(ShareGPT) / 三种 API 模式并存 / Context References @-expansion / Subagent 独立 Terminal / DM 配对码跨渠道身份绑定

12 条工程手法(上篇 §3):记忆容量硬上限 / 记忆写入三路并行 / 压缩 5 阶段 + 7 段摘要 / 孤儿 tool stub 注入 / Path-scoped 并发 / 五跳 Fallback Chain + 同步窗口 / Skill 3 层渐进披露 / 模型族差异化 prompt / coerce_tool_args 类型强制 / SubdirectoryHintTracker / 双层 skill 进化链路(§3.11——承接下篇)/ Streaming 当健康探针

Self-Evolution 章节导航(下篇)

内容适合谁读
§6精确定义:什么是 / 不是 self-evolution所有人必读——澄清术语
§7官方原文 5 段 + 解读(定位、算法、成本、四层对象、零修改原则)想引用官方说法做采访提问
§8动机来源 5 条(技术、结构、产品、哲学、现实)采访”为什么做”这类问题
§9五 Phase 实现思路(PLAN.md 的设计图)想问 roadmap 的人
§10和 RL / fine-tuning / 运行时自改 / 黑盒方案的区别避免和受访者概念错位
§11PLAN vs 代码真实:七处差距 + 代码走读采访可信度核心章节

§11 摘要:PLAN vs 代码(本报告最硬的事实,措辞按代码核对过)

PLAN.md 长达 782 行,描绘完整的五阶段自动优化管道;代码仓库总计 7 次 commit,只有 Phase 1 有可跑实现。七处具体差距(每条都有代码位置可查):

  1. Fitness 实际是关键词重叠启发式,不是 PLAN 宣称的 LLM-as-judgefitness.py:107-136skill_fitness_metric()(word_overlap × 0.7) + 0.3 baseline;LLMJudge 类存在但未被调用 [§11.3 差距 1]
  2. GEPA 有 MIPROv2 fallback(evolve_skill.py:156-177 用 try/except 包裹,异常时降级)[差距 2]
  3. 约束门是四件不是五件:validate_all() 只跑 size / growth / non_empty / structure;语义保留检查、缓存兼容检查代码里没有;pytest 有方法但默认不跑 [差距 3]
  4. benchmark_gate.py 不存在——PLAN 设计的 TBLite/YC-Bench Gate 代码层面是空的 [差距 4]
  5. pr_builder.py 不存在——产物保存到本地 output/<skill>/<timestamp>/ 目录,不建分支不发 PR [差距 5]
  6. external_importers.py 785 行(仓库最大文件):支持挖 Claude Code / Copilot / Hermes 三处 session——比 PLAN 做得更多(PLAN 只要求挖 Hermes 自己的 SessionDB)[差距 6]
  7. CLI 不是 hermes evolve 子命令,而是 python -m evolution.skills.evolve_skill [差距 7]

Phase 实现状态:Phase 1 ✅ 可跑 / Phase 2-5 ⛔ 四个目录都只有 1 行空的 __init__.py [§11.2]

本节是我(调研者)对代码的直接审计,非原文结论。PLAN.md 自己也写了 “we may stop at Phase 1 or 2 if the returns diminish — no obligation to do all five”——说明 Nous 团队对落差有预期。

采访可问的点(仅基于材料梳理,不是建议清单)

  • 术语确认:想问 self-evolution 具体指 [§6] 的精确定义,还是涵盖运行时 nudge?官方 PLAN 明示不包含权重训练和 hot-swap
  • GEPA fallback 现状:evolve_skill.py:156-177 的 try/except 是临时措施还是永久设计?DSPy 的 GEPA 集成何时稳定?
  • Fitness 函数演进:LLMJudge 类已经写了但没接入主流程,是因为成本考虑、正确性考虑、还是还没开工?
  • 基建超出 PLAN:external_importers 支持 Claude Code / Copilot session 挖取——这是否暗示 Hermes 想做跨 agent 的 skill 优化基建?[§11.3 差距 6]
  • Phase 2-5 的优先级:目前四个目录都是空的,但 PLAN 写了 13-17 周时间表——实际优先级和 PLAN 一致吗?
  • Roadmap 与落差的关系:PLAN.md 780 行 vs 代码 3762 行,文档写作的节奏是否刻意超前于代码?
  • 跨框架 skill 生态:Hermes 默认装 openai/skillsanthropics/skills 是出于什么判断?agentskills.io 是 Hermes 推动的吗? [§2.2]
  • “给东西起名字”的方法论:Procedural Memory、Durable Identity、Frozen Snapshot 这些命名是事后总结还是设计时就这么构思的?[§1]
  • 9400 行单体的取舍:作者是否考虑过拆分?常驻 agent 形态是否在本质上不适合组件化?[§4.4]

全报告脉络图

[上篇] Hermes 独特做法盘点
  §1 概念命名 ──── 7 项独有命名(Procedural Memory 等)
  §2 设计独走 ──── 10 条产品/架构选择
  §3 工程手法 ──── 12 条实现细节(§3.11 承接下篇)
  §4 产品姿态 ──── 为什么这么设计(出身 / 用户 / 生态 / 代码形态)
  §5 命名对照表 ── 快速查阅

[下篇] Self-Evolution 专题
  §6 精确定义 ──── 什么是 / 不是
  §7 官方描述 ──── 5 段 PLAN.md 引用 + 解读
  §8 动机来源 ──── 5 条(推论,基于 PLAN.md 字里行间)
  §9 五 Phase 设计 ─ PLAN 版的实现思路
  §10 方案区别 ──── 不是 RL / 不是 fine-tune / 不是运行时 / 不是黑盒
  §11 PLAN vs 代码 ─ 七处差距 + Phase 1 代码走读 10 步 ★硬事实集中区

[总结] 7 条核心观察
[附录] A. 主仓库索引 / B. Self-Evolution 仓库索引(真实代码 vs PLAN 宣称) / C. 外部引用

上篇:Hermes 独特做法盘点

1. 概念命名:Hermes 用什么词描述自己

Hermes 官方文档和源码里有一批其他框架没有其他框架不这么叫的命名。这些命名不是市场话术,它们对应着实际的代码分支和行为差异。

1.1 Skills = Procedural Memory

Hermes 官方文档(website/docs/user-guide/features/skills.md:235):

The agent can create, update, and delete its own skills via the skill_manage tool. This is the agent’s procedural memory — when it figures out a non-trivial workflow, it saves the approach as a skill for future reuse.

工具参考(website/docs/reference/tools-reference.md:127)也明写:

skill_manage … Skills are your procedural memory — reusable approaches for recurring task types.

这是 Hermes 独有的认知命名。其他四框架对 Skills 的定位:

框架对 Skill 的叫法含义
Claude CodeSkills”指令资产”——告诉 Agent 怎么做一件事
Codex CLISlash Commands / Prompts”预设任务入口”
OpenClawSkills(通过 Gateway daemon)“用户/开发者配置的任务流”
Pi不做 Skills完全交给 Extension
HermesProcedural Memory记忆的一种——和 MEMORY.md 的事实记忆对偶

Hermes 把 Skills 放进了记忆论的坐标系——“怎么做”是记忆的一种(procedural),“知道什么”是另一种(declarative / semantic)。MEMORY.md + USER.md 承载后者,SKILL.md 承载前者。

这种对偶命名带来了具体的行为后果:

  • Agent 发现”跑通了一个非平凡工作流”时会主动沉淀(如同写记忆)
  • 触发条件明写在文档里(skills.md:239-242):5+ 工具调用的任务完成、错误后找到可行路径、用户纠正过、发现非平凡流程
  • skill_manage 工具和 memory 工具的命名风格对齐——两者都是”agent 自己管理自己记忆”的工具

对照来看其他四框架里 Skill 和 Memory 是分属两个独立维度的工具,只有 Hermes 把它们放在一个维度上。

1.2 Semantic Memory = MEMORY.md + USER.md 双文件

延续”记忆类型学”的命名逻辑,Hermes 把事实记忆进一步拆成两种:

  • MEMORY.md(2200 字符硬上限):项目事实、环境配置、工具坑、学到的做法——“agent 的个人笔记”
  • USER.md(1375 字符硬上限):用户画像、沟通偏好、忌讳——“agent 对用户的认知”

官方文档(memory.md:17-20)把这两份文件并列呈现,字符上限和用途各自明写。其他框架的处理:

框架记忆拆分
Claude Code一类目录下多主题文件(用户/项目/反馈/引用 4 类)
Codex CLIAGENTS.md 单文件 + 两阶段管道
OpenClaw短期日记 → MEMORY.md 晋升
Pi不做
HermesMEMORY.md(事实)+ USER.md(用户画像)两份文件并列

Hermes 的拆法是”把用户本人单独建档”——和 Claude Code 4 分类不同,粒度更粗但含义更直白。配合 Skills 是 procedural memory 的命名,Hermes 的完整记忆图景是:

Hermes 记忆论
├── Semantic(事实)
│   ├── MEMORY.md — 环境/工具/项目
│   └── USER.md — 用户画像
└── Procedural(过程)
    └── ~/.hermes/skills/*/SKILL.md — 怎么做事

别家没有这样的总分结构。

1.3 SOUL.md = Durable Identity

官方文档(personality.md:9):

SOUL.md is the primary identity — it’s the first thing in the system prompt and defines who the agent is.

关键设计:

  • 占据 system prompt 第 1 槽位,替换 hardcoded 默认身份
  • 只从 HERMES_HOME(即 ~/.hermes/)读取,不从当前工作目录读——“personality belongs to the Hermes instance itself”(personality.md:47)
  • 首次启动自动生成初始 SOUL.md,已有的永不覆盖
  • /personality preset 分层:SOUL.md 是持久身份,preset 是会话级临时叠加

其他框架对”agent 是谁”的处理:

框架身份命名形态
Claude CodeSystem Prompt(内置)代码常量
Codex CLISystem Prompt(内置)代码常量
OpenClawPersona(通过 Gateway config)YAML 配置项
Pi默认身份(可覆盖)通过 API 参数传
HermesSOUL.md用户可编辑的独立文件,绑定到实例而非项目

“身份是实例的属性,不是项目的属性”——这个判断让 Hermes 在 monorepo/多项目场景下身份稳定。其他框架的”身份”要么写死在代码里,要么会被项目级配置覆盖。

1.4 Frozen Snapshot Pattern

官方文档(memory.md:47)显式命名了这个设计:

Frozen snapshot pattern: The system prompt injection is captured once at session start and never changes mid-session. This is intentional — it preserves the LLM’s prefix cache for performance. When the agent adds/removes memory entries during a session, the changes are persisted to disk immediately but won’t appear in the system prompt until the next session starts.

这个模式所有框架都在某种程度上做(Anthropic prompt cache 的存在逼迫大家这么设计),但只有 Hermes 给它起了名字并明示这个取舍

代价也写得很直白:session 中途写的记忆要下次 session 才能被 agent 看到(但 tool response 仍然看到最新状态)。

这种”命名 + 文档化取舍”本身是 Hermes 的姿态——把设计决策暴露给用户,而不是藏在实现里。

1.5 Input Guardrails vs Output Guardrails

Hermes 在自己的 security 文档和源码注释里显式区分两类安全边界:

  • Output Guardrails:拦截 agent 要做的事(工具调用审批、危险命令黑名单、沙箱边界)——所有框架都做
  • Input Guardrails:拦截外部内容进入 agent 上下文(用户指令文件扫描、记忆写入扫描、Skill 上传扫描、日志脱敏)——只有 Hermes 做了一整套

具体源码:

  • agent/prompt_builder.py:36-74 — 用户指令文件(.hermes.md / AGENTS.md / CLAUDE.md)10+ 种 prompt injection 正则
  • tools/memory_tool.py:60-76 — 记忆写入前 ~15 类威胁正则(包括 authorized_keys / ~/.ssh / .env 检测)
  • tools/skills_guard.py:82-484 — Skill 上传前 120+ 条威胁正则
  • agent/redact.py — 日志输出前 50+ 种 API Key 模式脱敏

命名本身就是设计——把”拦外部进来”和”拦自己出去”分成两个概念后,工程上能各自独立演进。

1.6 Subagents Know Nothing

官方文档(delegation.md:35,特别用 warning 标签):

:::warning Critical: Subagents Know Nothing Subagents start with a completely fresh conversation. They have zero knowledge of the parent’s conversation history, prior tool calls, or anything discussed before delegation.

这不是实现细节,是写入契约的设计原则。后果:

  • 父 agent 必须把所有需要的 context 塞进 goal + context 字段
  • 子 agent 完成后只把 summary 回传,不带完整 transcript
  • 父子 context 完全隔离

Claude Code 也做 sub-agent(Task tool),但没有明示这条”零知识”契约——实际上 Claude Code 允许父子通过 memory 文件间接共享信息。Hermes 把这条挑明后,delegation 的用法和错误模式都变得可预测。

1.7 Shadow Git Checkpoint

官方文档(checkpoints-and-rollback.md:12):

This safety net is powered by an internal Checkpoint Manager that keeps a separate shadow git repository under ~/.hermes/checkpoints/ — your real project .git is never touched.

设计要点:

  • 独立的 git 仓库,挂在 ~/.hermes/checkpoints/<dir_hash>/——用户项目的 .git 不碰
  • 自动触发于 write_file / patch / rm / mv / sed -i / truncate / shred / > redirect / git reset|clean|checkout
  • 一个目录每个 turn 最多一次 checkpoint(避免长 session 刷屏)
  • /rollback N 恢复 + 附带撤销最近一轮对话;/rollback diff N 预览差异;/rollback N <file> 按文件恢复

五框架里其他四家要么不做文件级回滚(Pi / OpenClaw),要么依赖用户自己的 git 操作(Claude Code / Codex CLI 的”建议用户 commit”)。命名上”shadow git”很精确——不是新写存储系统,就是藏一个独立的 .git 起来自用。

1.8 小结:命名带来的视角差

Hermes 的命名别家叫什么视角差
Procedural Memory(Skills)Skills / PlaybooksSkills 是记忆论的一部分
Semantic Memory(MEMORY+USER)Memory / Notes事实记忆再拆用户画像
Durable Identity(SOUL.md)System Prompt身份是实例属性不是项目属性
Frozen SnapshotPrompt Cache把取舍明示给用户
Input Guardrails拦外部进来单独建模
Subagents Know NothingSub-agent零知识契约写进文档
Shadow Git Checkpoint独立 .git 做安全网

这些命名不是修辞——每一条都对应一段实打实的代码和一种用户可见的行为。


2. 设计选择上的独走

除了命名,Hermes 在几个方向上走了别人没走的路。

2.1 产品形态:常驻多平台个人 Agent

Hermes 不是 CLI 工具,也不是 IDE 插件。它的默认形态是常驻进程:

  • 17 个平台适配器(gateway/platforms/*.py):Discord、Slack、Telegram、Feishu、Signal、WhatsApp、Matrix、Mattermost、DingTalk、WeCom、Email、SMS、Webhook、Home Assistant、Telegram Network、API Server
  • Cron jobs 内置在 Gateway 进程里
  • SessionDB(SQLite + FTS5)持久化所有会话
  • 同一个 Agent 能在手机 Telegram、桌面 Slack、Web、Email 之间无缝切换——跨渠道共享同一身份

对照:

  • Claude Code:CLI/IDE,单用户 REPL 形态
  • Codex CLI:CLI + Web(ChatGPT 专属),面向编码任务
  • OpenClaw:20+ 消息渠道,但定位是”个人 AI 网关”——用户和 agent 是 1:1 关系
  • Pi:面向开发者的 SDK,产品形态由使用者决定
  • Hermes:既像 OpenClaw(多渠道),又像 Claude Code(编码能力重),做得比谁都重

这是 run_agent.py 9439 行的直接原因——要塞进 17 平台适配、cron、browser、voice、TTS、vision、MCP、RL 训练轨迹导出…产品形态决定了工程形态。

2.2 Skills Hub:联邦式技能生态

官方文档(skills.md:259-356)展示了 Hermes 对接的 skills 来源:

来源例子性质
officialofficial/security/1passwordHermes 官方仓库的可选 skills
skills-shskills-sh/vercel-labs/agent-skills/...Vercel 的 skills.sh 公开目录
well-knownwell-known:https://mintlify.com/docs/...任意网站发布 /.well-known/skills/index.json
githubopenai/skills/k8s任意 GitHub repo/path
clawhubOpenClaw 社区仓库跨框架互操作
lobehubLobeChat 社区跨框架互操作
claude-marketplaceAnthropic 官方跨框架互操作

默认 taps(skills.md:346-350):

  • openai/skills
  • anthropics/skills
  • VoltAgent/awesome-agent-skills
  • garrytan/gstack

Hermes 直接装 OpenAI 和 Anthropic 发布的官方 skills——不是自己写一套格式,而是对齐 agentskills.io 开放标准。这是”agent 框架互通”的一个具体形态——skill 不再是某家的私产,而是可以跨框架搬的标准化文档。

2.3 Skill 的条件激活

官方文档(skills.md:110-120):

metadata:
  hermes:
    fallback_for_toolsets: [web]      # 只在 web toolset 不可用时显现
    requires_toolsets: [terminal]     # 只在 terminal toolset 可用时显现
    fallback_for_tools: [web_search]  # 只在 web_search 不可用时显现
    requires_tools: [terminal]        # 只在 terminal 可用时显现

再加 platforms: [macos, linux] 按操作系统限制。

Fallback Skill 这个概念其他框架都没有——免费/本地版 skill 只在付费工具不可用时才冒出来。不是 skill 被加载的问题,而是 skill 从 agent 视野里消失——不进 system prompt、不进 skills_list()、不注册 slash command。

这是把”skill 暴露面”做成动态可配置——比 Claude Code 的 always / ondemand 二元、比 OpenClaw 的插件开关都更细。

2.4 Skill 即 Slash Command

官方文档(skills.md:22-35):

Every installed skill is automatically available as a slash command.

/gif-search funny cats
/axolotl help me fine-tune Llama 3 on my dataset
/github-pr-workflow create a PR for the auth refactor
/plan design a rollout for migrating our auth provider

装一个 skill 就自动多一条 slash command,不需要额外注册。Claude Code 的 slash command 和 skill 是两套东西——skill 在 ~/.claude/skills/,slash command 在 ~/.claude/commands/,用户要写两份文件。Hermes 统一到一套。

更进一步,skill 可以和持久化产物绑定:plan skill 运行后把产物保存到 .hermes/plans/(skills.md:35)——skill 不只是指令,还能约定产物存放路径。

2.5 Memory Provider 插件化

官方文档列了 7 个外部 memory provider(overview.md:42):

Plug in external memory backends (Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover) for cross-session user modeling and personalization beyond the built-in memory system.

这些都是独立的开源/商业 AI 记忆研究项目。Hermes 自己的 MEMORY.md + USER.md 是 baseline,接入任意一个 provider 后能叠加更强的记忆(例如 Honcho 的用户建模、Mem0 的向量检索、Holographic 的分布式表示)。

Nous Research 是 AI 研究机构——这个设计暴露了他们的野心:agent 框架不只是应用层,还是研究记忆系统的实验床。别家(Claude Code / Codex CLI / OpenClaw / Pi)都是”自己做一套记忆就够了”,只有 Hermes 把记忆层做成了可插拔。

2.6 RL 数据导出

rl_cli.py 是顶层文件(与 run_agent.py 同级)。overview.md:45:

Generate trajectory data from agent sessions for reinforcement learning and model fine-tuning.

轨迹格式是 ShareGPT——业界训练数据通用格式。任何一次 session 都可以导出成训练样本,用于 fine-tuning 或 RL。

这让 Hermes 变成双重角色:既是 agent 应用,也是数据采集管道。Nous Research 用它给自家模型产训练数据,顺便开源给同行。这条反映了出身——作为 Nous Research 的 infra,Hermes 的设计一开始就考虑了”喂给研究员用”。

2.7 三种 API 模式并存

architecture.md:30-37:

3 API Modes: chat_compl. / codex_resp. / anthropic

Hermes 同时支持三种 LLM API 形态:

  • OpenAI Chat Completions
  • OpenAI Codex Responses(codex_responses)
  • Anthropic Messages

后果:Hermes 能用上 Anthropic prompt cache、OpenAI 的 reasoning 字段、Codex 的 response mode——这些在”统一抽象”的框架里会被抹平掉。代价是维护 3 套分支代码。

2.8 Context References:@-expansion

官方文档(overview.md:17):

Type @ followed by a reference to inject files, folders, git diffs, and URLs directly into your messages. Hermes expands the reference inline and appends the content automatically.

用户在消息里写 @README.md@https://example.com/doc——Hermes 把内容展开塞到消息末尾。这是显式的引用语法,而不是 IDE 的 autocomplete。

Claude Code 有类似的 @file 语法(借用 IDE 集成),但 Hermes 做成语言级——无论在 CLI、Slack、Telegram 都能用。跨渠道一致。

2.9 Subagent 有独立 Terminal

delegation.md:9:

The delegate_task tool spawns child AIAgent instances with isolated context, restricted toolsets, and their own terminal sessions.

每个子 agent 拿一个独立的 shell 进程——父子的环境变量、工作目录、命令历史互不污染。Claude Code 的 Task tool 里子 agent 共用父的 bash 环境。Hermes 的隔离更严。

配合”subagents know nothing”的零 context 契约,这是一个完整的”子进程式 subagent”——像操作系统里的 fork + exec,而不是函数调用。

2.10 跨渠道身份绑定(DM 配对码)

gateway/pairing.py(11468 字节)实现了DM 配对身份绑定:

  1. 用户首次在 IM DM 里发话
  2. Hermes 返回一个 8 字符的配对码(OWASP/NIST 标准)
  3. 用户在已登录的主系统(CLI/Web)输入这个码
  4. Hermes 把 IM 平台身份和系统身份绑定

绑定后,用户的权限、记忆、审批历史跨渠道共享——在 Slack 里批准过的操作,在 Telegram 上 agent 记得。

五框架里只有 Hermes 实现过这种跨渠道身份统一。别家要么单渠道(Claude Code / Codex CLI / Pi),要么每个渠道独立身份(OpenClaw)。


3. 工程手法上的独特选择

3.1 记忆的容量驱动管理

MEMORY.md 2200 字符、USER.md 1375 字符——这是 硬上限tools/memory_tool.py:111:

def __init__(self, memory_char_limit: int = 2200, user_char_limit: int = 1375):

达到上限后 memory_add 直接拒绝,agent 必须先 memory_replacememory_remove 腾位置。

这条设计的含义:强制 agent 自己做整理(合并相近条目、淘汰过期信息)。别家的选择:

  • Claude Code:不设上限,加天龄警告让 agent 判断
  • Codex CLI:两阶段管道,合并时显式 remove
  • OpenClaw:数学衰减函数自动降权
  • Pi:不做

Hermes 的方法最激进也最省事——容量即质量,没空间就必须清理。

3.2 记忆写入三路并行

其他框架对”记忆从哪里来”一般只做一条路(要么 agent 显式调工具,要么后台定期扫)。Hermes 同时做三条:

  1. 显式工具调用:memory_add / memory_replace / memory_remove 三个拆开的工具
  2. 后台 nudge 审查:每累积 10 次工具调用(run_agent.py:1029, 1038),response 发给用户之后后台 spawn 一个 review agent 扫描轨迹、决定是否追加记忆
  3. 压缩前冲刷:flush_memories()(run_agent.py:5733)在压缩触发前让 LLM 把”被压缩就丢”的东西写进 MEMORY.md

后台 nudge 独立计数:skill 和 memory 各自 10 次间隔互不干扰(run_agent.py:1129, 1132)。

3.3 压缩:5 阶段 + 7 段摘要模板

agent/context_compressor.py:565-577compress() 5 阶段:

  1. Prune old tool results(无 LLM 调用的快速预剪)
  2. Protect head messages(system + 首次 exchange)
  3. Find tail boundary by token budget(~20K tokens recent)
  4. Summarize middle turns with structured LLM prompt
  5. Iteratively update the previous summary on re-compression

摘要模板 7 段(context_compressor.py:287-349):

## Goal
## Constraints & Preferences
## Progress (### Done / ### In Progress / ### Blocked)
## Key Decisions
## Relevant Files
## Next Steps
## Critical Context

五框架的压缩深度:Hermes 5 阶段 > OpenClaw 4 层 > Claude Code 3 级 > Codex CLI 2 级 > Pi 1 级。

3.4 压缩的孤儿 tool stub 注入

agent/context_compressor.py:412-470:压缩会破坏 tool_call/tool_result 配对,Hermes 的 _sanitize_tool_pairs() 做两件:

  1. 删掉 tool_call 被压缩但 tool_result 残留的孤儿
  2. 为 tool_call 还在、result 被压缩丢的情况注入 stub result:
    "[Result from earlier conversation — see context summary above]"

含义:LLM 看到的不是”某个 tool 调过但没结果”(会触发幻觉重试),而是”某个 tool 调过、结果在上面的摘要里”——明示丢失发生过,避免 LLM 重复调用。

其他框架压缩后要么只做第 1 步(删孤儿 result),要么不处理(直接抛给 LLM)。Hermes 的 stub 注入是五框架里唯一。

3.5 Tool 并发:path-scoped 判断

run_agent.py:213-231 三分类:

_NEVER_PARALLEL_TOOLS = frozenset({"clarify"})

_PARALLEL_SAFE_TOOLS = frozenset({
    "read_file", "search_files", "web_search", "web_extract",
    "session_search", "skill_view", "skills_list", "vision_analyze",
    "ha_get_state", "ha_list_entities", "ha_list_services",
})

_PATH_SCOPED_TOOLS = frozenset({"read_file", "write_file", "patch"})

其他框架要么全串行(简单但慢),要么按工具类型白名单(粒度粗)。Hermes 独有的是第三档——文件操作按路径判断能否并发:改 3 个不重叠文件的 patch 可以并行,改同一文件的两个 patch 必须串行。

3.6 五跳 Fallback Chain + 同步窗口

run_agent.py:4860-4981_try_activate_fallback():

429 rate limit → jittered backoff 重试
413 content too large → 触发压缩后重试
context window exceeded → 换 context tier 更大的候选
credential 过期 → refresh 或换备份
provider 不可用 → 换家

五跳退避链是五框架里最深的。比这更独特的是:切 provider 时同步更新 context_compressor 的窗口阈值(run_agent.py:4954-4967):

self.context_compressor.context_length = fb_context_length
self.context_compressor.threshold_tokens = int(
    fb_context_length * self.context_compressor.threshold_percent
)

后果:从 Claude 200K 切到 GPT-4o 128K 时,压缩触发阈值从 170K 自动降到 109K。别家切 provider 后阈值不变——下一轮必然 413。

3.7 Skill 渐进式披露(3 层)

tools/skills_tool.py:640 / 719 / 787:

Tier 0  skills_categories()          → 几十字节,只返类别名
Tier 1  skills_list(category)        → 类别下 skill 的 name+description
Tier 2  skill_view(name, file_path)  → 完整 SKILL.md 或子文件

配合 ~/.hermes/skills/ 下 26 个类别、数百个 skill。一次性塞 system prompt 会炸 context window——渐进披露让 LLM 按需加载。

其他框架的做法:

  • Claude Code:子 agent fork 模式(spawn 专门的 skill agent)
  • OpenClaw / Pi:全量注入 system prompt(skill 少时可行)
  • Codex CLI:metadata 先行
  • Hermes:三层 + 文件级细化(Tier 2 还可以只读 skill 的某个子文件)

粒度最细,适合 skill 数量过百的场景。

3.8 模型族差异化 Prompt

run_agent.py:2704-2712:

if "gemini" in _model_lower or "gemma" in _model_lower:
    prompt_parts.append(GOOGLE_MODEL_OPERATIONAL_GUIDANCE)
if "gpt" in _model_lower or "codex" in _model_lower:
    prompt_parts.append(OPENAI_MODEL_EXECUTION_GUIDANCE)

按模型名子串匹配,插不同的行为段落:

  • Google 段:简洁、绝对路径、并行 tool call、改动前先验证
  • OpenAI GPT/Codex 段:tool 持久化、前置条件检查、验证、防幻觉
  • Claude:无特殊段(直接走基础指令,体现作者判断”Claude 最听话”)

其他框架对多 Provider 的处理都是”尽量一致”——用最小公分母。Hermes 反过来:承认不同 Provider 需要不同的 prompt,在运行时做分支。

3.9 coerce_tool_args:类型强制

model_tools.py:372-456:

def coerce_tool_args(tool_name, args):
    """Coerce tool call arguments to match their JSON Schema types.
    Handles "integer", "number", "boolean", and union types."""

LLM 生成 "count": "42" 但 schema 要 integer——Hermes 直接强转成 42"true"True。不抛错、不让 LLM 重来、不 silently pass。

这条选择暴露了 Hermes 的工程哲学:LLM 输出不可预测,运行时要容忍典型错误,而不是严格校验。其他框架(Claude Code / Codex CLI)会 schema 校验失败后让 LLM 重试。

3.10 SubdirectoryHintTracker:上下文跟随 agent 移动

agent/subdirectory_hints.py:48-219:

Agent 每次调带路径的 tool 时,tracker 检测目标是否”进入了未访问过的新目录”。如果是,把该目录的 AGENTS.md / CLAUDE.md / .cursorrules 读出来——追加到 tool result(不改 system prompt)。

含义:

  • Agent 在 monorepo 里切到子目录工作,子目录规则自动生效
  • 不改 system prompt,所以 prefix cache 不失效
  • 每文件 8000 字符上限,再过一遍安全扫描

五框架里只有 Hermes 做”context 跟着 agent 物理位置移动”。别家的 AGENTS.md 发现都是 session 开始时一次扫完,中途不变。

3.11 运行时 Skill nudge + 离线 GEPA 进化(双层 skill 进化链路)

两条分开的 Skill 进化通道——这是本报告下篇 self-evolution 专题的主题:

运行时 nudge(run_agent.py:9156-9176):每 10 次工具调用后台 spawn 一个 review agent 扫描近期轨迹,只创建新 skill,不覆盖已有——这是 skill 进化的第一道安全门。

离线 GEPA(独立仓库 hermes-agent-self-evolution):用 DSPy + GEPA 算法对已有 SKILL.md、tool description、system prompt 段落做反思式进化。落地方式:PR 到 hermes-agent 主仓库,从不直接 commit(但见下篇 §11——当前代码实现和这个宣称有差距)。

两者是互补的两层:

  • 运行时可以往 skill 库加新文件(低风险、零影响)
  • 改老文件必须离线 + GEPA + 约束门 + PR + 人审(高风险、要管控)

完整展开见下篇 §6–§11

3.12 Streaming 即使无消费者也走

Hermes 即使没有消费者也走流式,用于检测连接是否卡死。非流式调用如果 30 秒没返回任何 chunk,有可能 TCP 连接已死但应用层不知道。流式 + 心跳超时能及时抓到。Hermes 把流式当连接健康探针用,而不只是 UX 的逐字输出。


4. 产品姿态:Hermes 为什么这么做

几个独走的背后有一致的产品哲学:

4.1 出身:Nous Research 是 AI 实验室

  • 记忆系统可插拔 → 当研究实验床用
  • 轨迹导出 ShareGPT → 给自家模型产训练数据
  • 三种 API 模式并存 → 不牺牲任何前沿 Provider 的能力
  • GEPA 离线进化 → 反思式 prompt 优化是研究方向

这些设计是”先服务研究,再服务用户”的选择。Claude Code(Anthropic 自家产品)、Codex CLI(OpenAI 自家产品)都是”先服务自家模型卖货”,姿态不同。

4.2 用户:个人使用者 + 常驻场景

  • SOUL.md 绑定到实例不绑定到项目——“我在哪里工作都是我”
  • 17 平台 + DM 配对身份——“我在哪里都能找到 agent”
  • cron + voice + home assistant——“agent 不只是对话,还是自动化助手”
  • Checkpoint + /rollback——“我不怕 agent 搞坏我的东西”

对照 Claude Code(编码助手)、Codex CLI(OpenAI 编码产品)、OpenClaw(个人 AI 网关),Hermes 走了 OpenClaw 的”多渠道”+Claude Code 的”编码能力”合集,把两条路合并做重

4.3 生态:跨框架 skill 兼容

  • 默认装 openai/skillsanthropics/skills 两个 taps
  • 兼容 agentskills.io 开放标准
  • 整合 skills.sh / well-known / clawhub / lobehub / claude-marketplace

Hermes 不建自己的封闭 skill 生态——它押的是”skill 作为跨框架共享的资产”。这个姿态其他框架都没有,最接近的 OpenClaw 也是”自己的插件市场”。

4.4 代码形态:9400 行单体是有代价的姿态

run_agent.py 9439 行的单体是以上所有设计选择的自然结果——17 平台 + 多 API 模式 + 多记忆层 + checkpoint + skill 生态 + RL 导出 + voice + browser + MCP 全塞进一个 AIAgent 类(行 472-9223,一个类 8752 行)。

其他框架的克制(Pi 617 行、Claude Code 1729 行)来自”这是给别人用的 SDK/工具”的定位约束。Hermes 没有这个约束——作者不在意组件化复用,他们要的是”一个可跑的常驻个人 agent”。


5. Hermes 独有命名对照表(快速查阅)

Hermes 命名出处别家对应差异含义
Procedural Memoryskills.md:235tools-reference.md:127Skills / PlaybooksSkills 是记忆的一种
Semantic Memory(隐含)memory.md 结构Memory / Notes事实记忆拆成环境+用户画像
Durable Identitypersonality.md:9System Prompt身份绑实例不绑项目
Frozen Snapshot Patternmemory.md:47Prompt Cache(未命名)把取舍明示
Input Guardrailssecurity 文档 + 源码无对应拦外部进来单独建模
Output Guardrails同上Permission / Approval和 Input 并列
Subagents Know Nothingdelegation.md:35Sub-agent零知识契约
Shadow Git Checkpointcheckpoints-and-rollback.md:12无对应独立 .git 做安全网
Skills Hubskills.md:259Plugins / Registry联邦多源
Fallback Skillskills.md:110无对应skill 级条件激活
Well-known Skillsskills.md:328无对应.well-known/skills/ URL 发现
Platform Hintsprompt_builder.py:261无显式对应Agent 知道自己在哪
Context Referencesoverview.md:17@-mention(仅 IDE)语言级引用展开
Memory Providersmemory-providers.md无对应记忆层可插拔
SKILL as Slash Commandskills.md:22两套系统统一到一套
Flush Memoriesrun_agent.py:5733无对应压缩前冲刷
SubdirectoryHintTrackeragent/subdirectory_hints.py无对应跟着 agent 物理位置移动
GEPA Self-Evolutionhermes-agent-self-evolution 仓库无对应反思式进化 + PR-only(但见下篇 §11 落地差距)

下篇:Self-Evolution 专题

本篇是上篇 §3.11 的纵深展开。源材料:独立仓库 hermes-agent-self-evolution(MIT,Nous Research 2026),README.md(85 行)+ PLAN.md(782 行)+ 实际代码走读(3762 行 Python)。

阅读提示:§6–§10 基于 PLAN.md 的设计宣称,§11 对照实际代码审计 PLAN vs 代码的差距。两个视角都重要——PLAN 是 roadmap,代码是 MVP。

6. Self-Evolution 在 Hermes 语境下是什么

这个词在 Hermes 语境下有精确的技术含义,不是通用的”Agent 自学习”。

官方 README 第一句(README.md:3-5):

Evolutionary self-improvement for Hermes Agent. Hermes Agent Self-Evolution uses DSPy + GEPA (Genetic-Pareto Prompt Evolution) to automatically evolve and optimize Hermes Agent’s skills, tool descriptions, system prompts, and code — producing measurably better versions through reflective evolutionary search.

拆开看每个词:

含义
Evolutionary进化算法——候选变体、适应度评分、保留最优、反复迭代
self-improvementagent 改的是自己的工件(skill / tool description / system prompt),不是改其他项目
DSPy + GEPA具体算法栈(Stanford 的 DSPy 框架 + GEPA 反思式进化算法,ICLR 2026 Oral)
skills, tool descriptions, system prompts, and code四类可优化的文本/代码工件
reflective evolutionary search”反思式”——读失败轨迹理解为什么失败,而不只是知道失败了

所以 self-evolution 在 Hermes 里的精确定义是:

用 GEPA 进化算法,基于 session 真实执行轨迹,自动迭代优化 Hermes 自身的 skill 文件、tool 描述、system prompt 段落和工具实现代码——产出经过基准测试门禁的改进版本,以 PR 形式等待人工合并。

关键限定:

  • 不训练模型权重(PLAN.md:17 明示:“No GPU training required… DSPy+GEPA and MIPROv2 optimize the text of prompts”)
  • 不 hot-swap(PLAN.md:694 明示:“No evolved content is ever hot-swapped into an active conversation”)
  • 不直接 commit(PLAN.md:705-706 明示:“All evolved changes go through a pull request”)
  • 只动文本和代码(权重训练的 BootstrapFinetune 被显式排除,PLAN.md:17)

Hermes 主仓库里还有另一层——运行时 nudge(run_agent.py:9156-9176,见上篇 §3.11)。这条做的是”Agent 在对话过程中偶尔沉淀新 SKILL.md 文件”。它只创建不修改,不涉及优化,不走 GEPA。离线的 self-evolution 才做真正的”改写已有”。两者是互补的两层,合起来才是 Hermes 完整的”skill 进化链路”。


7. 官方怎么描述:原文引用 + 解读

7.1 定位:独立仓库,不侵入主仓库

PLAN.md:5:

A standalone optimization pipeline that systematically improves Hermes Agent’s performance by evolving skills, prompts, tool descriptions, and agent configurations using automated optimization loops. Lives in its own repo (NousResearch/hermes-agent-self-evolution), operates ON hermes-agent — not part of it.

解读:self-evolution 是外挂工具链,不是主 Agent 的一部分。主 agent 跑不跑无所谓——优化流程在独立进程里离线运行,产物以 PR 方式回到主仓库。

这决定了它永远不会影响线上运行的 agent 稳定性,也让许可证隔离(Darwinian Evolver 是 AGPL v3,通过 CLI 调用,不被 import 进主仓库)。

7.2 核心算法:GEPA 和反思式进化

README.md:26:

GEPA reads execution traces to understand why things fail (not just that they failed), then proposes targeted improvements. ICLR 2026 Oral, MIT licensed.

解读:GEPA 的技术差异在输入信号形态。传统 RL 给个数字 reward(“这次跑得 0.3 分”),GEPA 让 LLM 读执行轨迹用自然语言说出”失败在哪一步、因为什么”(“agent 没有先看 SKILL.md 就开始调 tool,导致 search 用了错工具”),然后把这个自然语言反馈作为下一轮变异的提示。

后果:

  • 样本效率高(3 个例子就能开工)
  • 失败解释人类可读(不像 RL 的 reward 是黑盒)
  • 不需要 GPU,纯 API 调用

7.3 成本

README.md:7:

No GPU training required. Everything operates via API calls — mutating text, evaluating results, and selecting the best variants. ~$2-10 per optimization run.

解读:一次优化 $2-10 美元是这套方案能真正跑起来的关键。相比 RL 训练动辄几千美元的算力成本,GEPA 的 API 级成本让”每周自动优化一遍”变得现实。

7.4 优化对象:四个层次,风险递增

PLAN.md:22-48 列出四层优化对象,明写每层的风险/价值比:

Tier对象风险/价值工具
Tier 1SKILL.md 文件高价值 低风险DSPy + GEPA
Tier 2Tool description(schema 里的 description 字段)中价值 低风险DSPy + GEPA
Tier 3System prompt 段落高价值 高风险(改 prompt 会影响一切)DSPy + GEPA
Tier 4Tool 实现代码高价值 最高风险Darwinian Evolver(独立 CLI)

解读:这个分级揭示了Hermes 对”哪些东西能被算法改”的判断:

  • 独立的工件越好优化(SKILL.md 是独立文本文件)
  • 有明确评分标准的越好优化(tool 选对没选对是分类问题)
  • 影响面大的越后做(system prompt 改坏了整个 agent 都坏)
  • 代码放最后(因为测试集再严格也难穷举代码 bug)

7.5 全仓库零修改原则

PLAN.md:208:

hermes-agent-self-evolution operates ON hermes-agent, not inside it. Zero changes to the agent repo are needed. It reads from the hermes-agent codebase and writes evolved versions to git branches, creating PRs for human review.

解读:“零改动”是方法论承诺——主 agent 不因为 self-evolution 做任何让步。self-evolution 读主仓库的 batch_runner.py 做评估、读 skills/tools/registry.py 取优化对象、读 hermes_state.py(SessionDB)挖真实使用数据。写回只走 git 分支 + PR。


8. 为什么会想到这个:动机来源

Hermes 没在官方文档里写”我们为什么做 self-evolution”的哲学段落,但 PLAN.md 字里行间透露了几条动机。

8.1 技术原因:GEPA 刚好出现了

GEPA 论文是 ICLR 2026 Oral(PLAN.md 多处引用),是 Stanford DSPy 团队提出的新算法。出来之前,prompt 优化方案都不够理想:

  • 手工调 prompt:慢、主观、不可复现
  • DSPy MIPROv2:贝叶斯优化,收敛快但对失败理解差
  • RL(PPO 等):要 GPU + 大样本 + 数值 reward
  • GEPA:读轨迹、自然语言反馈、少样本、无 GPU——把 prompt 优化从”研究问题”变成”工程任务”

Hermes 的团队是 Nous Research——AI 研究机构。出现一个他们刚好能用的新算法,自然会做基建整合。

8.2 结构原因:Hermes 本身就是优化管道友好的

PLAN.md:90-99 列出 Hermes 现有组件能直接喂给优化管道:

现有组件在优化中的角色
batch_runner.py评估时批量并行跑 agent
agent/trajectory.py采集执行轨迹给 GEPA 反思用
hermes_state.py(SessionDB)挖真实会话历史做评估集
skills/ 目录主要优化对象
tools/registry.pytool description 在这里
agent/prompt_builder.pysystem prompt 段落在这里
tests/硬门禁——进化后必须全过
Git 历史追踪进化血线、一键回滚

Hermes 的设计里有几条”碰巧适合进化”的基建:

  • Trajectory 是完整的(包含每一步的 tool call、reasoning、result)→ GEPA 能读
  • SessionDB 带 FTS5 → 挖”这个 skill 被用过的所有例子”很快
  • Batch runner 能并行 → 评估 30 个候选只要 30 倍单次的时间
  • Skill 是 Markdown 文件 → 改一改不涉及数据库 migration

这些都不是为 self-evolution 专门设计的——但加起来就像已经铺好的基建等着被用。做 self-evolution 的工程成本主要是写评估集构建器和 GEPA wrapper,其他都复用。

8.3 产品原因:手工迭代 skill 的瓶颈

PLAN.md:26-27 讲 Tier 1 skill evolution 的理由:

Why it works: Skills are pure text, easily mutated, and directly measurable (did the agent complete the task correctly when following this skill?) Example: Evolve the github-code-review skill to produce better reviews by testing against a dataset of known-good code reviews

Hermes 的 skills 目录有 26 个类别、数百个 skill。每个 SKILL.md 都是人写的自然语言指令。问题:

  • 作者一个人凭经验写——未必是最优形态
  • 用户/社区贡献 skill 质量不齐
  • 模型升级后(例如从 Claude 3 到 Claude 4),老的 skill prompt 可能不再最优
  • 多个 skill 之间的相互影响(重叠指令、冲突建议)人工难察觉

手工迭代解决不了规模化问题。GEPA 能:

  • github-code-review 喂 20 个真实 PR + 已知好的 review → 反复迭代 SKILL.md 文字
  • 最终产出的 skill 可能有些表述是人想不到但算法找到的
  • 成本 $2-10,比招人改 skill 便宜 10 倍

8.4 哲学原因:Agent 应该成为自己的优化对象

README.md:1:

🧬 Hermes Agent Self-Evolution

emoji 🧬(DNA)暗示的姿态:agent 不是静态工件,是有”血线”(lineage)的活物。PLAN.md 反复用进化生物学的词:

  • organism(Darwinian Evolver 把每个 tool 文件当一个 organism)
  • evolutionary lineage(PLAN.md:99:“Track all evolution lineage, enable rollback”)
  • Pareto frontier(GEPA 的核心机制)
  • candidate variants(候选变体)

这种语言选择反映了 Nous Research 作为研究机构的姿态——Agent 是研究对象,它的改进过程本身也是研究课题。而不是”我们做一个产品交付出去就完了”。

对比 Claude Code 的姿态——它是 Anthropic 的商业工具,所有 skill 和 prompt 都由内部人员设计,不存在”用户/外部研究者可以优化我们”的可能。Hermes 的 self-evolution 仓库用 MIT License 开源,PLAN.md:82 写”© 2026 Nous Research”但代码可 fork 可商用——这是邀请外部参与的姿态。

8.5 现实原因:Session 数据已经在那了

Nous Research 跑 Hermes 自用(Hermes 本来就是他们日常工具),每天产生大量真实使用数据。这些数据(SessionDB):

  • 不用额外采集
  • 不涉及外部用户隐私(自用)
  • 真实场景而非合成
  • 覆盖率高(跨多个 skill / tool / 平台)

PLAN.md:310-315 明写 SessionDB 作为评估集来源:

Query SessionDB for sessions where the skill was loaded (search for skill name in messages) … Extract the task the user gave and the agent’s full response … Use LLM-as-judge to score each (task, response) pair on a rubric

“数据已经在那了”本身就是做 self-evolution 的理由——不做白不做。


9. 实现思路:五层优化的具体做法(PLAN 版)

本节按 PLAN.md 描述每层做什么。§11 会对照代码审计实际落地情况。

9.1 Phase 1:Skill Evolution(PLAN 宣称:已实现)

目标:让 hermes evolve skill <n> 这个命令能跑起来,产出改进版 SKILL.md 的 PR。

流程(PLAN.md:295-344):

1. 读取目标 skill 的当前 SKILL.md

2. 包装成 DSPy Module
   - SKILL.md 文本 → dspy.Signature 的某个字段
   - 整个 agent workflow → dspy.ReAct

3. 构建评估集(三源混合)
   A. Synthetic:用 Claude Opus 读 SKILL.md 生成 15-30 个测试任务
   B. SessionDB:查历史会话里这个 skill 被加载的例子
   C. Golden set:人工写的测试任务(可选)
   分成 train / val / holdout

4. 运行 GEPA 优化器
   - 读 trajectory(skill 跑失败时的完整步骤)
   - LLM 反思"为什么这个 SKILL.md 导致了这种失败"
   - 产出候选 SKILL.md 变体
   - batch_runner 并行评估每个候选
   - Pareto 前沿选择(只要某个候选在**任一**样本上最强就保留)

5. 约束门验证
   - pytest 全过(100%)
   - 大小 ≤ 15KB
   - 语义保留(LLM 判断新 SKILL 和原 SKILL 的核心意图一致)
   - 基准测试不回退(TBLite 分数变化 ≤ 2%)

6. 产出 PR
   - 分支名:evolve/<skill>-<timestamp>
   - PR body:before/after 分数、完整 diff、优化成本、被拒绝的候选数

7. 人工合并

评分函数(evolution/core/fitness.py:14-31):

composite = max(0, 0.5·correctness + 0.3·procedure_following + 0.2·conciseness − length_penalty)

四个维度,权重固定:

  • correctness(0.5):任务结果对不对
  • procedure_following(0.3):agent 是否按 skill 里写的步骤走
  • conciseness(0.2):输出是否简洁
  • length_penalty:接近 15KB 上限时扣分,防止进化漂移到”越写越多”

评分用的模型:

  • GEPA 反思用 openai/gpt-4.1(强模型,理解失败原因要深度)
  • LLM-as-judge 评分用 openai/gpt-4.1-mini(便宜,评分只要一致性)

9.2 Phase 2:Tool Description Evolution(规划中)

目标:优化 tool schema 里的 description 字段,让 agent 更可靠地挑对工具。

核心难点(PLAN.md:408-411):

Cross-tool evaluation — Ensure improving one description doesn’t hurt others. Always evaluate ALL tool descriptions together. Fitness function penalizes regressions on any tool’s selection rate. This prevents a search_files description from “stealing” selections from read_file.

解读:tool 选择是零和博弈——给 search_files 写得吸引人,agent 可能就不选 read_file 了。评估必须全局看,不能逐个 tool 优化。

约束(PLAN.md:433-438):

  • 单 tool description ≤ 500 字符
  • 单参数 description ≤ 200 字符
  • Schema 结构(参数名、类型、是否必需)冻结,只进化文本
  • 必须保持事实准确(不能给 tool 加上它没做的功能)

9.3 Phase 3:System Prompt Section Evolution(规划中)

目标:优化 system prompt 里可变的 5 个段落。

可进化段落清单(PLAN.md:460-470):

段落位置做什么能改吗
DEFAULT_AGENT_IDENTITYprompt_builder.py核心人格 / 行为特征
MEMORY_GUIDANCE同上什么时候写记忆、存什么
SESSION_SEARCH_GUIDANCE同上什么时候搜历史
SKILLS_GUIDANCE同上什么时候写 / 加载 skill
PLATFORM_HINTS同上平台特定格式提示
Memory block(真实记忆内容)memory_store.py用户的记忆❌(用户数据)
Skills indexprompt_builder.py自动生成的 skill 列表❌(自动生成)
Context files同上AGENTS.md 等❌(项目特定)

为什么这层风险最高:system prompt 影响 agent 所有行为。评估必须同时跑 TBLite(100 个编码/运维任务)和 YC-Bench fast_test(长对话连贯性)——任何一个回退就拒绝候选(PLAN.md:481-483)。

9.4 Phase 4:Tool Code Evolution(规划中)

目标:用 Darwinian Evolver 进化 tool 实现代码。

换引擎的原因:前三层动的是自然语言文本,GEPA 的”反思式变异”很适合。第四层动的是 Python 代码——文本进化算法不够,需要Git-based organism:

  • 每个 tool 源文件是一个 organism
  • 每次变异 = 一次 LLM 提出的代码修改 → commit 到专门分支
  • Fitness = pytest 结果 + benchmark 分数 + bug 复现是否通过
  • 零容忍:2550+ 个测试必须全过(PLAN.md:556-559)

最强约束(PLAN.md:578-584):

  • 全部测试通过
  • 函数签名冻结(动了就 break 上游调用)
  • registry.register() 调用冻结(动了就 break tool 发现)
  • 错误处理覆盖率不能下降
  • Darwinian Evolver 只作为外部 CLI 用(AGPL v3 许可证隔离)
  • 所有 PR 必须人工审——不允许 auto-merge

9.5 Phase 5:Continuous Loop(规划中)

目标:Agent 自动识别自己哪里最弱,自动触发优化。

核心组件(PLAN.md:604-625):

  1. Performance monitor

    • 每个 skill 的成功率(挖 SessionDB:skill 被加载的会话 → 任务是否完成)
    • Tool 选对率(挖 trajectory:agent 挑的 tool 是不是最合适的)
    • 基准测试分数的时间序列
    • 用户纠正次数(用户说”不对,用 X 而不是 Y”就是信号)
  2. Auto-triage:按”可改进空间 × 使用频率”排优化优先级

  3. Scheduled optimization(cron):

    • 每周跑 TBLite + YC-Bench fast_test,记录分数
    • 分数下降或 skill 失败率超阈值 → 自动触发 GEPA
    • 产出 PR
    • 通知人审

注意(PLAN.md:600):

Human still reviews and merges every PR — this phase automates detection and optimization, not deployment.

解读:即便全流程自动化,合并永远是人的决定。这条从 Phase 1 到 Phase 5 不变。

9.6 基准测试作为 Gate 而不是 Fitness

这是一条容易被忽略但重要的设计区分(PLAN.md:661-662):

Key principle: Benchmarks are GATES, not fitness functions. The fitness function is task-specific (did the skill/tool/prompt do its job better?). Benchmarks ensure the improvement didn’t break something else. A variant that improves skill quality by 20% but drops TBLite by 5% is REJECTED.

拆开看:

  • Fitness function:任务特定的质量分(skill 做没做好)——决定 A 和 B 谁更好
  • Gate:通用基准测试(TBLite、YC-Bench)——决定 A 是否允许进入 PR

这个区分避免了基准测试过拟合——如果基准分直接当 fitness,GEPA 就会优化出”TBLite 分高但 skill 本来的功能废了”的变体。改为 Gate 后,fitness 只看 skill 质量,Gate 只抓回退。

9.7 约束门五件套

PLAN.md:666-728 列出五件套,每件都有硬性标准:

#约束标准
1全量测试pytest tests/ -q 100% 过,零容忍
2字符上限skill ≤ 15KB、tool description ≤ 500 字符、prompt section 增长 ≤ 20%
3缓存兼容改动不 hot-swap进运行中对话,只在下个 session 生效
4语义保留新版和原版的核心意图通过 LLM judge 验证一致
5PR 合并所有改动走 git branch + PR,永不直接 commit

第 5 条在 README.md:76 也重复强调:

PR review — All changes go through human review, never direct commit.

这是 Hermes self-evolution 的最终安全兜底(设计层面)——算法不能直接改主仓库

⚠️ 但注意:§11 展示了这五件套里真正落到代码的只有四件(且不含语义保留),PR 自动化也还没做。设计层面的承诺和代码层面的实现要分开看。


10. 和其他”自我改进”方案的区别

10.1 不是 RL

PLAN.md:17:

No GPU training required… DSPy+GEPA and MIPROv2 optimize the text of prompts, instructions, and few-shot examples — they mutate and evaluate strings, not model weights.

  • RL:改模型权重,需要 GPU + 大样本 + 数值 reward
  • GEPA:改 prompt 文字,只要 API 调用 + 少样本 + 自然语言反馈

Hermes 明确选了后者。它的 rl_cli.py(顶层文件)做的是另一件事——导出轨迹给外部 RL 训练,而不是自己做 RL。这两条是并行的业务:

  • self-evolution:Nous Research 改自己的 Hermes agent(改文本)
  • RL trajectory export:Nous Research 喂给自己的模型训练管道(动权重)

别混淆。

10.2 不是 fine-tuning

DSPy 框架本身包含一个组件叫 BootstrapFinetune,可以在自己的数据上做 fine-tune。Hermes 的 self-evolution 明确排除(PLAN.md:17):

The only DSPy component that trains weights (BootstrapFinetune) is explicitly excluded from this plan.

理由和 10.1 一样——只动文本,不动权重。fine-tuning 要 GPU、要准备训练数据、要 eval infra、要 serve infra——边界比 self-evolution 大得多。Hermes 不做。

10.3 不是”agent 自己在对话中改进自己”

运行时 nudge(主仓库 run_agent.py:9156-9176,见上篇 §3.11)做的是创建新 SKILL.md——agent 发现”跑通了非平凡工作流”后沉淀一份。不覆盖已有

真正的”改写已有 SKILL.md”只能走离线 self-evolution 管道。

这个分层设计的意思是:

  • 运行时可以往 skill 库加新文件(低风险、零影响)
  • 但改老文件必须离线 + GEPA + 约束门 + PR + 人审(高风险、要管控)

这和 OpenClaw 的”Dreaming 晋升记忆”是不同思路——OpenClaw 让 agent 在运行时(每晚)直接写记忆库;Hermes 把这种高风险改动推到离线 + 人审

10.4 不是黑盒(设计上)

GEPA 的每一步都有可读产物:

  • 候选变体:完整的 SKILL.md diff,人能读
  • 反思:LLM 用自然语言写”为什么这个变体比上一个好”
  • 分数:四维分开打(correctness / procedure / conciseness / length),不是一个黑盒 reward

这个”可解释”是相对于 RL 黑盒的关键差别——PLAN.md 反复强调”human review” / “sensible to a human reviewer”。

⚠️ 但注意:当前代码的 fitness 实际是关键词重叠启发式(见 §11.3 差距 1),不是 PLAN 宣称的四维 LLM judge。“可解释”在 PLAN 层面成立,在当前代码层面相对粗糙。


11. PLAN vs 代码真实:七处差距 + 代码走读

本节是整个 self-evolution 调研最有价值的部分。外部调研者看 PLAN 会以为是生产管线,看代码才知道是研究原型。把两者分开读是基本功。

11.1 整体规模与仓库活跃度

仓库 hermes-agent-self-evolution(截至 2026-04 末)的真实状态:

  • 总代码量:3762 行 Python(其中 evolve_skill.py 323 行、external_importers.py 785 行、fitness.py 146 行、constraints.py 174 行、dataset_builder.py 201 行、skill_module.py 123 行,其他为 __init__ 和测试)
  • PLAN.md 规模:40694 字节(约 782 行)——设计文档比核心实现代码还长
  • Git 历史:只有 7 次 commit
0949dc7 feat: initial hermes-forge — Phase 1 skill evolution via DSPy + GEPA
2e4ec14 refactor: rebrand hermes-forge → hermes-agent-evolution
ea02cd5 fix: use CLI model for dataset generation, validate full pipeline
2377f9e docs: Phase 1 validation report (PDF)
96a1132 refactor: rebrand to Hermes Agent Self-Evolution
3fb26f1 feat: external session importers for Claude Code, Copilot, and Hermes (#2)
4693c8f feat: add Hermes session importer + fix short skill name matching (#4)

最初叫 hermes-forge,两次改名,最近两次 commit 都是加 session importer——说明当前重心是拿评估数据,不是优化算法本身。

  • 测试:2 个测试文件(tests/core/test_constraints.py 98 行 + tests/skills/test_skill_module.py 92 行),共 190 行测试覆盖
  • 发布产物:reports/phase1_validation_report.pdf(14.5KB)—— Phase 1 验证报告

11.2 按 Phase 的真实实现状态

Phase对象PLAN 宣称代码真实
1Skill✅ 已实现✅ 可跑:evolve_skill.py 323 行 + skill_module 123 行 + 共享核心 ~500 行
2Tool description🔲 规划evolution/tools/ 目录只有 __init__.py 1 行空文件
3System prompt section🔲 规划evolution/prompts/ 目录只有 __init__.py 1 行空文件
4Tool code🔲 规划evolution/code/ 目录只有 __init__.py 1 行空文件
5Continuous loop🔲 规划evolution/monitor/ 目录只有 __init__.py 1 行空文件

Phase 2-5 的代码现状字面意义上是空的——只有包的占位文件。PLAN.md 里详尽设计的”Tool description 优化器”、“System prompt 段落进化器”、“Darwinian Evolver 代码进化”、“连续自动优化管道”在代码层面都是 0 行。

11.3 PLAN 宣称 vs 代码真实:七处具体差距

差距 1:Fitness 函数不是 LLM-as-judge

PLAN 说:fitness.py 用 LLM-as-judge 打分,四维评分(correctness / procedure_following / conciseness / length_penalty),公式:

composite = max(0, 0.5·correctness + 0.3·procedure + 0.2·conciseness − length_penalty)

代码真实:fitness.py既有 LLMJudge 类(74 行)也有 skill_fitness_metric() 函数(30 行)。但GEPA 实际用的是后者(evolve_skill.py:158:metric=skill_fitness_metric),不是 LLMJudge

skill_fitness_metric 的实现(fitness.py:107-136):

def skill_fitness_metric(example, prediction, trace=None) -> float:
    agent_output = getattr(prediction, "output", "") or ""
    expected = getattr(example, "expected_behavior", "") or ""
    # ...
    # Simple keyword overlap as a fast proxy
    expected_words = set(expected_lower.split())
    output_words = set(output_lower.split())
    if expected_words:
        overlap = len(expected_words & output_words) / len(expected_words)
        score = 0.3 + (0.7 * overlap)
    return min(1.0, max(0.0, score))

关键词重叠占比 × 0.7 + 0.3 baseline——就这么简单。注释自承(第 121-123 行):

# Quick heuristic scoring (for speed during optimization)
# Full LLM-as-judge scoring is expensive — use it selectively

LLMJudge.score() 是存在的工具,但在当前 evolve_skill 流程里没被调用。Length penalty 也只在 LLMJudge 里实现,skill_fitness_metric 没用

含义:Phase 1 的真实优化信号比 PLAN 宣称的粗糙很多——一个词袋相似度。这也解释了为什么 Phase 1 validation report 是谨慎的 PDF 而不是强结论。

差距 2:GEPA 有 MIPROv2 fallback(因为 GEPA 不稳定)

PLAN 说:主优化器 GEPA,MIPROv2 是兜底(和 README 的 “fallback optimizer” 一致)。

代码真实(evolve_skill.py:156-177):

try:
    optimizer = dspy.GEPA(
        metric=skill_fitness_metric,
        max_steps=iterations,
    )
    optimized_module = optimizer.compile(baseline_module, trainset=trainset, valset=valset)
except Exception as e:
    console.print(f"[yellow]GEPA not available ({e}), falling back to MIPROv2[/yellow]")
    optimizer = dspy.MIPROv2(metric=skill_fitness_metric, auto="light")
    optimized_module = optimizer.compile(baseline_module, trainset=trainset)

try/except 包着 GEPA 调用,异常就用 MIPROv2 auto="light" 顶上。注释”GEPA not available in this DSPy version”说明 GEPA 作为 DSPy 组件还不稳定,所以代码写成”尽量用 GEPA,用不了就降级”。

含义:真实跑出来的”GEPA 优化”在 DSPy 版本不兼容时会静默变成 MIPROv2。外部调研者看 PLAN 以为都是 GEPA,看代码才知道这条 fallback 逻辑。

差距 3:约束门不是五件套,是四件

PLAN 说(PLAN.md:666-728):

  1. 全量测试(pytest tests/)
  2. 字符上限
  3. 缓存兼容
  4. 语义保留
  5. PR 合并

代码真实(constraints.py:30-53validate_all()):

def validate_all(self, artifact_text, artifact_type, baseline_text=None):
    results = []
    results.append(self._check_size(artifact_text, artifact_type))           # 1
    if baseline_text:
        results.append(self._check_growth(artifact_text, baseline_text, ...)) # 2
    results.append(self._check_non_empty(artifact_text))                      # 3
    if artifact_type == "skill":
        results.append(self._check_skill_structure(artifact_text))            # 4
    return results
  • _check_size:字符上限(skill ≤15KB、tool desc ≤500、param desc ≤200)
  • _check_growth:增长 ≤20%
  • _check_non_empty:非空
  • _check_skill_structure:YAML frontmatter 有 name 和 description 字段

run_test_suite() 作为独立方法存在(constraints.py:55-93,调 pytest tests/ -q --tb=no 超时 300s),但不在 validate_all() 里自动跑——CLI 默认 --run-tests 是 False。

缺失的:

  • 语义保留检查(PLAN 说”LLM 判断新版和原版意图一致”)——代码完全没有
  • 缓存兼容检查(PLAN 说”不 hot-swap”)——这是部署规则,代码层面无从检查
  • 全量测试自动跑——默认关

含义:PLAN 的”五件套约束”在代码里只落到字符上限 + 增长上限 + 非空 + 结构四项语法级检查。语义层面的防漂移没有实现。

差距 4:没有基准测试门禁

PLAN 说(PLAN.md:631-662):TBLite 作为 Gate(候选进 PR 前必过)、TerminalBench2 深度验证(top 3 候选跑)、YC-Bench 长对话连贯性。

代码真实:仓库里没有 benchmark_gate.pyevolution/core/ 目录下实际文件是:

config.py            72 行
constraints.py      174 行
dataset_builder.py  201 行
external_importers.py 785 行
fitness.py          146 行

PLAN 目录树里列的 benchmark_gate.py(PLAN.md:151)不存在。evolve_skill.py 里也没有基准测试调用。

含义:PLAN 设计的”基准测试 Gate”在代码层面完全是空的——Phase 1 的进化产物目前只过字符上限等语法检查,没有任何跨任务基准验证。这是 §9.6 那条”Gate vs Fitness”核心设计原则的实现缺口。

差距 5:没有 PR 自动生成

PLAN 说(PLAN.md:705-721):

git checkout -b evolve/<target>-<timestamp>
git add <files>
git commit -m "evolve: ..."
git push -u origin ...
gh pr create --title "evolve: ..." --body "..."

PLAN 目录里列 evolution/core/pr_builder.py 是这事的实现。

代码真实:仓库里没有 pr_builder.pyevolve_skill.py 第 255-286 行的”Save output”是:

output_dir = Path("output") / skill_name / timestamp
output_dir.mkdir(parents=True, exist_ok=True)
(output_dir / "evolved_skill.md").write_text(evolved_full)
(output_dir / "baseline_skill.md").write_text(skill["raw"])
(output_dir / "metrics.json").write_text(json.dumps(metrics, indent=2))

——产出保存到本地 output/<skill>/<timestamp>/ 目录,不碰 git、不建分支、不发 PR。运行完打印一句:

Review the diff: diff {output_dir}/baseline_skill.md {output_dir}/evolved_skill.md

把 diff 操作丢回给人工。

含义:PLAN 里的”PR-only 产出”在代码里其实是”保存到本地文件夹”,建 PR 完全是人工步骤。README/PLAN 强调的 “through human review, never direct commit” 在代码上合规——因为代码压根不 commit——但**“自动产 PR 等人审”**这个 PLAN 核心承诺没有实现。

差距 6:external_importers 是最近扩展(代码比 PLAN 做得更多)

PLAN 说(PLAN.md:310-315):数据来源 Source B 挖 Hermes 自己的 SessionDB。

代码真实:evolution/core/external_importers.py 785 行,是整个仓库最大的代码文件。最近 commit(#4 4693c8f)的标题是 feat: add Hermes session importer + fix short skill name matching——说明这个 importer 是渐进加入的。它支持挖 三种来源:

  • claude-code — Claude Code 的 session 存储
  • copilot — GitHub Copilot 的会话历史
  • hermes — Hermes 自己的 SessionDB

比 PLAN 更激进——不只挖 Hermes 自用数据,也挖其他 agent 的会话。这暗示一个野心:跨 agent 的 skill 优化——同一个 skill(如 github-code-review)在 Claude Code / Copilot / Hermes 三处都用过,挖这三份数据能得到更丰富的评估集。

含义:这条是代码比 PLAN 做得更多的地方,也是调研者容易漏掉的——仓库最近重心不是算法,是数据源。

差距 7:CLI 集成方式

PLAN 说(PLAN.md:346):

hermes evolve skill github-code-review --iterations 10

即作为 hermes CLI 的子命令。

代码真实:只有

python -m evolution.skills.evolve_skill --skill github-code-review --iterations 10

evolve_skill.py 第 296-319 行是独立的 click CLI,没有注册到主 hermes CLI。而且这个仓库只是 hermes-agent 的外挂,不会因为 pip install -e . 就给 hermes 命令加子命令。

含义:目前要跑 self-evolution 得 cd 到这个仓库单独执行,不是 Hermes 用户可以开箱即用的功能。

11.4 Phase 1 真实代码走读(10 步)

evolve_skill.py 的主函数 evolve()(第 36-293 行)做的事,对应 PLAN 里的步骤:

做什么代码位置
1找 skill 文件(直接匹配目录名 or fuzzy 匹配 frontmatter name:)skill_module.find_skill() :58-81
2解析 SKILL.md 为 {frontmatter, body, name, description}skill_module.load_skill() :15-55
3构建评估集(三源选一):synthetic / golden / sessiondb(走 external_importers)evolve_skill.py:81-117
4验证 baseline 约束(4 项硬检查)evolve_skill.py:119-132
5配置 DSPy LM + 把 skill body 包成 SkillModuleevolve_skill.py:134-149
6跑 GEPA(try/except MIPROv2 fallback)evolve_skill.py:151-180
7从优化后的 module 抽出 evolved body,用 reassemble_skill() 拼回完整 SKILL.mdevolve_skill.py:182-185
8验证 evolved 约束(带 baseline 做增长检查),不过就保存到 evolved_FAILED.mdevolve_skill.py:187-205
9在 holdout 集上分别跑 baseline 和 evolved,计算平均分差evolve_skill.py:207-227
10rich.Table 打印对比,保存三个文件到本地时间戳目录evolve_skill.py:229-293

关键细节:

  • SkillModule 的 DSPy Signature(skill_module.py:94-102)是通用的 TaskWithSkill——任何 skill 都用同一个 signature,agent 就是”按 skill 指令完成任务”
  • 其实并没有真的跑 Hermes Agent——而是让 DSPy 的 ChainOfThought 直接模拟一个遵循 skill 指令的 agent。这比 PLAN.md 设想的”用 batch_runner 在 Hermes agent 上跑评估”轻量得多
  • 所以”进化 skill”真实在做的是:调 DSPy 让 GEPA 去改 skill 文本,让一个通用的 ChainOfThought(skill + task → output) 模块在关键词重叠启发式下得分更高

11.5 Phase 1 验证报告

仓库 reports/phase1_validation_report.pdf(14.5KB)是 Phase 1 的唯一对外证据。PDF 内容未展开读(非纯文本),但存在这份文件说明 Nous 团队认为 Phase 1 结果够发。一份 14.5KB 的 PDF 通常是几页的短报告,不是大规模 benchmark 总结——和仓库的”早期原型”阶段吻合。

11.6 差距总表

条目PLAN代码真实
FitnessLLM-as-judge 四维关键词重叠启发式
优化器GEPAGEPA + MIPROv2 try/except fallback
约束门五件套(包括语义保留 + 缓存兼容 + pytest)四件(size/growth/non_empty/structure),pytest 方法存在但默认不跑
基准测试 GateTBLite + TerminalBench2 + YC-Bench无(benchmark_gate.py 不存在)
PR 产出自动 gh pr create保存到本地 output/ 目录
Phase 2 Tool desc详尽设计空目录
Phase 3 Prompt section详尽设计空目录
Phase 4 Tool code(Darwinian Evolver)详尽设计空目录
Phase 5 连续自动化详尽设计空目录
数据源三源(synthetic + SessionDB + golden)四源(加 external_importers 挖 Claude Code / Copilot / Hermes)——超出 PLAN
CLI 入口hermes evolve skill ...python -m evolution.skills.evolve_skill ...

核心判断:hermes-agent-self-evolution 目前是研究级原型,Phase 1 有一个可跑的 demo 但关键组件(LLM judge / benchmark gate / PR 自动化 / 语义保留)没落到代码。PLAN.md 780 行画的是三年的路线图,代码只走到 3 个月的进度。

外部调研者看完 README 可能以为这是个运行中的自动优化管道,但实际是:

  • 一个人能坐下来跑 python -m evolution.skills.evolve_skill --skill xxx --eval-source synthetic --iterations 10
  • 观察输出目录里的 diff
  • 手动决定是否把 diff 合进 hermes-agent 主仓库

仓库的活跃度(最近 commit 在加数据 importer)暗示:下一步不是扩 Phase 2-5,而是把 Phase 1 的评估数据做得更真实。这是务实的选择——fitness 信号没做好前,扩更多优化对象没意义。

每 Phase 之间有显式 validation gate(PLAN.md:250-258)。PLAN 明写:

But we may stop at Phase 1 or 2 if the returns diminish — no obligation to do all five.

这句话在代码状态下显得尤其可信——Phase 2-5 的实现压根没开工,如果 Phase 1 收益不够,Phase 2 可能就不做了。


总结:七条核心观察

关于 Hermes 整体(来自上篇):

  1. Hermes 的独特在于”给东西起名字”——Procedural Memory、Durable Identity、Frozen Snapshot、Input Guardrails、Subagents Know Nothing、Shadow Git——这些命名不是修辞,是对应实打实代码的认知承诺。框架设计师看框架先看它用什么词描述自己,Hermes 的词库最丰富。

  2. Hermes 的设计选择自洽——常驻多平台 + 记忆插件化 + RL 导出 + 跨框架 skill 兼容 + 9400 行单体——单独每一条看都有争议,合在一起是一个”给研究员自用的重度常驻个人 agent”的一致画像。

  3. Hermes 是能力参考字典而非样板——它的克制度不高(单体大、无 DI、无 Schema 校验),但独特做法的密度最高。想了解”agent 框架的一个子能力可以做到什么程度”,Hermes 的实现基本都是上限。

关于 Self-Evolution(来自下篇):

  1. “self-evolution” 在 Hermes 语境下是精确的工程术语——指 “用 GEPA 对 Hermes 自身工件做反思式进化优化”,不是 “Agent 自学习” 的泛称。四个可优化对象、五件套约束、PR-only 产出,每一条都有具体定义。

  2. 它是 Hermes 基建的自然延伸——trajectory、SessionDB、batch_runner、skills 目录、git 历史这些已有组件,碰巧合起来就是一条优化管道的前置条件。GEPA 出现后,把这些基建穿起来的工程成本很低。

  3. 风险管控的设计值得学——“benchmarks 作为 Gate 而非 Fitness”、“语义保留检查防漂移”、“PR 永不直接 commit”、“代码进化独立引擎 + 最强测试门禁”——这些机制回答了”如何让算法改自己的东西但不失控”。即便代码还没全部实现,设计层面的这些分类是外部调研最值得学的部分。

  4. PLAN 宣称和代码实现有显著落差——PLAN.md 780 行描绘了完整的五阶段自动优化管道,代码只走到 Phase 1 的研究级原型:

    • Phase 2-5 四个目录里只有空 __init__.py
    • Fitness 实际是关键词重叠启发式,不是 LLM-as-judge
    • 没有基准测试 Gate、没有自动 PR、没有语义保留检查
    • GEPA 不稳定,有 MIPROv2 fallback
    • 仓库总共 7 次 commit,最近重心在加评估数据源

    这个落差不等于”PLAN 是空头支票”——PLAN 是 roadmap,代码是 MVP。但外部调研者看 PLAN 以为是生产管线、看代码才知道是研究原型。把两者分开读是基本功


附录:源材料索引

A. Hermes 主仓库(hermes-agent)

官方文档

  • website/docs/user-guide/features/skills.md — Skills 系统,procedural memory 命名源头
  • website/docs/user-guide/features/memory.md — 双文件记忆、frozen snapshot 命名源头
  • website/docs/user-guide/features/personality.md — SOUL.md 的设计理由
  • website/docs/user-guide/features/delegation.md — Subagents Know Nothing 警告
  • website/docs/user-guide/checkpoints-and-rollback.md — Shadow Git Checkpoint
  • website/docs/user-guide/features/overview.md — 全能力导览
  • website/docs/developer-guide/architecture.md — 系统分层图
  • website/docs/reference/tools-reference.md — 48 tools 参考

源码锚点

  • run_agent.py:472-9223AIAgent
  • run_agent.py:167-252IterationBudget
  • run_agent.py:213-231 — Tool 并发三分类
  • run_agent.py:1029, 1038, 1129, 1132 — Nudge 间隔常量
  • run_agent.py:2638-2797 — System Prompt 10+ 段组装
  • run_agent.py:2704-2712 — 模型族差异化 prompt
  • run_agent.py:4860-4981, 4954-4967 — Fallback Chain + 同步窗口
  • run_agent.py:5733flush_memories()
  • run_agent.py:9156-9176 — 后台 nudge spawn(运行时 skill 创建)
  • agent/prompt_builder.py:36-74, 49-52, 330-332 — Input Guardrails 规则
  • agent/subdirectory_hints.py:48-219 — SubdirectoryHintTracker
  • agent/context_compressor.py:287-349 — 7 段摘要模板
  • agent/context_compressor.py:412-470 — 孤儿 tool stub 注入
  • agent/context_compressor.py:565-696 — 压缩 5 阶段
  • agent/retry_utils.py:19-57 — Jittered backoff
  • agent/trajectory.py — 执行轨迹格式(GEPA 的输入)
  • agent/redact.py — 50+ API Key 脱敏
  • tools/memory_tool.py:60-76, 111, 198+ — 记忆威胁正则 + 容量上限 + 三工具
  • tools/skills_tool.py:640, 719, 787 — 渐进披露三层
  • tools/skills_guard.py:82-484 — 120+ 威胁正则
  • model_tools.py:372-456 — coerce_tool_args
  • batch_runner.py — 被 self-evolution 复用的批量评估工具
  • hermes_state.py — SessionDB(挖评估数据)
  • skills/ — 优化对象目录(数百个 SKILL.md)
  • gateway/platforms/base.py:470-632 — BasePlatformAdapter
  • gateway/platforms/*.py — 17 平台适配
  • gateway/session.py:73-150, 202 — SessionSource + build_session_context_prompt
  • gateway/pairing.py — DM 配对身份绑定

B. Self-Evolution 独立仓库(hermes-agent-self-evolution)

文档

  • README.md(85 行)— 对外介绍,核心主张
  • PLAN.md(782 行)— 完整架构、动机、五 Phase 分解、约束、时间线
  • reports/phase1_validation_report.pdf(14.5KB)— Phase 1 唯一对外证据

真实存在的代码(Phase 1 已落地部分)

  • evolution/skills/evolve_skill.py(323 行)— Phase 1 主 CLI,evolve() 函数 36-293 行
  • evolution/skills/skill_module.py(123 行)— SKILL.md 包装成 DSPy Module
  • evolution/core/config.py(72 行)— 配置
  • evolution/core/constraints.py(174 行)— 约束门实现(四件,第 30-53 行 validate_all())
  • evolution/core/dataset_builder.py(201 行)— 评估集生成
  • evolution/core/external_importers.py(785 行)— 三源 session importer(Claude Code / Copilot / Hermes)
  • evolution/core/fitness.py(146 行)— 包含 LLMJudge 类(未启用)和 skill_fitness_metric()(实际在用,关键词重叠启发式)
  • tests/core/test_constraints.py(98 行)
  • tests/skills/test_skill_module.py(92 行)

PLAN 宣称但代码不存在的文件

  • evolution/core/benchmark_gate.py — 基准测试门禁(PLAN.md:151 列出,代码不存在)
  • evolution/core/pr_builder.py — PR 自动生成(PLAN.md:705-721 描述,代码不存在)
  • evolution/tools/* — Phase 2 Tool description 优化(空目录)
  • evolution/prompts/* — Phase 3 System prompt section 优化(空目录)
  • evolution/code/* — Phase 4 Tool code 优化(空目录)
  • evolution/monitor/* — Phase 5 连续自动化(空目录)

C. 外部引用