“用户提问:'我明天从北京飞杭州,落地后去西湖,要带伞吗?'——在 AgentScope 1.x 时代,我们通过 Pipeline 依次串联天气、航班、景点三个 Agent 来实现此类需求。而在 2.0 版本中,我们采用 subagent 机制,配合 workspace/subagents/*.md 文件进行描述:主 Agent 自主决策是优先查询天气还是航班,三个 subagent 并行启动,高效协同。这便是 AgentScope 2.0 推荐的『文件驱动 subagent』实战方案。”
通过本章学习,你将掌握以下核心技能:如何使用 Markdown 文件定义 subagent、如何借助 SubagentDeclaration 在 Java 端增强其能力、以及如何利用 agent_spawn 的同步与异步组合实现并行调研。
10.1 工程结构
首先,我们来看一个简洁的项目骨架。它没有复杂的继承关系,也没有冗长的配置信息,文件夹结构本身即代表了全部设计逻辑。
```text tra vel-assistant/ ├── pom.xml └── workspace/ ├── MEMORY.md ├── subagents/ │ ├── weather.md │ ├── flight.md │ └── attraction.md └── state/ └── session-*.json (JsonFileAgentStateStore 自动生成) ```所有核心业务逻辑均沉淀在 workspace/subagents/ 目录中。接下来,我们通过三个 Markdown 文件来定义三个微服务 Agent。
10.2 三个 subagent 文件
以下是 workspace/subagents/weather.md 的内容,这是一个典型的“文件驱动式”Agent 声明示例。
接下来是 flight.md 和 attraction.md,它们遵循相同的规范:一个明确的 id、一段精准的 description,以及一个指导行为逻辑的 sysPrompt。
简而言之,这三份描述文件共同构成了主 Agent 的“路由表”。主 Agent 调度哪个 subagent,完全依赖于 description 字段的内容。一个设计精巧的 description,其价值远超复杂的硬编码逻辑。
10.3 在 Java 端补强 subagent
对于那些需要真实后端能力(例如接入天气 API)的 subagent,我们可以在 Java 端注册一份增强声明。HarnessAgent 会自动合并文件声明与代码声明,实现“声明式 + 编程式”的有机结合。
关键点在于 SubagentDeclaration 中的 tools 白名单机制。它允许我们精细控制每个 subagent 能够调用哪些工具。下面的 WeatherLookupTool 是一个简单的 Mock 实现,在生产环境中,它背后连接的是真实的气象 API 服务。
10.4 同步与异步 spawn 的选择策略
回到用户最初的问题:“明天从北京飞杭州,落地后去西湖,要带伞吗?”这三个子任务彼此独立,最佳实践自然是“三连发”——通过 async spawn 让三个 subagent 并行运行,大幅提升响应效率。
我们可以在主 Agent 的 system prompt 中直接加入如下指令:
```text "用户问题涉及多主题时,优先使用 timeout_seconds=0 的 async spawn 一次发出, 拿到 task_id 后用 todo_write 跟踪,最后统一汇总。" ```这个“agent_spawn + todo_write”的组合,正是 AgentScope 2.0 版本的“fanout pipeline”实现,其灵活性和扩展性远超 1.x 版本的 FanoutPipeline。
不过,有一种场景需要同步处理:如果用户明确提出“先告诉我航班信息,再决定下一步”。此时,主 Agent 会自动调用同步 spawn 等待结果返回,而非一次性全量下发。这正是 AgentScope 2.0 的核心优势——调度逻辑由 LLM 根据 system prompt 自主决策,而非依赖硬编码的流程控制。
10.5 跨会话记忆:将“用户常驻地”写入 MEMORY.md
在第一轮对话中,用户提到“我从北京出发”。主 Agent 会自动将这条信息持久化到 workspace/MEMORY.md 文件中。
当用户第二周再次询问“周末去上海玩两天”时,主 Agent 会读取这份记忆,获知用户常驻北京,从而自动将返程航班规划为“北京-上海-北京”的完整行程。
在配置了 CompactionMiddleware 后,AgentScope 能够自主维护这份跨会话的长期记忆。关于这一机制的详细实现,我们将在第 18 章中深入展开。
10.6 完整工程演示
工程的 pom.xml 配置非常简洁,核心依赖仅需一个:
启动项目后,workspace/state/ 目录会自动生成会话状态文件:
该 JSON 文件完整记录了本次对话的状态信息。如果后续使用相同的 sessionId 进行调用,状态会自动恢复,实现无缝衔接的对话体验。
10.7 本章小结
- 声明式路由:通过
workspace/subagents/*.md文件,产品经理也能轻松参与路由配置,降低技术门槛。 - 编程式补强:在 Java 端通过
SubagentDeclaration可自定义工具、模型及中间件,实现精准的能力控制与扩展。 - 会话隔离:同一份
HarnessAgent支持多次调用,通过RuntimeContext.sessionId实现不同会话间的完全隔离。 - 跨会话记忆:
MEMORY.md由CompactionMiddleware自动维护,为 Agent 提供持久化的上下文记忆能力。
下一章我们将探讨“中断与恢复”场景——用户聊到一半关闭浏览器,二十分钟后返回,如何让 Agent 无缝衔接,继续之前的对话。
