委派模式

用四个 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

三个属性同时成立:

  1. worker 互相独立。 每份简历各自对照同一份 JD 评估。没有任何 worker 需要知道 其他 worker 的发现。32 个并行 job 之间从不交谈。

  2. 操作员在延迟临界路径 (latency-critical path) 上。 他每一秒等待都是被浪费的 人类注意力。这件工作必须并行——哪怕严格意义上并行比串行更贵,也得并行。

  3. 本次会话就是等待本身。 Jonathan 提交,agent 工作,结果落在同一个聊天会话里。 不存在”晚点再来”。不需要外部信号来唤起操作员。

这正是 task × N 的形态。Lead 在一次 assistant turn 里调 32 次 task(AI SDK 并发执行),每个 subagent 评一份简历,各自返回结构化评估,Lead 综合排序,操作员 看到结果。

如果改用 team 会失败成什么样

三个具体失败,都不是”还能跑,只是慢一些”那种:

  1. DB 写入只为仪式。 一个 team 会在 Postgres 里建 Team / TeamMember 行, 持久化任务记录,写 member 结果。对一份只跑 4 分钟的工作 32 个候选人来说,这是 几十到上百次 DB 写入——唯一目的是支撑这件工作根本不需要的异步生命周期。

  2. 推送通知打进有人值守的会话。 team 的价值在于操作员不在场时把信号推送出去。 Jonathan 就在屏幕前。一个他正盯着屏幕时弹出的通知是干扰,不是价值。通知通道有 有限的”信号 / 噪音预算”,在这里花掉,就让真正需要它的场景(3 和 4)留下更少的 额度。

  3. 同步流程上多套一层 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 的”性能开销”更有意思,是结构性的不匹配:

  1. team_message 写在协议里。 哪怕三个 reviewer 从不使用,系统对成员间消息 的可用性已经改变了工作的形状。member 2 的 prompt 里可能会出现”如果发现有意 思的点欢迎跟 member 1 协调”——交付物变了,变成”三个互相知道彼此存在的意见”。

  2. 异步交付破坏综合判断。 team 默认异步。如果技术负责人 2:35 到,架构师 2:42 到,工程经理 2:55 到,Jonathan 是一个一个读到的——他无法在 2:55 之前把 三份并排放好,而到那时他已经被前两份塑造了一个先入为主的 narrative。综合判断 的质量下降。

  3. 持久化没有意义。 三天后没有人会回查这份评估。工作产物是复盘决定本身。 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 的组合不一样:

  1. 操作员的会话生命周期 < 工作时长。 六周里 Jonathan 会关电脑约 30 次,有一周 出差完全不开 Zapvol。聊天会话会被销毁重建很多次。这件工作必须存活过每一次这样 的事件。

  2. push 是结构性的,不是可选。 没有 push,Jonathan 没办法”等”一个六周的流程。 系统隐形地跑着,如果它从不 ping 他,他不知道它找到了候选人。push 通道不是可选 特性——它是让长时长工作对人类操作员有意义的前提。

  3. 中途 steering 起作用。 第 2 周后,他看到三个后端候选人被推上来但都重 Python 轻 Go——他想要 Go-first。他敲:“对 Go 更严格。“team 通过给 worker 发 team_message 来支持这个——这条消息发出后评估的新候选人就会用收紧的 criteria。

如果改用 task × N 会失败成什么样

这里的失败不是”低效”,是结构性不可能:

  1. AI SDK stream 跑不了六周。 实际上受连接 / provider 超时 / 服务器重启限制, 最多分钟到小时。哪怕真能跑,把操作员的聊天会话阻塞六周是 category error—— Jonathan 这六周里还要用这个会话做其他所有事。

  2. 没有中途 surfacing。 task 要么 return 要么不 return。没有”跑到一半我找到 一个好候选人,先给你”这种消息机制。你只能让它早 return——但那样搜索就停了—— 所以 Jonathan 想要更多候选人时只能手工再发 task。他又回到”手工寻访一个寻访 请求”的循环。

  3. 没有中途 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 模块)LMSIT 账号已启用
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 会失败成什么样

  1. 同步模型不可能。 跟场景 3 同理——四周阻塞会话 absurd。

  2. 没有跨 task 依赖模型。 task 是”跑一个,return 一个”。可以靠等一个 return 再触发下一个来串联,但串联逻辑活在操作员的流程里,不在系统里。Jonathan 必须自己注意”新人 #2 的 IT 账号好了”,然后手工调 task 给他分配培训。他变成 协调者了。

  3. 没有基于阈值的 push。 task 要么成功要么失败。没有”这个 task 比预期慢, 通知操作员”这种机制。Jonathan 没办法表达”如果文书 72 小时还没签,告诉我”。

  4. 跨阶段跟踪活在操作员脑子里。 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 —— 异步团队协调,实现细节
这页有帮助吗?