
如果团队已经有共享技能目录可以让 Hermes 额外扫描~/.hermes/config.yamlskills:external_dirs:- ~/.agents/skills- /home/shared/team-skills- ${SKILLS_REPO}/skills外部目录支持 ~ 展开和 ${VAR} 环境变量替换。规则只读扫描Agent 创建或修改技能时仍然写入 ~/.hermes/skills/本地优先本地版本覆盖外部同名技能完整集成出现在技能索引、skills_list、skill_view 和斜杠命令中路径可选不存在的外部目录会被静默跳过1.4 Skill BundlesSkill Bundles 允许用一个斜杠命令同时加载多个技能。例如创建一个 writing-day bundlehermes skills bundle create writing-day --skills blogwatcher,markdown-style,seo-check之后只需执行 /writing-day 即可加载全部三个技能。1.5 Skills Hub 与 agentskills.ioHermes Skills 兼容 agentskills.io 开放标准。你可以从 Skills Hub 浏览和安装社区技能将自定义技能发布到 Hub 共享通过 URL 直接安装技能v0.16 精简了内置技能集将 NVIDIA/skills 添加为内置可信 Skills Hub tap。1.6 Conditional Activation条件激活技能可以根据工具可用性自动显示/隐藏。例如如果 Firecrawl API Key 缺失Hermes 会自动回退到 DuckDuckGo 搜索技能。1.7 Platform-Specific Skills平台特定技能技能可以限定在特定操作系统上生效就是在SKILL的元数据中写明支持的系统SKILL.md frontmatterplatforms:linuxmacos- windows # 此技能不在 Windows 上显示1.8 Agent-Managed Skills (skill_manage)【重要操作实用】Hermes 可以通过 skill_manage 工具创建、修改和删除自己的技能。这是 Agent 的「程序记忆」当它解决了一个有复用价值的复杂问题就可以把流程沉淀成 Skill。触发策略主要靠提示词驱动。整体规则复杂任务成功、克服错误、用户纠正后的方法有效、发现可复用流程或用户要求记住流程时可以创建 Skill发现 Skill 过时、缺步骤、命令错误、OS 相关失败或新坑点时应优先 patch 现有 Skillskill_manage 常见动作动作 用途create 从零创建一个新技能patch 对现有技能做小范围修改优先使用edit 整体重写技能内容delete 删除技能write_file 添加或更新 references/、scripts/ 等支持文件remove_file 删除支持文件create 完整调用示例当 Agent 发现一个值得沉淀的工作流程后skill_manage(action“create”,name“docker-troubleshooting”,category“devops”,description“Systematic Docker troubleshooting workflow for production environments.”,content“# Docker Troubleshooting\n…”,umbrella“devops/troubleshooting”, # 可选归到已有 umbrella 下)返回技能已创建在 ~/.hermes/skills/devops/docker-troubleshooting/SKILL.mdpatch 使用示例发现已有技能需要修正一小部分skill_manage(action“patch”,name“docker-troubleshooting”,old_string“docker logs --tail 50”,new_string“docker logs --tail 100 --timestamps”,reason“增加时间戳和日志行数便于关联时间线排查”,)Agent 优先使用 patch 而非 edit避免意外覆盖用户手动调整的内容。1.9 Curator 技能维护系统【重要原理须知】官方文档https://hermes-agent.nousresearch.com/docs/user-guide/features/curator默认非官方的SKILL具体解释看本节最后一句话超过30天未使用会被标记为 低活跃超过90天没用会移动到归档中再去会话中Agent无法自动调用需要用户指定才会重新唤醒这个SKILL唤醒成功后这个SKILL重新被标记为 活跃 。Curator 是 Hermes 的技能维护系统专门管理由后台自我改进 review agent 创建并标记的本地技能。它会跟踪这些技能的查看、使用和修改频率把长期不用的技能从 active 推进到 stale再归档到 ~/.hermes/skills/.archive/。Curator 的存在是为了防止通过自我提升循环产生的技能无限累积。如果不进行维护最终会导致数十个功能相近但范围狭窄的重复技能污染目录并浪费 token。Pinned 技能保护如果某个技能很重要可以把它 pin 住。Pinned 技能有三层保护Curator 不会把它自动迁移到 stale 或 archivedCurator 的 LLM Review 会跳过它Agent 的 skill_manage delete 也不能删除它但仍然可以 patch / edit运行机制Curator 在 Hermes 启动或 Gateway 后台 tick 时检查。自动运行需要同时满足curator.enabled 未被设为 false未被 hermes curator pause 暂停距离上次运行超过 interval_hours默认 168 小时 / 7 天Agent 已空闲超过 min_idle_hours默认 2 小时每次运行按两阶段执行自动状态迁移不调用 LLM超过 stale_after_days (30天) 未使用的技能变成 stale超过 archive_after_days (90天) 未使用的移动到 .archive/LLM Review启动辅助模型决定保留、修补、合并或归档。目标是构建类别级指令和经验知识的库配置~/.hermes/config.yamlcurator:enabled: trueinterval_hours: 168min_idle_hours: 2stale_after_days: 30archive_after_days: 90可以为 Curator 指定更便宜的辅助模型~/.hermes/config.yamlauxiliary:curator:provider: openroutermodel: google/gemini-3-flash-previewtimeout: 600常用命令hermes curator status # 查看技能状态hermes curator run # 手动运行策展hermes curator run --background # 后台运行hermes curator run --dry-run # 只预览不修改技能库hermes curator pause # 暂停自动运行hermes curator resume # 恢复自动运行hermes curator pin my-important-skill # 固定某个技能hermes curator unpin my-important-skill # 取消固定hermes curator restore my-skill # 恢复已归档的技能hermes curator rollback # 恢复最新备份同样的子命令也可以在会话中通过 /curator 斜杠命令使用。哪些技能会被处理Curator 只处理同时满足以下条件的技能位于本地技能目录 ~/.hermes/skills/不是 bundled 内置技能不是 Skills Hub 安装的技能被标记为 created_by: “agent” 或 agent_created: true用户手写的 SKILL.md、外部技能目录中的 Skill、bundled 内置技能和 Skills Hub 安装的技能都不会被 Curator 自动归档或合并。Hooks 钩子系统官方文档https://hermes-agent.nousresearch.com/docs/user-guide/features/hooksHermes 提供了三种钩子系统允许在关键生命周期点执行自定义代码。所有钩子都是非阻塞设计错误会被捕获并记录不会影响Agent 运行。三种钩子对比维度 Shell Hooks Plugin Hooks Gateway Hooks语言 任意Bash、Python、Go 等 仅 Python 仅 Python运行环境 CLI Gateway CLI Gateway 仅 Gateway事件名 Agent 内部事件名 Agent 内部事件名 带冒号的 Gateway 事件名注册位置 ~/.hermes/config.yaml 的 hooks: 插件 register(ctx) 中注册 ~/.hermes/hooks//HOOK.yaml典型用例 阻止危险命令、自动格式化、注入 git 状态 工具拦截、指标采集、防护措施、记忆召回 日志记录、告警通知、Webhook 回调常见钩子事件钩子 适用系统 触发时机 常见用途 是否能影响流程pre_tool_call Shell / Plugin 工具执行前 阻止危险命令、检查参数、审计调用 可以返回 block 阻止post_tool_call Shell / Plugin 工具返回后 记录结果、采集指标、跟踪生成文件 观察型pre_llm_call Shell / Plugin 每轮 LLM 调用前 注入 git 状态、外部上下文、策略提示 可以返回 context 注入post_llm_call Shell / Plugin 每轮 LLM 调用结束后 记录响应、同步记忆、采集 token 指标 观察型on_session_start Shell / Plugin 新会话开始时 初始化会话状态、打开外部连接 观察型on_session_end Shell / Plugin 会话结束、重置或退出时 清理资源、flush 缓存、发送通知 观察型gateway:startup Gateway Gateway 进程启动时 启动检查、告警、注册 Webhook 观察型session:start / session:end / session:reset Gateway Gateway 会话创建、结束或重置时 记录消息平台会话、审计用户行为 观察型agent:start / agent:step / agent:end Gateway Gateway 中 Agent 处理消息的过程 监控长任务、记录工具循环、统计耗时 观察型command:* Gateway Gateway 里执行任意斜杠命令时 命令审计、权限统计、外部通知 观察型7.1 Shell Hook 示例会话结束后弹出桌面通知适合在 WSL / Git Bash / Windows 终端里使用 Hermes。Linux注册 shell hook~/.hermes/config.yamlhooks:on_session_end:- command: “~/.hermes/agent-hooks/windows-session-end-popup.sh”timeout: 15 windows注册 shell hookxxxx/hermes/config.yamlhooks:on_session_end:command: C:/PROGRA~1/Git/bin/bash.exe “C:/Users/merge/AppData/Local/hermes/hooks/windows-session-end-popup.sh”timeout: 15hooks_auto_accept: true创建脚本目录mkdir -p ~/.hermes/agent-hooks创建脚本 ~/.hermes/agent-hooks/windows-session-end-popup.sh#!/usr/bin/env bashcat - /dev/null # 丢弃 hook payloadstdinif command -v powershell.exe /dev/null 21; thenpowershell.exe -NoProfile -WindowStyle Hidden -Command ’Add-Type -AssemblyName System.Windows.FormsAdd-Type -AssemblyName System.Drawing$f New-Object System.Windows.Forms.Form $f.Text Hermes $f.Width 300 $f.Height 100 $f.FormBorderStyle None $f.StartPosition CenterScreen $f.BackColor [System.Drawing.Color]::FromArgb(32, 32, 32) $f.ForeColor [System.Drawing.Color]::White $f.TopMost $true $f.ShowInTaskbar $false $label New-Object System.Windows.Forms.Label $label.Text Session finished $label.Font New-Object System.Drawing.Font(Segoe UI, 10, [System.Drawing.FontStyle]::Bold) $label.ForeColor [System.Drawing.Color]::White $label.AutoSize $true $label.Location New-Object System.Drawing.Point(20, 30) $f.Controls.Add($label) $timer New-Object System.Windows.Forms.Timer $timer.Interval 3000 $timer.Add_Tick({ $f.Close() }) $timer.Start() $f.ShowDialog() $f.Dispose()’ /dev/null 21 fiprintf ‘{}\n’赋予执行权限chmod x ~/.hermes/agent-hooks/windows-session-end-popup.sh首次运行时 Hermes 会询问是否允许这个 (event, command) 组合。7.2 pre_tool_call 安全拦截示例pre_tool_call 是唯一能阻止工具执行的钩子适合安全防护场景。场景阻止 Agent 执行危险的终端命令如 rm -rf /、DROP TABLE、未授权的 SSH 连接。注册 hook~/.hermes/config.yamlhooks:pre_tool_call:- command: “~/.hermes/agent-hooks/danger-guard.sh”timeout: 5创建 ~/.hermes/agent-hooks/danger-guard.sh#!/usr/bin/env bashPAYLOAD$(cat) # Hermes 把工具调用信息通过 stdin 传入JSON 格式TOOL_NAME( e c h o (echo (echoPAYLOAD | python3 -c “import sys,json; print(json.load(sys.stdin).get(‘name’,‘’))”)PARAMS( e c h o (echo (echoPAYLOAD | python3 -c “import sys,json; print(json.dumps(json.load(sys.stdin).get(‘parameters’,{})))”)仅检查 terminal 工具if [ “$TOOL_NAME” ! “terminal” ]; thenprintf ‘{“action”:“allow”}\n’ # 返回 allow 表示放行exit 0fi从参数中提取命令CMD( e c h o (echo (echoPARAMS | python3 -c “import sys,json; print(json.load(sys.stdin).get(‘command’,‘’))”)危险模式黑名单if echo “$CMD” | grep -qiE “rm\s±rf\s/|DROP\sTABLE|shutdown|mkfs.|/dev/sda|chmod\s±R\s777\s/”; thenprintf ‘{“action”:“block”,“reason”:“Dangerous command blocked by guard hook”}\n’exit 0fiprintf ‘{“action”:“allow”}\n’赋予权限chmod x ~/.hermes/agent-hooks/danger-guard.sh关键pre_tool_call 脚本返回 {“action”:“block”} 会阻止工具执行并告知 Agent 原因返回 {“action”:“allow”} 则放行。Plugins 插件系统官方文档https://hermes-agent.nousresearch.com/docs/user-guide/features/pluginsHermes 拥有一个插件系统无需修改核心代码即可添加自定义工具、钩子和集成。8.1 插件能做什么插件通过 register(ctx) 函数接入 Hermesctx 上所有公开 API 均可使用扩展类型 说明工具 给模型增加可调用能力例如外部 API、本地服务或自定义逻辑钩子 在工具调用、LLM 调用、会话开始 / 结束等生命周期点执行代码命令 增加 /name 斜杠命令或增加 hermes … 子命令会话注入 把外部事件、消息或数据注入当前会话Skill / 数据 随插件附带 Skill、模板、配置、静态数据等资源Gateway 平台 接入新的消息平台或自定义平台适配器后端提供商 接入新的记忆、上下文压缩、图像生成、视频生成或 LLM 提供商v0.14 插件可以通过 ctx.llm 直接在插件代码中调用当前活跃的模型提供商。v0.13 第三方提供商可通过 ProviderProfile ABC抽象基类实现自定义 LLM 提供商插件。8.2 插件目录【重要操作实用】用户插件目录是 ~/.hermes/plugins/每个插件一个独立子目录。最小可用插件只需要两个文件~/.hermes/plugins/hello-world/├── plugin.yaml # 插件清单名称、版本、描述等元信息└──init.py # 定义 register(ctx)在这里注册工具 / hook / 命令plugin.yaml 让 Hermes 知道这里有一个插件register(ctx) 决定这个插件实际提供什么能力。8.3 插件示例shake_window注册一个 shake_window 工具让当前 Windows 前台窗口轻微晃动。创建目录mkdir -p ~/.hermes/plugins/shake-window创建 ~/.hermes/plugins/shake-window/plugin.yamlname: shake-windowversion: “1.0”description: Provides a shake_window tool that briefly shakes the current Windows foreground window.创建 ~/.hermes/plugins/shake-window/init.pyimport jsonimport shutilimport subprocessPOWERSHELL_SHAKE r“”Add-Type using System;using System.Runtime.InteropServices;public static class Win32 {[DllImport(“user32.dll”)]public static extern IntPtr GetForegroundWindow();[DllImport(“user32.dll”)]public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);[DllImport(“user32.dll”)]public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);}[StructLayout(LayoutKind.Sequential)]public struct RECT {public int Left; public int Top; public int Right; public int Bottom;}h w n d [ W i n 32 ] : : G e t F o r e g r o u n d W i n d o w ( ) i f ( hwnd [Win32]::GetForegroundWindow() if (hwnd[Win32]::GetForegroundWindow()if(hwnd -eq [IntPtr]::Zero) { exit 1 }r e c t N e w − O b j e c t R E C T [ W i n 32 ] : : G e t W i n d o w R e c t ( rect New-Object RECT [Win32]::GetWindowRect(rectNew−ObjectRECT[Win32]::GetWindowRect(hwnd, [ref]$rect) | Out-Null$x $rect.Left; $y $rect.Top$w $rect.Right - $rect.Left; $h $rect.Bottom - $rect.Topfor ($i 0; $i -lt 8;KaTeX parse error: Expected }, got EOF at end of input: …2]::MoveWindow(hwnd, $x - 12, $y, $w, $h,t r u e ) S t a r t − S l e e p − M i l l i s e c o n d s 45 [ v o i d ] [ W i n 32 ] : : M o v e W i n d o w ( true) Start-Sleep -Milliseconds 45 [void][Win32]::MoveWindow(true)Start−Sleep−Milliseconds45[void][Win32]::MoveWindow(hwnd, $x 12, $y, $w, $h,KaTeX parse error: Expected EOF, got } at position 40: …illiseconds 45 }̲ [void][Win32]:…hwnd, $x, $y, $w, $h, $true)“”def register(ctx):schema {“name”: “shake_window”,“description”: “Shake the current Windows foreground window.”,“parameters”: {“type”: “object”,“properties”: {},},}def handle_shake(params, **kwargs): del params, kwargs powershell shutil.which(powershell.exe) if powershell is None: return json.dumps({ok: False, error: powershell.exe not found}) result subprocess.run( [powershell, -NoProfile, -Command, POWERSHELL_SHAKE], textTrue, capture_outputTrue, checkFalse, ) return json.dumps({ ok: result.returncode 0, stdout: result.stdout.strip(), stderr: result.stderr.strip(), }) ctx.register_tool( nameshake_window, toolsetdesktop_fun, schemaschema, handlerhandle_shake, descriptionShake the current Windows foreground window., )启用插件hermes plugins enable shake-window重新启动 Hermes 后模型就能调用 shake_window 工具。如使用shake_window 工具震动窗口