跳到主要内容

定时任务

CountBot 的定时任务系统不只是“按 Cron 时间触发一句话”,而是完整的任务调度与执行链路:任务定义持久化、精确唤醒、并发控制、会话复用、渠道投递,以及通过 cron-manager 技能进行自然语言管理。

这章包含什么

  • 当前 Cron API 的真实接口
  • max_retriesretry_delaydelete_on_success 等新能力
  • 任务会话查看、清理、重置
  • 批量创建、批量删除
  • 内置任务保护
  • cron-manager 技能的实际边界

核心组件

CronService

位置:

backend/modules/cron/service.py

负责:

  • 任务 CRUD
  • Cron 表达式校验
  • 下次运行时间计算
  • 调度描述生成

CronScheduler

位置:

backend/modules/cron/scheduler.py

负责:

  • 精确计算下次唤醒时间
  • 到点触发执行
  • 并发控制
  • 避免同一任务重复执行

CronExecutor

位置:

backend/modules/cron/executor.py

负责:

  • 把任务消息交给 Agent 执行
  • 维护任务会话
  • 按需把结果投递到渠道

当前任务模型的重点字段

  • name
  • schedule
  • message
  • enabled
  • channel
  • account_id
  • chat_id
  • deliver_response
  • last_run
  • next_run
  • last_status
  • last_error
  • run_count
  • error_count
  • max_retries
  • retry_delay
  • delete_on_success

当前 API

基础 CRUD

方法路径说明
GET/api/cron/jobs获取任务列表
POST/api/cron/jobs创建任务
GET/api/cron/jobs/{job_id}获取任务详情
PUT/api/cron/jobs/{job_id}更新任务
DELETE/api/cron/jobs/{job_id}删除任务
POST/api/cron/jobs/{job_id}/run手动触发执行
POST/api/cron/validate校验 Cron 表达式

批量操作

方法路径说明
POST/api/cron/jobs/batch批量创建任务
POST/api/cron/jobs/batch-delete批量删除任务

任务会话管理

方法路径说明
GET/api/cron/jobs/{job_id}/messages查看任务关联会话消息
POST/api/cron/jobs/{job_id}/session/cleanup清理任务会话,只保留最近 N 条
POST/api/cron/jobs/{job_id}/session/reset重置任务会话

创建任务

示例:

{
"name": "每日天气播报",
"schedule": "0 9 * * *",
"message": "查询今天的天气并生成播报",
"enabled": true,
"channel": "feishu",
"account_id": "bot",
"chat_id": "ou_xxxx",
"deliver_response": true,
"max_retries": 3,
"retry_delay": 60,
"delete_on_success": false
}

新能力

自动重试

  • max_retries:失败后最多重试次数
  • retry_delay:两次重试间隔秒数

成功后自动删除

  • delete_on_success=true
  • 适合一次性提醒和临时任务

批量操作

批量创建

{
"jobs": [
{
"name": "日报",
"schedule": "0 9 * * *",
"message": "生成日报"
},
{
"name": "周报",
"schedule": "0 10 * * 1",
"message": "生成周报"
}
]
}

批量删除

{
"job_ids": ["uuid1", "uuid2", "uuid3"]
}

注意当前真实接口是:

POST /api/cron/jobs/batch-delete

不是 DELETE /api/cron/jobs/batch

任务会话

每个定时任务执行时都会进入一条任务会话,用于保存上下文和历史结果。现在已经支持:

  • 查看消息
  • 清理旧消息
  • 重置整条任务会话

这意味着定时任务不只是“单次无状态执行”,也可以有连续上下文。

调度与执行行为

精确唤醒

调度器不是固定轮询,而是根据最近任务的 next_run 精确休眠到下一次唤醒点。

并发保护

当前实现还包含:

  • 最大并发数限制
  • 活跃任务集合,避免重复执行
  • 单任务超时保护
  • 数据库提交重试

手动触发防重入

手动 run 时,如果该任务已在执行中,会返回冲突错误,而不是重复启动一份相同任务。

渠道投递

如果任务设置了:

  • channel
  • chat_id
  • deliver_response=true

那么任务执行结果会被投递到对应渠道。

多账号渠道还需要:

  • account_id

否则通常会落到 default 账号。

内置任务保护

当前系统把以 builtin: 开头的任务视为内置任务,例如内置 heartbeat 任务。

保护规则:

  • 内置任务不可删除
  • 部分字段不可修改
  • cron-manager 脚本层也会主动过滤它们

cron-manager 技能

位置:

workspace/skills/cron-manager/scripts/cron_manager.py

它是“聊天管理定时任务”的正式入口,覆盖:

  • list
  • info
  • create
  • update
  • delete
  • enable
  • disable
  • run
  • validate
  • batch-create
  • batch-delete
  • messages
  • clean
  • reset

通过聊天创建任务

用户说:

  • “每天早上 9 点提醒我开会”
  • “帮我建一个每小时看天气的任务”
  • “把那个任务改成每 2 小时执行”

系统就应该优先走 cron-manager,而不是只返回解释性文字。

一个重要增强

cron-manager 现在会读取当前聊天环境变量,例如:

  • COUNTBOT_CHANNEL
  • COUNTBOT_CHAT_ID
  • COUNTBOT_ACCOUNT_ID

所以在带渠道上下文的聊天里,如果用户说“推送到这个群”,脚本可以自动补全当前渠道、账号和聊天 ID。

cron-manager 常用示例

创建任务

python3 skills/cron-manager/scripts/cron_manager.py create \
--name "每日天气" \
--schedule "0 9 * * *" \
--message "查询今天的天气并生成播报" \
--deliver

批量创建

python3 skills/cron-manager/scripts/cron_manager.py batch-create --file tasks.json

批量删除

python3 skills/cron-manager/scripts/cron_manager.py batch-delete abc123 def456

查看任务消息

python3 skills/cron-manager/scripts/cron_manager.py messages <job_id> --limit 20

清理或重置任务会话

python3 skills/cron-manager/scripts/cron_manager.py clean <job_id> --keep 10
python3 skills/cron-manager/scripts/cron_manager.py reset <job_id>

常见表达式

表达式含义
0 9 * * *每天 9:00
*/30 * * * *每 30 分钟
0 9 * * 1-5工作日 9:00
0 0 1 * *每月 1 日 0:00
0 */2 * * *每 2 小时

什么时候文档必须更新

如果你最近做了这些改动,文档就必须同步:

  • cron-manager 增加了新命令
  • 扩展了批量操作
  • 增加了任务会话管理
  • 增加了重试和一次性任务能力
  • 增加了渠道上下文自动识别
  • 修改了批量删除 API 或字段名

当前仓库就已经属于这种情况,所以旧文档确实应该改。

相关文档