现有的任务分解博客讲了「拆成子任务」,但几乎没讲「这些子任务在时间维度上如何组织」——哪些必须串行、哪些可以并行、异步等待如何实现、中途失败了怎么从断点恢复。任务分解是空间维度的切分,时间维度的组织才是让 AI Agent 真正能够执行长线任务的关键。


一、AI Agent 的时间盲区:一个被忽视的根本问题

当你对 Claude Code 说「等 5 分钟后检查这个构建是否完成」,它会怎么反应?

大多数情况下,Claude Code 会回答「好的,我会检查」,然后立即执行检查,而不是真的等 5 分钟。这是因为 AI Agent 的推理是事件驱动而非时间驱动——它不知道如何在时间轴上「暂停」和「恢复」。

这种时间盲区在短任务里不是问题(立即执行就行了),但当任务涉及:

时间盲区就会变成一个严重的架构缺陷。

问题示例:构建并部署到测试环境

用户:"把这个服务部署到测试环境,然后等它启动完成后跑一套冒烟测试"

Agent 的实际行为:
  Step 1: 执行部署命令(docker-compose up -d)
  Step 2: 立即执行冒烟测试
  Step 3: 测试失败(服务还没启动完成)
  Step 4: 报告"部署有问题"
  
正确行为应该是:
  Step 1: 执行部署命令
  Step 2: 轮询服务健康检查,直到返回 200
  Step 3: 执行冒烟测试

这个问题不是模型的问题,而是Agent 架构没有对时间维度进行显式建模


二、时间推理的形式化定义

在讨论具体实现之前,先把「AI Agent 的时间推理」拆解清楚。

2.1 三种时间语义

AI Agent 需要处理三种不同的时间语义:

同步等待(Synchronous Wait)

Agent 执行某个操作后,需要等待结果才能继续:

执行:发送 HTTP POST 创建资源
等待:服务器返回 201 Created
继续:基于返回的 resource_id 执行下一步

这种等待是 Agent 内在的,不需要外部计时器——操作本身是阻塞的,结果返回后立即继续。这是最简单的时间语义。

异步轮询(Async Polling)

Agent 触发了一个长时间运行的操作(构建、部署、数据处理),这个操作不会立即返回结果:

触发:启动 CI 流水线(返回 pipeline_id)
轮询:每隔 30 秒检查 pipeline 状态
等待:直到 pipeline 状态为 success 或 failure
继续:根据最终状态决定下一步(成功则发布,失败则回滚)

这里 Agent 需要自己管理「时间」——维护一个轮询计数器/计时器,在每次检查之间插入等待逻辑。

延迟执行(Delayed Execution)

Agent 需要在未来的某个时间点执行某个动作:

触发:"明早 9:00 发送报告"
处理:记录任务到 todo list,附上触发时间
等待:外部调度器(如 cron)在 9:00 触发 Agent 执行

这不是 Agent 自己计时,而是 Agent 把「时间承诺」外部化到一个调度系统。

2.2 时间推理的三个核心能力

一个具备时间推理能力的 AI Agent 需要能够:

能力一:时序依赖建模
  → 把任务分解为时序图(哪些必须等哪些)
  
能力二:异步状态追踪
  → 追踪异步操作的中间状态,知道"现在在哪一步"
  
能力三:断点恢复
  → 在中途失败后,能够从最后一个已知状态恢复,而不是从头开始

三、长线任务的时序依赖图

3.1 从「任务列表」到「时序图」

大多数任务分解的输出是一个任务列表(有序或无序的待办项),但长线任务真正需要的输出是一个时序依赖图(Directed Acyclic Graph,DAG)。

两者的区别:

任务列表(平面视角):
  1. 初始化数据库
  2. 启动服务
  3. 运行迁移脚本
  4. 执行冒烟测试

时序依赖图(有向无环图):
         [初始化数据库] ──────→ [运行迁移脚本]
                │                      │
                ↓                      ↓
         [启动服务] ───────────→ [执行冒烟测试]
         
时序约束:
  - [运行迁移脚本] 必须等待 [初始化数据库] 完成
  - [启动服务] 必须等待 [初始化数据库] 完成(服务依赖数据库)
  - [执行冒烟测试] 必须等待 [运行迁移脚本] AND [启动服务] 都完成

时序依赖图的优势:可以发现可并行的子任务(如「初始化数据库」和「准备配置文件」可以同时进行),以及关键路径(决定总时长的最长链)。

3.2 时序图的 AI Agent 表示法

在 Shared Brain 或任务上下文中,用这种格式记录时序依赖:

## 📋 任务时序图

| 任务 | 依赖 | 可并行?| 预计时长 |
|------|------|---------|----------|
| init-db | - | ✅ | 10s |
| run-migrations | init-db | ❌ | 30s |
| start-service | init-db | ✅ | 5s |
| smoke-test | run-migrations, start-service | ❌ | 60s |

关键路径:init-db → run-migrations → smoke-test (100s)
可并行区域:init-db 执行期间,start-service 可以同时进行

当 Agent 把这个图发给人类确认后,人类可以调整依赖关系(例如「迁移脚本不需要等数据库完全初始化,边初始化边跑迁移」),这是人机协作的关键——AI 擅长建模,但最终决策需要人类拍板

3.3 时序冲突的检测与消解

AI Agent 在规划时序时常见的问题:

循环依赖(Cycle)

A 依赖 B,B 依赖 C,C 依赖 A
→ 无法开始,任何任务都没有起点了
→ 检测到后需要报告人类,让人类重新设计

隐式依赖(Missing Edge)

Agent 认为任务 3 可以和任务 1 并行
但实际上任务 3 的输出文件是任务 1 的输入
→ 任务 3 执行失败,返回"文件不存在"
→ 浪费了任务 3 的时间和 token

资源竞争(Resource Conflict)

任务 A 和任务 B 都需要数据库连接池
如果并发执行,连接池耗尽,两个任务都失败
→ 需要在时序图上标注"资源约束",强制串行

四、异步等待的三种模式

当任务包含异步操作时,Agent 需要选择合适的等待模式。

4.1 轮询模式(Polling)

适用场景:外部系统没有 webhook 回调,只能主动检查状态。

伪代码:
  start_time = now()
  timeout = 300  # 5 分钟
  interval = 30  # 每 30 秒检查一次
  
  while now() - start_time < timeout:
      status = check_async_status(pipeline_id)
      if status == "success":
          return Result(success=True)
      if status == "failure":
          return Result(success=False, reason="pipeline failed")
      sleep(interval)
  
  return Result(success=False, reason="timeout")

Agent 层面的实现:在 Shared Brain 中记录异步任务的起始时间和轮询历史:

## 🔄 异步任务状态

| 任务 ID | 状态 | 开始时间 | 最后检查 | 轮询次数 |
|---------|------|----------|----------|----------|
| pipeline-7821 | polling | 14:32:05 | 14:35:35 | 7 |
| deployment-x99 | pending-start | 14:30:00 | - | 0 |

轮询历史(pipeline-7821):
  14:32:35 - status=pending
  14:33:05 - status=pending
  14:33:35 - status=running
  14:34:05 - status=running
  14:34:35 - status=success ✓

4.2 超时回滚模式(Timeout with Rollback)

适用场景:异步操作超时后,需要回滚已执行的部分。

场景:部署新版本服务
  Step 1: 启动新版本容器(新版本 running)
  Step 2: 等待健康检查(超时 2 分钟)
  Step 3a: 健康检查通过 → 切换流量到新版本
  Step 3b: 超时 → 回滚(停止新版本容器,启动旧版本)

这个模式的关键是保持已执行步骤的记录,以及预定义回滚逻辑

## 🔙 回滚计划

步骤 1(已执行):启动新版本容器 container-v2
  回滚操作:docker stop container-v2 && docker start container-v1

步骤 2(进行中):健康检查
  超时回滚:执行步骤 1 的回滚操作

步骤 3(未执行):切换流量
  超时回滚:恢复旧版流量配置

4.3 事件驱动模式(Event-Driven)

适用场景:外部系统支持 webhook 或状态变更通知。

Agent 不主动轮询,而是:
  1. 注册 webhook 回调 URL 到外部系统
  2. 挂起当前任务,进入等待状态
  3. 外部系统在状态变更时 POST 到回调 URL
  4. Agent 收到回调后恢复执行

这种模式效率最高,但依赖外部系统支持。在企业微信的 Agent 场景下,可以利用企微的 webhook 回调作为事件源。

4.4 三种模式的对比

模式 适用场景 缺点 实现复杂度
轮询 无 webhook 支持的外部系统 浪费轮询资源,可能延迟检测
超时回滚 有部分成功概念的异步任务 需要维护回滚逻辑
事件驱动 支持 webhook 的系统 需要外部系统配合 高(但效率最好)

五、Checkpoint-Restore:让 Agent 从断点恢复

5.1 问题定义

AI Agent 在执行长线任务时,最大的风险是中途失败

场景:重构整个后端(预计 3 小时)
  Step 1-20: 顺利进行(1.5 小时)
  Step 21: Claude Code session 因为 token 限制被重置
  问题:Agent 失去了所有上下文,不知道从哪继续

传统的 Session 管理只保存「记忆文件」,但没有保存「任务执行状态」——Agent 不知道自己在整个任务流程中的位置。

5.2 Checkpoint 的结构设计

每个 Checkpoint 记录三个要素:

状态快照(State Snapshot)

## 💾 Checkpoint: task-refactor-backend @ Step 21/47

时间:2026-04-24 15:32:00
已完成的步骤:1-20(共 1.5 小时)
当前步骤:Step 21(迁移用户认证模块)

当前上下文:
  - 已修改文件:src/auth/*.ts (12个文件)
  - 待修改文件:src/billing/*.ts (8个文件)
  - 最后修改的代码片段:
    ```typescript
    // src/auth/jwt.ts:45
    // 正在处理 token 刷新逻辑的重构
    ```
  
未完成的决策:
  - 决定:是否要把 jwt.ts 里的 refresh token 逻辑独立成独立模块?
  - 状态:等待 Architect 确认

任务时序图(当前进度)

## 📋 时序图进度

✅ Step 1-20: 数据库 schema 更新、ORM 重构
🔄 Step 21: 用户认证模块迁移(进行中)
⏳ Step 22-35: 业务逻辑模块迁移
⏳ Step 36-40: API 层重构
⏳ Step 41-47: 测试与部署

待确认事项(Blocking Items)

## ⏸️ 阻塞项

- [ ] Architect 确认 jwt.ts 重构方案(等待中,挂在 Step 21)
- [ ] DBA 审批大表 ALTER(等待中,挂在 Step 15)

5.3 Restore 后的恢复流程

当 Agent 从 Checkpoint 恢复时,执行以下流程:

Restore 流程:
  1. 读取 Checkpoint 文件
  2. 重建当前任务状态(识别"我在哪")
  3. 检查阻塞项状态("什么东西在等我")
  4. 处理阻塞项(向人类确认 / 等待 webhook / 继续)
  5. 从最后一步的下一条指令继续执行

关键原则:
  - 如果阻塞项已解决(人类已确认 / webhook 已到达)→ 立即继续
  - 如果阻塞项未解决 → 报告状态并等待,不自行绕过
  - 永远不"猜测"之前执行的正确性,必须基于 Checkpoint 的记录继续

5.4 Checkpoint 写入的时机

不是每一步都写 Checkpoint,那样开销太大。写入策略:

Checkpoint 触发条件(满足任一):
  - 完成一个阶段性里程碑(每 5-10 个步骤)
  - 遇到需要人类确认的决策点
  - 执行了不可逆操作(如 ALTER TABLE、删除文件)
  - Token 使用量达到当前 Session 的 70%

Checkpoint 不写入:
  - 纯计算步骤(如遍历数据生成报告)
  - 简单的文件修改(不涉及架构变更)
  - 读取操作(不会改变任何状态)

六、工程实现:在 Shared Brain 中记录任务时间线

把时间推理能力集成到双脑协作的 Shared Brain 架构中:

6.1 扩展 Shared Brain 结构

在标准 Shared Brain 的基础上,增加时间推理相关的 Section:

## ⏱️ 任务时间线

### 当前任务:后端重构(总任务 47 Steps)

| 时间 | 事件 | 状态 | 备注 |
|------|------|------|------|
| 14:02 | 任务开始 | ✅ | 启动完整重构 |
| 14:35 | Step 20 完成 | ✅ | ORM 层重构完成 |
| 14:35 | 💾 Checkpoint #3 写入 | ✅ | |
| 14:35 | Step 21 开始 | 🔄 | 迁移用户认证模块 |
| 14:38 | 等待 Architect 确认 JWT 方案 | ⏸️ | 挂在 Step 21 |

### 异步任务追踪

| 任务 ID | 类型 | 状态 | 开始时间 | 预计完成 |
|---------|------|------|----------|----------|
| ci-pipeline-8821 | 轮询 | 🔄 polling (5/10) | 14:32 | ~14:42 |
| deployment-v2 | 等待健康检查 | ⏸️ blocked | 14:30 | 超时 14:32 |

### ⏸️ 阻塞项

- [ ] JWT 重构方案确认(Architect,挂了 3 分钟)
- [ ] CI 流水线状态(自动检查中)

### 🔙 回滚计划(当前任务)

已执行:启动 container-v2 回滚操作:docker stop container-v2 && docker start container-v1

已执行:切换流量到 v2 回滚操作:恢复 nginx upstream 配置指向 container-v1

6.2 Architect 的时间推理职责

Architect 在规划阶段就要考虑时间维度:

Architect 的输出(在标准 PRD 之外):

## ⏱️ 时间规划

总预计时长:3 小时(估算,置信度:中)

关键路径(决定总时长):
  init-db → run-migrations → smoke-test (100s 串行段)

可并行区域(理论加速比):
  init-db 执行期间,start-service 可同时进行 → 节省 5s

异步任务清单:
  - CI 流水线:触发后需要轮询,最长等待 10 分钟
  - 部署:健康检查超时 2 分钟,超时回滚

Checkpoint 计划(每 10 Steps 写入一次):
  - 位置:Shared Brain 的 ⏱️ 时间线 Section

6.3 Coder 的时间推理执行

Coder 在执行阶段需要:

Coder 执行规范:

遇到异步触发时:
  1. 立即将任务状态写入 ⏱️ 时间线 Section
  2. 选择适当的等待模式(轮询 / 事件驱动)
  3. 定期更新轮询进度(至少每 3 次轮询更新一次)
  4. 超时时触发回滚(如果已定义回滚计划)

遇到需要等待人类确认时:
  1. 写入 ⏸️ 阻塞项 Section
  2. 通知 Architect(写入 Coder → Architect 反馈)
  3. 不阻塞其他可执行的任务(如果有)

Checkpoint 写入:
  1. 完成阶段性里程碑时主动写入
  2. 不可逆操作前主动写入
  3. Architect 特别要求时写入

七、决策框架:什么时候需要时间推理

不是所有任务都需要时间推理能力。在决定是否引入这套机制之前,问自己三个问题:

问题 1:任务是否涉及异步操作?
  是 → 需要时间推理(选择轮询 / 事件驱动)
  否 → 不需要,可以立即执行

问题 2:任务的预计时长是否超过 30 分钟?
  是 → 需要 Checkpoint(防止中途失败从头开始)
  否 → 标准 Session 管理足够

问题 3:任务是否有不可逆操作?
  是 → 需要回滚计划 + Checkpoint(在操作前写)
  否 → 可以不需要回滚计划,但 Checkpoint 仍然建议保留

总结

AI Coding Agent 的时间推理能力,本质上是一套把「时间维度」显式建模的机制:

时间语义 Agent 行为 适用场景
同步等待 阻塞直到结果返回 HTTP 请求、数据库查询
异步轮询 定时检查外部状态 CI 流水线、长时间构建
延迟执行 外部化到调度器 定时任务、人类审批
超时回滚 计时器触发回滚逻辑 部署、健康检查
Checkpoint 周期性保存任务状态 所有超过 30 分钟的任务

没有时间推理能力的 AI Agent,在短任务里表现良好,但无法可靠地执行长线任务。时间推理不是模型的额外负担,而是架构必须提供的基础能力——就像传统的任务调度系统(Celery、Airflow)都需要时间维度管理一样。

当你下次给 Agent 一个「部署 + 等启动 + 跑测试」的任务时,先问它一个问题:「你能告诉我,现在任务进行到哪一步了吗?」

如果它无法回答,说明你需要的是时间推理,而不是更多的 Prompt 调优。


相关博客