跳到主要內容

Cron 內部機制

cron 子系統提供定時任務執行功能——從簡單的單次延遲任務,到支持技能注入和跨平臺交付的週期性 cron 表達式任務。

核心文件

文件用途
cron/jobs.py任務模型、存儲,對 jobs.json 的原子讀寫操作
cron/scheduler.py調度器循環——檢測到期任務、執行任務、跟蹤重複任務
tools/cronjob_tools.py面向模型的 cronjob 工具註冊與處理器
gateway/run.py網關集成——在長期運行的循環中觸發 cron 時鐘
hermes_cli/cron.pyCLI 命令 hermes cron 的子命令

調度模型

支持四種調度格式:

格式示例行為
相對延遲30m, 2h, 1d單次執行,指定時長後觸發
間隔every 2h, every 30m週期性執行,按固定間隔觸發
Cron 表達式0 9 * * *標準 5 字段 cron 語法(分鐘、小時、日、月、星期幾)
ISO 時間戳2025-01-15T09:00:00單次執行,精確在指定時間觸發

面向模型的接口是一個單一的 cronjob 工具,採用操作風格的命令:createlistupdatepauseresumerunremove

任務存儲

任務存儲在 ~/.hermes/cron/jobs.json 中,並採用原子寫入語義(先寫入臨時文件,再重命名)。每個任務記錄包含:

{
"id": "job_abc123",
"name": "Daily briefing",
"prompt": "Summarize today's AI news and funding rounds",
"schedule": "0 9 * * *",
"skills": ["ai-funding-daily-report"],
"deliver": "telegram:-1001234567890",
"repeat": null,
"state": "scheduled",
"next_run": "2025-01-16T09:00:00Z",
"run_count": 42,
"created_at": "2025-01-01T00:00:00Z",
"model": null,
"provider": null,
"script": null
}

任務生命週期狀態

狀態含義
scheduled激活狀態,將在下次預定時間觸發
paused暫停狀態——直到恢復前不會觸發
completed重複次數耗盡或單次任務已執行完畢
running正在執行中(瞬態狀態)

向後兼容性

舊版任務可能僅包含一個 skill 字段,而非 skills 數組。調度器在加載時會進行標準化處理——單個 skill 會被提升為 skills: [skill]

調度器運行時

時鐘週期

調度器以週期性時鐘運行(默認:每 60 秒一次):

tick()
1. Acquire scheduler lock (prevents overlapping ticks)
2. Load all jobs from jobs.json
3. Filter to due jobs (next_run <= now AND state == "scheduled")
4. For each due job:
a. Set state to "running"
b. Create fresh AIAgent session (no conversation history)
c. Load attached skills in order (injected as user messages)
d. Run the job prompt through the agent
e. Deliver the response to the configured target
f. Update run_count, compute next_run
g. If repeat count exhausted → state = "completed"
h. Otherwise → state = "scheduled"
5. Write updated jobs back to jobs.json
6. Release scheduler lock

網關集成

在網關模式下,調度器時鐘被集成到網關的主事件循環中。網關在其定期維護週期中調用 scheduler.tick(),與消息處理並行運行。

在 CLI 模式下,cron 任務僅在運行 hermes cron 命令或處於活躍 CLI 會話期間觸發。

新會話隔離

每個 cron 任務都在一個完全獨立的 Agent 會話中運行:

  • 無前次運行的對話歷史
  • 無對之前 cron 執行的記憶(除非顯式持久化到內存或文件)
  • 提示必須自包含——cron 任務無法提出澄清性問題
  • cronjob 工具集被禁用(防止遞歸)

技能驅動的任務

cron 任務可通過 skills 字段附加一個或多個技能。在執行時:

  1. 技能按指定順序加載
  2. 每個技能的 SKILL.md 內容作為上下文注入
  3. 任務的提示作為任務指令追加
  4. Agent 處理合併後的技能上下文 + 提示

這使得可重用、可測試的工作流成為可能,而無需將完整指令粘貼到 cron 提示中。例如:

Create a daily funding report → attach "ai-funding-daily-report" skill

腳本驅動的任務

任務也可通過 script 字段附加一個 Python 腳本。該腳本在每次 Agent 執行前運行,其標準輸出作為上下文注入到提示中。這支持數據採集和變更檢測模式:

# ~/.hermes/scripts/check_competitors.py
import requests, json
# 獲取競爭對手的發行說明,與上次運行的差異
# 將摘要打印到標準輸出 — agent 分析和報告

腳本超時默認為 120 秒。_get_script_timeout() 通過三層鏈式機制解析限制:

  1. 模塊級覆蓋_SCRIPT_TIMEOUT(用於測試/猴子補丁)。僅當其不同於默認值時使用。
  2. 環境變量HERMES_CRON_SCRIPT_TIMEOUT
  3. 配置cron.script_timeout_secondsconfig.yaml 中(通過 load_config() 讀取)
  4. 默認值 — 120 秒

提供商恢復機制

run_job() 將用戶配置的備用提供方和憑證池傳遞給 AIAgent 實例:

  • 備用提供方 — 從 config.yaml 讀取 fallback_providers(列表)或 fallback_model(舊版字典),匹配網關的 _load_fallback_model() 模式。作為 fallback_model= 傳入 AIAgent.__init__,該方法將兩種格式統一為備用鏈。
  • 憑證池 — 通過 load_pool(provider)agent.credential_pool 加載,使用解析後的運行時提供方名稱。僅當池中存在憑證(pool.has_credentials())時才傳遞。支持同一提供方在 429/速率限制錯誤時的密鑰輪換。

這與網關行為保持一致——否則 cron Agent 在遭遇速率限制時將無法嘗試恢復。

交付模型

cron 任務的結果可交付至任何支持的平臺:

目標語法示例
原始聊天origin發送到任務創建時的聊天
本地文件local保存到 ~/.hermes/cron/output/
Telegramtelegramtelegram:<chat_id>telegram:-1001234567890
Discorddiscorddiscord:#channeldiscord:#engineering
Slackslack發送到 Slack 主頻道
WhatsAppwhatsapp發送到 WhatsApp 主聊天
Signalsignal發送到 Signal
Matrixmatrix發送到 Matrix 主房間
Mattermostmattermost發送到 Mattermost 主頻道
郵件email通過郵件發送
短信sms通過短信發送
Home Assistanthomeassistant發送到 HA 對話
釘釘dingtalk發送到釘釘
飛書feishu發送到飛書
企業微信wecom發送到企業微信
微信weixin發送到微信(WeChat)
BlueBubblesbluebubbles通過 BlueBubbles 發送到 iMessage

對於 Telegram 的主題,使用格式 telegram:<chat_id>:<thread_id>(例如 telegram:-1001234567890:17585)。

響應包裝

默認情況下(cron.wrap_response: true),cron 交付內容會被包裝為:

  • 一個標題,標識 cron 任務名稱和任務本身
  • 一個頁腳,註明 Agent 無法在對話中看到已發送的消息

在 cron 響應中使用 [SILENT] 前綴將完全抑制交付——適用於僅需寫入文件或執行副作用的任務。

會話隔離

Cron 交付不會被鏡像到網關會話的歷史記錄中。它們僅存在於 cron 任務自身的會話中。這可防止目標聊天對話中出現消息交替違規。

遞歸保護

Cron 運行的會話禁用了 cronjob 工具集。這可防止:

  • 定時任務創建新的 cron 任務
  • 遞歸調度導致令牌使用量爆炸
  • 在任務內部意外修改任務調度

鎖定機制

調度器使用基於文件的鎖定機制,防止多個重疊的 tick 同時執行同一組待處理任務。這在網關模式下尤為重要,因為如果前一個 tick 執行時間超過 tick 間隔,可能會導致多個維護週期重疊。

CLI 界面

hermes cron CLI 提供了直接的任務管理功能:

hermes cron list                    # 顯示所有職位
hermes cron create # 交互式創造就業機會(別名:添加)
hermes cron edit <job_id> # 編輯作業配置
hermes cron pause <job_id> # 暫停正在運行的作業
hermes cron resume <job_id> # 恢復暫停的作業
hermes cron run <job_id> # 觸發立即執行
hermes cron remove <job_id> # 刪除職位