第十五节 子任务与后台执行

复杂任务往往需要把工作拆给"子助手"。AVL Code 内置子任务调度能力,支持前台同步与后台并发两种模式。

15.1 派发子任务

助手在对话中可以调用一个「子助手」工具,把一段提示词派给独立的子任务执行,子任务完成后把结果合并回主对话流。这一过程对你是透明的,但你可以在工具调用卡片里看到每个子任务的详情。

15.1.1 子 Agent 继承外部 MCP 工具

派出去的子 Agent 自动继承你在工作区配好的外部 MCP 工具(之前子任务用不到这些外接工具,得回到主对话才行):

  • 机制:派发时经 /admin/routes + /admin/backends 解析本工作区所有外部后端的工具前缀(如 notion / memory / channels 等命名空间),通过环境变量 ZAGENT_MCP_INHERIT_PREFIXES 注入;子 Agent 的 ZAGENT_ALLOWED_TOOLS 白名单无条件穿透这些前缀。
  • 覆盖范围:所有声明了 tools: 的子代理(plan / assess / prepare / mcp-admin 与用户自建);所有工作模式统一(含 plan)。
  • fail-safe:解析失败 → 返空 → 不继承,不影响子任务正常派发。

15.1.2 子任务模型 / 供应商匹配修复

之前在多供应商配置下,派出去的子任务沿用父会话的模型,但供应商恒取列表里的第一个,两者对不上时会报「模型不存在」起不来。本版改为供应商跟着继承的模型走 — 优先选真正包含该模型的那个供应商,子任务能稳定启动。

15.1.3 并行 fan-out:一次拆多路同时跑

除了一次派一个子任务,AI 还能用 AgentParallel 工具把一个任务一次拆成 2–16 条「腿」同时跑,每条腿是独立的 fresh-context 子 Agent、互不可见,全部完成后自动汇总结果返回。适合需要多路并发的活(如同时审好几个模块、并行检索多个来源),比一个个排队串行快很多。

  • 每条腿各自带提示词、可单独指定子代理类型与模型;提示词需自包含(腿看不到主对话历史)。
  • 并发上限 16 条(远低于后台任务总并发 64,单次 fan-out 不会霸占全部槽位);不足 2 条请改用单个 Agent
  • 整体等待超时默认 600 秒、上限 1800 秒;到时未完成的腿返回 pending 并在后台继续,可用 TaskWait / TaskOutput 续跟。
  • 单条腿失败 / 被拦不会拖垮整批,失败原因会一并随结果返回让 AI 自行处置。每条腿输出过长会截断(提示用 TaskOutput 取全文)。
  • 执行期就能看到实时状态:并行子任务的调用卡片在执行期间即出现(不必等终态才冒出来),并实时反映各子任务的运行状态;停止后不再持续转圈,极简密度下结果块也不会被误折叠。

15.2 前台 vs 后台

  • 前台:主助手等待子任务完成(默认 10 分钟超时),适合"必须等结果"的任务。
  • 后台:子任务异步运行,主助手立刻得到一个任务编号,后续可主动拉取状态或停止该任务。后台任务有总数上限(防失控)和自动回收(终态超时清理)。

15.2.1 「空闲制」看门狗 + 绝对兜底

子任务超时改成「按空闲计时」:只要还在持续产出就不算超时,看门狗只针对真的卡住、长时间无任何输出的情形。再叠加一道绝对兜底(默认 60 分钟),防止极端死循环 / hang 把任务永远留在跑的状态。

  • 空闲窗口:默认 15 分钟无输出 即超时(错误信息会明确写「子 Agent 空闲超时」)。
  • 绝对上限:默认 60 分钟 强制结束(写「绝对兜底」)。
  • 正常长任务不受影响:只要还在 stream 产出(包括思考段、增量字符)就一直续命。
  • RunAgentToolBackground 后台路径不计执行超时(你显式把它放后台跑就接受它跑久)。

15.3 并发上限

为防止一次发起过多后台任务造成失控,AVL Code 会限制同时在跑的子任务数;超出后助手会被告知"先稍等再发起",避免雪崩。

15.3.1 阻塞等待 — TaskWait 工具

主助手可以「一次调用、阻塞等待」后台任务 / 子代理跑完,不用再一轮一轮反复查询进度:

  • 支持等「全部完成」或「任一完成」。
  • 可设超时(默认 5 分钟、最长 30 分钟);到点会如实返回「还在跑」让模型决定是否继续等。
  • 等待期间只回状态与最终结果,不把中间过程灌回主对话,省上下文也更省 token。

15.4 终止

  • 在桌面端,点击输入框右侧 停止 按钮会同步终止主助手与所有派生子任务。
  • 在微信侧,发送 /stop 同样会触发级联终止。
  • 子任务也能单独停止:子代理抽屉里每个正在跑的子任务都有独立的停止按钮,不必整轮一起停(对后台 / 并行 fan-out 的腿尤其方便;同步内联的子代理需停整轮)。

15.4.1 真实总消耗看得清(含子代理)

用量统计会把子代理(并行 / 子任务)的真实消耗也算进来:目标条(GoalStrip)与每轮结束的标识都显示真实总 token 消耗 + 工具调用次数,有子代理时还会拆出「自身 + 子代理」的构成。该统计按会话持久化,长会话看到的是全程真实总量(即使没设目标也照常累计)。

15.5 输出聚合

后台任务的中间日志可作为独立卡片在主对话流里展开查看;任务完成后会以一段精简摘要返回,避免淹没主线索。

15.5.1 AI 建议任务:一键拆分去做

AI 干活时如果顺手发现了分外但值得做的事(死代码、过期文档、确认存在的 TODO、安全隐患等),会在消息流里挂出一张「建议任务」卡片,而不是打断当前正事。

卡片上的执行按钮是个 split button

  • 主按钮一键:默认「开启新会话执行」。
  • 展开 ▾ 还有 4 种方式:
    • 新会话中执行(主按钮默认)
    • 当前会话中执行
    • 复制到输入框
    • 复制到剪贴板

由你来决定怎么处置。已执行的建议会标记状态,AI 也可以撤回已经过时的建议。多条建议会聚合到输入框上方的一个条里统一管理。

15.6 例行程序:让 AI 按计划自动干活

「例行程序(Routine)」让你给某个工作区定一条指令,让 AI 按时自动按需手动执行 — 比如每天早上拉取并总结昨日 issue。

新建入口

  • 工作区侧栏「新建例行程序」一键打开对话框(也支持从 Header 当前工作区进)。
  • 表单字段:名称、指令内容、执行模式、模型(与正常对话同款选择器:模式色卡说明、模型搜索分组)、计划时刻。
  • 写到一半自动暂存 — 中途跳去设置或 Agent 管理器调配置,回来自动重开并恢复已填内容。

计划方式

类型 行为
每小时一次(hourly) + 指定分钟 在每小时该分钟点触发一轮;复用 HH:MM 字段但只看分钟,小时锁 00、触发器显示 :MM
每天 / 工作日 / 每周某几天 + 指定时刻 到点自动触发一轮
不设计划(手动) 不自动跑;保存后立即触发一轮,按钮显示「运行一次」;之后需要时再点立即运行

时刻选择顺手

  • 时 / 分双列下拉(选中居中、选完分钟自动收起);每小时一次模式下只露分钟列
  • 周几用圆形单字字块,附「工作日 / 周末」一键预设
  • 调度精度:30 秒 tick;hourly 跨日 / DST 用时间算术天然正确

统一管理

设置 → 例行程序 Tab 按来源工作区分组:

  • 启停开关(与其它设置页同款)
  • 立即运行
  • 查看最近运行痕迹
  • 未打开的工作区有徽标提示并可一键打开
  • 侧栏图标直达本工作区的例行程序列表
  • 支持按名称 / 工作区搜索

运行行为

  • 每次运行会在对应工作区生成正常会话,过程与结果都可回看。
  • 同一条例行程序运行中会自动跳过下一次触发,不会叠跑。

15.7 长程任务崩溃后可恢复

放到后台跑的长任务(即以 run_in_background 派发的子任务),其进度会实时落盘保存;应用意外退出 / 被杀 / 崩溃 / 升级打断后重新打开,能把没正常结束的任务找回来接着干,不必从头再来。

它怎么工作:

  • 每个未结束的后台任务都以一份快照写到本机(跨工作区的全局目录);任务正常走到 done / error / killed 终态时会删除该快照。所以重开后还留在盘上的,就是上次被中断、没跑完的任务。
  • 启动时会异步扫描这些残留任务,先做一次「脏条目清理」——父会话已不存在、再也无法恢复的条目自动删掉;扫描不阻塞启动,没有残留就静默无感
  • 恢复并不是直接重启子进程,而是往原来的父会话里注入一句「之前委派的后台任务尚未完成,请继续或重新委派」,让主助手以「先派发」的方式接着完成——这一步对你可见,你能看到「正在恢复任务 X」。

你会看到什么(恢复横幅):

  • 有被中断的任务时,顶部出现一条恢复横幅,标题形如「N 个后台任务上次被中断」;没有就不显示。
  • 每条任务旁有两个按钮:恢复(,注入续跑消息并从盘上移除该条)/ 忽略(从盘上删除,下次不再提示)。右上角还有「全部忽略」。
  • 恢复成功后弹 toast「已恢复:将在原会话继续该任务」;失败则提示具体原因(如「原会话已不存在,已清除该恢复项」)。

自动恢复(可选,默认关):

  • 设置 → 智能体 → 自省 打开「自动恢复被中断的任务」开关,重启后会自动接着跑上次崩溃 / 被杀时未完成的后台任务,适合夜间无人值守的长任务。
  • 为防「续跑消息风暴」,启动自动恢复每次最多 5 个,其余仍留在顶部横幅供手动恢复。
  • 关闭该开关时(默认),所有被中断的任务都只在顶部列出,由你手动决定恢复或忽略。