执行型子 Agent
探索器收集信息。执行器会根据它采取行动。
这两个角色的分工沿着委托分开的线条划分,就像委托分开了Agent本身一样。探索成本低廉,只读且流量大。执行成本更高,可能修改文件,且需要更强的模型,因为出错的成本更高。
执行器从父 Agent那里继承信任。父 Agent决定执行器可以做什么,执行器严格按照指令操作,两个角色都不会向用户提出任何要求。这就留在父 Agent里。
学习成果
任务工具中的第二个分支会生成一个执行器子 Agent,包含read、grep和委托模式bash,使用claude-sonnet-4-6和15步预算。父 Agent现在可以在委派时选择探索器或执行器。
快速路径
- 用
subagentType: "explorer" | "executor"场扩展task工具schema - 添加一个执行器分支,使用更强的模型、更大的步长预算和委托模式的bash
- 更新描述,使路由对父 Agent清晰可见
动手练习 6.3
添加执行器角色并从task工具中路由到它。
要求:
- 将
subagentType添加到任务工具的输入 schema中,作为"explorer" | "executor"枚举,默认为"explorer" subagentType === "executor"后,实例化一个包含read、grep和委托模式的ToolLoopAgent``bash- 执行器使用
claude-sonnet-4-6和stopWhen: stepCountIs(15) - 用
createApproval({ mode: "delegated", trust: [...] })建立执行器的bash,通过一个小型信托名单("npm test"、"npm run build"、"npx tsc") - 更新任务工具描述,向父 Agent解释这两个角色
实现提示:
- 执行器需要自己的
bash工具,并支持委托模式的审批。不要重复使用父 Agent的互动式攻击,因为互动模式会暂停给提示词执行器无法回答的用户 - Sonnet是执行器工作的正确默认选择。Opus对大多数实现任务来说是大材小用,速度慢到让人感觉不到
- 信任名单故意较小。执行器应只运行父 Agent认为安全的命令。测试运行器和构建命令通常是安全的。软件包安装和迁移则不是
执行器分支
export function createTaskTool(
sandbox: Sandbox,
parentTools: { read: any; grep: any },
) {
return tool({
description: `Delegate work to a subagent.
Explorer (default): read-only research with a fast model.
Executor: implementation with a stronger model and delegated trust on bash.
WHEN TO USE: research across many files (explorer), bulk implementation (executor).
WHEN NOT TO USE: ambiguous requirements (use askUser),
architectural decisions (the parent decides).`,
inputSchema: z.object({
description: z.string().describe("Task instructions for the subagent"),
subagentType: z
.enum(["explorer", "executor"])
.default("explorer")
.describe("Subagent role"),
}),
execute: async ({ description, subagentType }) => {
if (subagentType === "executor") {
const executorBash = createBashTool(
sandbox,
createApproval({
mode: "delegated",
trust: ["npm test", "npm run build", "npx tsc"],
}),
);
const executor = new ToolLoopAgent({
model: "anthropic/claude-sonnet-4-6",
instructions: `You are an executor agent. Follow instructions precisely.
Working directory: ${sandbox.workingDirectory}
Do NOT ask questions. Do NOT explore beyond what's needed. Execute the task.`,
tools: {
read: parentTools.read,
grep: parentTools.grep,
bash: executorBash,
},
stopWhen: stepCountIs(15),
});
try {
const { text, steps } = await executor.generate({ prompt: description });
return text
? `[Executor: ${steps.length} steps]\n${text}`
: "(no response from executor)";
} catch (e: any) {
return `Executor error: ${e.message}`;
}
}
const explorer = new ToolLoopAgent({
model: "anthropic/claude-haiku-4-5",
instructions: `You are an explorer agent. Investigate and report back concisely.
Working directory: ${sandbox.workingDirectory}`,
tools: { read: parentTools.read, grep: parentTools.grep },
stopWhen: stepCountIs(5),
});
try {
const { text, steps } = await explorer.generate({ prompt: description });
return text
? `[Explorer: ${steps.length} steps]\n${text}`
: "(no response from explorer)";
} catch (e: any) {
return `Explorer error: ${e.message}`;
}
},
});
}探索器与执行器一览
| 探索器 | 执行器 | |
|---|---|---|
| 工具 | read,grep | read、grep、bash(委派) |
| 模型 | claude-haiku-4-5 | claude-sonnet-4-6 |
| 阶梯预算 | 5 | 15 |
| 可以修改 | 否 | 是的(在信托名单内) |
| 可以问问用户 | 否 | 否 |
这两个角色在工具能力、模型强度和预算上存在差异。他们一致同意一点:两人都不能向用户提问。这种责任属于父 Agent,也就是让人类参与其中的角色。
教学质量对执行器更重要
探索器主要是四处看看。模糊的描述仍然能带来有用的信息。执行器字面上完全按照指示操作。模糊的描述会得到模糊(甚至有害)的结果。
缺点:
Fix the auth bug.好:
In src/auth.ts, the login function at line 42 doesn't check for null email.
Add a null check before the database query. Run `npx tsc --noEmit` after the change.父 Agent的工作是提供目标、程序、约束和验证步骤。执行器的工作就是跟随他们。系统提示词的“请问问题吗”这句话在这里NOT真正发挥了作用。它迫使执行器要么基于现有条件采取行动,要么失败,而不是拖延澄清。
**注意:委托信任,而非全面信任**
执行器的bash使用模块2审批配置中的mode: "delegated"。父 Agent决定哪些命令值得信任。执行器可以npm test。它不能运行npm install、无rm -rf或列表中其他任何项目。这正是最初可辨识联合类型的合理性。
动手试试
请父 Agent委派需要行动的事务,而不仅仅是研究:
bun run index.ts . "Delegate to an executor: rename the 'cwd' variable in src/sandbox-local.ts to 'workingDir'. Then run npx tsc --noEmit and report the result."父 Agent应该调用 task和subagentType: "executor"。执行器应该进行更改,运行typecheck,并返回摘要。把你用探索器模式做同一任务的效果做比较(它不会改变任何东西)。
npx tsc --noEmit提交
git add src/tools.ts
git commit -m "feat(subagents): add executor role with delegated bash"完成标准
- [ ]
task工具schema包括subagentType: "explorer" | "executor" - [ ] 执行器使用
claude-sonnet-4-6和15步预算 - [ ] 执行器在
mode: "delegated"有自己的bash,信托名单较小 - [ ] 执行器严格执行指令,不问问题
- [ ] 探索器行为与上一节课无异
- [ ]
npx tsc --noEmit
**注意:从父 Agent处继承信任**
执行器的信任名单现在是硬编码的。试着把父 Agent的信任列表串联进去:当父 Agent生成执行器时,执行器会接收父 Agent的安全命令。现在想想界限。执行器是否应该被允许以同样的信任孕育出另一个执行器?还是说每升级一级就应该缩小信任组? 生产Harness的做法不同,答案取决于你对Agent规划的信任程度。
参考实现
完整实现请参见上文createTaskTool代码块。练习的解法是同样的代码,应用到你的src/tools.ts上。