team - 人工介入(HITL)
在多智能体协作中,人工介入(Human-In-The-Loop)的本质是团队协作流与成员执行流的联动。TeamAgent 的成员 ReActAgent 可通过 HITL 拦截器挂起敏感工具调用;pending 状态保存在 AgentSession,TeamTrace 用于保存协作轨迹。
更多可参考:ReActAgent 人工介入(HITL)
1、核心原理:协同拦截与断点恢复
- 原子拦截(借力 ReAct):
任务在团队中流转到某个 ReActAgent 时,若其试图调用敏感工具,会被 HITLInterceptor 捕捉。此时,拦截器会通过 session.pending(true, summary) 挂起当前会话,并向团队协议发出挂起信号。
- 协作挂起(Pending):
协作流程(如 SequentialProtocol / SupervisorTask)在每步流转前检查 session.isPending(),一旦发现挂起立即停止继续派发任务,形成“协作断点”。断点状态存放在 AgentSession 上(TeamTrace 本身不提供 isPending),而不是靠 FlowContext.stop() 这类方法。
- 精准恢复:
当人类回填决策后,使用同一个 Session 和空 Prompt 恢复。正常批准时通常复用挂起前的 Reason 状态并进入 Action;拒绝、跳过或异常路径下不保证一定执行工具,也不保证出现完整的 Action/Tool 事件链。
流式调用首次挂起时,典型事件是:
ReasonEndEvent
-> HITLPendingEvent
-> RunEndEvent(成员当前请求结束,isAbnormal=true)
首次挂起不会产生 ActionStartEvent、ToolCallStartEvent、ToolCallEndEvent 或 ActionEndEvent,并且不是 Reactor onError。团队流的最终边界仍是父 Team 的 TeamEndEvent。
2、代码实现详解
- 第一步:为执行层配置拦截器
// 1. 定义拦截器(只有 ReAct 会用到工具拦截)
HITLInterceptor hitl = new HITLInterceptor()
.onSensitiveTool("transfer", "refund");
// 2. 配置执行层 Agent
ReActAgent cashier = ReActAgent.of(chatModel)
.name("cashier")
.defaultInterceptorAdd(hitl) // 拦截器挂载到具体干活的 Agent 上
.build();
// 3. 配置管理层 Agent(编排流转)
TeamAgent financeTeam = TeamAgent.of(chatModel)
.protocol(TeamProtocols.SEQUENTIAL)
.agentAdd(accountant) // 会计不拦截
.agentAdd(cashier) // 出纳负责拦截
.build();
- 第二步:识别团队挂起状态
AgentSession session = InMemoryAgentSession.of("sid_001");
TeamResponse resp = financeTeam.prompt("查余额并转账 3000 元").session(session).call();
// 尽管拦截发生在 cashier 内部,但我们只需检查会话状态
if (session.isPending()){
// 此时会计的工作已记录在 trace 中,流程停在了出纳执行工具前
HITLTask task = HITL.getPendingTask(session);
System.out.println("团队协作暂停,等待审批工具: "+task.getToolName());
}
- 第三步:决策回填与团队唤醒
// 1. 人类提交决策(如:修改金额为 1000)
// 注意:决策主键是 callUuid,必须面向 HITLTask 提交;
// modifiedArgs 接收 Map,而非 (key, value) 两参
HITLTask task = HITL.getPendingTask(session);
Map<String, Object> newArgs = new HashMap<>();
newArgs.put("amount", 1000);
HITL.submit(session, task, HITLDecision.approve().modifiedArgs(newArgs));
// 2. 团队原位恢复
// 拦截器在 onAgentStart 发现全部已决策后,直接让出纳 Agent 执行修正后的工具
TeamResponse respFinal = financeTeam.prompt().session(session).call();
4、协作闭环的优势
- 精准定位断点:
由于借助了 ReAct 的拦截,断点精确发生在“工具执行前”。这意味着会计(Accountant)查余额的操作已经落库,恢复后不会重复查询,节省 Token。
- 职责分离:
TeamAgent 负责把球传给谁,ReActAgent 负责球怎么踢。HITL 解决了“球踢到一半”需要人看一眼的问题。
- 状态透明化:
通过 TeamTrace,人类可以追溯到是哪个 Agent 在哪一个步骤、因为哪一个参数被挂起的,提供了完整的协作链路审计。