【从0到1构建一个ClaudeAgent】规划与

📅 2026/6/30 4:33:41
【从0到1构建一个ClaudeAgent】规划与
因此这里主要展示了如何构建一个多智能体系统。在 原作者的Python代码 里run_subagent函数就像一个“虫洞”把任务传送到一个新的平行宇宙子线程/子上下文去执行执行完只带回结果。在 Java 中我们通常通过创建新的类实例来实现这种隔离。父 Agent 和子 Agent 拥有各自独立的messages列表互不干扰。Java 实现代码javapublic class AgentWithSubAgents { private static final Path WORKDIR Paths.get(System.getProperty(user.dir)); // --- 1. 工具定义 --- public enum ToolType { BASH(bash), READ_FILE(read_file), WRITE_FILE(write_file), EDIT_FILE(edit_file), TASK(task); // 新增 TASK 工具 public final String name; ToolType(String name) { this.name name; } } // ... 省略相同的 ToolExecutor 接口和基础工具注册 // --- 2. 子 Agent 类 (核心隔离单元) --- public static class SubAgent { private final ListMapString, Object messages new ArrayList(); // 独立上下文 private static final String SYSTEM_PROMPT You are a coding subagent. Complete the task and summarize findings.; // 子 Agent 只能使用基础工具不能递归创建子 Agent private final ListMapString, Object allowedTools Arrays.asList( createToolSpec(bash, Run shell command, command), createToolSpec(read_file, Read file, path), createToolSpec(write_file, Write file, path, content), createToolSpec(edit_file, Edit file, path, old_text, new_text) ); // 执行子任务 public String executeTask(String prompt) { messages.clear(); messages.add(Map.of(role, user, content, prompt)); System.out.println( [SubAgent] 启动子任务...); // 安全循环限制防止死循环 for (int i 0; i 30; i) { MapString, Object response callLLM(messages, SYSTEM_PROMPT, allowedTools); messages.add(response); if (!tool_use.equals(response.get(stop_reason))) { break; // 任务完成 } ListMapString, Object results new ArrayList(); ListMapString, Object content (ListMapString, Object) response.get(content); for (MapString, Object block : content) { if (tool_use.equals(block.get(type))) { String toolName (String) block.get(name); String toolId (String) block.get(id); MapString, Object inputArgs (MapString, Object) block.get(input); // 通过共享的 TOOL_HANDLERS 执行工具 ToolExecutor handler TOOL_HANDLERS.get(toolName); String output ; try { output handler ! null ? handler.execute(inputArgs) : Unknown tool; } catch (Exception e) { output Error: e.getMessage(); } MapString, Object result new HashMap(); result.put(type, tool_result); result.put(tool_use_id, toolId); result.put(content, output); results.add(result); } } messages.add(Map.of(role, user, content, results)); } // 提取最终文本结果 return extractText(response); } } // --- 3. 父 Agent 核心循环 --- // 父 Agent 拥有所有工具包括 TASK private final ListMapString, Object parentTools new ArrayList(); { // 复制基础工具 parentTools.addAll(Arrays.asList( createToolSpec(bash, Run shell command, command), createToolSpec(read_file, Read file, path), createToolSpec(write_file, Write file, path, content), createToolSpec(edit_file, Edit file, path, old_text, new_text) )); // 添加 TASK 工具 parentTools.add(createTaskToolSpec()); } // 创建任务工具规格 private static MapString, Object createTaskToolSpec() { MapString, Object spec new HashMap(); spec.put(name, task); spec.put(description, Spawn a subagent with fresh context.); MapString, Object schema new HashMap(); schema.put(type, object); MapString, Object props new HashMap(); props.put(prompt, Map.of(type, string, description, The task for the subagent)); props.put(description, Map.of(type, string, description, Short description)); schema.put(properties, props); schema.put(required, Arrays.asList(prompt)); spec.put(input_schema, schema); return spec; } public void agentLoop(ListMapString, Object messages) { SubAgent subAgent new SubAgent(); // 需要时创建子 Agent while (true) { System.out.println( [Parent] 思考中...); MapString, Object response callLLM(messages, You are a manager. Use task to delegate., parentTools); messages.add(response); if (!tool_use.equals(response.get(stop_reason))) return; ListMapString, Object results new ArrayList(); ListMapString, Object content (ListMapString, Object) response.get(content); for (MapString, Object block : content) { if (tool_use.equals(block.get(type))) { String toolName (String) block.get(name); String toolId (String) block.get(id); MapString, Object inputArgs (MapString, Object) block.get(input); String output; if (task.equals(toolName)) { // 委托给子 Agent String desc (String) inputArgs.getOrDefault(description, Subtask); String prompt (String) inputArgs.get(prompt); System.out.println( task ( desc ): prompt.substring(0, Math.min(prompt.length(), 50))); output subAgent.executeTask(prompt); } else { // 自己执行基础工具 ToolExecutor handler TOOL_HANDLERS.get(toolName); try { output handler ! null ? handler.execute(inputArgs) : Unknown tool; } catch (Exception e) { output Error: e.getMessage(); } } System.out.println( Result: output.substring(0, Math.min(output.length(), 100))); MapString, Object result new HashMap(); result.put(type, tool_result); result.put(tool_use_id, toolId); result.put(content, output); results.add(result); } } messages.add(Map.of(role, user, content, results)); } } // --- 辅助方法 --- private static String extractText(MapString, Object response) { ListMapString, Object content (ListMapString, Object) response.get(content); for (MapString, Object block : content) { if (text.equals(block.get(type))) return (String) block.get(text); } return (no summary); } }subAgent核心思想引入分层架构和上下文隔离让Agent能够分解复杂任务分配给专门的子Agent处理避免上下文污染。java// 子 Agent 类 - 独立的执行单元 public static class SubAgent { private final ListMapString, Object messages new ArrayList(); // 独立上下文 private static final String SYSTEM_PROMPT You are a coding subagent. Complete the task and summarize findings.; // 独立上下文每个子任务有自己独立的消息历史 // 系统提示为子任务定义专门的角色如编码专家 // 子 Agent 只能使用基础工具不能递归创建子 Agent private final ListMapString, Object allowedTools Arrays.asList( createToolSpec(bash, Run shell command, command), createToolSpec(read_file, Read file, path), // 权限控制限制工具集防止无限递归 ); public String executeTask(String prompt) { messages.clear(); // 清空历史从零开始 messages.add(Map.of(role, user, content, prompt)); // 每次调用都是全新的上下文避免历史干扰 // 安全循环限制防止死循环 for (int i 0; i 30; i) { // 最多30轮 // ... 执行子任务 } } }上下文隔离每个子任务在干净的环境中执行不继承父任务的上下文污染角色专业化可以通过不同的SYSTEM_PROMPT让子Agent专注特定领域防递归保护子Agent不能调用task工具防止无限递归资源限制限制最大轮数防止死循环任务委派TASK 工具核心思想将委派子任务抽象为一种工具实现任务分解和并行化。java// 父 Agent 的工具列表 private final ListMapString, Object parentTools new ArrayList(); { // 基础工具 parentTools.addAll(Arrays.asList( createToolSpec(bash, Run shell command, command), // ... 其他基础工具