7.7 KiB
7.7 KiB
| name | version | date | description | metadata | tags | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| cron-ops | 1.0.1 | 2026-09-10 | Use when managing cron jobs or configuring fallback chains. |
|
|
Cron 运维 Skill
Hermes 定时任务的配置、fallback、重试和故障排查。
配置结构
~/.hermes/config.yaml 中 cron 段:
cron:
model: glm-4-flash # 主模型
model_provider: zhipu # 主 provider
fallback_model: agnes-2.5-flash # fallback 模型
fallback_provider: agnes # fallback provider
provider: auto # auto = 按 model_provider 走
gateway_required: true # gateway 在才 fire
wrap_response: true
Fallback 链: 主模型失败 → fallback_model → 全局 fallback_providers(config.yaml 顶层)
Job 配置
~/.hermes/cron/jobs.json 中每个 job:
{
"id": "5b108ad99991",
"name": "蒸馏模型看门狗",
"script": "distill-model-watchdog.py",
"no_agent": true,
"schedule": "every 30m",
"model": null,
"provider": null
}
关键: model/provider 为 null 时继承 cron 默认配置;设置具体值会覆盖全局 fallback。
两种模式
| 模式 | no_agent | 执行方式 | 适用场景 |
|---|---|---|---|
| 脚本模式 | true | 直接执行脚本,stdout 投递 | 看门狗、数据采集、健康检查 |
| Agent 模式 | false | LLM 执行 prompt,可用工具 | 分析、报告、需要推理的任务 |
脚本路径规则(重要 Pitfall)
- 必须用绝对路径:
/home/muc/.hermes/scripts/xxx.sh,不能~/.hermes/scripts/xxx.sh - 不支持参数: script 字段不能
script.sh arg1 arg2,cron 系统会把整个字符串当文件路径 - 脚本必须在 scripts 目录:
~/.hermes/scripts/下,否则报 "Script not found" - Python 脚本自动用 sys.executable:
.py文件用当前 Python 解释器执行 - Shell 脚本自动用 bash:
.sh/.bash文件用/bin/bash执行
投递目标(deliver)语义(2026-09-05 实测)
| 值 | 实际去向 | 注意 |
|---|---|---|
origin |
创建该 job 时的 chat | 在 DM 里创建 → 通知回私聊!不是自动去群 |
feishu(裸值) |
Home channel(= 当前 profile 的 Home,可能是 DM) | 同样可能落私聊 |
local |
仅存 ~/.hermes/cron/output/,无消息投递 |
watchdog 静默模式 |
feishu:<chat_id> |
显式指定 chat | 群通知必须显式写群 ID |
- ⛔ 飞书 DM 的 chat_id 也以
oc_开头(如oc_cd14...)——不能凭前缀判断私聊/群。判定靠 MEMORY 映射:群=oc_81f6df701c872a1122f32080e366543f;小唯↔牧尘 DM=oc_cd14ec7518926e57d26c5e339ebba3b3(userou_f20eb15b3a76639fed35977c01ddcbb4)。 - ⛔ 牧尘铁律:任务通知一律发群,不发私聊。新建带通知的 cron 时 deliver 直接写
feishu:oc_81f6df701c872a1122f32080e366543f,别依赖 origin 默认。 - 检查存量:
jobs.json里deliver: origin或裸feishu的 job 若创建于 DM = 通知发私聊 → 逐个 update 为群 ID。
Fallback 配置最佳实践
Agent 模式 jobs
- 设置
model: null,provider: null→ 继承 cron 默认 - 默认配置已有 fallback: zhipu → agnes
- 全局 fallback: mimo → deepseek → opencode-free
脚本模式 jobs
- 脚本内部实现重试逻辑(Hermes 不自动重试脚本)
- 推荐模式:
import subprocess, sys, time
def run_with_retry(cmd, max_retries=3, delay=5):
for i in range(max_retries):
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
if result.returncode == 0:
print(result.stdout)
return 0
if i < max_retries - 1:
time.sleep(delay)
return result.returncode
if __name__ == "__main__":
sys.exit(run_with_retry([sys.executable, "target_script.py"]))
常用命令
# 列出所有 jobs
hermes cron list
# 手动触发
hermes cron run <job_id>
# 查看 job 详情
hermes cron show <job_id>
# 创建 job
hermes cron create "every 30m" --name "任务名" --script "script.py" --no-agent
# 暂停/恢复
hermes cron pause <job_id>
hermes cron resume <job_id>
故障排查
Job 状态为 error
- 检查
last_fire_error字段 - 脚本路径是否正确(绝对路径)
- 脚本是否有执行权限
- 手动执行脚本测试
- 先验上游依赖是否运行(非脚本问题占多数):
- llama-server cron → 查
pgrep -fa llama-server或systemctl --user is-active llama-server-7b - 织忆 cron → 查
curl -s http://127.0.0.1:7821/health - 股票 cron → 查网络/API key
- 41 次连续失败先看失败时间是否集中在某服务未启动的时间窗口
- llama-server cron → 查
Fallback 不生效
- 检查 job 的
model/provider是否覆盖了全局 - 确认 fallback_provider 的 API key 在 .env 中
- 检查 fallback 模型是否可用
脚本静默失败
- no_agent 模式下,空 stdout = 静默(不投递)
- 检查脚本是否有输出
- 查看 journalctl --user -u hermes-gateway
飞书 TTS 静默失败
- MiMo quota 429 exhausted → 飞书 TTS 消息被吞不报错
- 验证:直接 curl MiMo TTS 端点看是否返回 quota error
- 备选:切 edge-tts(内置,无 quota 限制)
Pitfalls
- 不要覆盖 job 级 model/provider: 除非特殊需求,让 job 继承 cron 默认配置
- 脚本重试在脚本内部实现: Hermes 不自动重试 no_agent 脚本
- 绝对路径: 所有脚本路径必须是绝对路径
- 不支持参数: 脚本不能带参数,需要参数时写 wrapper 脚本
模式 8 复发实例 + 全库扫描根治(2026-09-05)
同一天两个 no_agent 看门狗踩同一坑(各自脚本带 --apply 被当文件名):
backup-cleanup.py --apply(备份自动清理 6a87615b5155)→ Script not found → 备份清理停摆数天resource-watchdog.py --apply(文件资源看门狗 c336c1c3b39f)→ 同上
根治修复模板(wrapper 放 ~/.hermes/scripts/,chmod +x,hermes cron edit <id> --script <wrapper>):
#!/bin/bash
# <name> cron wrapper(参数放这里)
exec python3 /home/muc/.hermes/scripts/<script>.py --apply
全库扫描根治检查(新建/修改 no_agent job 后必跑):
python3 -c "import json; d=json.load(open('/home/muc/.hermes/cron/jobs.json')); jobs=d.get('jobs',d) if isinstance(d,dict) else d; items=jobs if isinstance(jobs,list) else list(jobs.values()); [print('❌', j['id'][:12], j.get('name'), repr(j.get('script'))) for j in items if j.get('script') and ' ' in str(j.get('script'))]"
# 无输出 = 全部干净;有 ❌ = 还有带参 script 待修
症状识别:cron 输出 "Script not found: /path/to/xxx.py --apply"(把参数拼进路径找)→ 100% 模式 8。修复后 hermes cron run <id> 验证 succeeded。
5. 状态文件保护: 脚本的状态文件(如 rsshub_ai_seen.json)要防并发写入
no_agent 模式下 prompt / skills 被完全忽略(2026-09-11 实测)
no_agent job 只执行 script 并把 stdout 原样投递,prompt 与 skills 字段根本不读。
- 想让告警自带判读提示(如「报警≠错误,主动放置请忽略」)→ 必须让脚本自己 print。
实测:改了 no_agent job 的
prompt,行为零变化;把提示挪进脚本才生效。 - 干净时 stdout 为空 = 不投递任何消息(watchdog 静默模式);非零退出码 / 超时会触发错误告警 → watchdog 脚本要区分「有发现」(正常输出)与「脚本自己崩了」(退出码)。
- 所以给 no_agent job 配 prompt 是白写;要改行为只能改脚本或wrapper(见上文模式 8)。