H繁中版
文件開發者指南cron internals
<!-- Source: https://hermesbible.com/docs/developer-guide/cron-internals -->

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 子命令

排程模型

支援四種排程格式:

格式範例行為
相對延遲30m2h1d單次執行,經過指定時間後觸發
間隔every 2hevery 30m週期性,以固定間隔觸發
Cron 運算式0 9 * * *標準 5 欄 cron 語法(分鐘、小時、日、月、星期)
ISO 時間戳2025-01-15T09:00:00單次執行,在精確時間觸發

面向模型的介面是一個單一的 cronjob 工具,帶有動作風格的操作:createlistupdatepauseresumerunremove

任務儲存

任務儲存在 ~/.hermes/cron/jobs.json 中,使用原子寫入語義(寫入臨時檔案,然後重新命名)。每個任務記錄包含:

{
  "id": "a1b2c3d4e5f6",
  "name": "Daily briefing",
  "prompt": "Summarize today's AI news and funding rounds",
  "schedule": {
    "kind": "cron",
    "expr": "0 9 * * *",
    "display": "0 9 * * *"
  },
  "skills": ["ai-funding-daily-report"],
  "deliver": "telegram:-1001234567890",
  "repeat": {
    "times": null,
    "completed": 42
  },
  "state": "scheduled",
  "enabled": true,
  "next_run_at": "2025-01-16T09:00:00Z",
  "last_run_at": "2025-01-15T09:00:00Z",
  "last_status": "ok",
  "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. 取得排程器鎖(防止重疊的作業)
  2. 從 jobs.json 載入所有任務
  3. 篩選到期任務(next_run <= now AND state == "scheduled")
  4. 對於每個到期任務:
     a. 設定狀態為 "running"
     b. 建立全新的 AIAgent session(無對話歷史)
     c. 按順序載入附加的技能(作為使用者訊息注入)
     d. 透過代理程式執行任務提示詞
     e. 將回應遞送到設定的目標
     f. 更新 run_count,計算 next_run
     g. 如果重複次數用盡 → state = "completed"
     h. 否則 → state = "scheduled"
  5. 將更新後的任務寫回 jobs.json
  6. 釋放排程器鎖

閘道器整合

在閘道器模式下,排程器在專用的背景執行緒中運行(gateway/run.py 中的 _start_cron_ticker),每 60 秒呼叫一次 scheduler.tick(),與訊息處理並行。

在 CLI 模式下,cron 任務只在執行 hermes cron 命令或活躍的 CLI session 期間觸發。

全新 Session 隔離

每個 cron 任務在完全全新的代理程式 session 中運行:

  • 沒有來自先前運行的對話歷史
  • 沒有先前 cron 執行的記憶(除非持久化到記憶體/檔案)
  • 提示詞必須是自包含的 — cron 任務無法提出澄清問題
  • cronjob 工具組被停用(遞迴保護)

基於技能的任務

cron 任務可以透過 skills 欄位附加一個或多個技能。在執行時:

  1. 技能按指定順序載入
  2. 每個技能的 SKILL.md 內容作為上下文注入
  3. 任務的提示詞作為任務指令附加在後面
  4. 代理程式處理結合的技能上下文 + 提示詞

這使得可重複使用、經過測試的工作流程無需將完整指令貼到 cron 提示詞中。例如:

建立每日資金報告 → 附加 "ai-funding-daily-report" 技能

基於腳本的任務

任務也可以透過 script 欄位附加一個 Python 腳本。腳本在每次代理程式回合之前運行,其 stdout 會作為上下文注入到提示詞中。這支援資料收集和變更偵測模式:

# ~/.hermes/scripts/check_competitors.py
import requests, json
# 取得競爭對手的發佈說明,與上次運行進行差異比較
# 將摘要列印到 stdout — 代理程式進行分析並報告

腳本逾時預設為 120 秒。_get_script_timeout() 透過三層鏈解析限制:

  1. 模組級覆寫_SCRIPT_TIMEOUT(用於測試/猴子補丁)。只在與預設值不同時使用。
  2. 環境變數HERMES_CRON_SCRIPT_TIMEOUT
  3. 設定config.yaml 中的 cron.script_timeout_seconds(透過 load_config() 讀取)
  4. 預設值 — 120 秒

Provider 恢復

run_job() 將使用者設定的後備 provider 和認證池傳遞給 AIAgent 實例:

  • 後備 provider — 從 config.yaml 讀取 fallback_providers(列表)或 fallback_model(舊式字典),與閘道器的 _load_fallback_model() 模式一致。作為 fallback_model= 傳遞給 AIAgent.__init__,該方法將兩種格式正規化為後備鏈。
  • 認證池 — 透過 load_pool(provider)agent.credential_pool 使用已解析的執行階段 provider 名稱載入。只有在池中有認證資訊時才傳遞(pool.has_credentials())。支援在 429/限流錯誤時進行同 provider 的金鑰輪替。

這與閘道器的行為一致 — 如果沒有它,cron 代理程式在遇到限流時會直接失敗而不嘗試恢復。

遞送模型

Cron 任務結果可以遞送到任何支援的平台:

目標語法範例
原始聊天origin遞送到建立任務的聊天室
本地檔案local儲存到 ~/.hermes/cron/output/
Telegramtelegramtelegram:<chat_id>telegram:-1001234567890
Discorddiscorddiscord:#channeldiscord:#engineering
Slackslack遞送到 Slack 主頻道
WhatsAppwhatsapp遞送到 WhatsApp 主頁
Signalsignal遞送到 Signal
Matrixmatrix遞送到 Matrix 主聊天室
Mattermostmattermost遞送到 Mattermost 主頁
Emailemail透過 email 遞送
SMSsms透過 SMS 遞送
Home Assistanthomeassistant遞送到 HA 對話
DingTalkdingtalk遞送到釘釘
Feishufeishu遞送到飛書
WeComwecom遞送到企業微信
Weixinweixin遞送到微信(WeChat)
BlueBubblesbluebubbles透過 BlueBubbles 遞送到 iMessage
QQ Botqqbot透過官方 API v2 遞送到 QQ(騰訊)

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

回應包裝

預設情況下(cron.wrap_response: true),cron 遞送會包裝:

  • 一個標題,標識 cron 任務名稱和任務
  • 一個頁尾,說明代理程式無法在對話中看到已遞送的訊息

cron 回應中的 [SILENT] 前綴會完全抑制遞送 — 對於只需要寫入檔案或執行副作用的任務很有用。

Session 隔離

Cron 遞送不會被鏡像到閘道器 session 的對話歷史中。它們只存在於 cron 任務自己的 session 中。這防止了目標聊天室對話中的訊息交替違反。

遞迴保護

Cron 運行的 session 停用了 cronjob 工具組。這防止了:

  • 排程任務建立新的 cron 任務
  • 可能導致 token 用量爆炸的遞迴排程
  • 從任務內部意外修改任務排程

鎖定

排程器使用跨進程的基於檔案的鎖定(Unix 上的 fcntl.flock,Windows 上的 msvcrt.locking),防止重疊的作業重複執行同一批到期任務 — 即使在閘道器的進程內排程器和獨立的 hermes cron / 手動 tick() 呼叫之間。如果無法取得鎖,tick() 會立即回傳 0。

CLI 介面

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

hermes cron list                    # 顯示所有任務
hermes cron create                  # 互動式任務建立(別名:add)
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>         # 刪除任務

相關文件



Image Generation Provider Plugins