三层机制非阻塞任务管理器
作者:荷叶 & 灵溪
仓库:https://github.com/colinxu1-sys/nonblocking-tasks
核心价值
安装此技能后,AI 的主会话永远空闲,不管后台跑什么任务都能秒回新消息,所有操作一律 spawn 子 agent 处理,不会因任何任务而被阻塞。
触发条件
安装后首次对话自动触发配置。
当用户发送任何消息时,激活此技能并检查配置状态。如果 active_tasks.md 不存在或配置未完成,立即执行安装后配置。
安装后首次对话自动配置
安装此技能后,AI 在收到用户的第一条消息时,自动执行以下配置步骤:
- 检查
<workspace>/active_tasks.md 是否存在,不存在则创建
- 检查
<workspace>/HEARTBEAT.md 是否存在,不存在则创建
- 检查 Cron 任务是否存在,不存在则创建心跳监控任务(每2分钟)
- 在
<workspace>/AGENTS.md 中查找「后台任务执行规范(非阻塞原则)」章节,用三层机制替换
- 在
<workspace>/MEMORY.md 中查找「非阻塞长任务处理规范」章节,用三层机制替换
配置完成后通知用户:"三层机制非阻塞任务管理器配置完成,已生效。"
核心:三层机制
所有通道、所有用户、所有任务统一执行以下三层机制。
第一层:主会话永远空闲
核心原则:默认全部 spawn,主会话只做即时响应。
主会话唯一职责:
- 接收消息
- 立即回复"收到了,后台处理"
- 立即 spawn 子agent
- 持续可用
所有读取操作,全部 spawn:
- 读文件、读日志、读聊天记录、读配置
- 搜索文件(grep/rg/find)
- 理解上下文需要读取多处文件
原因: 读本身也可能很慢。AI会误以为自己读得快,结果花了很长时间。荷叶的真实案例:让它读聊天记录,它以为自己读得快,结果花了很久才回来。
判断标准:不用判断时间长短。所有读取操作,一律 spawn。
主会话只做两件事:接收消息 → 立即响应。
任何涉及写入的操作,全部 spawn:
- 编辑文件(write/edit)→ spawn
- git 提交推送 → spawn
- 创建目录/移动文件 → spawn
- 运行脚本/命令 → spawn
- API 调用(curl/wget)
- 文件搜索(find/rg/find)
- 编译构建
- 量化回测
- 论文抓取
- 任何不确定耗时的操作
绝对禁止在主会话里执行的操作(无论时间长短):
- exec git push/pull/fetch/clone → 必须 spawn
- exec npm/pip install/yarn → 必须 spawn
- exec curl/wget/网络请求 → 必须 spawn
- exec 任何可能超时的命令 → 必须 spawn
- exec 编译构建类命令 → 必须 spawn
原因: 网络不稳定时,这些操作可能阻塞主会话数分钟,导致用户发消息 AI 无响应。这是执行纪律问题,不是时间判断问题。任何网络请求、git 操作、可能超时的命令,一律 spawn,不在主会话里执行。
第二层:新消息触发立即评估
规则:收到新消息时,无论主会话当前在做什么,立即中断评估这条消息。
评估流程:
- 这条消息和当前任务相关吗?
- 相关 → spawn 一个处理新消息的子agent,主会话立即响应"收到了,正在处理"
- 无关 → 立即回复,2秒内完成
- 消息是独立新任务吗?
- 是 → 立即 spawn,主会话立即响应
- 否 → 合并到当前任务
核心改变: 不再排队等待。新消息来了立即处理,不需要等上一个任务完成。
第三层:主动推送取代被动查询
规则:子 agent 完成后,不等用户来问,立即主动把结果发给用户。
执行标准:
- 子 agent 完成了 → 立即发飞书/企微通知用户
- 任务超过 30 分钟无进展 → 主动告知当前状态
- 真正卡住需要用户决定 → 才通知用户提供选项
禁止的行为:
- 等用户问"任务完成了吗?"才汇报 ❌
- 批量回复多条碎片消息 ❌
- 让用户主动查询进度 ❌
沟通补充原则(任务接收标准话术)
核心:站在B的角度接任务,不是站在A的角度要求A怎么做。
B(AI)接到任务时,根据任务性质主动向用户确认关键信息:
- 评估后认为需要确认的才问,不是所有任务都问一遍
- 优先确认时间节点:"什么时候要?"
- 根据时间调整执行方式:
- 5分钟内要 → 请最快的分身/专家,集中火力
- 1天内要 → 可以做更完整,加更多分析
- 1周后要 → 排期规划,逐步汇报
- 重要任务确认标准:"交付结果长什么样你才满意?"
示例话术:
- 简单任务:"收到,马上处理,X分钟后给你结果。"
- 复杂任务:"这个需要调研,大概X小时。我先开始,有结果第一时间通知你。"
- 时间紧迫:"5分钟要?好,我只做核心部分,结果不完整你能不能接受?"
关键:让用户清晰知道什么时候能拿到什么,同时我执行也有方向。
执行前同步计划原则
核心:执行前先说计划,让用户知道我要做什么。
接任务后,不要直接埋头做,而是先告诉用户:
"我要做三步:①… ②… ③…,完成后通知你。"
然后开始执行,执行过程中按计划节点汇报进度(不用等结果出来,每完成一步就可以简短同步)。
为什么这个重要:
- 用户知道我在干什么,不用等结果时才惊讶
- 如果计划有问题,用户可以提前纠正,不用等我做完才发现方向错了
- 减少了"读了很久没反应"的焦虑感
判断标准(是否需要同步计划):
- 1-2分钟能完成的简单任务 → 可以直接做,做完再汇报
- 需要多个步骤或超过5分钟的任务 → 先说计划再执行
- 不确定的任务 → 先问清楚再执行
示例:
- 简单:"收到,我去检查配置,2分钟后告诉你结果。"
- 复杂:"这个需要三步:①检查网络配置 ②测试各数据源连通性 ③修复问题。每步完成我会简短同步。预计15分钟。"
任务追踪:active_tasks.md
每次 spawn 子 agent 时,写入 <workspace>/active_tasks.md:
## 任务名
开始时间:YYYY-MM-DD HH:MM
状态:进行中
已通知:否
重试次数:0
备注:任务描述
子 agent 完成后:
- 验证结果为真
- 通知用户
- 通知成功 → 更新状态为「已完成」,已通知改为「是」
- 通知失败(如 API 超时)→ 保持「已通知=否」,已通知保持「否」,重试次数+1
通知失败重试机制(核心修复):
子 agent 通知用户失败时(如 WeCom/飞书 API 超时):
- 不立即放弃,在 active_tasks 里标记「已通知=否」+「重试次数=N」
- cron 心跳在检查「进行中」任务的同时,也检查已完成但「已通知=否」的任务
- 对「已通知=否」的任务:
- 重试次数 < 3 → 重新发起通知,重试次数+1
- 重试次数 >= 3 → 标记「已通知=失败」,进入「持续重试模式」
- 持续重试模式:即使 3 次都失败,仍每隔 30 分钟重新尝试通知,直到真正成功
- 成功后将「已通知」改为「是」,状态改为「已完成」,退出持续重试模式
心跳检查(每 2 分钟,默认开启)
读取 active_tasks.md,检查所有任务状态:
- 开关配置:在 HEARTBEAT.md 顶部添加/删除
状态:已关闭 即可开启或关闭
- 夜间(23:00-06:00):静默,回复 HEARTBEAT_OK
- 日间(06:00-23:00),<30 分钟:正常跑,不打扰
- 日间,>30 分钟无进展:主动查状态
- 确认完成 → 更新状态 + 立即通知
- 真的卡住 → 通知用户提供选项
- 正常跑 → 回复 HEARTBEAT_OK
通知失败补救检查(每次心跳必执行):
- 扫描 active_tasks 里所有「已通知=否」的任务
- 重试次数 < 3 → 重新发起通知,重试次数+1
- 重试次数 >= 3 → 标记「已通知=失败」,进入持续重试模式
- 对「已通知=失败」的任务 → 每隔 30 分钟重新尝试通知,直到成功
连续消息处理
收到连续多条消息时:
- 修订前一条 → 合理调整
- 补充新信息 → 合并处理
- 独立新任务 → 单独 spawn
禁止:没有上下文的"处理完成"碎片回复。
安装后自动配置
安装此技能时,自动执行以下步骤:
步骤 1:更新 active_tasks.md
写入/更新 <workspace>/active_tasks.md:
# 进行中任务追踪
<!-- 格式:
## 任务名
开始时间:YYYY-MM-DD HH:MM
状态:进行中 / 已完成
备注:任务描述
-->
步骤 2:更新 HEARTBEAT.md
写入/更新 <workspace>/HEARTBEAT.md:
# HEARTBEAT.md
## 每次心跳必须执行:长任务进度检查 + 通知失败补救
读取 `<workspace>/active_tasks.md`,检查所有任务状态。
**夜间(23:00-06:00):**
回复 HEARTBEAT_OK(不打扰)
**日间(06:00-23:00),进行中任务超过 30 分钟未完成的:**
自己主动去查状态(检查文件或 spawn 查证)
确认完成了 → 自动更新 active_tasks.md 为「已完成」→ 立即通知用户
确认真的卡住了 → 才通知用户提供帮助
任务还在正常跑(<30 分钟)→ 回复 HEARTBEAT_OK
**通知失败补救检查(每次心跳必执行):**
扫描 active_tasks 里所有「已通知=否」的任务:
- 重试次数 < 3 → 重新发起通知,重试次数+1
- 重试次数 >= 3 → 标记「已通知=失败」,进入持续重试模式
- 对「已通知=失败」的任务 → 每隔 30 分钟重新尝试通知,直到成功
**核心原则:只有真正需要用户做决定的事才通知用户。**
步骤 3:创建/更新 Cron 任务
如果 Cron 任务 "nonblocking-task-monitor" 不存在,则创建:
- 名称:nonblocking-task-monitor
- 调度:
*/2 * * * *(每 2 分钟)
- 时区:Asia/Shanghai
- 目标:isolated session
- Payload:读取 active_tasks.md,执行上述心跳检查逻辑
- Delivery:announce 到飞书
步骤 4:更新 AGENTS.md
在 AGENTS.md 的「后台任务执行规范(非阻塞原则)」章节中,用上述三层机制完整替换旧内容。
步骤 5:更新 MEMORY.md
在 MEMORY.md 的「非阻塞长任务处理规范」章节中,用上述三层机制完整替换旧内容。
跨通道召回:按需触发
除自动召回外,当用户主动提及跨通道历史时,立即执行按需召回。
触发条件: 用户提及另一个通道的讨论内容或任务时
识别逻辑:
- 用户说"飞书那边..."、"企微刚才..."、"钉钉让我..."
- 用户说"你还记得..."、"刚才说过..."
- 用户请求查另一个通道的内容或进度
- 任何暗示信息来自另一个通道的表达
执行流程:
- 识别目标通道和相关内容
- 读取
~/.openclaw/memory-tdai/conversations/YYYY-MM-DD.jsonl
- 召回该用户在目标通道的今日对话
- 注入上下文,继续处理
发布
此技能可发布到 GitHub 公开仓库,用户通过 clawhub 或 openclaw skills install 安装使用。
更新日志
v1.3.0(2026-04-03)
v1.2.9(2026-04-03)
- 新增:沟通补充原则,任务接收时主动确认时间节点和交付标准
v1.2.8(2026-04-03)
- 强化:通知失败后进入「持续重试模式」,每隔30分钟重试直到真正通知成功
- 彻底解决"石沉大海":无论何种故障,最终必定通知到用户
v1.2.7(2026-04-03)
- 修复:子 agent 完成后通知失败不补救的问题
- 通知失败时在 active_tasks 标记「已通知=否」+「重试次数」
- cron 心跳增加检查:已完成但「已通知=否」→ 最多重试3次
- 解决场景:WeCom/飞书 API 超时导致通知丢失,任务看似完成但用户不知道
v1.2.6(2026-04-02)
- 新增:绝对禁止在主会话里执行网络/git/编译类操作(无论时间长短)
- 明确 exec git push/pull、npm install、curl 等必须 spawn
v1.2.5(2026-04-02)
- 新增:安装后首次对话自动触发配置,确保用户安装后效果一致
v1.2.4(2026-04-02)
- 心跳监控支持开关配置,可在 HEARTBEAT.md 中开启或关闭
v1.2.3(2026-04-02)
v1.2.2(2026-04-02)
- 明确复杂读取也需 spawn,主会话不被阅读操作阻塞
v1.2.1(2026-04-02)
- 细化规则:写操作(edit/write/git)全部 spawn,主会话只做纯读
v1.2.0(2026-04-02)
- 新增:跨通道身份识别规则,支持多通道用户身份映射
- 解决飞书/企业微信等独立 session 导致的历史记忆丢失问题
v1.1.0(2026-04-01)