子代理优先 · 主代理不下场
主代理的注意力属于用户,不属于任务。 凡是预计要跑很多轮的活,一律派给子代理后台去做;主代理只负责拆解、派活、验收、收口,始终保留随时响应用户的能力。
很多 agent 用得别扭,根因不是模型不够强,而是主代理被重活占住了:用户发一句话,主代理埋头跑二十轮工具调用,中间既不能应答、也不能改向,用户只能干等。等它终于抬头,需求可能已经变了。
本技能提供的是一套作业纪律——把"什么时候该派、怎么派、怎么验收"变成可判定的规则,而不是靠手感。纪律是平台无关的:任何支持子代理 / 后台任务的 AI Agent(Claude Code、Codex、Cursor、WorkBuddy、Hermes 以及其他同类工具)都适用,差别只在工具名——映射见本文档的「工具名对照表」一节。
落到具体平台时的实况差异:Hermes 的字段名、并发上限、后台语义与成本口径整理在
references/hermes-runtime-reality.md(示例实现,其他平台可忽略)。正文只讲纪律,不依赖那一页。
触发条件
出现以下任一情况,就应当按本技能做事(而不是顺手自己干):
- 任务预计超过 2–3 轮工具调用:例如"读 8 个文件再汇总""跑一轮检索再整理"。
- 一次要处理多个相互独立的单元:多文件、多目录、多 URL、多份数据、多个候选方案。
- 长研究 / 长搜索:需要反复检索、抓取、比对,耗时以分钟计。
- 批量处理:对一批输入做同样的一套操作(清洗、转换、逐条核对、逐条生成)。
- 用户明确要求并行或要求"同时做几件事"。
- 主代理正处在与用户的对话中间:用户可能随时追问、改需求、插新任务。
- 子任务彼此无依赖、可以同时开工:典型如"三份文档分别校对,最后合并结论"。
- 重活在后台跑的同时,用户还想继续聊别的(这是本技能最主要的收益场景)。
反过来的触发条件:如果一件事一轮工具调用就能做完,用户发完这句话就不再跟你说话——那自己做。硬派子代理只会更慢。判据见下一节的决策树。
核心原则
- 主代理不下场做重活。 主代理只做四件事:拆解 → 派活 → 收口汇总 → 跟用户对话。它必须保持"随时可应答"的状态。
- 重活必派子代理(强制)。 满足上面的触发条件就派,不许"我觉得我快我顺手做了"。判断标准是任务属性,不是主代理的自信程度。
- 自报不等于事实。 子代理说"已完成"只是它的说法;没有经过验证的产出,一律视为未完成(详见"验收清单")。
- 上下文必须自包含。 子代理看不到你与用户的对话历史。你脑子里的背景,它一个字都收不到。派活工单写不全,它一定跑偏——这不是它笨,是你没给。
- 并行有边界。 无依赖的活才并行;有先后依赖的活必须串行,或者把上游产出喂给下游。
- 需要用户拍板的不外派。 需要用户确认、需要承担不可逆后果、需要即时把关的,留在主代理手里。
- 跨会话长任务换机制。 需要活过本次会话的(持续监控、定时触发、常驻进程),用你平台的定时 / 常驻机制(定时任务、计划任务、常驻后台进程),不用子代理——子代理的生命周期跟一次委派绑定。
- 失败要降级,不要编造。 子代理失败、超时、产出不合格:降级自己动手,或换路径重派。绝不允许把"没拿到的结果"写成"拿到了"。
这套原则对应的是工程上公开的 fork-join / fan-out-fan-in 范式:把任务分叉给多个执行单元,再汇合结果(Java 的
ForkJoinPool、以及 Dean 与 Ghemawat 在 OSDI 2004 提出的 MapReduce 都是这一思想的具体实现)。本技能不发明新概念,只把它落成 agent 场景下可执行的作业纪律。
决策树:什么算重活,什么自己做
按顺序回答下列问题,第一个答"是"的分支就是结论。
第 1 问:这件事一轮工具调用能做完吗?
| 判断项 | 判据 |
|---|---|
| 工具调用次数 | 你自己数得出来,且 ≤ 1 轮 |
| 是否要读多个文件 | 否(0–1 个) |
| 是否有循环 | 否(没有"对每一个…") |
| 预计耗时 | 秒级 |
四项全部满足 → 自己做。 任何一项不满足 → 进入第 2 问。
第 2 问:这件事需要用户拍板吗?
- 需要用户在几个方案里选一个 → 自己做(或先只做信息收集,把选项摆给用户)。
- 涉及不可逆操作(删数据、对外发布、付款、发消息给第三方)且需要即时把关 → 自己做。
- 只是"需要用户知道",不需要用户在过程中做决定 → 可以外派,但汇总时要交代清楚。
第 3 问:这件事需要活过本次会话吗?
- 是(定时触发、持续监控、常驻服务)→ 用平台的定时 / 常驻机制(定时任务、计划任务、后台进程),不用子代理。
- 否,本次会话内跑完就行 → 进入第 4 问。
第 4 问:能拆成互不依赖的几块吗?
- 能 → 并行派多个子代理,各自归各自的文件 / 目录 / URL / 数据集,最后主代理合并。
- 不能,但有明确先后 → 串行派,或者单派一个子代理把整条链跑完(它也比你下场省事)。
- 拆不动、又不长 → 回到第 1 问再确认一次,多半是自己做。
量化速查表
| 活的性质 | 典型耗时 | 处置 |
|---|---|---|
| 查一下某个值、读一个文件的某段 | 秒 | 自己做 |
| 改一处文案、跑一条命令 | 秒 | 自己做 |
| 读 3 个文件并汇总 | 1–2 分钟 | 可做可派;用户正在等你时派 |
| 读 8 个文件、逐份摘要 | 数分钟 | 派 |
| 多源检索 + 交叉比对 | 数分钟到十几分钟 | 派(可分块并行) |
| 批量处理 N 个输入(N ≥ 5) | 随 N 增长 | 派(切片并行) |
| 需要用户从方案里选 | 不定 | 自己做(收集 + 摆选项) |
| 每天定时跑一次 | 跨会话 | 定时任务(不是子代理) |
五步流程
第 1 步:拆解
先把活切成边界清晰的单元。每个单元必须能独立回答三个问题:
- 输入是什么:具体到文件路径、目录、URL 列表、数据集名、参数。
- 产出是什么:具体到文件名、格式、路径。
- 怎么算做完:可判定的判据,不是"弄好就行"。
切分时守住两条:
- 写文件不能撞车:两个子代理绝不能写同一个文件。要么各自写各自的文件,最后主代理合并;要么串行。
- 依赖要显式:A 产出喂给 B 的,不能并行派——必须串行,或者让一个子代理把 A+B 都做掉。
完成判据(逐项打勾)
- 每个单元都写清了输入(含具体路径 / 列表)
- 每个单元都写清了产出(文件名 + 格式 + 存放位置)
- 每个单元都有可判定的完成判据
- 没有两个单元写同一个文件
- 所有依赖关系已标注(哪些必须串行)
第 2 步:派活
用你平台的子代理 / 后台任务工具把每个单元派出去(Hermes 下是 delegate_task,其他平台按「工具名对照表」映射),工单按"四要素"写(见下一节)。要点:
- 一个子代理只领一件边界清楚的活,别把三件不相关的事塞进一个工单。
- 工单里把背景写全——子代理看不到你与用户的对话。
- 明确告诉它产出落到哪个路径,以及要回报什么(文件路径?行数?命令输出?)。
- 明确要求它只回报经得起验证的东西:跑了什么命令、拿到了什么输出;没做到就直说。
- 如果平台支持结构化回报 / 输出校验(例如按 JSON Schema 校验子代理的最终答复)——能给结构化就别给自由文本。
完成判据
- 每个工单四要素齐全(目标 / 背景 / 产出结构 / 验收方式)
- 每个工单都指定了产出路径
- 每个工单都要求回报可验证的证据(命令 + 真实输出)
- 工单里没有"你懂的""照之前那样"这类残缺指代
第 3 步:并行调度
- 能并行的并行派:彼此无依赖的单元一次性派出去,别排队等。
- 有依赖的串行:等上游验收通过,再把它的产出作为下游工单的 context。
- 并行度要有上限:同时开太多会互相抢资源、也增加你汇总时的负担。一次三到五个是常见的舒服区间;再多考虑分批(超上限的后果各平台不同,见「工具名对照表」与平台实况页)。
- 派完立刻回到用户身边:不要站在原地等子代理。这正是本纪律的目的——用户在等你的时候,你应该是可应答的。
- 不要轮询、不要干等:委派调用应当立即返回,结果由平台送回;主代理在等待期间要能接住用户的新消息。如果你的平台默认阻塞,就把委派调用放进后台 / 异步模式再派。
- 给用户留一个现场控制口:平台若支持查看在跑的子代理、给某个子代理补纠正、提前终止并保留部分成果,用它;不支持就退化为"下一批工单里带上纠正"。
完成判据
- 无依赖的单元已同时派出(不是一个个排队派)
- 有依赖的单元已按顺序串行,且下游拿到了上游产出
- 并行度在可控范围(没有一次性铺开十几个)
- 派完后主代理没有阻塞等待,仍可响应用户
第 4 步:验收
这是最容易被跳过、也最不能跳过的一步。 子代理的"已完成"是待验证声明,不是结论。
按顺序验证(详见"验收清单"):
- 产出存在吗:文件真的在吗?路径对不对?读一眼真实内容。
- 产出合规格吗:格式、字段、行数、范围符合工单要求吗?
- 结论有证据吗:它声称的关键数字/结论,有没有对应的命令输出或来源?
- 原文抽查:随机抽 1–2 处,回到一手来源核对。
任何一条不过 → 按第 5 步的失败处置走。
完成判据
- 每个子代理的产出都用平台的读文件 / 执行工具真实回读过(Hermes 下是
read_file/terminal)- 格式与字段符合工单要求
- 关键结论有可追溯的证据
- 至少抽查过一处原文,与子代理的说法一致
- 失败/不合格的产出已明确标记,没有混进最终结果
第 5 步:收口
汇总给用户时,必须做到三件事:
- 标明来源:哪部分是子代理做的、哪部分是你自己做的。用户有权知道。
- 标明状态:哪些已验证、哪些未验证、哪些失败。不要用"大概""应该是"糊过去。
- 给下一步:需要用户拍板的地方明确摆出来。
失败处置(按优先级):
- 降级自己做——活其实不大,那就自己动手。
- 换路径重派——把失败原因写进新工单,换个方法再来一次。
- 拆分重派——工单太大导致跑偏,切小了再派。
- 如实上报——跑不通就跑不通,把卡点和已排除的路径讲清楚。不允许编造结果。
完成判据
- 汇总里标明了每部分的来源(子代理 / 主代理)
- 汇总里标明了每部分的验证状态
- 失败的活已处置(自己做 / 重派 / 如实上报),没有隐身
- 需要用户决定的事项已单独列出
- 没有一句未经证实却被写成事实的话
派活四要素
每个工单都必须包含这四样。缺任何一样,事故概率显著上升。
1. 目标(goal)—— 要做什么
一句话说清目标,用动词开头、结果导向。
- 好:
把 3 份 CSV 合并成一份去重后的 combined.csv,保留原始列顺序 - 差:
处理一下这几个文件
2. 背景(context)—— 为什么做、凭什么做(必须自包含)
这是四要素里最容易写崩的一个。 原因很简单:
子代理看不到你与用户的对话历史。它只知道你在工单里写了什么。你脑子里的背景——用户的偏好、之前踩过的坑、为什么不能用某个方案、数据的口径——它一个字都收不到。
所以 context 里必须显式写:
- 任务背景:这件事服务于什么目标,用户在意什么。
- 硬性约束:必须遵守的口径、格式、命名规则、禁止事项。
- 输入清单:具体的文件路径 / 目录 / URL / 数据集,不写"那几个文件"。
- 已知的坑:之前试过什么不行、哪里有陷阱、容易误解的地方。
- 环境信息:工作目录、可用的工具、依赖是否已安装。
自查方法:把工单单独发给一个完全不了解前情的同事,他能照做吗? 能,就算自包含。
3. 产出结构(output schema)—— 产出长什么样
把产出结构写死,避免回来还要你再加工一遍。
- 文件类:路径 + 文件名 + 格式(
markdown/json/csv)+ 必需的字段或章节。 - 报告类:要求回报的结构(结论 / 证据 / 来源 / 未解决项),而不是一段散文。
- 机器可读优先:能给
json就别给自由文本——省掉你二次解析的功夫。 - 平台若支持输出校验(按 schema 校验子代理答复),打开它;平台不支持就在工单正文里把结构复述一遍,并要求"照此结构回报"。
4. 验收方式 —— 怎么证明做成了
提前告诉它你要怎么验,它就会照着做;事后才发现没证据,只能返工。
- 要求回报真实执行过的命令与输出(而不是"我检查过了")。
- 要求产出路径可直接回读。
- 要求明确列出未完成/存疑的部分——主动交代比被你抓出来好。
四要素速查表
| 要素 | 一句话 | 常见缺陷 |
|---|---|---|
| 目标 | 要做什么,结果导向 | 太笼统:"整理一下资料" |
| 背景 | 背景 + 约束 + 输入清单 + 已知坑 | 只写目标不写背景,子代理自由发挥 |
| 产出结构 | 产出路径、格式、字段 | 没指定路径,产出散落找不到 |
| 验收方式 | 用什么命令/标准判定 | 无判据,靠"感觉还行"放行 |
验收清单
对每一个子代理产出,逐项过一遍。任何一项"否",就不算完成。
A. 存在性
- 产出文件真实存在于工单指定的路径(用平台的读文件 / 执行工具实测,不是只看文件名)
- 文件非空,内容不是占位符 / 模板残留 / 明显截断
- 如果是代码或脚本:能真的跑起来(不是"看起来对")
B. 合规性
- 格式、字段、命名符合工单要求
- 数量对得上(要 10 条就是 10 条,不是"大概 8 条")
- 没有越界:没改不该改的文件、没写工单之外的位置
- 并行任务之间没有互相覆盖(检查文件修改时间 / 内容完整性)
C. 真实性
- 子代理声称跑过的命令,有对应的真实输出
- 关键结论能追溯到具体来源(文件、URL、命令结果)
- 随机抽 1–2 处,回到一手来源核对,结论一致
- 没有"看起来很合理但找不到出处"的数字或论断
D. 完整性
- 工单要求的每一项都交了
- 未完成 / 存疑的部分被主动列出,而不是被藏起来
- 失败项有明确说明(错在哪、试过什么)
E. 汇总前的最后一道
- 我在给用户的答复里标明了来源与验证状态
- 我没有把子代理的"自报成功"当成"已完成"写进结论