子 Agent 工具。 父 Agent 调用 task 时,这个工具会创建一段全新的 messages, 让子 Agent 在干净上下文中完成 description 描述的任务。
| 17 | * 让子 Agent 在干净上下文中完成 description 描述的任务。 |
| 18 | */ |
| 19 | public class TaskTool implements Tool { |
| 20 | |
| 21 | private final LlmClient subagentClient; |
| 22 | |
| 23 | private final ToolRegistry subagentTools; |
| 24 | |
| 25 | public TaskTool(LlmClient subagentClient, ToolRegistry subagentTools) { |
| 26 | this.subagentClient = subagentClient; |
| 27 | this.subagentTools = subagentTools; |
| 28 | } |
| 29 | |
| 30 | @Override |
| 31 | /* |
| 32 | * { |
| 33 | * "name": "task", |
| 34 | * "description": "Launch a subagent for a complex subtask. Returns only the final summary.", |
| 35 | * "input_schema": { |
| 36 | * "type": "object", |
| 37 | * "properties": { |
| 38 | * "description": {"type": "string", "description": "Subtask for a fresh-context subagent"} |
| 39 | * }, |
| 40 | * "required": ["description"] |
| 41 | * } |
| 42 | * } |
| 43 | */ |
| 44 | public ToolDefinition getDefinition() { |
| 45 | JSONObject properties = new JSONObject() |
| 46 | .fluentPut("description", new JSONObject() |
| 47 | .fluentPut("type", "string") |
| 48 | .fluentPut("description", "Subtask for a fresh-context subagent")); |
| 49 | JSONObject schema = new JSONObject() |
| 50 | .fluentPut("type", "object") |
| 51 | .fluentPut("properties", properties) |
| 52 | .fluentPut("required", new JSONArray().fluentAdd("description")); |
| 53 | return new ToolDefinition("task", |
| 54 | "Launch a subagent for a complex subtask. Returns only the final summary.", |
| 55 | schema); |
| 56 | } |
| 57 | |
| 58 | @Override |
| 59 | public ToolResult execute(JSONObject input) { |
| 60 | String description = input == null ? "" : input.getString("description"); |
| 61 | if (description == null || description.isBlank()) { |
| 62 | return new ToolResult("Error: No description provided"); |
| 63 | } |
| 64 | |
| 65 | System.out.println("[Subagent spawned]"); |
| 66 | // 子 Agent 不复用父 Agent 的 history,这是本章“干净上下文”的核心。 |
| 67 | AgentLoop subLoop = new AgentLoop(subagentClient, subagentTools, new AgentLoopListener() { |
| 68 | @Override |
| 69 | public void beforeToolUse(ToolUseBlock toolUse) { |
| 70 | System.out.println(" [sub] Tool> " + toolUse.getName() + " " + toolUse.getInput()); |
| 71 | } |
| 72 | }, 30); |
| 73 | AssistantMessage answer = subLoop.run(description); |
| 74 | System.out.println("[Subagent done]"); |
| 75 | // 父 Agent 只拿到最终摘要,不拿到子 Agent 的完整中间消息。 |
| 76 | return new ToolResult(extractText(answer)); |
nothing calls this directly
no outgoing calls
no test coverage detected