Hermes 自动提取技能
1. 前言
自动提取技能的本质是从原始经验中寻找可复用的时间抽象。它的核心驱动力是提升智能系统的扩展性与自主性,而主要瓶颈在于如何在没有明确监督的情况下,定义并识别出稳定、有语义、可组合的技能单元。当前研究多结合无监督分割、元学习、分层强化学习或程序合成,但距离通用、高效的自动技能发现仍有较大距离。
Hermes 的核心实践是将“技能提取”从一个被动任务,转变为一个由“学习循环”驱动的主动自动化过程。这意味着它能在执行任务后自主反思并沉淀可复用的知识,不再依赖人工编写所有技能。
Hermes 实现自动提取技能的核心机制:“学习循环”。该循环由“执行-学习-改进”的闭环。
Lexical error on line 15. Unrecognized text. ... E --> F[存储至技能库~/.hermes/skills/] -----------------------^
2. Skill自创建流程
1. Agent完成复杂任务(5+工具调用)
↓
2. SKILLS_GUIDANCE提示词触发
↓
3. Agent评估任务价值
↓
4. Agent调用skill_manage(action='create')
↓
5. 验证名称、frontmatter、内容大小
↓
6. 创建目录结构
↓
7. 原子写入`SKILL.md`
↓
8. 安全扫描
↓
9. 成功创建skill
↓
10. 后续会话中可复用
这个机制确保了agent能够从实际使用中学习,将成功的解决方案转化为可复用的技能,形成持续改进的循环。
3. 触发条件
3.1. 由SKILLS_GUIDANCE触发
在 \agent\prompt_builder.py#L164-L171 中定义的 SKILLS_GUIDANCE 会在每次会话中注入, 引导agent在特定情况下创建skill。
- 具体触发场景:
- ✅ 完成复杂任务(5+次工具调用)
- ✅ 修复棘手的错误
- ✅ 发现非平凡的工作流程
- ✅ 用户纠正的方法成功了
- ✅ 发现了新的做事方法
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_manage 将该方法保存为一个技能,以便下次复用。
当使用某个技能时,如果发现它已过时、不完整或有误,请立即用 skill_manage(action='patch') 对其进行修补——不要等着被要求。
不维护的技能会变成负担。
3.2. 由MEMORY_GUIDANCE触发
在 \agent\prompt_builder.py#L154-L155 中定义的 MEMORY_GUIDANCE 还有相关引导:
"If you've discovered a new way to do something, solved a problem that could be "
"necessary later, save it as a skill with the skill tool."
如果你发现了一种做事的新方法,或者解决了一个日后可能会用得到的问题,请使用技能工具将其保存为一个技能。
4. 核心工具:技能管理工具(skill_manage)
技能管理工具: Agent自主创建与编辑技能。技能是Agent的程序性记忆:它们基于已验证的经验,捕获“如何完成某类特定任务”。通用记忆(MEMORY.md、USER.md)是宽泛且陈述性的。技能则是具体且可操作的。
- 主要特性:
- 允许代理创建、更新和删除技能,将成功的方法转化为可复用的程序性知识。
- 新技能创建在
~/.hermes/skills/目录下。 - 已有的技能(无论是内置、从中心安装还是用户创建的)均可被修改或删除,无论它们位于何处。
4.1. 工具定义
在 \tools\skill_manager_tool.py#L660-L730 中定义了完整的skill管理工具:
支持的操作:
create- 从头创建新skillpatch- 针对性修复(推荐)edit- 完整重写SKILL.mddelete- 删除skillwrite_file- 添加/更新支持文件remove_file- 删除支持文件
4.2. 存储位置
统一存储位置:~/.hermes/skills/
这是skill的单一真实来源:
- 捆绑的skill在安装时从此处复制
- Hub安装的skill也存放在此
- Agent创建的skill也写入此目录
用户技能的目录结构:
~/.hermes/skills/
├── my-skill/
│ ├── `SKILL.md` # 必需:主要指令
│ ├── references/ # 可选:支持文档
│ ├── templates/ # 可选:模板
│ ├── scripts/ # 可选:辅助脚本
│ └── assets/ # 可选:资源文件
└── category-name/
└── another-skill/
└── `SKILL.md`
4.3. Skill格式标准
4.3.1. 必需的前置内容(YAML Frontmatter)
---
name: my-skill
description: Brief description (shown in skill search results)
version: 1.0.0
author: Your Name
license: MIT
platforms: [macos, linux] # 可选 - 限制特定OS平台
metadata:
hermes:
tags: [Category, Subcategory, Keywords]
related_skills: [other-skill-name]
requires_toolsets: [web] # 可选 - 仅在特定工具集激活时显示
requires_tools: [web_search] # 可选 - 仅在特定工具可用时显示
fallback_for_toolsets: [browser] # 可选 - 在特定工具集激活时隐藏
fallback_for_tools: [browser_navigate] # 可选 - 在特定工具可用时隐藏
config: # 可选 - config.yaml设置
- key: my.setting
description: "What this setting controls"
default: "sensible-default"
prompt: "Display prompt for setup"
required_environment_variables: # 可选 - 环境变量
- name: MY_API_KEY
prompt: "Enter your API key"
help: "Get one at https://example.com"
required_for: "API access"
---
4.3.2. Markdown正文结构(推荐)
# Skill Title
Brief intro.
## When to Use
Trigger conditions — when should the agent load this skill?
## Quick Reference
Table of common commands or API calls.
## Procedure
Step-by-step instructions the agent follows.
## Pitfalls
Known failure modes and how to handle them.
## Verification
How the agent confirms it worked.
4.4. 创建Skill的参数
{
"action": "create",
"name": "skill-name", # 小写,支持连字符/下划线,最大64字符
"content": "完整的SKILL.md内容", # YAML frontmatter + markdown正文
"category": "optional-category" # 可选分类(如devops, mlops等)
}
5. Skill创建时输入上下文的来源
创建Skill时,输入上下文来源包括:
| 上下文来源 | 提供的信息 | 使用场景 |
|---|---|---|
| 当前会话 | 实时工具调用、错误解决、成功路径 | 完成任务后立即创建skill |
| 历史会话 | 过去的成功经验、类似问题的解决方案 | 基于历史经验创建skill |
| 持久化记忆 | 用户偏好、环境细节、稳定约定 | 确保skill符合用户习惯 |
| 系统提示词 | 触发条件、格式要求、最佳实践 | 决定何时创建、如何格式化 |
| 上下文文件 | 项目特定规范、团队约定 | 创建符合项目标准的skill |
| 现有技能 | YAML结构、章节组织、表达方式 | 学习正确格式,避免错误 |
多源头的上下文机制确保了创建的skill既基于实际经验,又符合用户偏好和项目规范,同时遵循系统的最佳实践。
┌─────────────────────────────────────────────────────────────┐
│ Skill创建上下文来源 │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 当前会话轨迹 │ │ 历史会话 │ │ 持久化记忆 │
│ (实时对话) │ │ (session_ │ │ (memory工具) │
│ │ │ search) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└───────────────────┼───────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 系统提示词 │ │ 上下文文件 │ │ 现有技能 │
│ (SKILLS_ │ │ (AGENTS.md │ │ (skill_view) │
│ GUIDANCE) │ │ 等) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ 综合分析 │
│ 提取模式 │
│ 生成skill │
└──────────────┘
│
▼
┌──────────────┐
│skill_manage │
│ (create) │
└──────────────┘
5.1. 当前会话轨迹
最直接的来源,agent在实时对话中观察到的所有信息:
5.1.1. 包含内容
- 用户请求:用户的原始指令和需求
- 工具调用序列:agent执行了哪些工具(如
terminal,read_file,web_search) - 工具结果:每个工具的输出和返回值
- 错误和重试:遇到的问题和解决方案
- 最终成功路径:最终有效的工作流程
5.1.2. 代码
在 \run_agent.py#L526-L531 的 AIAgent 类中,维护着完整的消息历史:
class AIAgent:
"""
AI Agent with tool calling capabilities.
This class manages conversation flow, tool execution, and response handling
"""
agent会遍历 messages 列表,提取:
- 成功的工具调用模式
- 有效的命令序列
- 用户确认的解决方案
5.1.3. 示例场景
用户: "帮我部署一个Django应用到Docker"
↓
Agent: 调用 terminal 创建 Dockerfile
↓
Agent: 调用 terminal 构建镜像
↓
Agent: 调用 terminal 运行容器
↓
成功!
↓
SKILLS_GUIDANCE 触发:"After completing a complex task (5+ tool calls)..."
↓
Agent基于这些步骤创建 skill
5.2. 历史会话
长期记忆来源,通过 session_search 工具检索过去的成功经验:
5.2.1. 机制
在 \tools\session_search_tool.py#L1-L30 中实现:
"""
Session Search Tool - Long-Term Conversation Recall
Flow:
1. FTS5 search finds matching messages ranked by relevance
2. Groups by session, takes top N unique sessions (default 3)
3. Loads each session's conversation, truncates to ~100k chars
4. Sends to Gemini Flash with a focused summarization prompt
5. Returns per-session summaries with metadata
"""
5.2.2. 包含内容
- SQLite数据库:
~/.hermes/state.db存储所有会话元数据 - JSONL转录:
~/.hermes/sessions/存储完整对话历史 - FTS5全文搜索:快速检索相关历史会话
- 会话摘要:通过辅助模型生成的精简摘要
5.2.3. 使用场景
用户: "像上次那样配置Kubernetes"
↓
SESSION_SEARCH_GUIDANCE 触发:"When user references something from a past conversation..."
↓
Agent调用 session_search("Kubernetes配置")
↓
返回:3个相关历史会话的摘要
↓
Agent基于历史会话创建/更新 skill
5.3. 持久化记忆
事实性知识来源,存储在 memory 工具中的持久化信息:
5.3.1. 机制
在 \agent\prompt_builder.py#L144-L156 中定义:
MEMORY_GUIDANCE = (
"You have persistent memory across sessions. Save durable facts using the memory "
"tool: user preferences, environment details, tool quirks, and stable conventions.\n"
"Prioritize what reduces future user steering — the most valuable memory is one "
"that prevents the user from having to correct or remind you again.\n"
"Do NOT save task progress, session outcomes, completed-work logs, or temporary TODO "
"state to memory; use session_search to recall those from past transcripts.\n"
"If you've discovered a new way to do something, solved a problem that could be "
"necessary later, save it as a skill with the skill tool."
)
5.3.2. 包含内容
- 用户偏好:用户反复强调的习惯
- 环境细节:特定的配置、路径、工具版本
- 工具怪癖:某些工具的特殊用法
- 稳定约定:团队或项目的规范
5.3.3. 使用场景
Memory中记录:"用户总是用Python 3.11,不是3.12"
↓
Agent创建 skill 时包含这个约束
↓
Skill内容:"确保使用python3.11命令"
5.4. 系统提示词与引导
触发和格式化来源,告诉agent何时以及如何创建skill:
5.4.1. SKILLS_GUIDANCE
在 \agent\prompt_builder.py#L164-L171 中:
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.4.2. 触发条件:
- ✅ 完成复杂任务(5+工具调用)
- ✅ 修复棘手错误
- ✅ 发现非平凡工作流程
- ✅ 用户纠正的方法成功了
5.4.3. 格式化指导:
- Skill的YAML frontmatter结构
- Markdown正文组织方式
- 必需字段(name, description)
5.5. 上下文文件
项目特定知识来源,从项目文件中提取工作流程:
5.5.1. 机制
在 \agent\prompt_builder.py#L400-L499 中实现:
def _find_hermes_md(cwd: Path) -> Optional[Path]:
"""Discover the nearest ``.hermes.md`` or ``HERMES.md``.
Search order: *cwd* first, then each parent directory up to (and
including) the git repository root.
"""
5.5.2. 包含内容
AGENTS.md:项目特定的agent指令- .cursorrules:编码规范和工作流程
SOUL.md:全局配置和偏好.hermes.md:本地项目指令
5.5.3. 使用场景:
项目中存在 AGENTS.md:
"我们使用poetry管理依赖,不是pip"
↓
Agent读取 AGENTS.md
↓
创建 skill 时包含这个约定
5.6. 现有技能参考
格式和结构来源,通过查看现有skill了解正确格式.
5.6.1. 机制
通过 skill_view 工具查看现有skill的结构:
# 在 skill_manager_tool.py 中
"Good skills: trigger conditions, numbered steps with exact commands, "
"pitfalls section, verification steps. Use skill_view() to see format examples."
5.6.2. 包含内容
- YAML frontmatter示例:如何声明metadata
- 章节组织:When to Use, Quick Reference, Procedure, Pitfalls
- 最佳实践:渐进式披露、清晰的步骤
5.6.3. 使用场景:
Agent: "我需要创建一个新skill"
↓
调用 skill_view("docker-deployment")
↓
学习格式:
- YAML frontmatter结构
- 章节组织方式
- 命令的精确表达
↓
应用相同格式创建新skill
6. Skill创建过程的主要代码
- Agent在创建skill时会考虑:
- 任务复杂度 - 工具调用次数、迭代次数
- 错误解决过程 - 遇到的错误和解决方案
- 成功模式 - 什么方法最终有效
- 可复用性 - 这个方法是否值得保存
- 用户反馈 - 用户的纠正和偏好
-
创建前的检查:
- 是否符合触发条件(5+工具调用、修复错误、发现新方法)
- 是否有足够的可复用价值
- 用户是否明确要求保存为skill
-
更新时机:
- 发现指令过时或不正确
- 特定于操作系统的失败
- 使用过程中发现缺失步骤或陷阱
6.1. 创建Skill(_create_skill)
在 \tools\skill_manager_tool.py#L248-L288 中:
def _create_skill(name: str, content: str, category: str = None) -> Dict[str, Any]:
"""创建新的用户skill"""
# 验证名称
err = _validate_name(name)
if err:
return {"success": False, "error": err}
# 验证内容
err = _validate_frontmatter(content)
if err:
return {"success": False, "error": err}
# 创建skill目录
skill_dir = _resolve_skill_dir(name, category)
skill_dir.mkdir(parents=True, exist_ok=True)
# 原子写入SKILL.md
skill_md = skill_dir / "SKILL.md"
_atomic_write_text(skill_md, content)
# 安全扫描
scan_error = _security_scan_skill(skill_dir)
if scan_error:
shutil.rmtree(skill_dir, ignore_errors=True)
return {"success": False, "error": scan_error}
return {"success": True, "message": f"Skill '{name}' created.", ...}
6.2. 更新Skill(_patch_skill)
在 \tools\skill_manager_tool.py#L390-L470 中:
def _patch_skill(
name: str,
old_string: str,
new_string: str,
file_path: str = None,
replace_all: bool = False,
) -> Dict[str, Any]:
"""在skill文件中进行针对性查找替换"""
# 使用模糊匹配引擎
from tools.fuzzy_match import fuzzy_find_and_replace
new_content, match_count, _strategy, match_error = fuzzy_find_and_replace(
content, old_string, new_string, replace_all
)
# 验证大小限制
err = _validate_content_size(new_content, label=target_label)
if err:
return {"success": False, "error": err}
# 如果修改SKILL.md,验证frontmatter仍然完整
if not file_path:
err = _validate_frontmatter(new_content)
if err:
return {"success": False, "error": f"Patch would break SKILL.md structure: {err}"}
# 原子写入
_atomic_write_text(target, new_content)
# 安全扫描
scan_error = _security_scan_skill(skill_dir)
if scan_error:
_atomic_write_text(target, original_content)
return {"success": False, "error": scan_error}
return {"success": True, ...}
6.3. 验证机制
- 名称验证:
_validate_name()- 检查格式和长度 - Frontmatter验证:
_validate_frontmatter()- 检查必需字段 - 内容大小验证:
_validate_content_size()- 限制100,000字符 - 文件路径验证:
_validate_file_path()- 防止路径遍历
6.4. 安全扫描
所有agent创建的skill都会经过安全扫描\tools\skill_manager_tool.py#L67-L76:
def _security_scan_skill(skill_dir: Path) -> Optional[str]:
"""扫描skill目录,如果被阻止则返回错误字符串"""
result = scan_skill(skill_dir, source="agent-created")
allowed, reason = should_allow_install(result)
if allowed is False:
report = format_scan_report(result)
return f"Security scan blocked this skill ({reason}):\n{report}"
if allowed is None:
# "ask" - 允许但包含警告
logger.warning("Agent-created skill has security findings: %s", reason)
return None
return None
7. 最佳实践
什么是一个好的Skill?好的Skill应该具有哪些特质?
在 \tools\skill_manager_tool.py#L671-L672 的第 671-672行, 有一段关于Skill的描述。
SKILL_MANAGE_SCHEMA = {
"name": "skill_manage",
"description": (
"Manage skills (create, update, delete). Skills are your procedural "
"memory — reusable approaches for recurring task types. "
"New skills go to ~/.hermes/skills/; existing skills can be modified wherever they live.\n\n"
"Actions: create (full SKILL.md + optional category), "
"patch (old_string/new_string — preferred for fixes), "
"edit (full SKILL.md rewrite — major overhauls only), "
"delete, write_file, remove_file.\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.\n\n"
"Good skills: trigger conditions, numbered steps with exact commands, "
"pitfalls section, verification steps. Use skill_view() to see format examples."
""" 为了便于理解,下半部分为翻译内容 """
"管理技能(创建、更新、删除)。技能是你的程序性记忆——针对重复出现的任务类型的可复用方法。"
"新技能存放于 ~/.hermes/skills/;已有技能无论位于何处均可被修改。\n\n"
"操作:create(完整 SKILL.md + 可选分类),"
"patch(old_string/new_string — 优先用于修正),"
"edit(重写整个 SKILL.md — 仅用于重大改版),"
"delete, write_file, remove_file。\n\n"
"创建时机:复杂任务成功完成(5+ 次调用)、克服了错误、用户纠正的方法奏效、"
"发现了非平凡的工作流,或用户要求你记住某个流程。\n"
"更新时机:指令过时/错误、遇到特定操作系统的失败、"
"使用过程中发现遗漏步骤或陷阱。如果你使用了某个技能但遇到了该技能未覆盖的问题,应立即使用 patch 更新。\n\n"
"在困难/迭代性任务完成后,主动建议将其保存为技能。"
"简单的一次性任务则不必。创建或删除前需征得用户确认。\n\n"
"优秀的技能应包含:触发条件、带有精确命令的编号步骤、"
"陷阱章节、验证步骤。使用 skill_view() 查看格式示例。"
),
description 字段最后的一部分是OpenAI Function-Calling Schema的引用,具体内容为:
"优秀的技能应包含:触发条件、带有精确命令的编号步骤、"
"陷阱章节、验证步骤。使用 skill_view() 查看格式示例。"
这里提出了五个特征, 再补充一个 Skill 的核心思想,可以构成好的 skill 的核心特征。
| 特征 | 含义 | 示例 |
|---|---|---|
| 触发条件(trigger conditions) | 何时使用这个skill | “当需要部署Django应用到Docker时” |
| 编号步骤(numbered steps) | 清晰的操作顺序 | 1. 创建Dockerfile 2. 构建镜像 3. 运行容器 |
| 精确命令(exact commands) | 可直接执行的命令 | docker build -t myapp . |
| 陷阱部分(pitfalls section) | 已知问题和解决方案 | 常见错误:端口冲突,解决方案:使用不同端口 |
| 验证步骤(verification steps) | 如何确认成功 | 运行 docker ps 确认容器正在运行 |
| 渐进式披露(progressive disclosure) | 常用场景在前,边缘情况在后 | 常用场景:部署Django应用到Docker容器 边缘情况:处理端口冲突 |
8. 总结
Hermes 的技能自动提取实践,核心在于通过系统架构和工程方法,模拟了人类“从经验中学习”的本能,将知识管理内化为 Agent 自身的职责。
Hermes 的核心实践是将“技能提取”从一个被动任务,转变为一个由“学习循环”驱动的主动自动化过程。这意味着它能在执行任务后自主反思并沉淀可复用的知识,不再依赖人工编写所有技能。
8.1. 技能自动提取
- 任务执行与触发:执行任务时,Hermes 会自主判断是否为“学习时刻”。触发条件包括:
- 完成需要 5 次以上工具调用的复杂任务。
- 成功修复棘手的错误。
- 走通一套非常规但有效的流程。
- 技能创建 (skill_manage):触发后,Hermes 通过内置的
skill_manage工具自动生成标准化的SKILL.md技能文档。文档包含结构化元数据(YAML frontmatter)和核心正文(Markdown),清晰记录技能的目的、触发条件、详细步骤、潜在陷阱和验证方法。 - 技能存储与检索:生成的技能被保存在
~/.hermes/skills/目录下。为节省上下文窗口,Hermes 采用渐进式披露策略:- 第一层:仅加载技能列表(名称、简介)。
- 第二层:Agent确认需要后,才加载完整的技能文档。
- 技能自我进化 (Patch):后续调用技能时,若发现内容过时或不完美,Hermes 会再次调用
skill_manage工具,通过patch操作对技能进行“打补丁”式的精准修改,而非完全覆盖。
8.2. 多层次记忆架构
“学习循环”的背后,是多层记忆系统的支持,它赋予Hermes在不同时间尺度上“记忆”的能力。
- 第一层:过程性技能记忆:
~/.hermes/skills/*.md是“学习循环”的核心产出,存储了所有自动生成的技能,即解决问题的成功路径。 - 第二层:情境持久化检索:基于向量索引为技能建立检索能力,让Hermes能根据新任务的描述,主动找到最相关的技能。
- 第三层:全文可检索会话存档:将所有历史会话存储在本地SQLite数据库中,并提供全文检索功能,用以追溯任意细节。
8.3. 关键特性与优势
- 自动化与低门槛:将开发者从繁琐的技能编写和维护中解放出来,专注于更高价值的任务。
- 持续进化:Hermes 会随着使用时间的增加而不断优化自身技能,实现“越用越强”。
- 标准化:生成的技能遵循
agentskills.io开放标准,使其在不同Agent之间具备良好的可移植性和互操作性。 - 上下文节约:通过“渐进式披露”等策略,有效控制上下文长度,降低Token消耗。
当然,这项实践也存在挑战。例如,依赖LLM的反思能力可能受幻觉或逻辑错误影响;自动生成的技能质量需要有效评估。
- 点赞
- 收藏
- 关注作者
评论(0)