Agent Team 实现

配置、任务与运行分别管理

设计以具备分工、沟通和结果判断能力的 LLM 为基础,由 harness 让这些决策能够执行并被观察。产品原则与模型兼容边界见协调模型。

四组概念具有不同生命周期:

概念含义
AgentTeam 目录可复用的团队配置与专家角色。
频道成员列表会话可用的 agent;加入频道不会自动启动团队执行。
Runtime Team由 team_create 创建、由 team_dissolve 关闭的工作会话。
Member / Task / Run持久化成员拥有一个逻辑任务,可以执行多轮物理运行。

运行团队保持 active 时,已交付成员仍可被唤醒。持久化指身份和记录,不代表唤醒时自动恢复上轮完整对话。

聊天宿主与成员复用 agent loop

Agent Team — 服务端架构 ① setupTeamForLead() → team-registry { coordinator, execution } 单例 ② createTools(leadContext) 无 memberId → 按 Lead 角色执行 team_create team_dissolve team_replan team_status team_send_message ↓ Lead Agent (kind: "main") ⑤ createTools(memberContext) 有 memberId → 按 Member 角色执行 team_create team_dissolve team_replan team_status team_send_message ↓ Member Agent (kind: "member") ③ 状态 ③ team_create / team_replan / team_dissolve ⑥ team_send_message · 经 complete 交付 TeamCoordinator 团队协调器 任务依赖 消息路由 生命周期 自动解锁 TeamRepository PG / InMemory TeamExecutionService 团队执行服务 runAgentLoop prepareStep AbortController WS events consumeMessages UI ④ launchMember → memberContext Member A 共享沙箱 Member B 共享沙箱 Member C 共享沙箱 ⑦ 经 complete 交付 执行流程 (Execution Flow) ① setupTeamForLead → teamServicesRegistry.register(...) + ctx.team = {} ② runAgentLoop(leadContext) → createTools() → 同一套 5 个工具,按 Lead 角色执行 ③ LLM 调用 team_create → teamServicesRegistry.get() 查找 → coord 状态 + execution.launchMember ④ launchMember → memberContext.team = { memberId, teamId }(身份与运行控制) ⑤ runAgentLoop(memberContext) → createTools() 再次调用 → 同一套 5 个工具,按 Member 执行 ⑥⑦ 成员 → coord: team_send_message、team_status(snapshot);经 complete 交付

runChatTurn 构造 Lead 的运行环境、工具与 instructions。系统 Lead 拥有 team 工具且频道存在其他成员时,会获得 TEAM_LEAD_OVERLAY 与成员列表。宿主侧接线将服务注册到 teamServicesRegistry,并向上下文写入团队身份。

组件职责
team.tool.ts校验模型调用,将成员名称转换为内部身份。
TeamCoordinator持久化团队、任务、消息、交付与依赖状态变化。
TeamExecutionService启动独立的 runAgentLoop 成员运行,管理运行归属并处理退出。
team-wake-router.ts将事件转换为 Lead 或成员的唤醒请求和 UI 状态更新。
team-mailbox.ts将协调者收件箱正文注入 Lead 的逐步提醒。

成员执行独立于 TaskOrchestrator,使用 kind: "member"、TEAM_MEMBER_INSTRUCTIONS 和成员特化 instructions。Lead 与成员共享 workspace,但运行上下文和模型历史相互独立。任务说明应指定不同输出路径,避免并发覆盖。

当前双方都能看到五个 team 工具。成员调用 team_create、team_replan 或 team_dissolve 会被拒绝。成员工具集排除嵌套委派和直接向用户提问的工具;需要用户判断的问题经 Lead 转达。

创建时只启动依赖已满足的工作

以下示例假设工具成员列表包含所用 agent 类型。实际任务说明需要提供输入路径和验收标准。

{
  "name": "认证模块审查",
  "output_language": "Chinese",
  "members": [
    {
      "name": "Reviewer",
      "agentType": "general",
      "title": "审查认证边界",
      "prompt": "读取 /workspace/src/auth,审查会话过期与授权边界。将证据和发现写入 /workspace/auth-review.md,不修改源码。"
    },
    {
      "name": "Verifier",
      "agentType": "general",
      "title": "复核发现",
      "prompt": "读取上游审查和引用的源码,逐项复核,将报告写入 /workspace/auth-verified.md,区分已确认问题与不确定项。",
      "dependsOn": ["Reviewer"]
    }
  ]
}

team_create 单次接受 1–8 个成员,校验名称和依赖环,并为每个成员创建一个逻辑任务。这是创建调用的输入限制,不代表 team_replan.add 对团队累计成员数实施同样限制。

就绪任务进入 in_progress,启动动作延迟到 Lead 本轮提交后执行。依赖未满足的任务保持 blocked,不会启动模型运行。依赖完成后,任务变为 claimable,由成员运行时自动推进到 in_progress,模型无需调用 claim 工具。开始工作时记录所依赖的任务版本。

Lead 可以通过 team_replan 追加后来明确的工作,创建时无须预测完整流程。

事件推进工作,无需轮询

Agent Team — 生命周期 创建 → 分配 → 监控 → 解散 ① 创建 (Create) Lead 调用 team_create → Coordinator 创建团队 + 自动注册 Lead 成员 声明当前工作;就绪成员在 Lead 本轮结束后启动,依赖成员等待 → 客户端: initTeam(store) — Team Card出现在聊天流中 ② 分配 + 工作 (Assign + Work) 依赖来自 team_create 的 dependsOn → 自动解析: blocked → in_progress → completed 成员在上游完成后自动运行 → 使用工具执行 → 经通用 complete 工具交付 → 客户端: team:state-update 与 team:member-part 事件 ③ 监控 + 综合 (Monitor + Synthesize) 事件唤醒 Lead;team_status 立即返回,每轮最多一次 team_send_message 进行路线修正;综合所有结果产出最终交付物 → 客户端: updateTeam(store) — Team Card 静默刷新;内联显示 "状态已刷新" ack ④ 解散 (Dissolve) Lead 调用 team_dissolve → Execution 停止所有成员 (AbortController.abort()) 核对成员实际结果,关闭团队并标记为 "completed" → 客户端: 团队终态;持久化记录仍可读取

事件调度效果
消息唤醒接收者;运行中的成员可以在下一步读取。
任务完成唤醒就绪下游;没有就绪下游且没有任务处于 in_progress 时,唤醒 Lead。
任务失败或取消唤醒 Lead,处理恢复或决策。
团队解散通知 Lead。
任务创建、领取或普通成员状态变化更新状态,不仅为状态变化启动模型。

team_status 对双方都立即返回,每轮最多调用一次。它不是 long-poll;即使调用者仍在同一轮,并行执行也可能改变底层状态。

工具结果可能包含供 UI 使用的 teamId、成员 ID 和任务 ID。模型输入使用名称,不需要传入 teamId。状态响应中的任务状态位于成员的 work 内,成员状态与任务状态不能混用。

消息可以纠偏,也可以明确结束本轮等待

消息先持久化,再发送唤醒事件。唤醒事件延迟到发送者本轮结束;已在运行的接收者可能在此前就读取消息。因此,延迟唤醒不代表发送者整个回合具有事务性。

Lead 与成员在步骤开始前消费收件箱,将消息正文保留在接收消息的本轮提醒中。成员提醒还包含当前任务、修订要求和上游摘要及文件路径。

成员必须获得答复才能继续时,使用:

{
  "to": "Coordinator",
  "content": "需要验证哪个部署区域?当前进展已写入 /workspace/notes.md。",
  "wait_for_reply": true
}

该调用在工具步骤边界停止本轮,不完成也不判失败。不要在同一步同时调用 complete 或执行无关工作。普通消息不会停止发送者。Lead 用普通消息答复,后续消息可以启动成员的新一轮运行。退出补偿会检查清理期间到达的回复,避免回复被旧运行锁阻挡后无人处理。

本轮通过局部标记停止运行,正常结束后在现有运行记录中持久化 finishReason: "waiting"。重启与普通唤醒路径先检查最近完成的运行和未读消息;没有新消息时,已提交的等待继续保持。释放锁后再次检查,可处理判断期间到达的消息。逻辑任务仍为 in_progress,UI 可能继续显示为有未完成工作。记录提交前崩溃仍按中断运行恢复,当前也没有实现完整对话恢复或按问题匹配回复。

交付、修订与取消具有不同含义

成员在任务完成后调用 complete({ summary, paths })。简短结论可以使用 paths: []。任何提交路径无效时,交付被阻止,下游保持阻塞。有效交付会记录结果、刷新依赖并发送 task_completed,成功后结束成员本轮运行。

team_replan 支持三种操作:

  • add:以新名称创建成员并声明依赖,可以依赖已交付成员。
  • revise:使用原成员和任务身份重新打开已交付工作,并推进版本。已交付下游进入 stale,随后按依赖顺序重做。修订前,下游必须已经交付或取消。
  • cancel:取消未完成工作及依赖分支。失败根任务保留失败记录,未完成下游被清理。替代节点不会自动继承或转接旧依赖。

Replan 顺序执行,不是事务。名称、图和取消后依赖会在修改前校验,修订也会按调用顺序预演;导致后续操作失效的重复或相互影响的修订会在写入前被拒绝。并发变化或基础设施错误仍可能留下部分变更,重试前应先检查状态。

Lead 检查并验收结果,在没有后续工作时关闭团队,再最终交付。Lead 的 complete 不会自动关闭团队。用户 Stop/Clear 路径也会显式停止活跃成员。

六张表区分任务历史与执行历史

服务端定义 team、team_member、team_task、team_task_delivery、team_message 和 team_member_message。任务交付保留修订历史;成员运行记录物理轮次、触发原因、结束原因和用量。各宿主的仓储适配器实现共享核心契约。

进程内运行记录、唤醒锁、运行归属与心跳用于防止重复归属并支持清理。这些机制保障执行,不判断模型结果是否正确,也不合并冲突的文件写入。

客户端由工具结果初始化团队状态,team:state-update 传递任务与成员状态变化,team:member-part 传递成员流式内容,快照恢复用于重新打开历史会话。UI 事件是持久状态的展示,不是调度事实来源。

契约验证与模型质量分别评估

本轮针对团队服务和停止条件的回归套件共 60 项测试,覆盖消息正文注入、明确等待、SDK 循环停止、回复补偿、失败分支清理、已完成依赖和缺失产物拒绝。TypeScript 与格式检查通过。

这些是包含模拟模型的确定性验证,不代表真实模型的质量与成本已经得到验证。后续评测应覆盖独立工作、依赖交接、中途求助、相关修订、失败恢复,以及无需委派的简单请求。剩余边界见协调模型。

这页有帮助吗?