<!-- title: 三层调度配session续跑造无人值守Agent -->

# 三层调度配 session 续跑造无人值守 Agent

## 概述

本教程教你把 Claude Code 从"敲一下跑一下"的交互工具，升级成**关掉电脑也能按时干活**的无人值守 Agent。核心是把三件事拼起来：会话续跑（`--resume`/`--continue`）保证上下文不断、无头模式（`-p`）保证能脚本化、三层调度（云端 Routine / 桌面定时 / `/loop`）保证能定时自驱。适用人群：已经会用基础 `-p` 模式、想把 Claude Code 接进 CI、告警、夜间批处理与定时巡检的中高级开发者。

## 前置条件

- Claude Code **v2.1.72 以上**（定时任务功能要求），用 `claude --version` 确认；建议 **v2.1.196+** 以获得会话默认命名与技能调用收紧等改进。
- 一台可联网的开发机；想要"真·无人值守"还需 Pro / Max / Team / Enterprise 套餐并开通 Claude Code on the web（用于云端 Routine）。
- 熟悉 shell 与 `jq`；示例仓库（含 `package.json` 或可运行测试的任意项目）一个。
- 安装并登录：`claude` 命令可交互跑通；脚本场景建议备好 `ANTHROPIC_API_KEY` 或 `apiKeyHelper`。

---

## 第一步：先看清"三层调度"全景，别选错层

很多人卡在"为什么我的定时任务不跑"——根因是选错了调度层。Claude Code 现在有三层调度，能力边界完全不同：

| 维度 | 云端 Routine（Cloud） | 桌面定时任务（Desktop） | `/loop`（会话内） |
| :-- | :-- | :-- | :-- |
| 运行位置 | Anthropic 托管云 | 你的本机 | 你的本机 |
| 是否需要开机 | **否** | 是 | 是 |
| 是否需要打开会话 | 否 | 否 | **是** |
| 重启后是否留存 | 是 | 是 | 仅 `--resume` 时恢复（且未过期） |
| 能访问本地文件 | 否（每次全新 clone） | 是 | 是 |
| 权限提示 | 无（全自主跑） | 可逐任务配置 | 继承当前会话 |
| 最小间隔 | 1 小时 | 1 分钟 | 1 分钟 |

**选型口诀**：机器关了也要可靠跑 → 云端 Routine；要碰本地文件和工具 → 桌面定时；当下开着会话、只想轮询个部署状态 → `/loop`。

记住一个关键事实：`/loop` 和 `CronCreate` 是**会话级**（session-scoped）的——它只在你这条会话还活着、且空闲时才触发。关掉终端、开新会话，它们就停了（`--resume` 可在 7 天内救回未过期的任务）。要跨会话、跨重启的"真·定时"，必须上 Routine 或桌面定时。这是后面所有自动化的地基。

## 第二步：打通会话续跑——让上下文不断档

无人值守的前提是"上次干到哪、这次接着干"。Claude Code 的会话以本地 JSONL 形式持续保存，靠这几个入口续命：

```bash
claude --continue            # 续上当前目录里"最近一条"会话
claude --resume              # 打开会话选择器
claude --resume <name>       # 按名字直接续（精确匹配）
claude --resume <session-id> # 按 ID 直接续
claude --from-pr 1234        # 续上与某 PR 关联的那条会话
```

**操作**：给会话起个好认的名字，是无人值守流水线稳定的关键。名字可以在启动时设，也可以中途改：

```bash
claude -n nightly-pr-review      # 启动即命名
# 会话中：
/rename nightly-pr-review        # 改名
```

**预期结果**：之后无论脚本还是人，都能用 `claude --resume nightly-pr-review` 一键回到这条会话，而不必记一长串 UUID。

**常见问题**：
- *报错 `No conversation found with session ID: ...`* —— 续跑的"会话 ID 查找"是**按当前项目目录及其 git worktree 范围**的。你必须在当初启动该会话的那个目录里跑 `--resume`，换个目录就找不到。
- *`-p` 起的会话不在选择器里* —— 这是设计如此：`claude -p` / Agent SDK 创建的会话不出现在交互选择器，但照样能用 `claude --resume <session-id>` 续上。
- *两个终端同时 `--resume` 同一条会话* —— 消息会交错进同一条 transcript，互相污染。要并行就别续同一条，改用 `/branch --fork-session` 或 worktree。

## 第三步：无头模式 + session 续跑，串成批量管道

把 `-p` 和 `--resume` 组合起来，就能写出"分多步、上下文累积"的自动化脚本。诀窍是**第一次跑时抓出 `session_id`，后续步骤用它续跑**：

```bash
# 第 1 步：开始一次审查，抓出 session_id
session_id=$(claude -p "Review this codebase for performance issues" \
  --output-format json | jq -r '.session_id')

# 第 2 步：在同一上下文里追问数据库查询部分
claude -p "Now focus on the database queries" --resume "$session_id"

# 第 3 步：生成总结
claude -p "Generate a summary of all issues found" \
  --resume "$session_id" --output-format json | jq -r '.result'
```

**关键参数**（无人值守必备）：
- `--bare`：跳过自动加载 hooks/skills/MCP/CLAUDE.md，**脚本与 CI 的推荐模式**（官方说明未来会成为 `-p` 默认）。换台机器结果一致，队友 `~/.claude` 里的钩子不会偷偷改变行为。注意 bare 模式不读 OAuth/钥匙串，鉴权必须来自 `ANTHROPIC_API_KEY` 或 `--settings` 里的 `apiKeyHelper`。
- `--allowedTools "Bash,Read,Edit"`：预先放行工具，避免脚本卡在权限提示上。
- `--output-format json`：返回结构化结果，含 `result`、`session_id`、`total_cost_usd`——后者让你**按次核算花费**，不必翻用量面板。
- `--json-schema '{...}'`：强制输出符合 schema，结果落在 `structured_output` 字段，机器可解析。
- `--no-session-persistence`：某一次运行不想落盘 transcript 时加上它。

**预期结果**：三步命令跑完，终端依次打印审查意见、聚焦分析、最终汇总，且三步共享同一条会话上下文。

**常见问题**：
- *脚本里 `claude -p` 卡住不退出* —— 如果 Claude 起了后台 Bash 任务（如 dev server），`-p` 会在最终结果后约 5 秒终止该 shell（v2.1.163+）。后台 subagent/workflow 不享受 5 秒宽限，但从 v2.1.182 起等待上限默认 10 分钟，可用 `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS` 调。
- *权限被拒导致脚本中断* —— 用 `--allowedTools` 配合前缀语法，如 `Bash(git diff *)`（注意空格，否则 `git diff*` 会误匹配 `git diff-index`）。
- *stdin 超限* —— 管道输入自 v2.1.128 起上限 10MB，超了直接非零退出；大输入请写文件后在 prompt 里引用路径。

## 第四步：`/loop` + CronCreate——会话内的值守哨兵

当你会话还开着、想盯着某个"现在还没好"的东西（部署、CI、PR 评审），用 `/loop`：

```text
/loop 5m check if the deployment finished and tell me what happened
```

- 同时给"间隔 + 提示词"→ 固定 cron 调度。
- 只给提示词（`/loop check the deploy`）→ Claude **自选间隔**（1 分钟～1 小时），PR 活跃就等短、安静就等长，每轮结尾打印它选的延迟和理由。
- 啥都不给（`/loop`）→ 跑**内置维护提示**：先收尾本会话未完成的事，再照看当前分支的 PR（评审意见、失败 CI、合并冲突），没事时做 bug 扫描/简化。

想固定提示词，写 `.claude/loop.md`（项目级优先于 `~/.claude/loop.md`），如：

```markdown
# .claude/loop.md
检查 `release/next` 的 PR。CI 红了就拉失败日志、定位、推一个最小修复；
有新评审意见就逐条处理并 resolve 线程；全绿且安静就一行说明。
```

底层工具是 `CronCreate / CronList / CronDelete`（标准 5 段 cron：`分 时 日 月 周`）。用自然语言也能调度：

```text
remind me at 3pm to push the release branch   # 一次性，跑完自删
in 45 minutes, check whether integration tests passed
```

**预期结果**：`/loop 5m ...` 后 Claude 回一句确认的节奏与 8 位任务 ID；每 5 分钟（受 jitter 影响最多延后半周期）自动触发一次。`what scheduled tasks do I have?` 可列出，`cancel the deploy check job` 可取消。

**务必知道的坑**：
- **7 天自动过期**：周期任务创建满 7 天后跑最后一次再自删，防止被遗忘的 loop 永远跑。要更久就到期前重建，或上 Routine/桌面定时。
- **Jitter**：周期任务最多比计划晚 30 分钟（或半个间隔，取小）；一次性任务落在整点/半点最多早 90 秒。要精确时刻就**避开 `:00`/`:30`**，用 `3 9 * * *` 而非 `0 9 * * *`。
- **只在空闲时触发**：任务在你两轮对话之间排队，Claude 正忙就等当前轮结束；错过的时间不补，只会等空闲后补跑一次。
- **Esc 只停 `/loop` 的待触达**，不影响你直接让 Claude 调度的任务；想全停用调度设 `CLAUDE_CODE_DISABLE_CRON=1`。
- **新开会话会清空所有会话级任务**，只有 `--resume`/`--continue` 能在 7 天窗口内把未过期的救回来；后台 Bash/Monitor 任务**永不**在 resume 时恢复。

> 进阶：想要"事件驱动"而非轮询，用 **Channels**（CI 直接把失败推进会话）；想"一轮接一轮直到条件满足"而非按间隔，用 `/goal`。动态 `/loop` 还可能直接用 **Monitor 工具**后台跑脚本、逐行回灌输出，比轮询更省 token。

## 第五步：云端 Routine——机器关了也按时跑的"真·无人值守"

`/loop` 再强也得开着电脑。要"下班合上笔记本，半夜 2 点 Claude 自己把活干了"，上 **Routines**（2026 年 4 月起的 research preview）。它运行在 Anthropic 托管的云基础设施上：一次打包好（提示词 + 仓库 + 环境 + connectors），之后按触发器自动跑，全程**无权限提示、全自主**。

一个 Routine 可挂多个触发器：
- **Scheduled**：每小时/每天/工作日/每周；最低间隔 1 小时；也支持一次性（跑完自动停用）。
- **API**：每个 Routine 一个 `/fire` 端点 + bearer token，`POST` 即起一条新会话。
- **GitHub**：`pull_request` / `release` 事件触发，可按 author/branch/labels/is-draft/is-merged 过滤。

**创建方式（三端同账号同步）**：
- Web：[claude.ai/code/routines](https://claude.ai/code/routines) → New routine；
- 桌面 App：侧栏 Routines → New routine → 选 **Remote**（选 Local 则变成桌面定时任务）；
- CLI：`/schedule daily PR review at 9am`（自然语言）、`/schedule list`、`/schedule update`、`/schedule run`。

**配置要点**：
1. **提示词要自包含、明确成功标准**——Routine 全自主跑，没人盯着补一句"你刚才意思是？"。
2. **仓库**：每次运行从默认分支全新 clone，改动落在 `claude/`- 前缀分支；要能推已有分支需开"Allow unrestricted branch pushes"。
3. **环境**：控制网络出口、环境变量（密钥）、setup 脚本（结果会缓存）。默认环境的"Trusted 网络"只放行常见包注册表/云 API/容器仓库，要连自家服务得先改网络白名单。
4. **Connectors**：默认包含你所有已连 MCP 连接器，用不到的删掉——Routine 跑起来对包含的连接器**包括写操作都不再问权限**。

**一次性调度**（不占每日运行配额，走常规订阅用量）：

```text
/schedule tomorrow at 9am, summarize yesterday's merged PRs
/schedule in 2 weeks, open a cleanup PR that removes the feature flag
```

**常见问题**：
- *Routine 看不到/用不了* —— 需 Pro/Max/Team/Enterprise 且开通 Claude Code on the web；Team/Enterprise Owner 可在 admin 设置里整体关停。
- *GitHub 触发不生效* —— 必须在仓库上**安装 Claude GitHub App**（`/web-setup` 只管 clone 授权，不装 App、不开 webhook）。预览期 GitHub 事件还有每 Routine/每账号的小时上限，超量丢弃。
- *一切 Routine 行为都以"你"的身份执行* —— 提交、PR 是你的 GitHub 账号；Slack/Linear 等连接器动作走你绑定的账号。范围务必收到最小。

## 第六步：API 触发——把值守接进告警与 CI

API 触发是让 Routine "被外部事件叫醒"的开关。在 Web 上给 Routine 加 API 触发器，复制 URL、点 Generate token（**只显示一次**，丢了只能重新生成）。

触发示例（带告警正文）：

```bash
curl -X POST https://api.anthropic.com/v1/claude_code/routines/trig_01ABCDEFGHJKLMNOPQRSTUVW/fire \
  -H "Authorization: Bearer sk-ant-oat01-xxxxx" \
  -H "anthropic-beta: experimental-cc-routine-2026-04-01" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"text": "Sentry alert SEN-4521 fired in prod. Stack trace attached."}'
```

**预期结果**：返回新会话 ID 与可观看实时运行的 URL：

```json
{
  "type": "routine_fire",
  "claude_code_session_id": "session_01HJKLMNOPQRSTUVWXYZ",
  "claude_code_session_url": "https://claude.ai/code/session_01HJKLMNOPQRSTUVWXYZ"
}
```

`text` 是**自由文本不解析**——发 JSON 进去 Routine 也是当字符串收到。`/fire` 端点挂在 `experimental-cc-routine-2026-04-01` beta 头下，破坏性变更会换新日期头，最近两个旧头继续可用以便迁移。

**典型接线**：监控工具过阈值 → 调 `/fire` 传告警体 → Routine 拉堆栈、关联近期提交、开一个带修复建议的 draft PR → on-call 改 PR 而不是从空白终端起步。CD 流水线部署后调 `/fire` 跑冒烟检查、扫错误日志、在发布窗口关闭前给 go/no-go。

---

## 实战案例：三层联动的"夜间值守官"

目标：对一个真实仓库实现**全天候值守**——白天你在时用 `/loop` 盯现场，下班后脚本跑夜间批量审查，深夜云端的 Routine 在合上的笔记本上继续做文档漂移巡检。三者各司其职、互为兜底。

**A. 现场：会话内值守（本机，开着会话时）**

在仓库根目录放一个 `.claude/loop.md`：

```markdown
检查是否有失败的 CI run。若有，拉日志、定位根因、推一个最小修复到 claude/fix-* 分支；
有新评审意见就逐条回应。全绿则一行说明，不要发起任何 irreversible 操作。
```

开会话后输入 `/loop 10m`，它按这个提示词每 10 分钟巡一次（受 jitter 影响）。要离开就 `Esc` 停掉待触达，或 `claude agents`/后台会话把 `/loop` 任务带去后台会话继续跑。

**B. 夜间：脚本化批量审查（本机 + cron，需开机）**

把"对所有打开的 PR 做安全审查"写成脚本，靠 session 续跑让每条 PR 的上下文独立、可追加：

```bash
#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="$HOME/code/my-service"
cd "$REPO_DIR"

for pr in $(gh pr list --state open --json number -q '.[].number'); do
  # 每条 PR 一条独立会话，名字 = pr-<num>，方便事后 --resume pr-123
  session_id=$(gh pr diff "$pr" | claude --bare -p \
    --append-system-prompt "You are a security engineer. Review for vulnerabilities." \
    --output-format json \
    -n "pr-$pr" \
    "Review this PR diff for security issues. Be concise." \
    | jq -r '.session_id')

  # 同一上下文追加：把结论回写为 PR 评论
  claude --bare -p --resume "$session_id" \
    --allowedTools "Bash(gh pr comment *)" \
    "Post your findings as a single PR comment via gh." || true
done
```

交给系统 cron（macOS/Linux）或任务计划程序（Windows）每晩 23:00 跑一次：

```cron
# crontab -e
0 23 * * * /home/me/bin/nightly-review.sh >> /home/me/log/nightly-review.log 2>&1
```

> 这就是官方文档强调的"脚本抓 session_id、再 `--resume` 传回去"模式在批量场景的落地。注意脚本要 `--bare` 保证换机器一致、用 `--allowedTools` 收紧到 `gh pr comment *` 避免越权。

**C. 深夜：云端 Routine 做真·无人值守（机器关机也跑）**

```text
/schedule weekly scan for docs drift and open update PRs
```

在 Web 上把 Routine 的环境网络放行到你的文档站点域名、Connector 只留 GitHub，仓库选 docs 仓库。这样每周日凌晨，哪怕你笔记本合着，Routine 也会从默认分支 clone、扫描"引用了已变更 API 的文档"、开更新 PR 给编辑复审。它走的是云端全新 clone，不碰你本地未提交的东西。

**兜底逻辑**：B（脚本）需要开机；C（Routine）在云端，是 B 关机时的保险；A（`/loop`）只在你盯着时补位。三者各管一段窗口，构成 24×7 值守。

## 工作流总览

```mermaid
flowchart TD
    A[无人值守目标] --> B{机器是否开着?}
    B -- 关机/不可靠 --> C[云端 Routine]
    B -- 开机且开着会话 --> D["/loop + CronCreate<br/>(会话内值守)"]
    B -- 开机、可定时 --> E[桌面 cron + claude -p 脚本]

    C --> C1[触发器: Schedule / API / GitHub]
    C1 --> C2[Anthropic 云全新 clone 全自主跑]
    C2 --> C3[产物: claude/ 分支 PR]

    D --> D1[jitter/7天过期/仅空闲触发]
    D1 --> D2[.claude/loop.md 定制提示词]
    D --> D3[Esc 停止 或 --resume 7天内救回]

    E --> E1["首次 -p 抓 session_id<br/>后续 --resume 串联"]
    E1 --> E2[--bare + --allowedTools 收紧]
    E2 --> E3[--output-format json 核算成本]

    C3 --> F[PR / 评论 / 告警闭环]
    D2 --> F
    E3 --> F
```

```mermaid
sequenceDiagram
    participant User as 你(已下班)
    participant Cloud as 云端 Routine
    participant Repo as GitHub 仓库
    participant Alert as 告警/CI

    Note over User: 笔记本合上
    Alert->>Cloud: POST /fire (bearer token + 告警正文)
    Cloud-->>Alert: 返回 session_id + 会话 URL
    Cloud->>Repo: 从默认分支全新 clone
    Cloud->>Repo: 关联近期提交、定位根因
    Cloud->>Repo: 推最小修复到 claude/ 分支、开 draft PR
    Repo-->>Cloud: PR 链接
    Note over User: 次日打开会话 URL 复审 PR
```

## 延伸阅读

- 官方·定时任务总览：`code.claude.com/docs/en/scheduled-tasks`——`/loop`、CronCreate/CronList/CronDelete、jitter、7 天过期、cron 语法全集。
- 官方·编程式运行：`code.claude.com/docs/en/headless`——`-p`、`--bare`、`--resume` 续跑、`--output-format`/`--json-schema`、抓 `session_id`。
- 官方·会话管理：`code.claude.com/docs/en/sessions`——`--continue`/`--resume`/`--from-pr`、会话命名、transcript 落盘位置与脚本接口。
- 官方·Routines：`code.claude.com/docs/en/routines`——云端全自主 Routine、Schedule/API/GitHub 三触发器、`/fire` 端点。
- Channels（事件驱动，替代轮询）与 `/goal`（轮次驱动直到条件满足）文档，作为 `/loop` 的进阶替代。

## 训练营适用性评估

- **适合训练营**：中高级"DevOps 自动化 / AI 工程提效"训练营、企业内部"AI 研发流程改造"工作坊。
- **教学时长**：建议 4–5 课时。1 课时讲三层调度选型与会话续跑概念，1 课时做 `-p` + `--resume` 串联动手，1 课时配 `/loop` 与 `.claude/loop.md`，1 课时建云端 Routine 并接 API/GitHub 触发，最后 1 课时综合实战与排障。
- **前置衔接**：学员需先掌握 Round 1（安装配置）、`-p` 基础（Round 3/4 早期）。本教程承接"无头模式与批量"主题，把"批量"升级为"定时/事件驱动的无人值守"。
- **难度卡点**：会话作用域（session-scoped vs 持久化）与续跑目录范围是最易踩坑处，建议设专门的对照演示；云端 Routine 受套餐与 research preview 限制，无该套餐的学员可用桌面 cron + `-p` 脚本做等价练习。

## 参考来源

1. [Run prompts on a schedule — Claude Code Docs](https://code.claude.com/docs/en/scheduled-tasks) — `/loop`、CronCreate 与会话级调度、jitter、7 天过期的官方权威说明（v2.1.72+）。
2. [Run Claude Code programmatically — Claude Code Docs](https://code.claude.com/docs/en/headless) — `-p` 无头模式、`--bare`、`--resume` 续跑、抓 `session_id` 与 `--output-format json` 用法。
3. [Automate work with routines — Claude Code Docs](https://code.claude.com/docs/en/routines) — 云端 Routine 的 Schedule/API/GitHub 三触发器与 `/fire` 端点（research preview，2026-04-01 beta）。
4. [Manage sessions — Claude Code Docs](https://code.claude.com/docs/en/sessions) — `--continue`/`--resume`/`--from-pr`、会话命名与 transcript 脚本接口。
5. [Session Scheduling with Loop and Cron — AgentPatterns](https://agentpatterns.ai/tools/claude/session-scheduling/) — 第三方对 `/loop` 与 cron 动态间隔、Monitor 工具协同的实践补充。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
