# Agent Cron 任务部署最佳实践 **版本:** 1.0 **创建日期:** 2026-02-25 **作者:** 陈医生 (Eason) 👨‍⚕️ **基于:** 张大师运程推送重复发送问题教训 --- ## ⚠️ 问题回顾 ### 问题现象 - 张大师的 21:00 运程推送,**每天发送两次** - 陈医生(主 Gateway)和张大师(独立 Gateway)都推送了相同内容 ### 根本原因 ``` 主 Gateway (端口 18789) ├── Agents: main, life ├── Cron: 张大师运程推送 ← 配置在这里! └── 问题:Cron 在主 Gateway,但 agentId="life" 张大师 Gateway (端口 18790) ├── 独立运行 └── 也有自己的 cron 配置 ``` **架构错误:** - Cron 任务配置在**主 Gateway** - 但 `agentId: "life"` 指向张大师 - 两个 Gateway 都在运行 - 导致**双重触发** --- ## 📋 核心原则 ### 原则 1: 任务归属明确 > **Cron 任务应该配置在执行该任务的 Agent 所属的 Gateway 中** ``` ✅ 正确: 张大师的运程推送 → 配置在张大师的 Gateway ❌ 错误: 张大师的运程推送 → 配置在主 Gateway ``` ### 原则 2: 默认不重复推送 > **除非特殊说明需要同步推送,否则只在指定 Agent 推送一次** - 默认:单一推送 - 同步推送:需要明确说明 ### 原则 3: Gateway 职责分离 | Gateway | 职责 | Cron 任务 | |---------|------|----------| | **主 Gateway** (陈医生) | 系统管理、main Agent | 仅 main 相关任务 | | **独立 Gateway** (张大师) | 专用功能 | 该 Agent 的所有任务 | --- ## 🔧 正确配置方法 ### 场景 A: 为张大师创建定时任务 **步骤 1: 确定目标 Gateway** ```bash # 张大师的独立 Gateway Gateway: 张大师 (端口 18790) 配置目录:/root/.openclaw-life/ ``` **步骤 2: 配置 Cron** ```bash # 编辑张大师 Gateway 的 cron 配置 cat > /root/.openclaw-life/cron/jobs.json << 'EOF' { "version": 1, "jobs": [ { "id": "unique-id-here", "agentId": "life", "name": "张大师 - 每日运程推送", "schedule": { "kind": "cron", "expr": "0 21 * * *", "tz": "Asia/Shanghai" } } ] } EOF ``` **步骤 3: 重启目标 Gateway** ```bash systemctl --user restart openclaw-gateway-life.service ``` --- ### 场景 B: 为 main Agent 创建定时任务 **步骤 1: 确定目标 Gateway** ```bash # 主 Gateway Gateway: 陈医生 (端口 18789) 配置目录:/root/.openclaw/ ``` **步骤 2: 配置 Cron** ```bash cat > /root/.openclaw/cron/jobs.json << 'EOF' { "version": 1, "jobs": [ { "agentId": "main", "name": "main Agent 的任务", "schedule": { "kind": "cron", "expr": "0 9 * * *", "tz": "Asia/Shanghai" } } ] } EOF ``` **步骤 3: 重启主 Gateway** ```bash systemctl --user restart openclaw-gateway.service ``` --- ## 🚫 常见错误 ### 错误 1: 跨 Gateway 配置 Cron ```json // ❌ 错误:在主 Gateway 配置张大师的任务 /root/.openclaw/cron/jobs.json { "agentId": "life" // 张大师的 agentId } // 问题: // - 主 Gateway 运行 cron // - 唤醒 life Agent // - 但张大师的独立 Gateway 也在运行 // - 可能双重触发 ``` **正确做法:** ```json // ✅ 正确:在张大师 Gateway 配置 /root/.openclaw-life/cron/jobs.json { "agentId": "life" } ``` --- ### 错误 2: 未确认 Gateway 数量 ```bash # ❌ 错误:不知道有几个 Gateway 在运行 systemctl --user list-units | grep openclaw # 应该先检查! ``` **正确做法:** ```bash # ✅ 正确:先检查 Gateway 状态 systemctl --user list-units | grep openclaw # 确认: # - openclaw-gateway.service (主 Gateway) # - openclaw-gateway-life.service (张大师 Gateway) # - 还有其他吗? ``` --- ### 错误 3: 假设"修复一次就永远有效" **问题:** - 昨天修复了配置 - 今天又出现重复推送 - 原因:配置被覆盖或备份文件干扰 **正确做法:** 1. 修复后立即验证 2. 第二天再次检查 3. 监控至少一个完整周期(24 小时) --- ## ✅ 验证清单 部署 Cron 任务后,必须验证: ### 部署前检查 - [ ] 确认目标 Gateway 是哪个 - [ ] 确认该 Gateway 的配置目录 - [ ] 确认是否有多个 Gateway 运行相同 Agent ### 部署后验证 - [ ] Cron 配置文件语法正确 - [ ] 重启了正确的 Gateway - [ ] 检查 Gateway 日志,确认 cron 已加载 - [ ] 等待第一次执行,确认只推送一次 ### 持续监控 - [ ] 第二天检查是否重复推送 - [ ] 检查 cron 执行日志 - [ ] 确认 delivery 状态 --- ## 📊 验证命令 ```bash # 1. 检查 Gateway 状态 systemctl --user list-units | grep openclaw # 2. 检查 Cron 配置 cat /root/.openclaw/cron/jobs.json | python3 -m json.tool cat /root/.openclaw-life/cron/jobs.json | python3 -m json.tool # 3. 检查 Cron 任务数量 cat /root/.openclaw*/cron/jobs.json | python3 -c " import sys,json for f in sys.stdin: d=json.loads(f) print(f'Tasks: {len(d.get(\"jobs\",[]))}') " # 4. 查看 Cron 执行日志 journalctl --user -u openclaw-gateway*.service | grep cron # 5. 验证 Telegram 消息 # 手动检查 Telegram,确认没有重复推送 ``` --- ## 🎯 决策树 ``` 需要创建定时任务 ↓ 哪个 Agent 执行? ├─→ main Agent → 配置在主 Gateway └─→ 独立 Agent (如 life) ↓ 该 Agent 有独立 Gateway 吗? ├─→ 是 → 配置在独立 Gateway └─→ 否 → 配置在主 Gateway ↓ 需要同步推送吗? ├─→ 是 → 在多个 Gateway 都配置 (明确说明) └─→ 否 → 只在一个 Gateway 配置 (默认) ``` --- ## 📝 经验教训 ### 教训 1: 架构决定配置位置 - **集中式架构** (所有 Agent 在主 Gateway) → Cron 都在主 Gateway - **分布式架构** (Agent 有独立 Gateway) → Cron 分散到各 Gateway **当前架构:** 混合架构 - 主 Gateway: main + life (路由) - 独立 Gateway: life (张大师) **正确做法:** 独立 Agent 的 Cron 配置在独立 Gateway --- ### 教训 2: 验证必须跨越完整周期 - **不要**修复后立即认为"已解决" - **要**监控至少 24 小时(一个完整日周期) - **要**在实际执行时间点验证 --- ### 教训 3: 文档化架构决策 **应该记录:** - 哪些 Agent 有独立 Gateway - 每个 Gateway 的职责 - Cron 任务的归属 **不应该:** - 假设"大家都知道" - 依赖口头沟通 - 不写文档 --- ## 🔗 相关文档 - [AGENT_DEPLOYMENT_BEST_PRACTICES.md](./AGENT_DEPLOYMENT_BEST_PRACTICES.md) - [张大师部署日志](../logs/agents/life/2026-02-23-deployment-check.log) - [张大师问题修复报告](../logs/agents/life/2026-02-23-issue-fixes.md) --- **最后更新:** 2026-02-25 **维护者:** 陈医生 (Eason) 👨‍⚕️