多Agent协作实战:Java AgentScope新手教程

2026-06-16阅读 0热度 0
其他

第八章 多 Agent 协作:orchestrator + workers 模式,主 Agent 主持 Subagent 群聊

继续深入。在 1.x 版本中,实现多 Agent 对话通常依赖 MsgHub,它把“群聊”抽象为一个共享消息总线——任何 Agent 发出的消息自动广播给 Hub 内所有成员。设计直观,但在 2.0 中,这个类已被移除。

【AgentScope Ja va新手村系列】(8)多Agent协作

替代方案?等价语义完全可由一个“主 Agent”接管。就像会议不需要自动广播喇叭,只需一位主持人,明确谁该发言、谁该倾听。下表对比了 1.x 与 2.0 的对应关系:

1.x MsgHub 语义2.0 替代方案
多 agent 共享消息总线主 agent 持有 Map 状态
任一 agent 发言自动广播主 agent 逐一向每个 subagent 传递“上一人发言”
hub.add(a, b, c)HarnessAgent.builder().subagent(a, b, c)
hub.broadcast(msg)主 agent 自行构造 prompt,循环中 spawn
异步 / 多轮主 agent 每轮执行 agent.call(...) 一次

8.2 首个群聊实例:四方圆桌会议

理论落地,直接上手。模拟一种典型场景:产品、技术、运营、法务就一个需求各抒己见。这是团队协作中最易出状况、也最能凸显多 Agent 价值的环节。

import io.agentscope.core.agent.RuntimeContext;
import io.agentscope.core.formatter.openai.OpenAIChatFormatter;
import io.agentscope.core.message.UserMessage;
import io.agentscope.core.model.OpenAIChatModel;
import io.agentscope.harness.HarnessAgent;
import io.agentscope.harness.agent.subagent.SubagentDeclaration;
import ja va.nio.file.Path;
import ja va.util.List;

public class Chapter08_Roundtable {
    public static void main(String[] args) {
        OpenAIChatModel model = OpenAIChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .baseUrl("https://api.openai.com")
                .stream(true)
                .formatter(new OpenAIChatFormatter())
                .build();

        SubagentDeclaration product = speaker("product", "产品经理", "关注用户价值与优先级");
        SubagentDeclaration tech= speaker("tech","技术负责人", "关注实现成本与稳定性");
        SubagentDeclaration ops = speaker("ops", "运营负责人", "关注上线节奏与风险");
        SubagentDeclaration legal = speaker("legal", "法务顾问", "关注合规与用户协议");

        HarnessAgent host = HarnessAgent.builder()
                .name("roundtable_host")
                .sysPrompt("""
                        你是一个会议主持人。
                        1. 你管辖 4 位参与者:product / tech / ops / legal。
                        2. 拿到议题后,调用 agent_spawn 让 product 先发言,
                           然后把 product 的发言喂给 tech,再把 tech 的发言喂给 ops,
                           最后喂给 legal,legal 收尾。
                        3. 最后用一句话总结四方共识。
                        """)
                .model(model)
                .workspace(Path.of("./workspace"))
                .subagent(product)
                .subagent(tech)
                .subagent(ops)
                .subagent(legal)
                .build();

        host.call(List.of(new UserMessage("user", "议题:我们打算把免费用户的 API 限速从 60/min 降到 30/min,请四方评估。")),
                RuntimeContext.empty()).block();
    }

    static SubagentDeclaration speaker(String id, String role, String concern) {
        return SubagentDeclaration.builder()
                .name(id)
                .description(role + ",参与四方会议;每次发言聚焦自己的关切:" + concern)
                .inlineAgentsBody("你是" + role + "。发言简洁(不超过 60 字),聚焦:" + concern)
                .build();
    }
}

执行这段代码,四个角色的输出自然串联成一段逼真的“圆桌会议纪要”。实现成本极低,效果生动。

8.3 多轮群聊:将“上一轮”传递给“下一轮”

1.x 中 MsgHub 的真正精髓在于多轮对话——上一轮 A 的发言自动成为下一轮 B 的上下文。2.0 未丢失此能力,只是换了一种实现:借助主 Agent 自身的 AgentState

具体而言,每执行完一个 subagent,主 Agent 在其 call() 上下文中自动获得该 subagent 的回复。当需要 spawn 下一轮 subagent 时,主 Agent 可在 system prompt 中显式拼接“上一个发言者说了什么”。

// 在主 agent 的 system prompt 里加一条规则:
"""
第 N 轮发言前,先在 user 输入里写:
'以下是上一位 speaker 的发言:<上一段完整文本>'
然后再让下一个 subagent 接着说。
"""

关键点在于:主 Agent 每轮自行拼接这段前缀,业务代码无需编写循环。这正是 HarnessAgent + agent_spawn 相比硬编码 Pipeline 更灵活之处——LLM 自行组织“上下文传递”。

8.4 规避“消息风暴”

1.x 的 MsgHub 长期被诟病:4 个 Agent 在 Hub 内互发消息,跑 5 轮后 token 用量暴增。2.0 通过两种机制解决。

8.4.1 限制发言轮次

最直接有效的办法:在主 Agent 的 system prompt 中加入规则 "每位参与者最多发言 1 轮"。LLM 受到约束后,自然会避免重复 spawn 对话。

8.4.2 使用 CompactionMiddleware 自动摘要

更优雅的方式是挂载 CompactionMiddleware

HarnessAgent host = HarnessAgent.builder()
        ...
        .middleware(new CompactionMiddleware(CompactionConfig.builder()
                .triggerTokens(8000)            // 上下文超过 8k token 时压缩
                .keepRecentMessages(6)          // 保留最近 6 条
                .summaryTarget("MEMORY.md")
                .build()))
        .build();

当上下文超过 8k token 时,自动将“早期发言”压缩为摘要,写入 workspace/MEMORY.md。下一章将详细拆解此机制,此处只须了解其存在。

8.5 最小迁移清单(1.x MsgHub → 2.0 orchestrator)

若你正从 1.x 迁移,下面速查表可快速定位。核心原则:1.x 要求手动编排 Agent 顺序,2.0 则将此顺序交由 system prompt 控制。

1.x 用法2.0 等价实现
MsgHub hub = new MsgHub()隐式:主 agent 持有 subagent 列表
hub.add(a, b, c)HarnessAgent.builder().subagent(a, b, c)
hub.broadcast(Msg)主 agent 自行组织 prompt,循环 spawn
hub.enter().broadcastAll(...)主 agent 一次性发送多 spawn(async)
Pipelines.conversation([a,b,c])主 agent 编写“轮次规则” + subagent 列表

迁移技巧:先明确你的“四方会议”发言顺序,然后将该顺序用自然语言描述到 system prompt 中。1.x 时代编写 Pipeline 时本就需要设计此顺序,现在只是换了位置。

8.6 完整可运行示例:3 人辩论赛

最后看一个更生动的场景——辩论赛。正方、反方陈述观点,裁判判定胜负。此例可作为理解 orchestrator + workers 模式的补充素材。

public class Chapter08_Debate {
    public static void main(String[] args) {
        DashScopeChatModel model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .build();

        SubagentDeclaration pro= debater("pro","正方","AI 会大幅提升生产力");
        SubagentDeclaration con= debater("con","反方","AI 不会减少劳动时间");

        SubagentDeclaration judge = SubagentDeclaration.builder()
                .name("judge")
                .description("辩论赛裁判;正反方发言结束后给出一句胜负判定")
                .inlineAgentsBody("你是裁判,只返回'正方胜'或'反方胜',不要解释。")
                .build();

        HarnessAgent host = HarnessAgent.builder()
                .name("debate_host")
                .sysPrompt("""
                        你是辩论赛主持人。流程:
                        1. 拿议题,先 agent_spawn pro,让正方开场
                        2. 把 pro 发言喂给 con,反方反驳
                        3. 把 con 反驳喂给 pro,正方再反驳(最多 1 轮)
                        4. 最后让 judge 收尾
                        5. 总结一句:哪个论据最有说服力
                        """)
                .model(model)
                .workspace(Path.of("./workspace"))
                .subagent(pro)
                .subagent(con)
                .subagent(judge)
                .build();

        host.call(List.of(new UserMessage("user", "辩题:未来 5 年,AI 是否会替代大部分白领工作?")),
                RuntimeContext.empty()).block();
    }

    static SubagentDeclaration debater(String id, String side, String stance) {
        return SubagentDeclaration.builder()
                .name(id)
                .description(side + "辩手;坚持立场:" + stance)
                .inlineAgentsBody("你是" + side + "辩手,立场:" + stance + "。发言不超过 80 字。")
                .build();
    }
}

8.7 本章小结

  • 1.x 的 MsgHubPipelines 在 2.0 中整体移除,取而代之的是 SubagentDeclaration + agent_spawn 组合。
  • 所谓“群聊”,在 2.0 中本质上是 orchestrator + workers 模式:一个主 Agent 担任主持人,用 system prompt 描述发言顺序。
  • 多轮群聊的上下文保留依赖主 Agent 自身的 AgentState,无需共享消息总线。
  • 防止 token 爆炸的两道防线:一是限制发言轮次,二是挂载 CompactionMiddleware 实现自动摘要。
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策