委派模式
用四个 HR 场景画出 task 与 team 的边界
这篇文档要回答的问题
team 简化之后(4-5 个工具,member 的 initialPrompt 就是它的工作),task
(同步 subagent)和 team(异步 agent 团队)的表面 API 看起来非常接近:
task({ subagent_type, prompt }) ← Lead 调用,直接拿到结果
team_create({ members: [{ name, agentType, initialPrompt }] })
← Lead 调用,拿到 teamId,稍后再查状态
那么当一个 HR 操作员打开 Zapvol 说”做这件事”时,到底由哪个工具承载?
答案在工作本身里,不在工具里。下面四个场景都取自真实的 HR 实践,每个场景从四层 往下挖——什么触发了它、操作员真正想要什么、为什么对应的工具是对的、以及选错了 会具体失败成什么样。边界在最后自然浮现。
场景 1:简历筛选 — task
触发的瞬间
周二早晨 9:00。Jonathan 是 200 人 SaaS 公司的招聘官,打开 ATS 队列:昨夜进来 32 份简历,投的是开放中的高级后端工程师岗位。
10:00 有每日站会。他需要在站会前知道:今天下午要给谁打 30 分钟电话筛选。
他敲:
“把这 32 份简历对照 JD 筛一遍。排个序,前 5 名带上入选理由。“
Jonathan 真正想要的
不只是一个排名。他要的是入选理由——“5 年 Go 经验,前 Stripe,主导过支付限流器 重写”这种一行话——让他无需重读完整简历,就能在 30 秒内对每个候选人做出接受 / 拒绝 决定。
他希望 3-5 分钟内出答案。他不会离开屏幕。看完答案直接去安排电话筛选。
为什么这是 task
三个属性同时成立:
-
worker 互相独立。 每份简历各自对照同一份 JD 评估。没有任何 worker 需要知道 其他 worker 的发现。32 个并行 job 之间从不交谈。
-
操作员在延迟临界路径 (latency-critical path) 上。 他每一秒等待都是被浪费的 人类注意力。这件工作必须并行——哪怕严格意义上并行比串行更贵,也得并行。
-
本次会话就是等待本身。 Jonathan 提交,agent 工作,结果落在同一个聊天会话里。 不存在”晚点再来”。不需要外部信号来唤起操作员。
这正是 task × N 的形态。Lead 在一次 assistant turn 里调 32 次 task(AI SDK
并发执行),每个 subagent 评一份简历,各自返回结构化评估,Lead 综合排序,操作员
看到结果。
如果改用 team 会失败成什么样
三个具体失败,都不是”还能跑,只是慢一些”那种:
-
DB 写入只为仪式。 一个
team会在 Postgres 里建 Team / TeamMember 行, 持久化任务记录,写 member 结果。对一份只跑 4 分钟的工作 32 个候选人来说,这是 几十到上百次 DB 写入——唯一目的是支撑这件工作根本不需要的异步生命周期。 -
推送通知打进有人值守的会话。 team 的价值在于操作员不在场时把信号推送出去。 Jonathan 就在屏幕前。一个他正盯着屏幕时弹出的通知是干扰,不是价值。通知通道有 有限的”信号 / 噪音预算”,在这里花掉,就让真正需要它的场景(3 和 4)留下更少的 额度。
-
同步流程上多套一层 indirection。 不是直接返回,而是
team_status长轮询。 一样的数据,多了 round-trip,多了失败模式(心跳 / 超时 / 重连)。纯增成本。
“操作员可能离开”这个假设在这里根本不适用。他明明就在那里。team 的异步机制 是为不存在的问题付费。
这揭示了 task / team 的什么设计约束
task 是对的工具,当且仅当操作员的注意力本身就是等待。 决定性的属性不是
“worker 少”或”工作短”——这些都是结果。决定性的是:操作员没有为离开预留任何
时间。任何异步机制都有成本;只在操作员的离开是真实的时候才花这个成本。
场景 2:多角度笔试评估 — task
触发的瞬间
周四下午 1:30。Jonathan 招聘 pipeline 里有一个强候选人进了那个后端工程师岗位的 终面。他刚交了笔试题:实现一个限流器,带具体语义(滑动窗口、分布式、fail-open)。
3:00 PM 是终面复盘。他有 90 分钟。他要三个独立角度评这份笔试:
- 技术负责人 —— 设计选型、正确性、是否处理了边界 case
- 架构师 —— 可扩展性假设、系统思维
- 工程经理 —— 代码质量、问题分解、README 里的沟通能力
他敲:
“找三个 reviewer 各自从一个角度评这份笔试题:技术负责人、架构师、工程经理。 给我三份独立评估。“
Jonathan 真正想要的
三个垂直的角度,不是共识。 矛盾才是信号:如果技术负责人说”优雅”,架构师说 “上不了 1k QPS”,他就学到了一个具体的点,可以在复盘里追问。
这要求三个 reviewer 在提交前彼此看不到对方的评估。一旦交流,他们就会收敛—— 而收敛出的中庸意见,价值远低于三个清晰的独立意见。
他希望 2:55 三份都到手,并排放好,识别共识与分歧,3:00 主持复盘。
为什么这是 task
跟场景 1 一样:短、并行、操作员在等。但这个场景的深度分析要更进一步——它有一个 属性主动要求 task 而不是 team:
worker 之间的独立性本身就是交付物。 三个 reviewer 各自独立的读,比三个 reviewer 协调后的读更有价值。工作的形状是”三个封装的过程产生三份读后感”。
task 给的就是这个:三次 subagent 调用,各自有 scoped sandbox,无共享状态,无进程
间通信。独立性是被架构强制的,不是靠约定。
如果改用 team 会失败成什么样
这里的失败比场景 1 的”性能开销”更有意思,是结构性的不匹配:
-
team_message写在协议里。 哪怕三个 reviewer 从不使用,系统对成员间消息 的可用性已经改变了工作的形状。member 2 的 prompt 里可能会出现”如果发现有意 思的点欢迎跟 member 1 协调”——交付物变了,变成”三个互相知道彼此存在的意见”。 -
异步交付破坏综合判断。 team 默认异步。如果技术负责人 2:35 到,架构师 2:42 到,工程经理 2:55 到,Jonathan 是一个一个读到的——他无法在 2:55 之前把 三份并排放好,而到那时他已经被前两份塑造了一个先入为主的 narrative。综合判断 的质量下降。
-
持久化没有意义。 三天后没有人会回查这份评估。工作产物是复盘决定本身。 team 的 DB 记录为一次性决策永久存活。
这揭示了 task / team 的什么设计约束
多 worker ≠ team。 task 和 team 的分水岭不是 worker 数,而是:
- worker 之间独立:
task - worker 之间协调:
team
team 的 team_message 在”协调是价值”时是特性(研究员告诉撰稿人”我找到一个关键
数据,你用上”)。在”独立是价值”时则是 liability——三个对同一份产物的封装
reviewer 就是这种情况。某些场景的工作质量,靠架构禁止协调来保障。task 是其中
一种。
场景 3:多岗位长期寻访 — team
触发的瞬间
周五下午 4:00。Jonathan 看着自己手上三个开放的工程岗位:
- 高级后端工程师(已开 2 周,还没有可接受的候选人)
- 高级前端工程师(已开 3 周)
- 平台工程师(已开 1 周)
每个目标 6 周关闭。手工做意味着每天 5 小时左右——寻访、触达、资质审核。他这个季度 还有六个大项目,每周根本拿不出 25 小时做寻访。
他敲:
“接下来六周,对这三个岗位在 LinkedIn 持续做寻访。按每个岗位的 JD 做预筛。 只推给我匹配度 75% 以上、且初次触达有正向回应的候选人。有合适的就 ping 我。“
Jonathan 真正想要的
一个在后台跑六周的系统,只把值得他花时间的候选人推到他面前。具体来说:
- 每日持续 LinkedIn 寻访
- 按 role-specific JD 做候选人资质审核
- 对合格候选人做初次触达,看响应
- 过滤到 ≥75% 匹配 + 初次响应成功
- 通过他实际的通知通道通知他(浏览器推送、邮件,什么渠道都行)
- 跨过他关电脑、跨过周末、跨过第 3 周的出差
- 中途允许他调整 criteria:“对后端的 Go 经验更严格些”——这条新规则下一轮就应该 被 worker 读到,不用他重新设置整个流程
为什么这是 team
三个属性,但跟 task 的组合不一样:
-
操作员的会话生命周期 < 工作时长。 六周里 Jonathan 会关电脑约 30 次,有一周 出差完全不开 Zapvol。聊天会话会被销毁重建很多次。这件工作必须存活过每一次这样 的事件。
-
push 是结构性的,不是可选。 没有 push,Jonathan 没办法”等”一个六周的流程。 系统隐形地跑着,如果它从不 ping 他,他不知道它找到了候选人。push 通道不是可选 特性——它是让长时长工作对人类操作员有意义的前提。
-
中途 steering 起作用。 第 2 周后,他看到三个后端候选人被推上来但都重 Python 轻 Go——他想要 Go-first。他敲:“对 Go 更严格。“team 通过给 worker 发
team_message来支持这个——这条消息发出后评估的新候选人就会用收紧的 criteria。
如果改用 task × N 会失败成什么样
这里的失败不是”低效”,是结构性不可能:
-
AI SDK stream 跑不了六周。 实际上受连接 / provider 超时 / 服务器重启限制, 最多分钟到小时。哪怕真能跑,把操作员的聊天会话阻塞六周是 category error—— Jonathan 这六周里还要用这个会话做其他所有事。
-
没有中途 surfacing。 task 要么 return 要么不 return。没有”跑到一半我找到 一个好候选人,先给你”这种消息机制。你只能让它早 return——但那样搜索就停了—— 所以 Jonathan 想要更多候选人时只能手工再发 task。他又回到”手工寻访一个寻访 请求”的循环。
-
没有中途 steering。 task 的
prompt在调用时定死,中途不能改。第 2 周 收紧 criteria 意味着 kill 当前 task 再起一个新的——丢掉 worker 已经积累的所有 状态。
这揭示了 task / team 的什么设计约束
team 是对的工具,当操作员的会话生命周期有限,但工作没有。 会话与工作的解耦,
是 team 在结构上的核心贡献。push 通道则是让这个解耦对人类有价值的环节——
没有 push,工作就在后台跑完并消失在沉默里。
如果 push 还没接通(浏览器通知、邮件、Slack 都没有),team 就退化成”task 加更 差的体验”。push 不是特性,是承重的。
场景 4:5 人入职批次 — team
触发的瞬间
周五下午 5:00,长周末前。下周一来 5 个新人:
- 2 个工程(一个前端,一个平台)
- 2 个产品(PM)
- 1 个客户支持
每个新人有大约六个入职阶段:
| 阶段 | 责任方 | 依赖 |
|---|---|---|
| 1. 入职文书(录用函、I-9、福利) | HR + 候选人 | — |
| 2. IT 配置(笔记本发货、账号配置) | IT | 文书已完成 |
| 3. 工位(工位、门禁卡、停车位) | 后勤 | 录用函签了 |
| 4. 主管见面会 | 直属主管 | 入职第 1 天 |
| 5. 角色相关培训(LMS 模块) | LMS | IT 账号已启用 |
| 6. 30 天回访 | Jonathan | 日历 |
5 个新人共 30 个待跟踪项,跨四周。有些是每个新人内部顺序,有些是跨新人并行。 Jonathan 是 HR 协调员,这个月还有 30 件其他事。
他敲:
“给这 5 个新人安排入职,周一开始。跟踪每个人的六个阶段。只在阻塞点或里程碑触 及时告诉我,其他时候不用跟我说。“
Jonathan 真正想要的
周五一次性把 5 个 pipeline 都设好,然后让系统自己跑。每个新人按自己的节奏推进 ——有的快,有的慢,取决于候选人响应速度、IT 物流时间、主管的日历。
只在以下情况通知他:
- 阻塞点(文书 3 天没签)
- 里程碑(30 天回访明天到了)
- 异常(培训已分配,但 1 周内没开始)
其他时候保持沉默。他还有 30 件别的事;他不想看到”FYI 新人 3 的笔记本发货了”这种 零增量信息。
为什么这是 team
场景 3 的三个属性都在,还多了一个,而且这一个反而是主导:
跨阶段的依赖关系。 阶段 5(培训)要求阶段 2(IT 账号启用)先完成。系统必须 知道这件事,在阶段 2 报告完成前 hold 住阶段 5,然后自动推进——不需要 Jonathan 介入。
team 的 coordinator 正是这个形状:任务可以声明 dependencies,状态机推进 pending → blocked → claimable → in_progress → completed,下游任务在前置完成时 自动 unblock。
乘以 5 个新人,就是一个跨周的 30 项任务依赖图。这种形状下,team 不是”可选工具”, 而是唯一能干净建模这个形状的 primitive。
如果改用 task × N 会失败成什么样
-
同步模型不可能。 跟场景 3 同理——四周阻塞会话 absurd。
-
没有跨 task 依赖模型。 task 是”跑一个,return 一个”。可以靠等一个 return 再触发下一个来串联,但串联逻辑活在操作员的流程里,不在系统里。Jonathan 必须自己注意”新人 #2 的 IT 账号好了”,然后手工调 task 给他分配培训。他变成 协调者了。
-
没有基于阈值的 push。 task 要么成功要么失败。没有”这个 task 比预期慢, 通知操作员”这种机制。Jonathan 没办法表达”如果文书 72 小时还没签,告诉我”。
-
跨阶段跟踪活在操作员脑子里。 5 新人 × 6 阶段 = 30 项,Jonathan 等于在头脑 里运行一个状态机。这正是协调系统的存在意义。
这揭示了 task / team 的什么设计约束
team 的真正贡献是流程编排,不是并行执行。 场景 3 看起来像 team 是因为时长 + push。 场景 4 看起来像 team 是因为跨阶段依赖。
操作员的角色从执行者(task:我等你做完)切换到监督者(team:我看着一个 系统在跑这个流程,只在异常时干预)。当系统的价值在协调上——当”X 完成 → 触发 Y” 是核心动作——task 在结构上就不够用了。team 的 coordinator 正是为这种形状设计的。
边界,提炼一下
两个问题,依次问,可以决定上面所有场景的归属:
问题 1:操作员会留在屏幕前等结果吗?
| 答案 | 工具 |
|---|---|
| 会——他在屏幕前,结果落下来前不会离开 | task |
| 不会——他的会话生命周期短于工作时长 | team |
场景 1 和 2 是会。场景 3 和 4 是不会。时长是结果,不是原因:工作短允许等, 工作长通常不允许。但时长是表象,在场状态才是因。
问题 2:worker / 阶段之间需要协调吗?
| 答案 | 工具 |
|---|---|
| 不需要——独立性是价值的一部分,或无所谓 | task |
| 需要——X 完成 → 触发 Y,或成员之间要共享发现 | team |
场景 1 和 2 是不需要。场景 3 和 4 是需要。只有”多 worker”不能区分两个工具, “协调与否”才能。
两个问题答案不一致时怎么办
通常它们方向一致。少数情况下不一致时,问题 2 胜:
-
“一周内筛 30 份简历”(问题 1 说 team,问题 2 说 task)→ 还是 task。独立并行 工作不会仅仅因为操作员没盯着每一秒就需要 team 的开销。
-
“3 个 worker 在 5 分钟内协调”(问题 1 说 task,问题 2 说 team)→ 还是 team。 协调需求是结构性的,无法在
task × N里模拟出来。
工作的形状决定工具的程度,比操作员的日程更大。
模糊地带场景
“根据 200 个销售线索的 LinkedIn 资料,给每个人草拟一封个性化开场邮件。”
worker 独立(问题 2 说 task)。时长约 30 分钟——Jonathan 可以等也可以去开会 (问题 1 模糊)。
默认走 task;操作员明确说”我要走,跑完通知我”才升级到 team。
如果 Jonathan 对”这会跑 30 分钟”的回应是”OK,我等”,task 合适。如果是”OK, 跑完告诉我”,team 合适。提交时可以携带这个意图(一个 flag、一句话、一次显式选择), 但默认应该是 task。理由:对任何中等长度并行批处理默认走 team,会让通知通道 一直处于触发状态,把每次批处理都搞得像 deployment 一样。通道的”信号 / 噪音预算” 有限,要为场景 3 和 4 留着,不是为”我草拟了一些邮件”留着。
当前要诚实承认的限制
team 只暴露简单形态。 每个 member 的 initialPrompt 就是它的工作,member
完成则结束。上述场景 3 和 4 正好就需要这个形态——不需要池模型,不需要从队列认领。
member 从共享池抢动态任务的高级模式在 coordinator 代码里就绪,但工具未暴露。上述
四个场景里没有一个需要它。
Push 通知通道。 team 的结构性价值生死系于 push 投递——浏览器通知、邮件、Slack。 没有 push,场景 3 和 4 会变成”沉默的系统,没人发现它在跑”。架构层面已经准备好接 push;接到各投递渠道是独立的工作线,也是 team 真正可用的前提。
注意力流动场景 (attention-fluid)。 操作员有时一开始盯着,中途又走开。当前 task 还是 team 的选择在提交时锁定。上面”模糊地带场景”段就是这一点的可见代价。
接下来读什么
task.md—— 同步 subagent 委派,实现细节agent-team.md—— 异步团队协调,实现细节