团队 - 委派模式
Supervisor(主智能体)委派子智能体,适合“一次性找个专家帮忙”。用户仍然只和主智能体对话;主智能体在需要时调用一个临时子智能体,让它完成一个明确任务,再把子智能体的最终答案以 tool_result 形式取回。
这个模式适合:
explore子智能体:读取代码库并报告相关发现。plan子智能体:给出实现方案。review子智能体:检查一次 patch。implement子智能体:真正动手写代码,产出一个明确的 artifact,并汇报改了什么、如何验证。
这个模式中,子智能体只为一次请求运行,返回一个结果,然后由 supervisor 决定下一步。
import { agentTool, createAgent,} from "agent-lattice";
const explorer = createAgent({ apiKey: process.env.DEEPSEEK_API_KEY, baseURL: "https://api.deepseek.com/anthropic", model: "deepseek-v4-flash", name: "explorer", systemPrompt: [ "你是 explore 子智能体。", "检查仓库,找出相关文件,并输出简洁发现。", "不要修改代码。", ].join("\n"), workspace: ".agent-workspaces/explorer",});
const supervisor = createAgent({ apiKey: process.env.DEEPSEEK_API_KEY, baseURL: "https://api.deepseek.com/anthropic", model: "deepseek-v4-flash", name: "supervisor", systemPrompt: "你负责监督任务,并在需要时调用专门的子智能体。", tools: [ agentTool("explore", explorer, { description: "让一个临时 explore 子智能体检查代码库并报告发现。", }), ],});
const result = await supervisor.prompt("找出 SDK team delegation 涉及的模块。");console.log(result.result);当 supervisor 智能体用 mode: "ask" 调用 explore 工具时,SDK 会调用 explorer.prompt(...)。explorer 的最终结果会成为 supervisor 这一轮的 tool_result,然后 supervisor 继续自己的 agent loop。
agentTool() 把子智能体包装成一个普通工具——返回的就是一个 ToolDefinition,用法和任何自定义 tool 一样,丢进 createAgent 的 tools 即可。对 supervisor 模型来说,它和别的工具毫无区别;唯一的不同在内部:模型调用它时,SDK 不执行代码,而是转去运行被包装的子智能体,再把结果作为工具结果返回。
这个工具暴露给模型的是一套标准输入:
{ mode: "ask", task: "检查 SDK team runtime,并总结相关文件。", expectedOutput: "简洁的文件地图和实现笔记", acceptanceCriteria: [ "提到 runner 入口", "提到 mailbox 状态转换" ]}对于一次性 supervisor 委派,优先使用 mode: "ask"。
| 模式 | 在 supervisor 委派中的含义 |
|---|---|
ask |
立即运行子 AgentLike,并把它的最终答案作为当前工具结果返回。 |
handoff |
需要 team runtime。没有 runtime 时会返回明确错误。异步 handoff 应该使用 mailbox team。 |
observe |
预留给可观察长任务。当前除非宿主 runtime 提供支持,否则会报告 unsupported。 |
这里的 team runtime 指驱动 mailbox 持久团队的运行时——它维护消息队列、保存任务状态,并负责
handoff之后成员的生命周期。本模式是一次性委派,默认没有 runtime,所以handoff/observe基本用不上;需要它们时请改用 Mailbox Team 持久团队。
AgentToolOptions 还接收 metadata:一个宿主持有的 Record<string, unknown>,原样透传到生成的 ToolDefinition.metadata(例如契约版本)。SDK 不读也不解释它,也不会展示给模型。需要 0.22.0 及以上版本。
模板目标还是会话目标
Section titled “模板目标还是会话目标”需要 0.15.0 及以上版本。
agentTool() 的 target 既可以传存活的 AgentLike 会话(如上例),也可以传 defineAgent() 创建的 AgentSpec 模板:
import { agentTool, defineAgent } from "agent-lattice";
const explorerSpec = defineAgent({ apiKey: process.env.DEEPSEEK_API_KEY, baseURL: "https://api.deepseek.com/anthropic", model: "deepseek-v4-flash", name: "explorer", systemPrompt: "You are an explore subagent. Inspect and report; do not make code changes.",});
const supervisor = createAgent({ // ... tools: [ agentTool("explore", explorerSpec, { description: "Ask a temporary explore subagent to inspect the codebase and report findings.", }), ],});模板目标会在每次工具调用时 spawn 一个全新会话——不相关的任务之间不会泄漏历史,并发调用也不会争抢同一段对话。会话目标则跨调用保留历史,先前的任务可能影响后续回答。Supervisor 委派场景优先传模板;只有当专家需要记住之前的任务时,才注册 spec.spawn() 产生的会话。生成的工具描述会声明目标是哪种语义,supervisor 模型据此知道任务是否必须自包含。
结构化子级输出
Section titled “结构化子级输出”需要 0.20.0 及以上版本。
当子智能体的交付物应该是带类型的数据而不是一段散文时,在子级声明一份 OutputSchema(zod schema 直接可用):子 agent 必须通过注入的 submit_output 工具提交答案,父级一侧负责校验返回的内容。自 0.21.0 起 agentTool() 会从 target 的声明继承 schema——AgentSpec 走 spec.options.outputSchema,活 Agent 走 outputSchema getter——父级这份可以省略:
import { agentTool, createAgent } from "agent-lattice";import { z } from "zod/v4";
const findingsSchema = z.object({ files: z.array(z.string()), notes: z.string(),});
const explorer = createAgent({ model: "deepseek-v4-flash", name: "explorer", systemPrompt: "你是 explore 子智能体。检查并报告;不要修改代码。", outputSchema: findingsSchema,});
const supervisor = createAgent({ model: "deepseek-v4-flash", name: "supervisor", tools: [ agentTool("explore", explorer, { description: "让一个临时 explore 子智能体检查代码库并报告发现。", // outputSchema 自 target 继承(0.21.0+)。 }), ],});mode: "ask" 时,工具结果是子级校验后的结构化输出序列化成的 JSON 字符串,生成的工具描述也会告诉 supervisor 模型这一点。如果子级没有提交就结束了,或提交的内容没通过 schema 校验,工具会返回一条以 child_output_invalid: 开头的 is_error tool_result——这在 supervisor 的 loop 里就是一条普通的工具错误,supervisor 可以重试或换个说法再派。runtime delegate 路径同理:子级失败会抛 child_output_invalid,并带上原始的 failure code 和 message。
结构由 harness 把守,而不是靠 prompt 纪律;与 outputFormat 不同,它不依赖各 provider 的 response_format/json_schema 特性——任何支持工具调用的 provider 都能用(见 Provider 兼容性)。
契约继承与装配期校验
Section titled “契约继承与装配期校验”需要 0.21.0 及以上版本。
仍然可以显式传 AgentToolOptions.outputSchema,但它必须与 target 的声明一致——先按引用相等比较,再按派生 JSON Schema 的结构比较。不一致时 agentTool() 在装配期直接抛错,错误信息会建议在 createAgent/defineAgent 和 agentTool() 之间共享一个 schema 实例,或省略 agentTool() 这份直接继承。宿主自定义的 AgentLike 适配器没有可读的声明,因此对它们既不继承也不核对——显式传的 outputSchema 仍然生效。
自 0.23.0 起还固定了一种组合:target 未声明 schema、agentTool() 显式声明时,装配期放行(没有可核对的对象),ask 会把子级的 structuredResult 按父级这份 schema 校验后以 JSON 返回。这适合子级用自造的 endTurn + structuredResult 工具做 schema 之外的领域校验(如引用真实性)、契约由父级单方面声明的场景。
*0.21.0 行为变化:*子级声明了 outputSchema 而父级没声明的现存代码,ask 的工具结果从固定文本 "Structured output submitted." 变为校验后的 JSON。这是修复意图,0.x 阶段随 minor 发布。
无 schema 时 structuredResult 透出
Section titled “无 schema 时 structuredResult 透出”需要 0.23.0 及以上版本。
父子都没声明 outputSchema 时,如果子级带着 structuredResult 结束(经自定义 endTurn 工具),ask 的工具结果会原样返回它的 JSON——不做校验——而不是回退成文本 content 把它丢掉。信任等级与回文本相同;schema 的职责收敛为「校验」,不再是结构化通道的开关。直连路径和 team runtime delegate 路径都生效。
*0.23.0 行为变化:*现存「子级 endTurn 带 structuredResult、父级无 schema」的代码,ask 的结果从文本变为结构化 JSON。
Typed 委派
Section titled “Typed 委派”需要 0.21.0 及以上版本。
AgentToolOptions.inputSchema 把默认的 {mode, task, expectedOutput, acceptanceCriteria, workspaceGrants} 输入形状换成你自己的 schema,mapInput 负责把校验后的 typed 入参投影成子级 prompt:
const judge = createAgent({ model: "deepseek-v4-flash", name: "judge", systemPrompt: "你负责判案并提交结构化裁决。", outputSchema: verdictSchema,});
const judgeTool = agentTool("judge", judge, { description: "根据案情摘要和文档判案。", inputSchema: z.object({ caseSummary: z.string(), documents: z.array(z.object({ title: z.string(), content: z.string() })), }), mapInput: input => renderJudgeTask(input.caseSummary, input.documents),});父模型的入参先按 inputSchema parse,不合格当场作为 error tool_result 打回 supervisor 的 loop——与普通 tool() 的打回语义一致——子级不会被调用。inputSchema 和 mapInput 必须成对出现,缺一个在 agentTool() 装配期抛错。Typed 委派是 ask-only:没有 mode 字段,也没有 workspaceGrants。mapInput 可以返回 string 或 ContentBlock[],但 ContentBlock[] 只支持直连 ask 调用;在 team runtime 里投影出的 prompt 必须是 string,否则运行时报错。
Workspace
Section titled “Workspace”每个子智能体都有自己的 workspace。对于报告、日志、生成文件或代码等持久交付物,让子智能体写在自己的 workspace 下,并在最终文本里说明关键路径。
workspace 是可选的。不传时 SDK 会按智能体的 name 自动分配一个默认工作区 ~/.agent/workspaces/<name>/(没有 name 则用 agent-<sessionId>),并在首次运行时自动创建。大多数情况下直接用默认即可——它已经按智能体隔离,而且落在仓库目录之外,不会污染项目。只有当你想把产物放到指定位置(例如仓库内某个目录)时,才需要显式传 workspace,就像下面这样:
const reviewer = createAgent({ model: "deepseek-v4-flash", apiKey: process.env.DEEPSEEK_API_KEY, baseURL: "https://api.deepseek.com/anthropic", systemPrompt: "检查 patch,并把 review notes 写入你的 workspace。", workspace: ".agent-workspaces/reviewer",});什么时候用 mailbox team
Section titled “什么时候用 mailbox team”本模式里子智能体的交付物就是一段自然语言 tool_result(说明做了什么、产物在 workspace 的哪个路径、怎么验证)——没有持久状态、消息队列或结构化事件协议。
当工作需要留在团队里——持久状态、具名成员 mailbox、可回复/可跟进、可持久化,或需要嵌套团队——请改用 Mailbox Team 持久团队。一句话区分:Supervisor 委派是“现在调用这个 helper 拿一个结果”;mailbox team 是“把任务放进 mailbox,由成员按消息流完成并回报”,过程中还产出 team_message / team_agent 等结构化事件,供 tracing 和 UI 使用。