AI开发-Hermes:会让 Skill 迭代进化的 Agent
前言
这篇文章重新说一下 Hermes。这里的 Hermes 不是某个偏函数调用的模型系列,也不是单纯的格式化能力。更准确地说,我想讨论的是一种 Agent:它不是只完成一次任务,而是会把一次任务中的有效做法沉淀成 Skill,再在后续任务里复用、校验、修正,最终让自己的工作方法慢慢变好。
普通 Agent 的循环通常是计划、执行、观察、继续执行。Hermes 更进一步,它会关心“这次任务里有没有可复用的方法”。例如它修好了一个前端布局问题,不只是把这次代码改完,还会总结出一个 Skill:如何定位页面重叠、如何判断是 sticky 布局问题还是 z-index 问题、如何做截图验证、哪些改动容易影响其它页面。下一次遇到相似问题时,它不需要从零开始摸索,而是先调用这个 Skill。
所以我理解的 Hermes 有两个关键词:一个是 Agent,另一个是 Skill Evolution。Agent 负责在环境里行动,Skill Evolution 负责把行动经验转成可复用的能力单元,并且允许这个能力单元继续被测试、被拆分、被合并、被淘汰。
Hermes 的定位
如果把 Agent 看成一个执行者,Hermes 更像一个会写工作手册、会更新工作手册、还会检查工作手册是否过期的执行者。它不是把所有知识都塞进 prompt,而是把稳定的经验变成一个个 Skill。Skill 可以是很小的,也可以是组合型的。
一个小 Skill 可能只是“读取一个仓库时先找 package.json、README、配置文件,再判断启动方式”。一个组合型 Skill 可能是“修复静态博客页面错位”,里面包含定位页面、识别主题生成结构、修改 CSS 或 HTML、验证线上缓存等多个步骤。
这和普通 memory 不太一样。memory 经常只是记录“用户喜欢什么”或“之前发生过什么”,而 Skill 更强调可执行。一个 Skill 应该能指导 Agent 下一次怎么做,最好还能被单独测试。它不是一句经验,而是一段可调用的方法。
Skill 是 Hermes 的能力单位
要让 Hermes 真正进化,Skill 不能只是自然语言笔记。比较实用的 Skill 至少应该包含这些字段:
- name:Skill 的名字,要求短、清楚、可检索。
- intent:这个 Skill 解决什么问题,不解决什么问题。
- trigger:什么样的任务或上下文适合调用它。
- inputs:调用时需要哪些信息,例如仓库路径、错误日志、截图、用户目标。
- procedure:具体步骤,可以是自然语言,也可以是工具调用模板。
- checks:完成后怎么验证。
- failure_cases:曾经失败过的场景,用来提醒 Agent 不要复读错误。
- version:Skill 的版本,方便回滚和对比。
一个最小 Skill 可以长这样:
{
"name": "fix_static_blog_sidebar_overlap",
"intent": "修复静态博客中侧栏卡片随滚动覆盖其它卡片的问题",
"trigger": ["sidebar overlap", "sticky layout", "archive card covers comments"],
"inputs": ["page_url", "screenshot", "repo_path"],
"procedure": [
"定位页面中 aside-content 和 sticky_layout 的结构",
"判断 sticky 是否在错误容器中生效",
"优先用局部 CSS 修正 position/top,不改全局主题布局",
"对归档、分类、标签等单栏页面检查是否需要移除侧栏 HTML",
"用本地和线上页面分别验证"
],
"checks": [
"页面主内容没有 aside-content 残留",
"滚动后最新评论、归档、标签卡片不重叠",
"移动端菜单仍可正常打开"
],
"failure_cases": [
"只用 display:none 隐藏侧栏,但 HTML 仍残留,用户会认为没有真正删除"
],
"version": "1.2.0"
}
这里面最重要的不是 JSON,而是 Skill 的边界。很多 Agent 失败,是因为它把“经验”写得太空。比如“检查页面布局”这种 Skill 基本没用,因为它既不知道什么时候用,也不知道怎么验证。Hermes 要进化,Skill 必须可触发、可执行、可验证。
从一次任务提炼 Skill
Hermes 的关键动作不是“执行任务”,而是“任务结束后复盘”。一次任务完成后,它可以把轨迹拆成三类内容:有效步骤、无效步骤、环境约束。有效步骤可能进入 Skill,失败步骤可能进入 failure_cases,环境约束则变成触发条件或注意事项。
下面是一段简化的伪代码,展示如何从任务轨迹中生成候选 Skill。真实系统里,这一步可以由模型完成,但最好再经过规则和测试过滤。
from dataclasses import dataclass, field
@dataclass
class TraceStep:
thought: str
action: str
observation: str
success: bool
@dataclass
class SkillDraft:
name: str
intent: str
trigger: list[str]
procedure: list[str]
checks: list[str]
failure_cases: list[str] = field(default_factory=list)
def propose_skill(task_goal: str, trace: list[TraceStep]) -> SkillDraft:
useful_steps = [s for s in trace if s.success]
failed_steps = [s for s in trace if not s.success]
return SkillDraft(
name="draft_from_task",
intent=f"复用解决任务的流程: {task_goal}",
trigger=[task_goal[:40]],
procedure=[f"执行 {s.action},观察 {s.observation[:80]}" for s in useful_steps],
checks=["重新运行验证命令", "确认用户报告的问题已经消失"],
failure_cases=[f"避免重复: {s.action}" for s in failed_steps]
)
这个版本当然很粗糙,但它说明了 Hermes 的核心:任务不是一次性消耗品,任务轨迹是训练 Skill 的原料。Agent 做得越多,如果不沉淀,下一次还是从零开始;如果会沉淀,就会慢慢形成自己的工具箱。
Skill 的迭代闭环
Skill 不能一写完就永久有效。代码库会变,工具会变,用户偏好会变,模型能力也会变。Hermes 需要一个迭代闭环:生成候选 Skill,选择是否启用,在任务中调用,记录成功率,失败后修订,长期无效就降权或删除。
我更喜欢把 Skill 分成三个状态:
- draft:刚从任务中提炼出来,还没有被充分验证。
- active:多次任务验证有效,可以被自动检索和调用。
- deprecated:已经过期或效果不稳定,只保留历史记录。
状态切换最好依赖数据,而不是只靠模型自信。比如同一个 Skill 最近 10 次调用中有 8 次成功,它可以保持 active;如果连续 3 次引导 Agent 走错方向,就应该降权。下面是一个很小的评分器:
def update_skill_score(skill, run_result):
if run_result.passed_checks:
skill.score += 2
if run_result.required_human_fix:
skill.score -= 3
if run_result.caused_regression:
skill.score -= 6
if skill.score >= 10:
skill.state = "active"
elif skill.score <= -5:
skill.state = "deprecated"
else:
skill.state = "draft"
return skill
这里的分数不需要复杂,关键是让 Hermes 有“经验是否真的有效”的反馈。没有反馈的 Skill 进化,很容易变成越写越长的提示词垃圾堆。
Skill 检索与调用
当用户给 Hermes 一个任务时,系统可以先做 Skill 检索。检索不只是看关键词,还要看触发条件、输入是否满足、风险等级是否匹配。例如“修复博客分类页显示异常”可以召回静态博客布局 Skill;但如果用户只是问“分类页是什么意思”,就不应该调用修复 Skill。
一个可控的调用流程可以是:
- 理解任务目标,抽取关键词和约束。
- 从 Skill Registry 中召回候选 Skill。
- 让模型判断 Skill 是否适用,并给出理由。
- 只把最相关的 1 到 3 个 Skill 注入上下文。
- 执行后记录 Skill 是否真的帮上忙。
这里有一个细节:不要把所有 Skill 一次性塞给模型。Skill 太多会污染上下文,模型可能为了使用 Skill 而使用 Skill。Hermes 的 skill system 应该像一个工具箱,而不是一本永远展开的百科全书。
和普通 Agent 的区别
普通 Agent 更关注“这次任务能不能完成”。Hermes 更关注“这次任务完成后,系统有没有变得更会做这类事”。这两者的工程重心不同。
普通 Agent 需要计划器、工具调用、记忆和验证。Hermes 还需要 Skill Registry、Skill 版本管理、Skill 评分、回滚机制和去重机制。没有这些东西,所谓进化就只是把聊天记录存起来,下一次再翻出来看看。
我觉得 Hermes 最适合那些重复但不完全相同的任务场景,例如代码库维护、自动化测试修复、文档整理、数据清洗、运营报表生成、静态站点发布。每一次任务都有差异,但底层套路可以复用,这正是 Skill 可以发挥价值的地方。
风险与边界
让 Agent 自己进化听起来很诱人,但也有风险。第一,坏 Skill 会被反复调用,导致错误固化。第二,Skill 如果权限太大,可能把危险操作包装成“标准流程”。第三,Skill 太细会检索困难,太粗又会失去指导意义。
比较稳的做法是把 Skill 进化分层:低风险 Skill 可以自动晋级,例如阅读项目结构、生成检查清单;高风险 Skill 必须人工确认,例如删除文件、修改数据库、部署生产环境。Skill 本身也应该能被 diff、review 和回滚。
Hermes 不应该追求“完全自治”。更好的目标是让 Agent 在可追溯、可验证、可回滚的前提下,逐步沉淀自己的工作方法。这样的进化比较慢,但工程上更靠谱。
小结
Hermes 的核心不是某个模型名字,而是一种会成长的 Agent 形态。它把任务轨迹提炼成 Skill,把 Skill 放进 Registry,在后续任务中检索和调用,再根据验证结果持续修订。这个过程让 Agent 不只是“完成一次任务”,而是逐渐形成自己的方法库。
如果要实现一个最小 Hermes,我建议先做三件事:记录完整任务轨迹,允许任务结束后生成候选 Skill,为每个 Skill 设计可执行检查。等这三件事稳定,再考虑自动召回、自动评分和多 Skill 组合。Skill 进化不是魔法,它是工程化复盘、验证和版本管理的组合。





