一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

深刻理解Hermes Agent Skill 机制

时间:2026-07-16 18:23:49 编辑:袖梨 来源:一聚教程网

Summary

Hermes Agent 的 Skill 系统是一个完整的知识注入机制,包含发现索引→触发加载→预处理→Prompt注入→LLM响应五个阶段。Skill 以 SKILL.md 文件形式存储,通过 YAML frontmatter 声明元数据,支持条件激活、平台过滤、安全检测等特性。

深入理解Hermes Agent Skill 机制

1. Skill 目录结构

~/.hermes/skills/
├── category-a/
│   └── skill-name/
│       ├── SKILL.md              # 必需:主文件
│       ├── references/           # 可选:参考资料
│       ├── templates/            # 可选:模板文件
│       ├── scripts/              # 可选:脚本文件
│       └── assets/               # 可选:资源文件
├── category-b/
│   └── another-skill/
│       └── SKILL.md
└── ...

关键特性

  • 支持任意深度的子目录嵌套(通过 os.walk 递归扫描)
  • 子目录仅用于分类组织,不影响索引
  • 排除目录:.git, .github, .hub, .archive

2. 完整生命周期(5阶段)

Phase 1: 发现与索引(启动时)

get_all_skills_dirs()
  ├── ~/.hermes/skills/           # 本地目录(始终在前)
  └── skills.external_dirs        # 外部目录(config.yaml配置)
       ↓
iter_skill_index_files()          # 递归扫描所有 SKILL.md
       ↓
parse_frontmatter()               # 解析 YAML 元数据
       ↓
过滤规则:
  ├── skill_matches_platform()    # 平台兼容性检查
  ├── get_disabled_skill_names()  # 禁用列表过滤
  └── _skill_should_show()        # 条件激活规则
       ↓
build_skills_system_prompt()      # 生成分类索引 Prompt

两级缓存机制

层级类型容量Key
L1进程内 LRU 缓存8 entries(skills_dir, external_dirs, tools, toolsets, platform, disabled)
L2磁盘快照持久化.skills_prompt_snapshot.json(mtime/size验证)

生成的 System Prompt 格式

## Skills (mandatory)
Before replying, scan the skills below. If a skill matches or is even partially relevant
to your task, you MUST load it with skill_view(name) and follow its instructions.


  category-a:
    - skill-name: brief description
    - another-skill: another description


Only proceed without loading a skill if genuinely none are relevant to the task.

Phase 2: 触发(3种方式)

方式 A: LLM 自主调用(主要路径)

System Prompt 引导:
"Before replying, scan the skills below... MUST load with skill_view(name)"
       ↓
LLM 判断任务与 skill 相关
       ↓
tool_call: skill_view(name="skill-name")

触发条件:

  • Skill 名称或描述与用户请求匹配
  • Skill 的 description 字段包含关键词
  • LLM 自主判断"部分相关"就应加载

方式 B: Slash 命令(用户显式调用)

用户输入: /skill-name some instruction
       ↓
scan_skill_commands()           # 扫描所有 SKILL.md 生成命令映射
       ↓
匹配 /skill-name
       ↓
build_skill_invocation_message() # 构建触发消息

Skill 命令命名规则

  • Skill name 规范化:小写,空格/下划线→连字符,去除非法字符
  • 示例:My Skill/my-skill

方式 C: CLI 预加载(Session 启动时)

hermes --skills skill-name
build_preloaded_skills_prompt()
       ↓
注入到 session prompt 开头

Phase 3: 加载与预处理

skill_view() 执行流程

skill_view(name)
  ├── 解析 qualified name          # plugin:skill → 路由到 plugin 系统
  ├── 目录搜索(first match wins) # local → external
  │   ├── 直接路径: search_dir/name/SKILL.md
  │   ├── 分类路径: search_dir/category/name/SKILL.md
  │   └── 名称匹配: 遍历所有 SKILL.md 比对目录名
  ├── 安全检查
  │   ├── 路径穿越检测(防止 .. 攻击)
  │   └── prompt injection 模式扫描
  ├── 平台/禁用检查
  ├── 前置条件检查
  │   ├── 环境变量(prerequisites.env)
  │   └── 凭证文件(prerequisites.credential_files)
  ├── preprocess_skill_content()
  │   ├── 模板变量替换: ${HERMES_SKILL_DIR} → 绝对路径
  │   └── inline shell 展开: !`cmd` → 执行结果
  ├── 收集 linked_files
  │   ├── references/*.md
  │   ├── templates/*.yaml
  │   ├── scripts/*.py
  │   └── assets/*
  └── 返回 JSON:
      {
        "success": true,
        "name": "skill-name",
        "content": "",
        "linked_files": {"references": [...], "templates": [...]},
        "skill_dir": "/path/to/skill",
        "setup_needed": false,
        "readiness_status": "available"
      }

预处理机制

模板变量替换

${HERMES_SKILL_DIR}     → skill 的绝对路径
${HERMES_SESSION_ID}    → 当前会话 ID

Inline Shell 展开(需配置启用):

!`ls -la ${HERMES_SKILL_DIR}/scripts/`
→ 替换为命令执行结果

Phase 4: Prompt 注入

方式 A: LLM tool call 返回

tool 返回 JSON
       ↓
作为 tool_result 注入 conversation history
       ↓
LLM 在下一轮看到完整 skill 内容

方式 B: Slash 命令消息构建

_build_skill_message()
  ├── [IMPORTANT: The user has invoked the "xxx" skill...]
  ├── 
  ├── [Skill directory: /path/to/skill]
  ├── [Skill config: key = value]        # 配置变量注入
  ├── [Skill setup note: ...]            # 安装提示
  ├── [This skill has supporting files:] # 支持文件列表
  │   ├── references/api.md → /path/to/references/api.md
  │   └── scripts/run.py → /path/to/scripts/run.py
  └── The user has provided the following instruction: ...
       ↓
作为 user message 注入 → LLM 响应

方式 C: CLI 预加载

[IMPORTANT: The user launched this CLI session with "xxx" ...]

       ↓
追加到 system prompt 的 prompt_parts

Phase 5: LLM 响应与执行

LLM 接收包含 skill 内容的 message
  ├── 遵循 skill 中的 instructions
  ├── 可通过 skill_view(name, file_path) 加载 supporting files
  ├── 执行 skill 中的 scripts(通过 skill_dir 绝对路径)
  ├── 使用 skill 声明的配置变量
  └── 任务完成后可选:skill_manage(action='patch') 更新 skill

3. Skill 元数据(YAML Frontmatter)

---
name: skill-name
description: "简短描述(≤1024字符)"
version: 1.0.0
author: Author Name
license: MIT
platforms: [macos, linux]  # 可选:平台限制
metadata:
  hermes:
    tags: [tag1, tag2]
    related_skills: [skill-a, skill-b]
    fallback_for_toolsets: [web]     # 当 web toolset 可用时隐藏
    fallback_for_tools: [web_fetch]  # 当 web_fetch tool 可用时隐藏
    requires_toolsets: [browser]     # 当 browser toolset 不可用时隐藏
    requires_tools: [browser_click]  # 当 browser_click tool 不可用时隐藏
    config:                          # 配置变量声明
      - key: api_endpoint
        description: API endpoint URL
        default: "https://api.example.com"
        prompt: Enter API endpoint
prerequisites:
  env:
    - name: API_KEY
      description: API key for authentication
  credential_files:
    - path: ~/.config/skill/credentials.json
      description: Credentials file
---

4. 条件激活规则

字段含义示例
fallback_for_toolsets当指定 toolset 可用时隐藏此 skill有 web toolset 时不需要 web-fallback skill
fallback_for_tools当指定 tool 可用时隐藏此 skill有 web_fetch tool 时不需要备用方案
requires_toolsets当指定 toolset 不可用时隐藏没有 browser toolset 时浏览器 skill 不可用
requires_tools当指定 tool 不可用时隐藏没有 git tool 时 git 相关 skill 不可用

5. 安全机制

Prompt Injection 检测

检测模式

  • ignore previous instructions
  • disregard your instructions
  • you are now
  • system prompt:

处理方式

  • Context 文件注入:拒绝加载并警告
  • Skill 内容注入:记录警告但仍加载(skill 是可信来源)

路径安全

  • 防止路径穿越攻击(..
  • 验证解析路径仍在 skill 目录内
  • 禁止访问 skill 目录外的文件

6. 关键文件职责

文件职责
hermes_constants.pyget_skills_dir() → ~/.hermes/skills/ 路径解析
agent/skill_utils.py核心工具:frontmatter 解析、平台匹配、禁用列表、外部目录、条件提取、文件迭代
agent/prompt_builder.pybuild_skills_system_prompt() 生成分类索引,两级缓存,_skill_should_show() 条件过滤
agent/skill_commands.pySlash 命令扫描、消息构建、CLI 预加载
agent/skill_preprocessing.py模板变量替换、inline shell 展开
tools/skills_tool.pyTool 注册(skills_list, skill_view)、skill 加载、安全检查、linked_files 发现
model_tools.pyTool 注册触发、toolset 过滤
tools/registry.pyTool 注册机制,registry.register() 统一注册 schema + handler
run_agent.pyAgent 循环中调用 build_skills_system_prompt(),注入 system prompt

7. 优化与最佳实践

Skill 设计原则

  1. 描述清晰description 字段是 LLM 判断是否加载的主要依据,应包含关键词
  2. 触发词明确:在 description 中列出典型触发场景
  3. 条件激活合理使用:避免与内置 tool 冲突,使用 fallback_for_* 声明备选关系
  4. 支持文件组织:将参考资料、模板、脚本放在对应子目录中
  5. 配置变量声明:需要用户配置的参数应在 frontmatter 中声明

性能优化

  1. 两级缓存:避免重复扫描文件系统
  2. 条件过滤前置:在索引阶段就过滤掉不兼容的 skill
  3. 延迟加载:只加载与当前任务相关的 skill 内容

热门栏目