Skills

Hermes Agent的Skill自进化机制

这几天(4月初级到四月中旬),Nous Research开源的Hermes Agent突然火起来了,github的star数在疯涨,热度高到有超越open claw的势头了。 为什么他这么火呢?主要是因为他解决了open claw中…

TL;DR

这几天(4月初级到四月中旬),Nous Research开源的Hermes Agent突然火起来了,github的star数在疯涨,热度高到有超越open claw的势头了。 为什么他这么火呢?主要是因为他解决了open claw中…

这几天(4月初级到四月中旬),Nous Research开源的Hermes Agent突然火起来了,github的star数在疯涨,热度高到有超越open claw的势头了。 为什么他这么火呢?主要是因为他解决了open claw中的这样一个痛点: 在使用 OpenClaw 完成一个任务后,无论过程中走了多少弯路、犯了多少错误,这些宝贵的经验都不会沉淀下来,都是用后即焚的。即使下次再遇到相同的任务,他还会从头再来一遍,把踩过的坑再踩一遍。即使你让它记录Memory,他也只是会记录一些简要的重点事项和用户习惯,并不会记录太多执行细节。 Hermes则引入了一种Skill自进化机制,来解决这个问题。 说的简单点,就是引入了一种动态的Skill沉淀的能力。在Hermes Agent中,每次完成复杂任务后,Hermes不会简单地丢弃对话历史,而是会启动一个“复盘”流程。它会回过头来审视整个执行轨迹,提取其中的关键步骤,特别是那些“踩过的坑”、有效的纠错手段以及人工验证过的最佳实践。 随后,系统将这套经验总结、抽象为一个结构化的Skill技能文件包。这就带来了一个根本性的转变:Skill 从“静态调用”变成了“动态生成”。 总结一下:Skill 自进化是指 AI Agent 能够在执行任务的过程中自动创建新的技能,并在后续使用中持续改进这些技能的能力。 在Hermes中,Skill生成的触发时机包括:

## agent/prompt_builder.py 第 164-171 行
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 with skill_manage so you can reuse it next time.\n"
    "When using a skill and finding it outdated, incomplete, or wrong, "
    "patch it immediately with skill_manage(action='patch') — don't wait to be asked. "
    "Skills that aren't maintained become liabilities."
)
触发条件 说明
复杂任务成功完成后 任务使用了 5+ 个工具调用
克服错误后 在解决错误后形成可复用的方法
用户纠正的方法奏效后 用户指导的方法被验证有效
发现非平凡的工作流 发现了复杂的工作流程
用户明确要求记住某个流程 用户主动要求保存为 Skill

触发原则: - 在困难/迭代任务后,Agent 会主动提议保存为 Skill - 简单的一次性任务跳过 - 创建/删除前需要用户确认 入口函数:skill_manage()

def skill_manage(
    action: str,           # "create", "edit", "patch", "delete", "write_file", "remove_file"
    name: str,             # Skill 名称
    content: str = None,   # SKILL.md 完整内容(create/edit 时需要)
    category: str = None,  # 可选分类(如 "devops", "mlops")
    ...
) -> str:

Skill 创建的核心步骤(_create_skill 函数)

def _create_skill(name: str, content: str, category: str = None) -> Dict[str, Any]:

Skill的创建有多种触发机制:

自动触发机制

自动触发完全依赖 LLM 的自主决策。通过在系统提示中植入指导文本,让 LLM 自己判断何时应该创建或更新 Skill。 在 Hermes Agent 中,系统会在每次对话开始时给 AI 发送一段"指导语",告诉它什么情况下应该创建 Skill。AI 在工作的过程中,会自主决定什么时候调用创建工具。 首先,系统提示词注入:

## agent/prompt_builder.py 第 164-171 行
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 with skill_manage so you can reuse it next time.\n"
    "When using a skill and finding it outdated, incomplete, or wrong, "
    "patch it immediately with skill_manage(action='patch') — don't wait to be asked. "
    "Skills that aren't maintained become liabilities."
)
  • 完成一项复杂任务(涉及5次以上工具调用)
  • 修复一个棘手的错误
  • 发现一种复杂且有效的工作流程后
  • 使用某项技能时,若发现它已过时、不完整或存在错误,立即修正 系统提示组装:
## run_agent.py 第 3374-3383 行
def _build_system_prompt(self, system_message: str = None) -> str:
    # ...
    # Tool-aware behavioral guidance: only inject when the tools are loaded
    tool_guidance = []
    if "memory" in self.valid_tool_names:
        tool_guidance.append(MEMORY_GUIDANCE)
    if "session_search" in self.valid_tool_names:
        tool_guidance.append(SESSION_SEARCH_GUIDANCE)
    if "skill_manage" in self.valid_tool_names:      # ← 检查 skill_manage 是否可用
        tool_guidance.append(SKILLS_GUIDANCE)         # ← 注入 Skill 指导
    if tool_guidance:
        prompt_parts.append(" ".join(tool_guidance))

关键点: - 只有在 skill_manage 工具可用时才注入指导 - 指导文本成为系统提示的一部分 - LLM 每次响应都会"看到"这个指导 工具Schema强化:

## tools/skill_manager_tool.py 第 683-701 行
SKILL_MANAGE_SCHEMA = {
    "name": "skill_manage",
    "description": (
        "Manage skills (create, update, delete). Skills are your procedural "
        "memory — reusable approaches for recurring task types.\n\n"
        # ===== 被动触发条件定义 =====
        "Create when: complex task succeeded (5+ calls), errors overcome, "
        "user-corrected approach worked, non-trivial workflow discovered, "
        "or user asks you to remember a procedure.\n"
        "Update when: instructions stale/wrong, OS-specific failures, "
        "missing steps or pitfalls found during use. "
        "If you used a skill and hit issues not covered by it, patch it immediately.\n\n"
        "After difficult/iterative tasks, offer to save as a skill. "
        "Skip for simple one-offs. Confirm with user before creating/deleting."
    ),
    ...
}

自动触发工作流程:

用户输入
    │
    ▼
┌─────────────────────────────────────┐
│  系统提示包含 SKILLS_GUIDANCE        │
│  "After completing a complex task   │
│   (5+ tool calls)..."               │
└─────────────────────────────────────┘
    │
    ▼
LLM 处理任务
    │
    ├─── 工具调用 1 ────┐
    ├─── 工具调用 2 ────┤
    ├─── 工具调用 3 ────┤  LLM 自主计数
    ├─── 工具调用 4 ────┤  和判断
    ├─── 工具调用 5 ────┘
    │
    ▼
LLM 判断:"这是一个复杂任务,应该保存为 Skill"
    │
    ▼
主动调用 skill_manage(action="create")
    │
    ▼
创建 Skill 文件

后台审查机制

除了自动触发外,还有一种后台审查机制的触发,即系统跟踪工具调用次数,达到阈值后自动启动后台审查,无需 LLM 主动决策。 在 Hermes Agent 中,系统会默默计数——每次 AI 使用工具(比如查资料、运行命令、读取文件)都会 +1。当累计达到 10 次后,系统会在后台自动启动一个"审查员"(另一个 AI 实例),让它回顾刚才的对话历史,判断是否需要创建或更新 Skill。这个审查是在后台悄悄进行的,不会打扰用户,如果发现值得保存的内容,会发送一个通知。 计数器初始化:

## run_agent.py 第 1219 行 (AIAgent.__init__)
self._iters_since_skill = 0  # 自上次 skill 操作以来的迭代计数器

配置加载:

## run_agent.py 第 1340-1346 行
## Skills config: nudge interval for skill creation reminders
self._skill_nudge_interval = 10  # 默认每 10 次工具调用触发一次
try:
    skills_config = _agent_cfg.get("skills", {})
    self._skill_nudge_interval = int(skills_config.get("creation_nudge_interval", 10))
except Exception:

迭代计数(核心):

## run_agent.py 第 8642-8646 行
## 在每次工具调用迭代后执行

## Track tool-calling iterations for skill nudge.
## Counter resets whenever skill_manage is actually used.
if (self._skill_nudge_interval > 0           # 功能已启用
        and "skill_manage" in self.valid_tool_names):  # 工具可用
    self._iters_since_skill += 1              # ← 计数器 +1

计数器重置条件:

## run_agent.py 第 7416-7417 行
## 当实际调用 skill_manage 时重置计数器

elif function_name == "skill_manage":
    self._iters_since_skill = 0  # ← 重置计数器

触发判断:

## run_agent.py 第 11338-11344 行
## 在响应用户完成后执行

## Check skill trigger NOW — based on how many tool iterations THIS turn used.
_should_review_skills = False
if (self._skill_nudge_interval > 0           # 1. 功能已启用
        and self._iters_since_skill >= self._skill_nudge_interval  # 2. 达到阈值
        and "skill_manage" in self.valid_tool_names):  # 3. 工具可用
    _should_review_skills = True
    self._iters_since_skill = 0              # ← 重置计数器

启动后台审查:

## run_agent.py 第 11356-11366 行
## Background memory/skill review — runs AFTER the response is delivered
## so it never competes with the user's task for model attention.
if final_response and not interrupted and (_should_review_memory or _should_review_skills):
    try:
        self._spawn_background_review(
            messages_snapshot=list(messages),
            review_memory=_should_review_memory,
            review_skills=_should_review_skills,  # ← 触发 Skill 审查
        )
    except Exception:
        pass  # Background review is best-effort

后台审查执行:

## run_agent.py 第 2371-2469 行
def _spawn_background_review(
    self,
    messages_snapshot: List[Dict],
    review_memory: bool = False,
    review_skills: bool = False,
) -> None:
    """Spawn a background thread to review the conversation for memory/skill saves."""
    import threading

    # 选择审查提示词
    if review_memory and review_skills:
        prompt = self._COMBINED_REVIEW_PROMPT
    elif review_memory:
        prompt = self._MEMORY_REVIEW_PROMPT
    else:
        prompt = self._SKILL_REVIEW_PROMPT  # ← Skill 专用提示词

    def _run_review():
        review_agent = None
        try:
            with contextlib.redirect_stdout(_devnull), \
                 contextlib.redirect_stderr(_devnull):

                # ===== 创建 Fork 的 Review Agent =====
                review_agent = AIAgent(
                    model=self.model,
                    max_iterations=8,        # 限制迭代次数
                    quiet_mode=True,         # 静默模式
                    platform=self.platform,
                    provider=self.provider,
                )

                # 禁用嵌套触发(避免无限循环)
                review_agent._memory_nudge_interval = 0
                review_agent._skill_nudge_interval = 0

                # 执行审查
                review_agent.run_conversation(
                    user_message=prompt,
                    conversation_history=messages_snapshot,
                )

            # ===== 扫描审查结果 =====
            actions = []
            for msg in getattr(review_agent, "_session_messages", []):
                if msg.get("role") != "tool":
                    continue
                data = json.loads(msg.get("content", "{}"))
                if not data.get("success"):
                    continue

                message = data.get("message", "")
                if "created" in message.lower() or "updated" in message.lower():
                    actions.append(message)

            # ===== 通知用户 =====
            if actions:
                summary = " · ".join(dict.fromkeys(actions))
                self._safe_print(f"  💾 {summary}")  # 终端显示
                if self.background_review_callback:
                    self.background_review_callback(f"💾 {summary}")

        finally:
            if review_agent:
                review_agent.close()

    # 启动后台线程
    threading.Thread(target=_run_review, daemon=True, name="bg-review").start()

Skill 审查专用提示词:

## run_agent.py 第 2347-2355 行
_SKILL_REVIEW_PROMPT = (
    "Review the conversation above and consider saving or updating a skill if appropriate.\n\n"
    "Focus on: was a non-trivial approach used to complete a task that required trial "
    "and error, or changing course due to experiential findings along the way, or did "
    "the user expect or desire a different method or outcome?\n\n"
    "If a relevant skill already exists, update it with what you learned. "
    "Otherwise, create a new skill if the approach is reusable.\n"
    "If nothing is worth saving, just say 'Nothing to save.' and stop."
)

后台审查触发工作流程:

用户输入
    │
    ▼
工具调用循环
    │
    ├─── 每次迭代后 ───► _iters_since_skill += 1
    │
    ▼
响应用户完成
    │
    ▼
检查触发条件
    │
    ├─── _iters_since_skill >= 10? ─── 否 ─── 继续等待
    │
    └─── 是 ───► _should_review_skills = True
                  │
                  ▼
         调用 _spawn_background_review()
                  │
                  ▼
         创建 Fork Review Agent
                  │
                  ▼
         执行 _SKILL_REVIEW_PROMPT
                  │
                  ▼
         LLM 审查对话历史
                  │
    ┌─────────────┴─────────────┐
    ▼                           ▼
 Nothing to save.           调用 skill_manage
    │                           │
    ▼                           ▼
   结束                    创建/更新 Skill
                               │
                               ▼
                          显示 💾 通知
版本提示

模型、框架与接口会持续变化。涉及版本号、参数与生产配置时,请在实践前对照对应官方文档。

LLMentor系统化学习大模型应用工程

内容来自个人课程知识库备份,并经过结构化整理。技术版本持续演进,生产使用前请结合官方文档验证。