Hermes cron 调度系统:11 个活跃任务的自动化编排
一、规模:30 个任务,11 个活跃
venxine.vip 运行在 Hermes Agent 的 cron 引擎上。目前共 30 个注册任务,其中 11 个活跃:
| # | 任务 | 调度 | 类型 | 模型 |
|---|---|---|---|---|
| 1 | 🌐 全球AI新闻聚合 | 每日 08:00 | LLM 驱动 | deepseek-v4-pro |
| 2 | 🦙 Crypto新闻日报 | 每日 07:00 | LLM 驱动 | deepseek-v4-pro |
| 3 | ⚠️ 基金涨跌预警 | 交易日 每10分钟 | no_agent 脚本 | — |
| 4 | 📡 基金数据采集 | 交易日 每10分钟 | no_agent 脚本 | — |
| 5 | 🇺🇸 华尔街日报 | 周二~六 06:00 | LLM 驱动 | deepseek-v4-pro |
| 6 | 📋 每日收益数据 | 交易日 22:00 | no_agent 脚本 | — |
| 7 | 📊 A股收盘分析 | 每日 20:00 | LLM 驱动 | deepseek-v4-pro |
| 8 | 🔍 每日基金分析 | 每日 21:00 | LLM 驱动 | deepseek-v4-pro |
| 9 | 🌐 QDII基金分析 | 周二~六 08:00 | LLM 驱动 | deepseek-v4-pro |
| 10 | 🔁 自改进引擎 | 每周日 03:00 | no_agent 脚本 | — |
| 11 | 🔄 网关每日重启 | 每日 04:30 | no_agent 脚本 | — |
另外 19 个暂停,包括 8 个社交媒体下载脚本、6 个基金报告推送、以及其他实验性任务。
二、Model Pinning:防止模型漂移
早期用 v4-flash 跑 cron,某天早上 06:00~08:00 三个任务(华尔街日报、Crypto 日报、AI 新闻)全部报 Broken pipe。
原因:deepseek-v4-flash 在早高峰时段不稳定。但更根本的问题是:cron 任务没有固定模型,自动跟随当前会话的默认模型。一旦我换了默认模型,所有 cron 也跟着变。
解决方案是 model pinning,在创建 cron 时显式指定 provider 和 model,写到 jobs.json 中:
{
"name": "华尔街日报",
"model": {
"provider": "custom:api.deepseek.com",
"model": "deepseek-v4-pro"
}
}
所有 13 个 LLM 驱动的 cron 任务全部 pin 到了 deepseek-v4-pro。即使在交互会话中切换模型,cron 任务永远用固定的生产模型。
三、Prompt 精简:砍掉 75% Token
chinastock(A股收盘分析)是第一次遇到 HTTP 400 Content Exists Risk 的情况。不是网络问题,是 DeepSeek 的内容审核拦截了过长的 prompt。
排查发现:cron 加载了 cn-web-search skill,这个 skill 的全文(约 5K tokens)被注入到 prompt 中。加上系统指令和用户 prompt,总计 ~7K tokens。
# 修复前
cronjob(action='create',
prompt='生成A股收盘分析...',
skills=['cn-web-search']) # ← 5K token 注入
# 修复后
cronjob(action='create',
prompt='生成A股收盘分析,使用内置 web_search 工具...',
skills=[]) # ← 只依赖内置指令
去掉不必要的 skill 加载后,prompt 从 ~7K 降到 ~1.5K tokens,审核拦截概率大幅降低。
原则:cron 任务的 prompt 应该自包含,只加载必不可少的 skill。每多加载一个 skill 就多注入几千 token,既烧钱又增加审核风险。
四、no_agent 模式:零 Token 脚本
基金数据采集和涨跌预警是纯数据操作(抓取实时估值、写 JSON、计算阈值),不需要 LLM 推理。
Hermes cron 支持 no_agent=True 模式:跳过 LLM,调度器直接执行 Python/Shell 脚本,stdout 作为推送内容:
cronjob(action='create',
name='基金数据采集',
schedule='9:15 on trading days, every 10 minutes',
no_agent=True,
script='scripts/fund-tracker.py')
5 个活跃任务用了 no_agent 模式:零 token 消耗,零模型依赖。
| 模式 | Token 消耗 | 适用场景 |
|---|---|---|
| LLM 驱动 | 每次几千~几万 token | 新闻分析、内容生成、推理 |
| no_agent 脚本 | 0 | 数据采集、阈值告警、看门狗 |
五、Watchdog:网关自愈
网关 Python 进程存在内存泄漏:RSS 每天增长约 110MB,从初始 200MB 涨到 475MB。
但 Hermes 网关禁止自重启:从网关内部运行 hermes gateway restart 会被命令拦截。唯一的绕过方式:no_agent=True 的 cron 脚本。
#!/bin/bash
# scripts/gateway-daily-restart.sh
systemctl --user restart hermes-gateway
cronjob(action='create',
name='网关每日重启',
schedule='0 4:30 * * *',
no_agent=True, # 不经过 LLM
script='scripts/gateway-daily-restart.sh')
cron 调度器是独立进程,不受网关重启影响。每天 04:30 触发,在 04:00 session_reset + 04:04 session_expiry 清理之后,把网关 RSS 重置回 ~200MB。
六、失败恢复流程
LLM 驱动的 cron 偶尔会失败。以 chinastock 为例,标准恢复流程:
1. cronjob(action='list') → 找到 FAILED 的输出 .md 文件 → 删除
2. web_search 获取当日实际收盘数据(上证/深证/创业板/科创50)
3. 用 Python 生成三段式 market_analysis:
├── 📈 指数表现(4 个指数收盘涨跌幅)
├── 💰 市场概况(~500 字)
└── 🔥 驱动因素(6 个维度各 ~200 字)
4. json.dump 写入 daily-analysis.json
5. 页面刷新即生效
关键原则:手动恢复时写的是数据文件,不是 prompt 重跑。 数据文件是 Flask 直接读的 JSON,不受 cron 状态影响。
七、架构总结
cron 调度器
├── LLM 驱动任务 (6个) → 模型 pin 到 deepseek-v4-pro
│ ├── 新闻分析 ×4 → prompt 精简,不加载非必要 skill
│ └── 基金分析 ×2 → 失败时手动写 JSON 恢复
│
├── no_agent 脚本 (5个) → 零 token
│ ├── 数据采集 ×2 → 每10分钟抓取 + 写 JSON
│ ├── 数据写入 ×1 → 交易日 22:00
│ ├── 自改进引擎 ×1 → 每周日 03:00
│ └── 网关 watchdog ×1 → 每日 04:30 重启
│
└── 暂停任务 (19个) → 按需恢复
├── 基金推送 ×6
├── 社交媒体 ×8
└── 其他 ×5
这套 cron 系统跑了 68 天,累计 API 调用 21,000+ 次,处理了超过 54 亿 token,全部自动化,无人值守。