Cron 定时任务 —— 调度表达式、Job 配置、脚本模式、自动跑任务
简介
在前一篇文章中,我们全面掌握了 Hermes Agent 的 Slash 命令与 TUI 交互体系。你学会了如何高效地管理会话、控制 Agent 行为、调整运行时配置。这让你的交互式使用体验达到了一个全新的高度。
但今天我们要讨论一个更重要的问题:
当你在睡觉的时候,Agent 在做什么?
想象以下场景:
- 每天早晨 8 点,你希望 Hermes 自动检查 GitHub 上的 PR,生成一份代码审查摘要,发送到你的 Telegram
- 每小时,你希望它扫描服务器的错误日志,发现异常模式后第一时间通知你
- 每周五下午 5 点,你希望它自动生成一份本周的项目进度报告
- 每 30 分钟,你希望它检查 API 的健康状态,发现问题立即告警
这些都不是"对话"能解决的问题。这是自动化的需求。
这就是 Hermes Agent 的 Cron 定时任务系统 存在的意义。
Cron 定时任务让 Hermes 从一个"你问它答"的被动工具,升级为一个自主运行的智能代理。它可以在指定的时间自动触发,执行预定义的任务,并将结果发送到你指定的平台。
本文将带你全面掌握 Hermes Agent 的 Cron 系统:
- 调度表达式:从标准 Cron 到 Hermes 的扩展语法
- Job 配置:如何定义任务、设置触发条件、处理输出
- 脚本模式:让 Agent 执行复杂的自动化工作流
- 自动跑任务实战:从简单到复杂的真实场景
读完本文后,你将能够让 Hermes Agent 成为你 24/7 的自动化工友。
目录
Cron 系统架构概述
为什么需要 Cron?
Hermes Agent 的核心能力在于其智能推理和工具执行。但这些能力默认是被动触发的——你发送消息,Agent 响应。
Cron 系统补上了最后一块拼图:主动触发。
┌────────────────────────────────────────────────────────┐
│ Hermes Agent 触发模式 │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 被动触发 │ │ 主动触发 │ │
│ │ (Reactive) │ │ (Proactive) │ │
│ │ │ │ │ │
│ │ • 用户消息 │ │ • Cron 定时任务 │ │
│ │ • API 调用 │ │ • Webhook 事件 │ │
│ │ • Webhook │ │ • 事件订阅 │ │
│ │ │ │ │ │
│ │ "你问它答" │ │ "它主动工作" │ │
│ └──────────────┘ └──────────────────────┘ │
│ │
└────────────────────────────────────────────────────────┘Cron 架构组件
┌─────────────────────────────────────────────────────┐
│ Cron 调度引擎 │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ 调度器 (Scheduler) │ │
│ │ │ │
│ │ • 解析 Cron 表达式 │ │
│ │ • 计算下次触发时间 │ │
│ │ • 管理触发队列 │ │
│ │ • 处理时区和夏令时 │ │
│ └───────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Job 1 │ │ Job 2 │ │ Job 3 │ ... │
│ │ 代码审查 │ │ 日志分析 │ │ 报告生成 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └────────────┼────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────┐ │
│ │ 执行引擎 (Executor) │ │
│ │ │ │
│ │ • 创建 Agent 实例 │ │
│ │ • 注入上下文和参数 │ │
│ │ • 执行 Prompt │ │
│ │ • 处理工具调用 │ │
│ │ • 收集输出 │ │
│ └───────────────────┬───────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 输出到 │ │ 输出到 │ │ 输出到 │ │
│ │ Telegram │ │ 文件 │ │ Webhook │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────┘Cron 与 Gateway 的关系
Cron 系统运行在 Gateway 进程内部,是 Gateway 的一个子模块:
# 查看 Gateway 状态(包含 Cron 信息)
hermes gateway status
# → Gateway Status: running
# PID: 12345
# Uptime: 3d 14h 22m
# Active Platforms: wechat, telegram, discord
# Active Sessions: 12
# Cron Jobs: 5 (3 active, 2 paused)
# Next Trigger: "daily-pr-review" in 4h 32m调度表达式详解
标准 Cron 语法
Hermes 完全兼容标准 Cron 表达式:
┌───────────── 分钟 (0 - 59)
│ ┌───────────── 小时 (0 - 23)
│ │ ┌───────────── 日 (1 - 31)
│ │ │ ┌───────────── 月 (1 - 12)
│ │ │ │ ┌───────────── 星期 (0 - 6, 0=周日)
│ │ │ │ │
* * * * *常用表达式速查
# 每分钟执行
* * * * *
# 每 5 分钟执行
*/5 * * * *
# 每小时执行
0 * * * *
# 每天凌晨 2 点执行
0 2 * * *
# 每周一上午 9 点执行
0 9 * * 1
# 每月 1 号凌晨执行
0 0 1 * *
# 工作日(周一到周五)每天上午 9 点执行
0 9 * * 1-5
# 每天早上 9 点和下午 5 点执行
0 9,17 * * *
# 工作日每 30 分钟执行
*/30 9-17 * * 1-5
# 每季度第一天执行
0 0 1 1,4,7,10 *预定义快捷表达式
# 快捷表达式(@开头)
@hourly # 等同于 0 * * * *
@daily # 等同于 0 0 * * *(每天午夜)
@weekly # 等同于 0 0 * * 0(每周日午夜)
@monthly # 等同于 0 0 1 * *(每月 1 号午夜)
@yearly # 等同于 0 0 1 1 *(每年 1 月 1 日午夜)
@every_5m # 每 5 分钟
@every_15m # 每 15 分钟
@every_30m # 每 30 分钟
@every_1h # 每小时
@every_6h # 每 6 小时Hermes 扩展语法
标准 Cron 在某些场景下不够用。Hermes 在此基础上做了扩展:
1. 秒级精度
# 标准 Cron 只支持分钟级精度
# Hermes 扩展:6 字段格式支持秒级
# 每 30 秒执行一次
*/30 * * * * *
# 每天 8:30:00 执行
0 30 8 * * *2. 特殊时间修饰符
# 工作日(周一到周五)
0 9 * * WORKDAY
# 周末(周六和周日)
0 10 * * WEEKEND
# 交易日(排除节假日)
0 9 * * TRADING_DAY
# 自定义排除日期
0 9 * * * EXCLUDE:2025-01-01,2025-05-01,2025-10-013. 区间和步进
# 9 点到 18 点之间,每 2 小时执行
0 9-18/2 * * *
# 每月 1-15 号,每天执行
0 0 1-15 * *
# 每 3 个月执行(1月、4月、7月、10月)
0 0 1 1-12/3 *4. 随机延迟
对于大批量定时任务,Hermes 支持随机延迟以避免同时触发:
# 每天午夜执行,随机延迟 0-300 秒
0 0 * * * RANDOM:0-300
# 每小时执行,随机延迟 0-60 秒
0 * * * * RANDOM:0-605. 条件触发
# 仅在文件存在时触发
0 9 * * * IF_FILE:/tmp/trigger.flag
# 仅在环境变量为 true 时触发
0 9 * * * IF_ENV:ENABLED=true
# 仅在 API 返回 200 时触发
0 9 * * * IF_HTTP:https://api.example.com/health=200Job 配置详解
基础 Job 配置
Cron Job 的配置文件位于 ~/.config/hermes/cron-jobs.yaml:
# ~/.config/hermes/cron-jobs.yaml
cron:
timezone: "Asia/Shanghai" # 全局时区设置
jobs:
# ─────────────────────────────────────
# Job 1: 每日 PR 审查摘要
# ─────────────────────────────────────
- name: "daily-pr-review"
description: "每天审查 GitHub 上的 PR 并生成摘要"
# 调度配置
schedule:
cron: "0 8 * * 1-5" # 工作日早上 8 点
timezone: "Asia/Shanghai"
# 执行配置
execution:
provider: "openai"
model: "gpt-4o"
max_tokens: 4096
temperature: 0.3
# Prompt 模板
prompt: |
请执行以下任务:
1. 使用 terminal 工具运行: git fetch origin
2. 列出最近 24 小时内创建或更新的所有 PR:
gh pr list --state open --json number,title,author,createdAt,updatedAt
3. 对每个 PR,获取详细信息:
gh pr view <number> --json body,files,commits
4. 审查代码变更,关注以下方面:
- 代码质量和最佳实践
- 潜在的安全问题
- 测试覆盖情况
- 性能影响
5. 生成一份结构化的审查报告,包含:
- PR 概览
- 每个 PR 的审查意见
- 优先级排序的建议
- 需要人工复核的项目
报告格式使用 Markdown,保持简洁明了。
# 输出配置
output:
# 发送到 Telegram
- type: "telegram"
chat_id: "-100987654321"
parse_mode: "MarkdownV2"
# 同时保存到文件
- type: "file"
path: "~/reports/pr-review/{{date('%Y-%m-%d')}}.md"
# 通知配置
notification:
on_success: true # 成功时通知
on_failure: true # 失败时通知
on_empty: false # 无结果时不通知
# 启用状态
enabled: true
# ─────────────────────────────────────
# Job 2: 错误日志扫描
# ─────────────────────────────────────
- name: "error-log-scan"
description: "每小时扫描应用错误日志"
schedule:
cron: "0 * * * *"
timezone: "Asia/Shanghai"
execution:
provider: "anthropic"
model: "claude-sonnet-4"
max_tokens: 2048
temperature: 0.1
prompt: |
执行以下任务:
1. 读取最近 1 小时的应用日志:
tail -n 5000 /var/log/app/production.log | grep "$(date -d '1 hour ago' '+%Y-%m-%d %H')"
2. 分析日志中的 ERROR 和 WARN 级别的条目
3. 识别以下模式:
- 重复出现的错误(频率 > 10 次/小时)
- 新增的错误类型(之前未出现过)
- 关键路径上的错误(支付、认证等)
4. 对每个识别到的问题,给出:
- 错误类型和频率
- 可能的原因分析
- 建议的修复方案
- 严重程度(P0/P1/P2/P3)
如果发现 P0 或 P1 级别的问题,在报告开头用 ⚠️ 标注。
如果没有严重问题,回复 "✅ 系统运行正常" 即可。
output:
- type: "telegram"
chat_id: "-100987654321"
- type: "webhook"
url: "https://hooks.slack.com/services/T00/B00/XXX"
format: "slack"
enabled: true
# ─────────────────────────────────────
# Job 3: 周报生成
# ─────────────────────────────────────
- name: "weekly-report"
description: "每周五生成项目周报"
schedule:
cron: "0 17 * * 5"
timezone: "Asia/Shanghai"
execution:
provider: "openai"
model: "gpt-4o"
max_tokens: 8192
temperature: 0.5
# 使用脚本模式(详见下文)
mode: "script"
script: "~/.hermes/scripts/weekly-report.py"
output:
- type: "telegram"
chat_id: "-100987654321"
- type: "file"
path: "~/reports/weekly/{{date('%Y-W%V')}}.md"
- type: "email"
to: "team@example.com"
subject: "项目周报 - {{date('%Y-%m-%d')}}"
enabled: trueJob 配置项详解
# 完整的 Job 配置项
jobs:
- name: "job-name" # 唯一标识符
description: "Job 描述" # 人类可读的描述
# 调度配置
schedule:
cron: "0 8 * * 1-5" # Cron 表达式(必填)
timezone: "Asia/Shanghai" # 时区(可选,默认取全局)
# 执行配置
execution:
provider: "openai" # 使用的 Provider
model: "gpt-4o" # 使用的模型
max_tokens: 4096 # 最大输出 Token 数
temperature: 0.3 # 温度(0-1)
timeout: 300 # 执行超时(秒)
retry: # 重试配置
max_attempts: 3 # 最大重试次数
backoff: "exponential" # exponential | linear | fixed
delay: 60 # 初始延迟(秒)
# Prompt 或脚本(二选一)
prompt: | # 直接指定 Prompt
请执行以下任务...
# 或
mode: "script" # 使用脚本模式
script: "path/to/script.py" # 脚本路径
# 输出配置
output:
- type: "telegram" # 输出目标
chat_id: "..."
parse_mode: "MarkdownV2"
- type: "file"
path: "path/to/output.md"
- type: "webhook"
url: "https://..."
# 通知配置
notification:
on_success: true
on_failure: true
on_empty: false
# 上下文注入
context:
env_vars: # 注入的环境变量
GITHUB_TOKEN: "${GITHUB_TOKEN}"
DATABASE_URL: "${DATABASE_URL}"
files: # 注入的文件内容
config.yaml: "~/.config/app/config.yaml"
# 启用状态
enabled: true # 是否启用管理 Cron Job
# 列出所有 Job
hermes cron list
# → ┌────┬──────────────────┬────────────┬────────┬───────────────────┐
# │ # │ 名称 │ 调度表达式 │ 状态 │ 下次执行 │
# ├────┼──────────────────┼────────────┼────────┼───────────────────┤
# │ 1 │ daily-pr-review │ 0 8 * * 1-5│ ✅ 活跃│ 明天 08:00 │
# │ 2 │ error-log-scan │ 0 * * * * │ ✅ 活跃│ 下一小时整点 │
# │ 3 │ weekly-report │ 0 17 * * 5 │ ⏸️ 暂停│ 周五 17:00 │
# └────┴──────────────────┴────────────┴────────┴───────────────────┘
# 启用/暂停 Job
hermes cron enable daily-pr-review
hermes cron pause weekly-report
# 手动触发 Job
hermes cron run error-log-scan
# → 正在执行 error-log-scan...
# → 执行完成 ✅
# → 输出已发送到 telegram
# 查看 Job 历史
hermes cron history error-log-scan --limit 10
# → ┌────┬─────────────────────┬─────────┬─────────────────────────┐
# │ # │ 执行时间 │ 状态 │ 详情 │
# ├────┼─────────────────────┼─────────┼─────────────────────────┤
# │ 1 │ 2025-05-22 15:00:00 │ ✅ 成功 │ Token: 2,340 | 耗时: 12s│
# │ 2 │ 2025-05-22 14:00:00 │ ✅ 成功 │ Token: 1,890 | 耗时: 8s │
# │ 3 │ 2025-05-22 13:00:00 │ ❌ 失败 │ Timeout after 300s │
# │ 4 │ 2025-05-22 12:00:00 │ ✅ 成功 │ Token: 3,120 | 耗时: 18s│
# └────┴─────────────────────┴─────────┴─────────────────────────┘
# 删除 Job
hermes cron delete old-job-name
# 添加 Job
hermes cron add --file ./my-job.yaml脚本模式
简单的 Prompt 模板适合线性任务,但复杂的工作流需要更灵活的控制。Hermes 的脚本模式允许你用 Python 脚本定义完整的自动化工作流。
脚本模式基础
# ~/.hermes/scripts/weekly-report.py
"""
每周项目报告生成脚本
每周五 17:00 自动执行
"""
from hermes.cron import CronScript
import subprocess
from datetime import datetime, timedelta
class WeeklyReportScript(CronScript):
"""周报生成脚本"""
def setup(self):
"""初始化配置"""
self.report_date = datetime.now()
self.week_start = self.report_date - timedelta(days=self.report_date.weekday())
self.week_end = self.week_start + timedelta(days=6)
# 设置 Agent 配置
self.agent_config = {
"provider": "openai",
"model": "gpt-4o",
"temperature": 0.5,
"max_tokens": 8192,
}
def run(self):
"""主执行逻辑"""
# 步骤 1: 收集 Git 数据
git_commits = self.get_git_commits()
git_stats = self.get_git_stats()
# 步骤 2: 收集 Jira/Issue 数据
issues = self.get_open_issues()
completed = self.get_completed_issues()
# 步骤 3: 收集 CI/CD 数据
build_status = self.get_build_status()
deployment_status = self.get_deployment_status()
# 步骤 4: 构建 Prompt
prompt = self.build_prompt(
git_commits=git_commits,
git_stats=git_stats,
issues=issues,
completed=completed,
build_status=build_status,
deployment_status=deployment_status,
)
# 步骤 5: 调用 Agent 生成报告
report = self.agent.generate(prompt, **self.agent_config)
# 步骤 6: 后处理
report = self.post_process(report)
return report
def get_git_commits(self):
"""获取本周的 Git 提交记录"""
result = subprocess.run(
["git", "log",
f"--since={self.week_start.strftime('%Y-%m-%d')}",
f"--until={self.week_end.strftime('%Y-%m-%d')}",
"--oneline", "--all"],
capture_output=True, text=True
)
return result.stdout
def get_git_stats(self):
"""获取 Git 统计信息"""
result = subprocess.run(
["git", "shortlog", "-sn",
f"--since={self.week_start.strftime('%Y-%m-%d')}"],
capture_output=True, text=True
)
return result.stdout
def get_open_issues(self):
"""获取未关闭的 Issue"""
result = subprocess.run(
["gh", "issue", "list", "--state", "open",
"--json", "number,title,assignees,labels"],
capture_output=True, text=True
)
return result.stdout
def get_completed_issues(self):
"""获取本周关闭的 Issue"""
result = subprocess.run(
["gh", "issue", "list", "--state", "closed",
"--json", "number,title,closedAt",
"--search", f"closed:>{self.week_start.strftime('%Y-%m-%d')}"],
capture_output=True, text=True
)
return result.stdout
def get_build_status(self):
"""获取构建状态"""
result = subprocess.run(
["gh", "run", "list", "--limit", "10",
"--json", "conclusion,name,createdAt"],
capture_output=True, text=True
)
return result.stdout
def get_deployment_status(self):
"""获取部署状态"""
# 实现部署状态获取逻辑
pass
def build_prompt(self, **kwargs):
"""构建生成报告的 Prompt"""
return f"""你是项目管理助手,请根据以下数据生成本周项目报告({self.week_start.strftime('%m/%d')} - {self.week_end.strftime('%m/%d')}):
## Git 提交统计
{kwargs['git_stats']}
## 最近提交
{kwargs['git_commits']}
## 未关闭 Issue
{kwargs['issues']}
## 本周关闭 Issue
{kwargs['completed']}
## 构建状态
{kwargs['build_status']}
请生成一份结构化的周报,包含:
1. **本周概述**:2-3 句话总结本周进展
2. **完成的工作**:按模块分类列出完成的事项
3. **进行中的工作**:当前正在进行的工作和预计完成时间
4. **问题和风险**:需要关注的潜在问题
5. **下周计划**:基于当前进度的下周工作计划
6. **关键指标**:提交数、关闭 Issue 数、构建成功率等
格式使用 Markdown,保持简洁专业。"""
def post_process(self, report):
"""后处理报告内容"""
# 添加报告头
header = f"# 项目周报\n\n**周期**: {self.week_start.strftime('%Y-%m-%d')} 至 {self.week_end.strftime('%Y-%m-%d')}\n"
header += f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n---\n\n"
return header + report
# 注册脚本
script = WeeklyReportScript()脚本模式的配置文件
# ~/.hermes/cron-jobs.yaml 中的脚本模式 Job
jobs:
- name: "weekly-report"
schedule:
cron: "0 17 * * 5"
execution:
mode: "script"
script: "~/.hermes/scripts/weekly-report.py"
# 脚本参数
args:
--project: "my-project"
--format: "markdown"
# 环境变量
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
DATABASE_URL: "${DATABASE_URL}"
WORKSPACE: "/path/to/project"
# 工作目录
workdir: "/path/to/project"
# 超时
timeout: 600
output:
- type: "telegram"
chat_id: "-100987654321"
- type: "file"
path: "~/reports/weekly/{{date('%Y-W%V')}}.md"脚本 API 参考
from hermes.cron import CronScript
class MyScript(CronScript):
def run(self):
# ── Agent 调用 ──
# 简单的 Prompt 调用
result = self.agent.generate("分析这段代码...", model="gpt-4o")
# 带工具的调用
result = self.agent.generate(
"查看当前目录的文件结构",
tools=["terminal", "read_file", "search_files"],
model="claude-sonnet-4"
)
# 多轮对话
messages = [
{"role": "system", "content": "你是一个资深的代码审查员"},
{"role": "user", "content": "审查这个 PR..."},
]
result = self.agent.chat(messages)
# ── 工具调用 ──
# 直接调用工具
files = self.tools.search_files(pattern="*.py")
content = self.tools.read_file("main.py")
output = self.tools.terminal("git status")
# ── 文件操作 ──
self.files.write("output.md", result)
content = self.files.read("output.md")
# ── HTTP 请求 ──
response = self.http.get("https://api.example.com/data")
response = self.http.post("https://api.example.com/notify", json={"message": "done"})
# ── 日志 ──
self.logger.info("任务开始")
self.logger.warning("发现潜在问题")
self.logger.error("执行失败", exc_info=True)
# ── 返回值 ──
return result # 返回值会作为 Job 输出任务执行与输出处理
执行流程
Cron 触发
│
▼
┌──────────────┐
│ 加载 Job 配置 │
└──────┬───────┘
│
▼
┌──────────────┐ 否
│ 检查 enabled? │──────→ 跳过(记录日志)
└──────┬───────┘
│ 是
▼
┌──────────────┐ 否
│ 检查条件? │──────→ 跳过(记录日志)
│ (IF_FILE 等) │
└──────┬───────┘
│ 是
▼
┌──────────────┐
│ 创建 Agent │
│ 实例 │
└──────┬───────┘
│
▼
┌──────────────┐
│ 注入上下文 │
│ (env, files) │
└──────┬───────┘
│
▼
┌──────────────┐ ┌──────────────┐
│ 执行 Prompt │────▶│ 工具调用循环 │
│ / 脚本 │ │ (Agent Loop) │
└──────┬───────┘ └──────────────┘
│
▼
┌──────────────┐
│ 后处理输出 │
│ (format) │
└──────┬───────┘
│
▼
┌──────────────┐
│ 分发输出 │
│ (多目标) │
└──────┬───────┘
│
▼
┌──────────────┐
│ 记录执行历史 │
│ & 发送通知 │
└──────────────┘输出目标详解
output:
# ── 发送到消息平台 ──
- type: "telegram"
chat_id: "-100987654321"
parse_mode: "MarkdownV2"
disable_web_page_preview: true
- type: "wechat"
chat_id: "room_xyz789"
- type: "discord"
channel_id: "123456789"
thread_name: "自动化报告" # 可选:创建线程
# ── 发送到文件 ──
- type: "file"
path: "~/reports/{{name}}-{{date('%Y-%m-%d')}}.md"
# 路径模板变量:
# {{name}} - Job 名称
# {{date('%Y-%m-%d')}} - 当前日期
# {{timestamp}} - Unix 时间戳
# ── 发送到 Webhook ──
- type: "webhook"
url: "https://hooks.slack.com/services/T00/B00/XXX"
method: "POST"
headers:
Content-Type: "application/json"
format: "slack" # slack | generic | custom
# generic 格式:
# {"content": "<输出内容>"}
# custom 格式:
body_template: '{"text": "{{output}}", "channel": "#reports"}'
# ── 发送到邮箱 ──
- type: "email"
to: "team@example.com"
cc: "manager@example.com"
subject: "日报 - {{date('%Y-%m-%d')}}"
format: "html" # html | text
# ── 保存到数据库 ──
- type: "database"
connection: "postgresql://user:pass@localhost/reports"
table: "cron_outputs"
columns:
job_name: "{{name}}"
executed_at: "{{timestamp}}"
content: "{{output}}"
status: "{{status}}"自动跑任务实战
实战 1:每日构建检查
# 每天早上 9 点检查最近的 CI 构建状态
jobs:
- name: "daily-build-check"
description: "每日构建状态检查"
schedule:
cron: "0 9 * * 1-5"
timezone: "Asia/Shanghai"
execution:
provider: "openai"
model: "gpt-4o-mini"
max_tokens: 2048
temperature: 0.1
prompt: |
执行以下 CI/CD 检查任务:
1. 检查最近 24 小时内的所有 GitHub Actions 运行:
gh run list --limit 20 --json conclusion,name,createdAt,databaseId
2. 识别失败的构建:
gh run list --status failure --limit 5
3. 对每个失败的构建,获取失败日志的摘要:
gh run view <id> --log-failed
4. 分析失败原因,分类为:
- 测试失败
- 编译错误
- 部署失败
- 超时/基础设施问题
5. 生成报告
如果所有构建都通过了,只回复 "✅ 所有构建正常通过"。
如果有失败,列出失败构建、原因分析和建议修复步骤。
output:
- type: "telegram"
chat_id: "-100987654321"
notification:
on_success: false # 正常时不打扰
on_failure: true # 失败时通知
on_empty: false实战 2:定期安全扫描
jobs:
- name: "security-scan"
description: "每日安全扫描"
schedule:
cron: "0 3 * * *"
timezone: "Asia/Shanghai"
execution:
provider: "anthropic"
model: "claude-sonnet-4"
max_tokens: 4096
temperature: 0.1
prompt: |
执行安全扫描任务:
1. 运行依赖安全检查:
npm audit --json
pip-audit --format json
2. 运行代码安全扫描:
bandit -r src/ -f json
semgrep --config=auto src/ --json
3. 检查 Docker 镜像漏洞:
trivy image myapp:latest --format json
4. 汇总所有扫描结果
5. 按严重程度排序发现的问题
6. 对每个问题提供:
- 漏洞描述
- CVSS 评分
- 影响的组件
- 修复建议
- 修复优先级
生成一份安全报告,包含:
- 总览(高危/中危/低危数量)
- 详细问题列表
- 修复行动计划
⚠️ 如果发现高危漏洞(CVSS ≥ 9.0),在报告开头用醒目标注。
output:
- type: "telegram"
chat_id: "-100987654321"
- type: "file"
path: "~/reports/security/{{date('%Y-%m-%d')}}.md"
- type: "webhook"
url: "https://hooks.slack.com/services/T00/B00/SECURITY"
format: "slack"
notification:
on_success: true
on_failure: true
on_empty: false实战 3:自动化数据报告
jobs:
- name: "daily-metrics-report"
description: "每日业务指标报告"
schedule:
cron: "0 10 * * *"
timezone: "Asia/Shanghai"
execution:
mode: "script"
script: "~/.hermes/scripts/metrics-report.py"
env:
DATABASE_URL: "${DATABASE_URL}"
API_KEY: "${ANALYTICS_API_KEY}"
output:
- type: "telegram"
chat_id: "-100987654321"
- type: "email"
to: "management@example.com"
subject: "日报 - {{date('%Y-%m-%d')}}"
notification:
on_success: true
on_failure: true# ~/.hermes/scripts/metrics-report.py
"""
每日业务指标报告生成
"""
from hermes.cron import CronScript
import subprocess
import json
from datetime import datetime, timedelta
class MetricsReportScript(CronScript):
def run(self):
yesterday = datetime.now() - timedelta(days=1)
# 获取数据库指标
metrics = self.get_db_metrics(yesterday)
# 获取 API 指标
api_metrics = self.get_api_metrics(yesterday)
# 让 Agent 分析趋势并生成报告
prompt = f"""你是数据分析助手,请分析以下昨日({yesterday.strftime('%Y-%m-%d')})业务指标:
## 核心指标
- 活跃用户: {metrics['active_users']} (环比 {metrics['active_users_change']:+.1f}%)
- 新增用户: {metrics['new_users']} (环比 {metrics['new_users_change']:+.1f}%)
- 订单数: {metrics['orders']} (环比 {metrics['orders_change']:+.1f}%)
- 营收: ¥{metrics['revenue']:,.2f} (环比 {metrics['revenue_change']:+.1f}%)
## API 指标
- 请求总量: {api_metrics['total_requests']:,}
- 平均响应时间: {api_metrics['avg_response_time']:.0f}ms
- 错误率: {api_metrics['error_rate']:.2f}%
- P99 延迟: {api_metrics['p99_latency']:.0f}ms
请生成一份简洁的日报,包含:
1. 一句话总结昨日表现
2. 关键指标的环比变化
3. 异常波动分析(如有)
4. 需要关注的趋势
5. 建议的跟进行动"""
return self.agent.generate(prompt, model="gpt-4o")
def get_db_metrics(self, date):
"""从数据库获取指标"""
# 实现数据库查询逻辑
pass
def get_api_metrics(self, date):
"""从 Analytics API 获取指标"""
# 实现 API 调用逻辑
pass
script = MetricsReportScript()任务监控与调试
实时查看任务输出
# 跟随查看任务实时输出
hermes cron logs error-log-scan --follow
# → [2025-05-22 15:00:01] Job started: error-log-scan
# → [2025-05-22 15:00:01] Creating agent instance...
# → [2025-05-22 15:00:02] Injecting context...
# → [2025-05-22 15:00:02] Executing prompt...
# → [2025-05-22 15:00:02] [Tool] terminal: tail -n 5000 /var/log/app/production.log...
# → [2025-05-22 15:00:05] [Tool] terminal: completed (3s)
# → [2025-05-22 15:00:05] [Agent] Analyzing logs...
# → [2025-05-22 15:00:12] [Agent] Generating report...
# → [2025-05-22 15:00:18] Job completed successfully
# → [2025-05-22 15:00:18] Output sent to: telegram, webhook
# → [2025-05-22 15:00:18] Token usage: 2,340
# → [2025-05-22 15:00:18] Duration: 17s调试模式
# 调试模式运行(不发送输出,只显示)
hermes cron run error-log-scan --dry-run
# → [Dry Run] 正在执行 error-log-scan...
# → [Dry Run] 调度: 0 * * * *
# → [Dry Run] 模型: claude-sonnet-4
# → [Dry Run] 预期输出目标: telegram (-100987654321), webhook
# → [Dry Run] 模拟执行...
# → [Dry Run] 输出预览:
# ✅ 系统运行正常
# 最近 1 小时未发现严重错误
# ERROR 级别日志: 3 条(均为已知的超时问题)
# WARN 级别日志: 12 条任务健康检查
# 查看所有任务的健康状态
hermes cron health
# → ┌──────────────────┬────────┬────────────┬────────────┬──────────┐
# │ Job │ 状态 │ 最近执行 │ 成功率 │ 下次执行 │
# ├──────────────────┼────────┼────────────┼────────────┼──────────┤
# │ daily-pr-review │ ✅ 健康│ 2 小时前 │ 98% (49/50)│ 明天 8:00 │
# │ error-log-scan │ ✅ 健康│ 15 分钟前 │ 95% (285/300)│ 11:00 │
# │ weekly-report │ ⚠️ 警告│ 上周五 │ 80% (4/5) │ 周五 17:00│
# │ security-scan │ ❌ 异常│ 昨天 │ 60% (3/5) │ 明天 3:00 │
# └──────────────────┴────────┴────────────┴────────────┴──────────┘
#
# ⚠️ weekly-report: 最近一次执行超时 (600s > 300s limit)
# ❌ security-scan: 最近两次执行失败,检查脚本依赖总结与下篇预告
总结
本文全面介绍了 Hermes Agent 的 Cron 定时任务系统:
核心要点:
Cron 让 Agent 从被动变主动 —— 不再只是"你问它答",而是"它主动工作"。定时任务让 Hermes 成为你 24/7 的自动化工友。
标准 Cron + Hermes 扩展 —— 完全兼容标准 Cron 语法,同时支持秒级精度、特殊时间修饰符、随机延迟、条件触发等扩展功能。
三种执行模式:
- Prompt 模式:适合简单的线性任务,直接在 YAML 中定义 Prompt
- 脚本模式:适合复杂工作流,用 Python 脚本控制完整的数据收集→处理→报告流程
- 混合模式:脚本收集数据 + Agent 分析生成
多目标输出 —— 一条任务的输出可以同时发送到 Telegram、文件、Webhook、邮箱等多个目标。
完善的监控体系 ——
hermes cron logs、hermes cron health、--dry-run等工具让你随时掌握任务状态。
实战建议:
- 从简单的定时任务开始(如每日构建检查),逐步扩展到复杂工作流
- 使用
--dry-run验证任务配置,避免误操作 - 为重要任务配置失败通知,确保问题及时发现
- 合理设置超时和重试,避免任务卡死
- 用脚本模式处理需要多步骤数据收集的场景
下篇预告
多 Agent 编排 —— Spawn 实例与 Tmux 协调、单发模式、PTY 模式、多 Agent 协作
在下一篇文章中,我们将探索 Hermes Agent 最强大的能力之一:多 Agent 协作。
- Spawn 实例:如何在运行时动态创建多个 Agent 实例
- Tmux 协调:利用 Tmux 管理多 Agent 终端会话
- 单发模式:Fire-and-forget 式的任务分发
- PTY 模式:交互式多 Agent 协作
- 多 Agent 协作模式:主从模式、并行模式、流水线模式、辩论模式
当单个 Agent 不够用时,让多个 Agent 协同工作——这才是 AI Agent 的真正威力。
敬请期待!