跳到主要内容

定时任务故障排查

当定时任务表现不符合预期时,按顺序检查以下项目。大多数问题属于四类之一:调度、投递、权限或技能加载。


任务不触发

检查 1:确认任务存在且处于活跃状态

hermes cron list

找到任务,确认其状态为 [active](不是 [paused][completed])。如果显示 [completed],可能是重复次数已耗尽——编辑任务以重置它。

检查 2:确认调度表达式正确

格式错误的调度会静默地被当作一次性任务或完全被拒绝。测试你的表达式:

你的表达式应该表示
0 9 * * *每天上午 9:00
0 9 * * 1每周一上午 9:00
every 2h从现在起每 2 小时
30m从现在起 30 分钟后
2025-06-01T09:00:002025 年 6 月 1 日 UTC 上午 9:00

如果任务触发一次后从列表中消失,说明是一次性调度(30m1d 或 ISO 时间戳)——这是预期行为。

检查 3:网关是否正在运行?

定时任务由网关的后台定时线程触发,每 60 秒一次。普通的 CLI 聊天会话不会自动触发定时任务。

如果你希望任务自动触发,需要运行网关(hermes gateway 用于前台运行,或 hermes gateway start 用于已安装的服务)。调试时可以用 hermes cron tick 手动触发一次。

检查 4:检查系统时钟和时区

任务使用本地时区。如果机器时钟有误或处于非预期时区,任务会在错误的时间触发。验证:

date
hermes cron list # 对比 next_run 时间与本地时间

投递失败

检查 1:验证投递目标是否正确

投递目标区分大小写,且需要正确配置相应平台。目标配置错误会静默丢弃响应。

目标需要
telegram~/.hermes/.env 中的 TELEGRAM_BOT_TOKEN
discord~/.hermes/.env 中的 DISCORD_BOT_TOKEN
slack~/.hermes/.env 中的 SLACK_BOT_TOKEN
whatsapp已配置 WhatsApp 网关
signal已配置 Signal 网关
matrix已配置 Matrix 家庭服务器
emailconfig.yaml 中已配置 SMTP
sms已配置 SMS 提供商
local~/.hermes/cron/output/ 有写入权限
origin投递到创建任务的聊天

其他支持的平台包括 mattermosthomeassistantdingtalkfeishuwecomweixinbluebubblesqqbotwebhook。也可以使用 platform:chat_id 语法指定特定聊天(例如 telegram:-1001234567890)。

如果投递失败,任务仍然运行——只是不会发送到任何地方。检查 hermes cron list 中的 last_error 字段(如果有的话)。

检查 2:检查 [SILENT] 的使用

如果定时任务没有输出,或 Agent 响应包含 [SILENT],投递将被抑制。这对于监控类任务是有意为之——但要确保你的提示词没有意外抑制所有内容。

如果提示词写着"如果没有变化就响应 [SILENT]",会静默吞掉非空响应。请检查你的条件逻辑。

检查 3:平台令牌权限

每个消息平台的机器人都需要特定权限才能收发消息。如果投递静默失败:

  • Telegram:机器人必须是目标群组/频道的管理员
  • Discord:机器人必须有在目标频道发送消息的权限
  • Slack:机器人必须已加入工作区且拥有 chat:write 权限

检查 4:响应包装

默认情况下,定时任务响应会被添加页眉和页脚(config.yamlcron.wrap_response: true)。某些平台或集成可能无法很好地处理这个。要禁用:

cron:
wrap_response: false

技能加载失败

检查 1:验证技能已安装

hermes skills list

技能必须先安装才能附加到定时任务。如果技能缺失,先用 hermes skills install <skill-name> 安装,或通过 CLI 的 /skills 安装。

检查 2:检查技能名称与技能文件夹名称

技能名称区分大小写,必须与已安装技能的文件夹名称完全匹配。如果任务指定了 ai-funding-daily-report,请从 hermes skills list 确认准确的名称。

检查 3:需要交互式工具的技能

定时任务运行时会禁用 cronjobmessagingclarify 工具集。这可以防止递归创建定时任务、直接发送消息(投递由调度器处理),以及交互式提示。如果技能依赖这些工具集,在定时任务上下文中将无法工作。

查阅技能文档,确认其是否支持非交互式(无界面)模式。

检查 4:多技能加载顺序

使用多个技能时,它们按顺序加载。如果技能 A 依赖技能 B 的上下文,确保 B 先加载:

/cron add "0 9 * * *" "..." --skill context-skill --skill target-skill

在此示例中,context-skill 先于 target-skill 加载。


任务错误与失败

检查 1:查看最近的任务输出

如果任务运行并失败,可以在以下位置找到错误上下文:

  1. 任务投递的聊天(如果投递成功的话)
  2. ~/.hermes/logs/agent.log 中的调度器消息(或 errors.log 中的警告)
  3. 通过 hermes cron list 查看任务的 last_run 元数据

检查 2:常见错误模式

脚本出现"No such file or directory" script 路径必须是绝对路径(或相对于 Hermes 配置目录的路径)。验证:

ls ~/.hermes/scripts/your-script.py # 必须存在
hermes cron edit <job_id> --script ~/.hermes/scripts/your-script.py

任务执行时出现"Skill not found" 技能必须安装在运行调度器的机器上。如果你在不同机器间切换,技能不会自动同步——用 hermes skills install <skill-name> 重新安装。

任务运行但没有投递任何内容 可能是投递目标问题(见上文投递失败部分),或响应被静默抑制([SILENT])。

任务挂起或超时 调度器使用基于不活跃状态的超时(默认 600s,可通过 HERMES_CRON_TIMEOUT 环境变量配置,0 表示无限制)。Agent 在主动调用工具期间可以持续运行——计时器仅在持续不活跃后触发。长时间运行的任务应使用脚本处理数据收集,只投递结果。

检查 3:锁竞争

调度器使用基于文件的锁来防止定时触发重叠。如果有两个网关实例在运行(或 CLI 会话与网关冲突),任务可能被延迟或跳过。

终止重复的网关进程:

ps aux | grep hermes
# 终止重复进程,只保留一个

检查 4:jobs.json 的权限

任务存储在 ~/.hermes/cron/jobs.json。如果该文件无法被你的用户读写,调度器将静默失败:

ls -la ~/.hermes/cron/jobs.json
chmod 600 ~/.hermes/cron/jobs.json # 你的用户应该拥有它

性能问题

任务启动慢

每个定时任务都会创建一个全新的 AIAgent 会话,可能涉及提供商认证和模型加载。对于时间敏感的调度,预留缓冲时间(例如用 0 8 * * * 代替 0 9 * * *)。

过多任务重叠

调度器在每次定时触发内顺序执行任务。如果多个任务同时到期,它们会一个接一个地运行。考虑错开调度(例如 0 9 * * *5 9 * * *,而不是都设为 0 9 * * *)以避免延迟。

脚本输出过大

输出数兆字节数据的脚本会拖慢 Agent,可能触及 token 限制。在脚本层面过滤/摘要——只输出 Agent 需要推理的内容。


诊断命令

hermes cron list # 显示所有任务、状态和 next_run 时间
hermes cron run <job_id> # 在下次定时触发时调度(用于测试)
hermes cron edit <job_id> # 修复配置问题
hermes logs # 查看最近的 Hermes 日志
hermes skills list # 验证已安装的技能

获取更多帮助

如果已按本指南操作但问题仍然存在:

  1. hermes cron run <job_id> 运行任务(在下次网关定时触发时执行),观察聊天输出中的错误
  2. 检查 ~/.hermes/logs/agent.log 中的调度器消息,以及 ~/.hermes/logs/errors.log 中的警告
  3. github.com/NousResearch/hermes-agent 提交 issue,附上:
    • 任务 ID 和调度表达式
    • 投递目标
    • 你预期的行为与实际发生的情况
    • 日志中相关的错误消息

完整的定时任务参考请参阅用定时任务实现自动化定时任务(Cron)