模块三:进化篇 — Skills、Hooks、Plugins、Cron
学习理念:理解 Hermes Agent 自进化的核心机制——Skill 是程序记忆,
/learn是自动提取工具,Curator 是维护管家,Hooks/Plugins/Cron 是扩展和自动化手段。 海外对标:对标 Claude Code 的 CLAUDE.md + 自定义指令,Hermes 的 Skill 系统是完整的"可复用工作流管理"方案。本节 AI 替代率:~25% | 人工干预率:~75%
角色 能力范围 🤖 AI 擅长 /learn自动提取 Skill、Curator 后台维护、Cron 任务执行👤 人类需理解 Skill 设计哲学、Hooks 安全拦截策略、插件编写、Cron 流水线编排
目录
1. Skills 技能系统
官方文档:https://hermes-agent.nousresearch.com/docs/user-guide/features/skills
Skills 是 Hermes Agent 最核心的差异化能力——自进化。Agent 解决复杂问题后,会把可复用流程保存为 Skill,下次遇到类似任务时自动加载。Skill 是透明的人类可读 Markdown 文件,你可以随时查看、编辑或删除。
Skills 系统包含 166 个已追踪的技能(87 个内置 + 79 个可选),覆盖 26+ 个类别。
已安装的技能会以斜杠命令的形式提供。
1.1 基本操作
hermes skills list # 列出已安装的技能
hermes skills browse # 浏览可用的技能
hermes skills search honcho # 搜索技能
hermes skills install honcho # 通过 ID 安装技能
hermes skills install https://example.com/my-skill/SKILL.md # 通过 URL 安装技能
hermes skills uninstall honcho # 卸载技能
/skills # 会话内管理技能1.2 技能目录结构
所有技能默认存放在 ~/.hermes/skills/:
~/.hermes/skills/
├── mlops/ # 类别目录
│ ├── axolotl/ # 技能目录
│ │ ├── SKILL.md # 主说明文件,必需
│ │ ├── references/ # 额外参考资料
│ │ ├── templates/ # 输出模板
│ │ ├── scripts/ # 技能可调用的辅助脚本
│ │ └── assets/ # 图片、数据等附加资源
│ └── vllm/
│ └── SKILL.md
├── devops/
│ └── deploy-k8s/
│ ├── SKILL.md
│ └── references/
├── .hub/ # Skills Hub 状态
│ ├── lock.json
│ ├── quarantine/
│ └── audit.log
└── .bundled_manifest # 记录内置技能同步状态SKILL.md 是每个技能的入口文件。references/、templates/、scripts/、assets/ 都是可选目录。
可以把 Skill 粗略分成三种层级:
| 类型 | 例子 | 含义 |
|---|---|---|
| 普通具体 Skill | mlops/axolotl | 面向某个具体工具或流程 |
| 总括型 Skill(umbrella) | mlops/training | 覆盖一组相关流程 |
| 类别级总括型 Skill | software-development/debugging | 抽象到任务类别 |
一个完整的 SKILL.md 示例(~/.hermes/skills/writing/tech-blog/SKILL.md):
# Technical Blog Post Writing
Write technical blog posts targeting AI/ML developers. Follow this workflow:
## Pre-writing
1. Read all provided research summaries
2. Identify 3-5 key takeaways that readers will find actionable
3. Check for conflicting claims — flag them before writing
## Structure
- **Hook** (100-150 words): Start with a real problem or surprising finding
- **Background** (200-300 words): Context that makes the topic accessible
- **Deep Dive** (1000-1500 words): Core content with code examples
- **Implications** (200-300 words): Why this matters for practitioners
- **Key Takeaways** (bullet points): 3-5 actionable conclusions
## Code Examples
- Must be complete and runnable
- Use Python 3.11+ syntax
- Include error handling in production-facing code
- Prefer `uv` over `pip` for package management commands
## Language
- Main content in Chinese, technical terms in English
- Target 2000-2500 words
- Avoid passive voice in Chinese
## Frontmatter Template
```yaml
---
title: "<English Title>"
date: <YYYY-MM-DD>
tags: [<3-5 relevant tags>]
author: "AI+Human"
---
可以看到,SKILL.md 就是一份结构化的工作指南,Agent 加载后会自动按照其中的流程执行。
### 🆕 1.3 `/learn` 命令(v0.18+,一键提取技能)
v0.18 最核心的新功能——**一句话从任意源提取可复用 Skill**,无需手动编写 SKILL.md。
```bash
/learn ~/code/my-project # 从本地目录学习
/learn https://example.com/api-docs # 从文档 URL 学习
/learn 我刚才的操作流程 # 从当前对话学习内部流程:Agent 用 read_file、web_extract 等现有工具收集源材料 → 自动按标准编写 SKILL.md → 使用 skill_manage 保存。在 Telegram/Discord 中还有交互式学习流(创建 #learnables 话题 → 调研包 → 用户 review → "learn this" 确认)。
数据显示:拥有 2+ 自创技能的 Agent,同类任务完成速度快 40%。
1.4 外部技能目录
如果团队已经有共享技能目录,可以让 Hermes 额外扫描:
# ~/.hermes/config.yaml
skills:
external_dirs:
- ~/.agents/skills
- /home/shared/team-skills
- ${SKILLS_REPO}/skills外部目录支持 ~ 展开和 ${VAR} 环境变量替换。规则:
- 只读扫描:Agent 创建或修改技能时仍然写入
~/.hermes/skills/ - 本地优先:本地版本覆盖外部同名技能
- 完整集成:出现在技能索引、
skills_list、skill_view和斜杠命令中 - 路径可选:不存在的外部目录会被静默跳过
1.4 Skill Bundles(v0.15+ ★ 新增)
Skill Bundles 允许用一个斜杠命令同时加载多个技能。例如,创建一个 writing-day bundle:
hermes skills bundle create writing-day --skills blogwatcher,markdown-style,seo-check之后只需执行 /writing-day 即可加载全部三个技能。
1.5 Skills Hub 与 agentskills.io
Hermes 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.md frontmatter
platforms:
- linux
- macos
# - windows # 此技能不在 Windows 上显示1.8 Agent-Managed Skills (skill_manage)
Hermes 可以通过 skill_manage 工具创建、修改和删除自己的技能。这是 Agent 的「程序记忆」:当它解决了一个有复用价值的复杂问题,就可以把流程沉淀成 Skill。
触发策略主要靠提示词驱动。整体规则:
- 复杂任务成功、克服错误、用户纠正后的方法有效、发现可复用流程,或用户要求记住流程时,可以创建 Skill
- 发现 Skill 过时、缺步骤、命令错误、OS 相关失败或新坑点时,应优先
patch现有 Skill
skill_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.11 /journey 学习时间线(v0.18+)
运行 /journey 展示 Agent 积累的所有记忆和技能的时间线,可直接编辑或删除条目。Desktop 中对应 Memory Graph(辐射状可操作时间线)。
1.9 Curator 技能维护系统
官方文档:https://hermes-agent.nousresearch.com/docs/user-guide/features/curator
Curator 是 Hermes 的技能维护系统,专门管理由后台自我改进 review agent 创建并标记的本地技能。它会跟踪这些技能的查看、使用和修改频率,把长期不用的技能从 active 推进到 stale,再归档到 ~/.hermes/skills/.archive/。
Curator 的存在是为了防止通过自我提升循环产生的技能无限累积。如果不进行维护,最终会导致数十个功能相近但范围狭窄的重复技能,污染目录并浪费 token。
Pinned 技能保护
如果某个技能很重要,可以把它 pin 住。Pinned 技能有三层保护:
- Curator 不会把它自动迁移到
stale或archived - Curator 的 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.yaml
curator:
enabled: true
interval_hours: 168
min_idle_hours: 2
stale_after_days: 30
archive_after_days: 90🆕 v0.17 优化:非例行运行时不再消耗辅助模型预算,降低了 Curator 的运行成本。
可以为 Curator 指定更便宜的辅助模型:
# ~/.hermes/config.yaml
auxiliary:
curator:
provider: openrouter
model: google/gemini-3-flash-preview
timeout: 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 自动归档或合并。
2. Hooks 钩子系统
官方文档:https://hermes-agent.nousresearch.com/docs/user-guide/features/hooks
Hermes 提供了三种钩子系统,允许在关键生命周期点执行自定义代码。所有钩子都是非阻塞设计,错误会被捕获并记录,不会影响 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/<name>/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 里执行任意斜杠命令时 | 命令审计、权限统计、外部通知 | 观察型 |
2.1 Shell Hook 示例:会话结束后弹出桌面通知
适合在 WSL / Git Bash / Windows 终端里使用 Hermes。
- 注册 shell hook:
# ~/.hermes/config.yaml
hooks:
on_session_end:
- command: "~/.hermes/agent-hooks/windows-session-end-popup.sh"
timeout: 15 windows创建方式:
hooks:
on_session_end:
- command: C:/PROGRA~1/Git/bin/bash.exe "C:/Users/merge/AppData/Local/hermes/hooks/windows-session-end-popup.sh"
timeout: 15
hooks_auto_accept: true- 创建脚本目录:
mkdir -p ~/.hermes/agent-hooks- 创建脚本
~/.hermes/agent-hooks/windows-session-end-popup.sh:
#!/usr/bin/env bash
cat - >/dev/null # 丢弃 hook payload(stdin)
if command -v powershell.exe >/dev/null 2>&1; then
powershell.exe -NoProfile -WindowStyle Hidden -Command '
Add-Type -AssemblyName System.Windows.Forms
Add-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 2>&1 &
fi
printf '{}\n'- 赋予执行权限:
chmod +x ~/.hermes/agent-hooks/windows-session-end-popup.sh首次运行时 Hermes 会询问是否允许这个 (event, command) 组合。
2.2 pre_tool_call 安全拦截示例
pre_tool_call 是唯一能阻止工具执行的钩子,适合安全防护场景。
场景:阻止 Agent 执行危险的终端命令(如 rm -rf /、DROP TABLE、未授权的 SSH 连接)。
- 注册 hook:
# ~/.hermes/config.yaml
hooks:
pre_tool_call:
- command: "~/.hermes/agent-hooks/danger-guard.sh"
timeout: 5- 创建
~/.hermes/agent-hooks/danger-guard.sh:
#!/usr/bin/env bash
PAYLOAD=$(cat) # Hermes 把工具调用信息通过 stdin 传入(JSON 格式)
TOOL_NAME=$(echo "$PAYLOAD" | python3 -c "import sys,json; print(json.load(sys.stdin).get('name',''))")
PARAMS=$(echo "$PAYLOAD" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin).get('parameters',{})))")
# 仅检查 terminal 工具
if [ "$TOOL_NAME" != "terminal" ]; then
printf '{"action":"allow"}\n' # 返回 allow 表示放行
exit 0
fi
# 从参数中提取命令
CMD=$(echo "$PARAMS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('command',''))")
# 危险模式黑名单
if echo "$CMD" | grep -qiE "rm\s+-rf\s+/|DROP\s+TABLE|shutdown|mkfs\.|>\/dev\/sda|chmod\s+-R\s+777\s+/"; then
printf '{"action":"block","reason":"Dangerous command blocked by guard hook"}\n'
exit 0
fi
printf '{"action":"allow"}\n'- 赋予权限:
chmod +x ~/.hermes/agent-hooks/danger-guard.sh关键:pre_tool_call 脚本返回 {"action":"block"} 会阻止工具执行并告知 Agent 原因;返回 {"action":"allow"} 则放行。
3. Plugins 插件系统
官方文档:https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins
Hermes 拥有一个插件系统,无需修改核心代码即可添加自定义工具、钩子和集成。
3.1 插件能做什么
插件通过 register(ctx) 函数接入 Hermes,ctx 上所有公开 API 均可使用:
| 扩展类型 | 说明 |
|---|---|
| 工具 | 给模型增加可调用能力,例如外部 API、本地服务或自定义逻辑 |
| 钩子 | 在工具调用、LLM 调用、会话开始 / 结束等生命周期点执行代码 |
| 命令 | 增加 /name 斜杠命令,或增加 hermes <plugin> ... 子命令 |
| 会话注入 | 把外部事件、消息或数据注入当前会话 |
| Skill / 数据 | 随插件附带 Skill、模板、配置、静态数据等资源 |
| Gateway 平台 | 接入新的消息平台或自定义平台适配器 |
| 后端提供商 | 接入新的记忆、上下文压缩、图像生成、视频生成或 LLM 提供商 |
v0.14+ 插件可以通过
ctx.llm直接在插件代码中调用当前活跃的模型提供商。
v0.13+ 第三方提供商可通过
ProviderProfileABC(抽象基类)实现自定义 LLM 提供商插件。
3.2 插件目录
用户插件目录是 ~/.hermes/plugins/,每个插件一个独立子目录。最小可用插件只需要两个文件:
~/.hermes/plugins/hello-world/
├── plugin.yaml # 插件清单:名称、版本、描述等元信息
└── __init__.py # 定义 register(ctx),在这里注册工具 / hook / 命令plugin.yaml 让 Hermes 知道"这里有一个插件",register(ctx) 决定"这个插件实际提供什么能力"。
3.3 插件示例:shake_window
注册一个 shake_window 工具,让当前 Windows 前台窗口轻微晃动。
创建目录:
mkdir -p ~/.hermes/plugins/shake-window创建 ~/.hermes/plugins/shake-window/plugin.yaml:
name: shake-window
version: "1.0"
description: Provides a shake_window tool that briefly shakes the current Windows foreground window.创建 ~/.hermes/plugins/shake-window/__init__.py:
import json
import shutil
import subprocess
POWERSHELL_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;
}
"@
$hwnd = [Win32]::GetForegroundWindow()
if ($hwnd -eq [IntPtr]::Zero) { exit 1 }
$rect = New-Object RECT
[Win32]::GetWindowRect($hwnd, [ref]$rect) | Out-Null
$x = $rect.Left; $y = $rect.Top
$w = $rect.Right - $rect.Left; $h = $rect.Bottom - $rect.Top
for ($i = 0; $i -lt 8; $i++) {
[void][Win32]::MoveWindow($hwnd, $x - 12, $y, $w, $h, $true)
Start-Sleep -Milliseconds 45
[void][Win32]::MoveWindow($hwnd, $x + 12, $y, $w, $h, $true)
Start-Sleep -Milliseconds 45
}
[void][Win32]::MoveWindow($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],
text=True, capture_output=True, check=False,
)
return json.dumps({
"ok": result.returncode == 0,
"stdout": result.stdout.strip(),
"stderr": result.stderr.strip(),
})
ctx.register_tool(
name="shake_window",
toolset="desktop_fun",
schema=schema,
handler=handle_shake,
description="Shake the current Windows foreground window.",
)启用插件:
hermes plugins enable shake-window重新启动 Hermes 后,模型就能调用 shake_window 工具。
3.4 插件发现
Hermes 会从多个来源发现插件:
| 来源 | 路径 / 方式 | 用途 |
|---|---|---|
| Bundled | Hermes 仓库内置 plugins/ | 官方随 Hermes 发布的插件 |
| User | ~/.hermes/plugins/ | 用户自己的本地插件 |
| Project | .hermes/plugins/ | 当前工作目录插件;默认不扫描,需设置 HERMES_ENABLE_PROJECT_PLUGINS=true |
| pip | hermes_agent.plugins entry points | 通过 Python 包分发的插件 |
3.5 管理插件
hermes plugins # 交互式开关插件
hermes plugins list # 查看已安装插件
hermes plugins install user/repo # 从 GitHub 安装插件
hermes plugins update <name> # 更新插件
hermes plugins remove <name> # 移除插件
hermes plugins enable <name> # 启用插件
hermes plugins disable <name> # 禁用插件新安装或捆绑的插件默认不启用,必须加入 ~/.hermes/config.yaml:
# ~/.hermes/config.yaml
plugins:
enabled:
- my-plugin
disabled:
- noisy-pluginplugins.disabled 是拒绝列表,如果同一个插件同时出现在 enabled 和 disabled,禁用优先。
4. Cron 定时任务
官方文档:https://hermes-agent.nousresearch.com/docs/user-guide/features/cron
Hermes 内置定时任务系统,可以用自然语言、cron 表达式安排任务。
定时任务通过 Gateway daemon 执行:Gateway 每 60 秒 tick 一次,检查到期任务。为每个到期任务启动一个新的 Agent 会话执行 prompt,然后投递最终结果。Cron 运行时会禁用 cron 管理工具,避免递归创建更多定时任务造成调度循环。
4.1 创建任务
可在会话中通过 /cron,或使用 CLI 命令 hermes cron 来创建:
/cron add 30m "提醒我检查构建结果"
/cron add "every 2h" "检查服务器状态"
/cron add "every 1h" "总结新动态" --skill blogwatcher
/cron add "every 1h" "加载两个技能并合并结果" --skill blogwatcher --skill maps
hermes cron create "every 2h" "检查服务器状态"
hermes cron create "every 1h" "总结新动态" --skill blogwatcher也可以直接用自然语言让 Hermes 创建:
每天早上 9 点检查 Hacker News 上的 AI 新闻,然后发一份摘要到 Telegram。Hermes 会在内部调用 cronjob 工具完成创建:
cronjob(
action="create",
schedule="every 1d at 09:00",
prompt="检查 Hacker News 上的 AI 新闻,筛选值得关注的条目,并写成中文摘要。",
name="HN AI daily",
deliver="telegram",
)4.2 调度格式
| 类型 | 示例 | 行为 |
|---|---|---|
| 相对延迟 | 30m、2h、1d | 一次性运行 |
| 循环间隔 | every 30m、every 2h、every 1d | 持续重复运行 |
| Cron 表达式 | 0 9 * * *、0 9 * * 1-5、0 */6 * * * | 按 cron 规则重复运行 |
| ISO 时间 | 2026-03-15T09:00:00 | 指定时间运行一次 |
Cron 表达式格式为 分 时 日 月 周:
0 9 * * *每天 9:00 执行0 9 * * 1-5工作日每天 9:00 执行0 */6 * * *每 6 小时执行30 8 1 * *每月 1 日 8:30 执行
4.3 管理任务
/cron list # 查看定时任务
/cron list --all # 查看所有任务,包括已暂停的
/cron edit <job_id> --schedule "every 4h" # 修改调度时间
/cron edit <job_id> --prompt "使用新的任务说明" # 修改任务说明
/cron edit <job_id> --skill blogwatcher --skill maps # 替换技能列表
/cron edit <job_id> --add-skill maps # 追加技能
/cron edit <job_id> --remove-skill blogwatcher # 移除指定技能
/cron pause <job_id> # 暂停任务
/cron resume <job_id> # 恢复任务
/cron run <job_id> # 下一个 scheduler tick 触发任务
/cron remove <job_id> # 删除任务
hermes cron status # 查看调度器状态
hermes cron tick # 手动触发一次 scheduler tick任务存储在 ~/.hermes/cron/jobs.json,运行输出保存到 ~/.hermes/cron/output/{job_id}/{timestamp}.md。
4.4 运行结果投递方式
deliver 控制定时任务运行完成后,把 Agent 的最终回复发送到哪里:
| deliver | 说明 |
|---|---|
origin | 回到创建任务的聊天来源,消息平台默认值 |
local | 只保存到本地文件,CLI 默认值 |
telegram、discord、slack | 投递到对应平台的 home channel |
telegram:123456 | 投递到指定 Telegram chat ID |
discord:#engineering | 投递到指定 Discord 频道 |
all | 投递到所有已配置 home channel 的平台 |
telegram,discord | 投递到多个指定平台 |
origin,all | 投递到来源聊天 + 所有 home channel |
ntfy | v0.15+:推送通知,无需账号 |
示例:
hermes cron create "every 30m" "检查服务状态" --deliver telegram
hermes cron create "every 1d" "生成日报" --deliver telegram,discord如果 Agent 的最终回复以 [SILENT] 开头,成功运行时会抑制投递,但输出仍会保存到本地。失败任务仍会投递错误信息。适合只有出现问题才需要报告的作业:
Check if nginx is running. If everything is healthy, respond with only [SILENT].
Otherwise, report the issue.4.5 No-Agent 模式
对于不需要 LLM 推理的周期性任务(监控程序、磁盘/内存警报、心跳检测、CI ping 等),可传递 no_agent=True:
hermes cron create "every 5m" \
--no-agent \
--script memory-watchdog.sh \
--deliver telegram \
--name "memory-watchdog"脚本必须放在 ~/.hermes/scripts/ 中。.sh / .bash 用 /bin/bash 执行,其他脚本用当前 Python 解释器执行。
脚本运行默认超时 120 秒,可调整:
# ~/.hermes/config.yaml
cron:
script_timeout_seconds: 3004.6 使用 context_from 链接作业
Cron 任务彼此之间默认隔离。context_from 用来把一个任务的最新输出接到另一个任务的 prompt 前面。它只能由 Agent 通过 cronjob 工具设置,CLI 命令不支持。
典型流程:
Job 1:收集原始数据
Job 2:读取 Job 1 的最新输出,筛选 / 排序
Job 3:读取 Job 2 的最新输出,生成最终报告并投递示例:
# Job 1:收集 AI 新闻
cronjob(action="create", name="ai-news-fetch",
schedule="0 7 * * *",
prompt="Fetch the top 10 AI/ML stories from Hacker News.")
# Job 2:使用 Job 1 的最新输出做筛选
cronjob(action="create", name="ai-news-rank",
schedule="30 7 * * *",
context_from="<job1_id>",
prompt="Score each story for novelty and engagement. Keep the top 5.")
# Job 3:使用 Job 2 的最新输出生成日报
cronjob(action="create", name="ai-news-brief",
schedule="0 8 * * *",
context_from="<job2_id>",
prompt="Write a concise daily brief and deliver it to Telegram.")context_from 支持单个或多个 job ID。多个上游输出会按列表顺序拼接,每个上游输出在注入前被截断至 8,000 字符。
注意:
context_from读取的是上游任务「最近一次已完成输出」,不会等待同一个 tick 中仍在运行的上游任务。需要强依赖同一批数据时,应把上下游任务错开足够长时间。