多 Agent 协作实战:任务编排与子代理系统

发布时间:2026/7/10 21:18:45

多 Agent 协作实战:任务编排与子代理系统 引言一个 Agent 搞不定的事在构建智能应用的过程中我逐渐发现一个残酷的真相单个 Agent 的能力存在天花板。即便你给了它最强大的模型、最丰富的工具集、最详尽的系统提示它仍然会在某些场景下力不从心。拿写一篇技术文章这件事来说。如果让一个 Agent 独立完成它通常的做法是打开浏览器搜索几个资料然后一气呵成写完。看起来效率很高但结果往往差强人意——调研不够深入、文章结构松散、技术细节经不起推敲。为什么因为写一篇好文章本质上是一个多阶段工程调研需要广度与批判性思维规划需要全局视角写作需要流畅表达校对需要严谨细致。这些能力放在一个 Agent 身上就像让一个人同时做 CEO 和校对员——不是不可能但一定会顾此失彼。这其实就是软件工程里最朴素的分治思想把一个复杂问题拆解成若干子问题每个子问题交给最擅长的执行者。在 Solon AI Harness 中这套思想落地为任务编排Task Orchestration与子代理系统Sub-Agent System。通过 task 和 multitask 工具主 Agent 可以动态委派子任务通过 AgentManager我们可以统一管理所有 Agent 定义通过子代理的独立心智与记忆每个员工都能在自己的领域里专注执行。今天我就用技术文章写作团队这个场景完整演示 Harness 的多 Agent 协作能力。这也是 Harness 系列实战文章的第五篇前面我们聊过基础对话、工具调用、记忆系统和 Prompt 工程现在是时候把这些能力组合起来构建一个真正的 Multi-Agent 系统了。二、场景一个技术文章写作团队假设我们要开发这样一个系统用户只需要给一个文章主题比如Solon AI Harness 的记忆系统实现原理系统就能自动完成一篇高质量的技术文章。整个流程分四步走调研阶段 —— 调研 Agent 搜索相关资料输出调研简报规划阶段 —— 规划 Agent 根据简报输出文章大纲写作阶段 —— 写作 Agent 根据大纲输出完整初稿校对阶段 —— 校对 Agent 审阅初稿输出修改建议这个流程天然是一个有向无环图DAG每个节点是一个子代理节点间的依赖关系决定了执行顺序。Harness 的 multitask 工具天然支持这种编排——它允许主 Agent 一次性委派多个子任务并声明任务间的依赖。为了管理这些子代理我们会用到 AgentManager。它的角色类似于人力资源系统注册 Agent 定义、查询可用 Agent、获取特定 Agent 实例。每个子代理通过 AgentDefinition 定义包含独立的系统提示词和工具集拥有自己的心智System Prompt和记忆Session。整体架构大致如下用户输入│▼┌─────────────────────────────────┐│ 主 Agent主编 ││ - 理解用户需求 ││ - 拆解任务 ││ - 通过 task/multitask 委派 ││ - 汇总结果 │└─────────────────────────────────┘│├── task: 调研 Agent ──────────► 输出调研简报├── task: 规划 Agent ──────────► 输出文章大纲├── task: 写作 Agent ──────────► 输出文章初稿└── task: 校对 Agent ──────────► 输出修改建议值得注意的是这些子代理都是在运行时动态创建的并非事先注册好的固定实例。主 Agent 通过 task 工具调用时会指定需要哪个子代理来执行Harness 引擎根据 Agent 名称找到对应的定义实例化后执行执行完毕后可以释放。这种按需创建、用完即走的模式让系统非常轻量和灵活。三、实现定义子代理 构建引擎 任务委派现在我们来完整实现这个系统。代码将分为三个部分定义子代理 — 为每个角色创建 AgentDefinition构建引擎 — 配置 HarnessEngine注册子代理任务委派 — 主 Agent 使用 task 工具编排流程3.1 定义子代理每个子代理需要一个 AgentDefinition 对象。核心要素有两个systemPrompt 定义角色心智metadataname, description, tool… 定义元数据。// 1. 调研 Agent负责搜索和资料整理AgentDefinition researchAgentDef AgentDefinition.builder().name(“researcher”).description(“资深技术调研员可以联网搜索”).toolsAdd(“websearch”, “webfetch”) // 需要搜索和网页抓取工具.systemPrompt(“”你是一名资深技术调研员。你的工作是1. 理解用户的研究主题2. 搜索相关技术资料和官方文档3. 输出结构化的调研简报包含关键概念、技术原理、最佳实践、参考来源4. 保持客观区分事实和观点输出格式 ## 调研主题 ## 关键发现 ## 技术原理摘要 ## 参考来源 ) .build();// 2. 规划 Agent负责制定文章大纲AgentDefinition planAgentDef AgentDefinition.builder().name(“planner”).description(“技术文章策划编辑”).toolsAdd(“read”) // 只需要读取调研简报.systemPrompt(“”你是一名技术文章策划编辑。你的工作是1. 根据调研简报设计文章结构2. 确保逻辑连贯、层次分明3. 输出详细大纲包含引言要点、各章节核心论点、示例规划、总结方向输出格式 ## 文章标题建议 ## 章节结构含每段核心内容说明 ## 需要重点突出的技术点 ## 建议的代码示例位置 ) .build();// 3. 写作 Agent负责撰写初稿AgentDefinition writerAgentDef AgentDefinition.builder().name(“writer”).description(“资深技术写手”).toolsAdd(“edit”) // 只需要读取大纲.systemPrompt(“”你是一名资深技术写手。你的工作是1. 根据大纲撰写完整的技术文章2. 语言专业、流畅适合开发者阅读3. 包含必要的代码示例和配置说明4. 注意文章的可读性适当分段、使用列表、突出重点写作风格 - 专业但不晦涩 - 简洁但不冷漠 - 用 我们 而非 你 拉近距离 - 多举实际例子 输出格式完整的 Markdown 文章 ) .build();// 4. 校对 Agent负责质量审查AgentDefinition reviewerAgentDef AgentDefinition.builder().name(“reviewer”).description(“一名严格的技术文章校对员”).toolsAdd(“read”) // 只需要读取初稿.systemPrompt(“”你是一名严格的技术文章校对员。你的工作是1. 检查技术准确性概念是否正确、代码能否运行2. 检查文章结构逻辑是否连贯、章节划分是否合理3. 检查语言表达是否有语病、用词是否准确4. 给出具体的修改建议输出格式 ## 总体评价 ## 技术问题逐条列出 ## 结构建议逐条列出 ## 语言问题逐条列出 ## 优先级排序 ) .build();你可能注意到了我在每个 Agent 的 systemPrompt 里明确写了你的工作是什么和输出格式。这很重要——子代理的心智越清晰主 Agent 委派时的沟通成本就越低。从工程角度看这其实就是契约式设计每个子代理承诺自己能产出什么格式的输出主 Agent 按契约调用即可。3.2 构建引擎有了子代理定义接下来构建 HarnessEngine。这里有几个关键配置toolsAdd(ToolPermission.TOOL_ALL_FULL) — 启用全部工具权限包括 task 和 multitaskmemoryEnabled(true) — 开启记忆让主 Agent 能记住对话的关键信息autoRethink(true) — 开启自动重新思考当 Agent 遇到困难时自动调整策略// 构建引擎注册子代理HarnessEngine engine HarnessEngine.of(“writing-team”, “/data/workspace”).systemPrompt(“”你是一个技术文章写作团队的主编Editor-in-Chief。你的职责是管理整个写作流程按顺序完成以下步骤第1步调研 — 委派 researcher 子代理进行资料调研 第2步规划 — 委派 planner 子代理制定文章大纲 第3步写作 — 委派 writer 子代理撰写初稿 第4步校对 — 委派 reviewer 子代理进行质量审查 每一部完成后仔细审阅子代理的输出确认质量后再进入下一步。 如果某个步骤的输出不满足要求可以重新委派改进。 最终输出完整的文章和校对报告。 ) .sessionProvider(InMemoryAgentSession::new) .toolsAdd(ToolPermission.TOOL_ALL_FULL) // 启用所有工具包括 task/multitask .modelAdd(new ChatConfig()...) .memoryEnabled(true) .maxTurns(30) // 预留足够的交互轮次 .autoRethink(true) // 遇到困难时自动调整 .build();这种设计让子代理系统非常灵活——你可以完全自定义也可以复用内置能力甚至可以混合使用。3.3 注册子代理到 AgentManager有了引擎之后我们把上面定义好的子代理注册进去// 注册子代理定义engine.getAgentManager().addAgent(researchAgentDef);engine.getAgentManager().addAgent(planAgentDef);engine.getAgentManager().addAgent(writerAgentDef);engine.getAgentManager().addAgent(reviewerAgentDef);// 确认注册成功System.out.println(“已注册子代理: engine.getAgentManager().getAgents().stream().map(AgentDefinition::getName).collect(Collectors.joining(”, )));// 输出: 已注册子代理: researcher, planner, writer, reviewer除了自定义子代理Harness 还内置了四个通用子代理名称 用途 适用场景general 通用对话与推理 通用的问答、分析任务explore 探索与信息收集 搜索、资料调研、代码阅读plan 规划与任务分解 制定计划、拆分步骤bash Shell 命令执行 文件操作、代码运行这些内置子代理可以作为基座能力来使用。如果你的自定义子代理不需要特殊心智直接使用内置的就可以。3.4 执行任务委派一切就绪后启动引擎// 用户输入String userRequest “”请写一篇关于「Solon AI Harness 记忆系统」的技术文章。要求- 介绍记忆系统的核心概念和工作原理- 包含完整的代码示例- 适合 Java 开发者阅读- 字数 3000 字左右“”;// 创建会话并执行AgentSession session new InMemoryAgentSession();String result engine.prompt(userRequest).session(session).call();System.out.println(result);当主 Agent 收到需求后它会按照 System Prompt 中设定的流程依次调用 task 工具委派子代理。整个过程是自动的我们只需要观察输出即可。四、运行过程从需求到成品的完整链路为了更好地理解多 Agent 协作的内部机制让我们深入到运行过程看看每一步发生了什么。4.1 主 Agent 的思考过程当用户输入请求后主 Agent 首先进行内部推理。由于我们开启了 autoRethink(true)它会先规划再执行。通过查看日志Harness 默认会输出详细的运行日志能够看到类似这样的过程[主Agent] 收到用户请求撰写关于记忆系统的技术文章[主Agent] 规划流程调用 researcher 进行调研调用 planner 制定大纲调用 writer 撰写初稿调用 reviewer 校对[主Agent] 开始第1步调研[主Agent] → 调用 task 工具参数agent: “researcher”task: “调研 Solon AI Harness 的记忆系统…”4.2 task 工具的内部机制当主 Agent 调用 task 工具时引擎内部执行了以下操作解析参数获取目标 Agent 名称“researcher”和任务描述从 AgentManager 查找名为 “researcher” 的 AgentDefinition调用 extensionAdd 中注册的逻辑通过 def.builder(engine).build() 构建子代理为子代理创建一个独立的子会话sub-session继承主会话的上下文用子代理执行任务传入任务描述作为 prompt返回执行结果给主 Agent关键点在于子会话的继承机制。子代理不是从头开始的——它能看到主会话中与任务相关的上下文包括用户的原始需求、已经完成步骤的输出等。这保证了信息在流程中顺畅传递。4.3 各子代理的实际输出为了让你有更直观的感受这里展示一下各子代理实际产出内容的风格调研 Agent 输出摘要调研主题Solon AI Harness 记忆系统关键发现记忆系统基于 InMemoryAgentSession 实现支持会话级记忆持久化核心接口包括AgentSession、SessionProvider、AgentMemory记忆类型分为对话记忆、事实记忆、会话属性…规划 Agent 输出大纲文章标题建议Solon AI Harness 记忆系统深度解析从入门到原理章节结构引言为什么需要记忆系统从一个对话困境说起核心概念Session、Memory、Provider 三角关系快速上手10 行代码开启记忆深入原理记忆的存储、检索与过期策略实战技巧自定义 SessionProvider、多会话管理总结与展望…写作 Agent 输出初稿Solon AI Harness 记忆系统深度解析一、引言从一个对话困境说起“你刚才说什么来着”这大概是我们在对话中最不愿意听到的一句话。对于 AI 应用来说…校对 Agent 输出报告总体评价文章质量良好结构清晰技术准确。建议修改以下问题技术问题高优先级第三节中 SessionProvider 的 SPI 配置路径写错了应为 META-INF/services/…示例代码第 45 行缺少 .build() 调用结构建议中优先级第四节原理部分篇幅过长建议拆分为两个小节…4.4 主 Agent 的最终汇总所有子代理执行完毕后主 Agent 会汇总结果输出最终回复给用户[主Agent] 所有步骤完成输出汇总报告[主Agent] 生成完整文章正文 校对报告用户看到的最终输出是一篇完整的文章附带校对报告。如果用户对某部分不满意可以直接要求主 Agent 重新委派某个步骤——比如第三部分的示例代码再完善一下主 Agent 会再次调用 task 工具仅重新执行写作步骤保留其他步骤的成果。五、进阶通过挂载动态加载外部子代理定义上面我们演示了在代码中硬编码子代理定义的方式。但在实际生产环境中你可能会遇到这样的需求插件化第三方开发者可以贡献自己的子代理无需修改主程序代码热加载运行时动态添加新的子代理无需重启应用配置化用 YAML/JSON 定义子代理而非 Java 代码Harness 的挂载系统Mount System 正好解决这些问题。通过 MountDir我们可以将文件系统中的目录挂载到引擎中引擎会自动扫描并加载子代理定义。5.1 定义外部子代理文件假设我们在 agents/ 目录下存放子代理定义文件每个文件描述一个子代理agents/researcher.yamlname: “researcher”tools: [“web_search”, “web_fetch”]你是一名资深技术调研员…agents/writer.yamlname: “writer”tools: [“read”]你是一名资深技术写手…5.2 挂载目录到引擎// 创建挂载目录定义MountDir agentMount MountDir.builder().alias(“agents”) // 挂载点名称.path(“./agents”) // 本地文件系统路径.type(MountType.AGENTS) // 挂载类型.build();// 添加到引擎engine.addMount(agentMount);添加挂载后引擎会在启动时扫描 ./agents/ 目录下的定义文件自动解析为 AgentDefinition 并注册到 AgentManager。5.3 运行时动态添加子代理除了文件挂载你还可以在运行时通过 API 动态添加子代理// 运行时动态创建并注册子代理AgentDefinition dynamicAgent AgentDefinition.builder().name(“fact-checker”).description(“事实核查员负责验证文章中的技术声明是否准确”).toolsAdd(“websearch”).systemPrompt(“你是一个事实核查员负责验证文章中的技术声明是否准确…”).build();engine.getAgentManager().addAgent(dynamicAgent);// 现在主 Agent 就可以调用 fact-checker 了这种动态注册的能力让多 Agent 系统具备了自适应扩展的可能。比如你可以构建一个Agent 市场用户可以从市场中安装新的子代理系统在运行时动态加载。5.4 内置子代理的挂载Harness 本身也内置了一些挂载点。你可以通过 engine.addMount() 挂载自定义目录引擎会自动合并内置和自定义的子代理。如果自定义子代理与内置子代理名称冲突自定义的优先级更高——这允许你覆盖默认行为。// 查看当前所有可用子代理List allAgents engine.getAgentManager().getAgents();allAgents.forEach(def -System.out.println( - def.getName()));输出可能类似general (built-in)explore (built-in)plan (built-in)bash (built-in)researcher (custom, from ./agents/researcher.yaml)writer (custom, from ./agents/writer.yaml)reviewer (custom, code registered)fact-checker (custom, dynamic)六、总结任务编排的最佳实践通过技术文章写作团队这个场景我们完整地走了一遍 Harness 多 Agent 协作的落地路径。最后总结几个关键认知和最佳实践6.1 什么时候该用多 Agent不是所有场景都需要多 Agent。我的经验是如果你的任务可以一句话描述清楚、一步执行完成单 Agent 就够了。 多 Agent 适合以下特征的任务多阶段任务有明显的阶段划分不同阶段需要不同的能力多角色任务需要多个专业视角协同可并行某些子任务可以同时执行提高效率需隔离不同子任务需要独立的上下文和记忆避免混淆6.2 子代理设计的三个原则原则一心智单一每个子代理只做一件事把它做到极致。researcher 只负责调研writer 只负责写作。不要在一个子代理里塞太多职责否则你又回到了单 Agent 的老路。原则二契约明确每个子代理的 systemPrompt 里写清楚输入输出格式。这不仅是给子代理看的也是给主 Agent 看的——主 Agent 需要知道每个子代理能产出什么才能正确编排流程。原则三粒度适中子代理的粒度不要太细也不要太粗。太细比如写第一段、“写第二段”会导致编排开销过大太粗比如完成整篇文章又失去了多 Agent 的意义。以一个独立可交付的中间产物为粒度通常比较合适。6.3 心智与记忆的隔离这是多 Agent 系统最容易忽视的问题。每个子代理需要独立的心智System Prompt — 定义角色定位和行为准则独立的记忆Session — 只看到与自己任务相关的上下文Harness 通过子会话机制实现了这种隔离。子代理能继承必要的主会话信息但不会把整个历史都加载进来。这既保护了隐私子代理不需要知道用户全部对话历史也节省了 Token子代理只关注自己需要的上下文。6.4 编排 vs 自治最后想讨论一个设计哲学问题主 Agent 应该严格编排流程还是让子代理自治协作Harness 的设计偏向于可控编排。主 Agent 通过 task/multitask 明确指定谁做什么流程清晰可预期。这种方式更适合工程化落地——你能追踪每一步的执行情况能在任意步骤介入干预能精确控制资源消耗。

相关新闻