第 13 章 从串行到异步 · Agent架构实操十三 开始测验

从串行到异步:慢操作填坑指南

npm install 要几分钟,Agent 像被暂停。问题不在等待本身,而在等待期间能否完成别的工作。本章:工具调用通过校验/审批后,先返回后台占位,完成后通过 typed runtime event 回到同一 Loop。
⏱ 约 14 分钟 🔄 后台 job 📥 EventInbox +background

🎯 学习目标

学完能答
  • 后台化改变的是「谁等待结果」还是「谁拥有权限」?
  • run_in_background 三态(true/false/null)分别什么决策?
  • 为什么后台提交必须在权限之后,不能先创建 worker 再补权限?
  • EventInbox 传递什么?能接收普通字典或伪 tool result 吗?
  • 后台只后台化了哪个工具?Cron/teammate/后台subagent 在范围内吗?
  • 工具执行顺序在后台下变了几条?

🧠 核心概念

点击展开。
1 · 后台改变「谁等待」,不改变「谁拥有权限」

第12章 Task DAG 描述「要做什么」,不替你执行慢命令。第13章增加生命周期:工具调用通过参数校验、Hook、权限和审批后,先返回后台占位,完成后通过 typed runtime event 回到同一 Loop。

工具执行顺序仍只有一条 PreToolUse → 硬权限/审批 → 同步分发后台提交 → PostToolUse → 追加恰好一个匹配的 tool result。后台只改变「谁等待结果」,不改变「谁拥有权限」。
2 · 显式参数是三态

只有 P13 主 Agent 的 shell schema 增加 run_in_background;P01-P12 和一次性 subagent 仍只看到 command。

输入决策
true强制后台
false强制同步,即使命中慢命令关键词
null 或省略才使用启发式

启发式只判断慢命令关键词(cargo build/npm install/pip install/pytest 等),不预测任意命令耗时。concurrency:"background_eligible" 是第二道门,没该标记的工具永远直接执行。

3 · 为什么提交必须在权限之后

AgentRunner 唯一工具执行点:先解析 JSON+Zod,再 Pre Hook+PermissionPolicy,最后才调可注入的 ToolDispatcher。Dispatcher 拿到的是 Hook 改写后、权限审查过的 PreparedToolCall。

禁止软边界 把 worker 提前创建再补权限会留竞态:拒绝结果还没返回,副作用已经开始。正确顺序:Pre Hook 阻断→不创建job;权限拒绝→不创建job不启动executor;权限通过后→容量检查→持久化running→登记worker。
4 · 五个角色的责任边界
角色责任不负责
BackgroundDispatcher判断同步/后台,提交已获批调用不做权限判断,不重放原始JSON
JobSupervisor持有worker,控制容量/超时/取消/关闭/终态不充当Task DAG
query/cancel_background_job按job_id查询/取消持久化后台job不暴露给subagent与P01-P12
EventInboxFIFO传递typed RuntimeEvent不接收普通字典或伪tool result
JsonBackgroundJobStoreworkspace内原子保存job状态不盲目重放崩溃前未知副作用

三个关键细节:①终态由 finishRunning 条件迁移仲裁——谁先写进磁盘谁定终态,晚到一方拿到 undefined 安静跳过发事件,「只发一次」靠磁盘状态不靠内存标记;②刻意不做进度事件:3 分钟每秒报一次=180 条 user 消息吃光上下文,模型想知道进度就调 query_background_job 查一次——拉取优于推送;③崩溃恢复把遗留 running 迁移为 interrupted(error_code=background_interrupted)且幂等:连续崩 5 次,模型也只收到一份中断通知。

5 · 范围:只后台化 PowerShell

本章只后台化 P13 主 Agent 的 PowerShell 工具。Cron、持续 teammate、后台 subagent、输出流文件、交互式提示看门狗不在范围内(后续章节)。

Task、TODO、Hook、权限、恢复、记忆、动态 Prompt 和上下文压缩全部保留,不复制第二套 Loop。同样刻意不做的:排队(容量满直接报 background_capacity,否则「提交成功」变成谎言)、抢占式取消(JS 杀不死 Promise,协作式发信号+等+超时报错)、自动重试。P13 的后台任务本质是 Promise 不是子进程——架构可平移,换的只是 BackgroundOperation 内部实现。

▶️ 交互演示:同步 vs 后台

对比同步阻塞和后台执行:后台job先返回占位,主循环继续干别的,job完成后通过 EventInbox 回到 Loop。

🔑 一句话总结

后台只改变「谁等待结果」,不改变「谁拥有权限」——提交必须在权限之后

QA 测验