子智能体挂载Skill和大模型结构化输出与Agent生命周期拦截器
1.子智能体SubAgent
子智能体是指被父级 Agent 当作"工具"来调用的下层 Agent。它不是普通的函数调用,而是一个具备独立推理能力的Agent,有自己的 prompt、tools、skills,能自主完成父 Agent 分配的专项任务。这本质上就是 AI Agent 领域的服务化拆分 —— 和微服务把单体拆成多个独立服务是同一个思想。
子智能体创建,现在我们的行程规划智能体下有一个子智能体景点推荐作为工具:
@Component
public class SuggestSightAgent {
@Resource
private AgentUtils agentUtils;
public ReActAgent getSuggestSightAgent() {
Toolkit toolkit = new Toolkit();
//构建Skill,并将工具包和Skill结合
SkillBox skillBox = new SkillBox(toolkit);
//以文件形式读取Skill.md
JarSkillRepositoryAdapter repo = null;
try {
repo = new JarSkillRepositoryAdapter(
"skills"
);
} catch (IOException e) {
throw new RuntimeException(e);
}
//景点推荐技能
AgentSkill SuggestSightsSkill = repo.getSkill("Suggest-Sights");
//AgentSkill MakeATableSkill = repo.getSkill("Make-A-Table");
skillBox.registerSkill(SuggestSightsSkill);
//skillBox.registerSkill(MakeATableSkill);
//注册工具
skillBox.registration().tool(new Calculate());
ReActAgent.Builder builder = agentUtils.getReActAgentBuilder(
"SuggestSightAgent",
"擅长景点推荐"
)
//挂载工具包
.toolkit(toolkit)
//挂载Skills
.skillBox(skillBox);
return builder.build();
}
}
接着在主智能体当中把子智能体作为工具导入:
@Component
public class TripPlannerAgent {
@Resource
private AgentUtils agentUtils;
@Bean
public ReActAgent getTripPlannerAgent() throws Exception {
Toolkit toolkit = new Toolkit();
SuggestSightAgent suggestSightAgent = new SuggestSightAgent();
//将子智能体作为工具
toolkit.registration().subAgent(
suggestSightAgent::getSuggestSightAgent
).apply();
//构建skill ,将工具包和skill结合
return agentUtils.getReActAgentBuilder(
"TripPlannerAgent",
"擅长处理景点行程规划"
)
//挂载工具包
.toolkit(toolkit)
.build();
}
}
在工具包注册方法源码中就有这个段代码解释:
public ToolRegistration subAgent(SubAgentProvider<?> provider) {
return this.subAgent(provider, (SubAgentConfig)null);
}
2.Skill配置
在resources文件下,创建这个目录:

.py是python的脚本
SKILL.md文件的头部写入:
---
name: Make-A-Table
description: 擅长在有限预算内规划出精彩的旅行体验
---
name属性必须和目录名字一样。
以另一个skill为主,skill的主要内容:
---
name: Suggest-Sights
description: 擅长在有限预算内规划出精彩的旅行体验
---
## 核心能力
### 1. 免费景点推荐
- 推荐自然风光、历史古迹、特色街区
- 提供最佳游览时间和小众路线
- 分享避开人群的技巧
### 2. 美食探索
- 推荐当地特色小吃和地道餐厅
- 侧重性价比高的本地美食
- 分享当地人常去的隐瞒美食店
### 3. 打卡点推荐
- 推荐网红打卡点和拍照圣地
- 分享小众但出片的秘密景点
### 4. 住宿建议
提供住宿方案:
- **经济型**:青旅、民宿
- **舒适型**:连锁酒店
## 工作流程
1. **分析规划**:综合考虑距离、时间、费用、景点分布因素
2. **方案输出**:提供景点推荐、美食指南、住宿方案
## 回答原则
1. **务实优先**:所有建议要考虑实际可行性和经济性
2. **信息准确**:提供具体的地址、价格区间、开放时间
3. **因地制宜**:根据季节、天气给出适当的建议
skillbox即可以注册工具也可以加载技能,而且主智能体不需要挂载skill。
行程规划主智能体下面有一个景点推荐子智能体挂载了景点推荐的skill。
3.结构化输出
让语言大模型返回类型,创建一个相应格式(必须要有一个无参构造函数):
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseSchema {
private String response;
}
return agentUtils.getReActAgentBuilder("ManagerAgent", "主管Agent").planNotebook(planNotebook)
//拦截器
.hook(new PlanHook(planNotebook))
.toolkit(toolkit)
//结构化输出
.structuredOutputReminder(StructuredOutputReminder.PROMPT)
.build();
让它自动匹配我们规定要返回的格式。老模型是不支持的
4.Agent生命周期拦截器:
@Slf4j
public class PlanHook implements Hook {
//监听用户输入
private final UserAgent user;
//计划步骤
private final PlanNotebook plan;
public PlanHook(PlanNotebook planNotebook) {
this.user = UserAgent.builder()
.name("User")
.build();
this.plan = planNotebook;
}
@Override
public <T extends HookEvent> Mono<T> onEvent(T event) {
/* **********************
*
* Hook 是对 HookEvent事件 的拦截
* HookEvent事件:
*
* PreReasoningEvent:用户的输入事件
* PostReasoningEvent: Agent推理思考过程事件
* PreActingEvent: Agent执行过程准备调用工具的事件
* PostActingEvent:Agent执行过程调用工具完成的事件
*
* *********************/
//匹配不同的事件
switch (event) {
//用户输入事件
case PreReasoningEvent e -> {
String reason = e.getInputMessages().get(0).getTextContent();
log.info("#### 用户的Prompt:#######");
log.info(reason);
}
//推理思考事件
case PostReasoningEvent e -> {
String reason = e.getReasoningMessage().getTextContent();
log.info("#### 思考过程:#######");
log.info(reason);
//当计划列表已生成
Plan currentPlan = plan.getCurrentPlan();
if (currentPlan != null) {
System.out.println("请输入修改意见: ");
user.call().block();
}
}
//调用工具事件
case PostActingEvent e -> {
String toolName = e.getToolUse().getName();
log.info("##### 调用工具:" + toolName);
}
default -> {
// 其他事件忽略
}
}
// 返回原事件
return Mono.just(event);
}
}
四个事件的的作用:
| PreReasoningEvent e | 用户输入 |
| PostReasoningEvent e | 推理完成 ← 计划监听在这里 |
| PostActingEvent e | 工具调用完成 |
| default | 忽略其他 |
其中与计划相关的是 PostReasoningEvent:
case PostReasoningEvent e -> {
Plan currentPlan = plan.getCurrentPlan();
if (currentPlan != null) { // 计划步骤已生成
user.call().block(); // 暂停,等用户确认/修改
}
}
当 Agent 推理完成并生成了计划步骤(PlanNotebook 中的子任务列表)后,这里检测到 currentPlan != null,就调用 UserAgent阻塞等待,让用户有机会审核计划、提出修改意见,然后 Agent 再继续执行。
所以准确地说:PlanHook 是 Agent 生命周期拦截器,它的核心职责是"当计划生成后暂停,实现人在回路",而不仅仅是监听计划。
5.PlanNotBook
TripPlan类作为PlanNotebook 的配置工厂:
public class TripPlan {
public PlanNotebook getPlan() {
return PlanNotebook.builder()
//计划步骤是否需要用户确认
.needUserConfirm(true)
//分解出来的子任务数量限制
.maxSubtasks(5)
//计划的存储方式
//.storeage()
.build();
}
}
真正负责任务分解、分配、跟踪的是 PlanNotebook 这个对象。ManagerAgent 把它注入进来后,ReActAgent 在运行时会自动:
1. 将用户复杂需求拆解成子任务列表
2. 按步骤调用远程 Agent 执行
3. 跟踪每个子任务状态(pending → in_progress → completed)
4. 根据中间结果动态调整计划
简单类比:TripPlan = 配置参数,PlanNotebook = 规划引擎,ManagerAgent = 执行者。
在ManagerAgen中声明:
@Component
public class ManagerAgent {
@Resource
private AgentUtils agentUtils;
public ReActAgent getManagerAgent() {
TripPlan plan = new TripPlan();
//计划对象
PlanNotebook planNotebook = plan.getPlan();
ToolUtils toolUtils = new ToolUtils();
//将远程Agent封装为工具的封装
Toolkit toolkit = toolUtils.getToolkit(new RemoteAgentTool());
return agentUtils.getReActAgentBuilder("ManagerAgent", "主管Agent").planNotebook(planNotebook)
//拦截器
.hook(new PlanHook(planNotebook))
.toolkit(toolkit)
//结构化输出
.structuredOutputReminder(StructuredOutputReminder.PROMPT)
.build();
}
public ResponseSchema run(String prompt) {
ReActAgent agent = getManagerAgent();
Flux<Event> stream = AgentUtils.streamResponse(agent, prompt);
return stream.blockLast().getMessage().getStructuredData(ResponseSchema.class);
}
}
ReActAgent 具备自主分解复杂任务的能力,并自动生成计划步骤。 启用规划有两种方式:
- enablePlan():内部调用 PlanNotebook 的 Builder 构造方法,使用默认配置,适合快速启动。
- planNotebook():传入自定义的 PlanNotebook 实例,可对规划行为进行精细配置(如子任务数量上限、是否需要用户确认等)。
PlanNotebook 赋予主管 Agent 完整的规划闭环:
1. 复杂任务分解
2. 生成执行步骤
3. 状态跟踪
4. 动态调整
5. 任务完成
核心定位:PlanNotebook = 自主规划(Plan) + 自主决策(Act),是 ReActAgent 实现 "先规划、后执行、按需修正" 的引擎。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)