Solon v3.9.3

team - 人工介入(HITL)

</> markdown
2026年2月5日 下午9:00:45

在多智能体协作中,人工介入(Human-In-The-Loop) 的本质是“协作流”与“执行流”的深度联动。由于 TeamAgent 本身不直接调用工具,其 HITL 机制本质上是借助底层 ReActAgent 的拦截能力,结合 TeamTrace 的状态断点实现的。

更多可参考:ReActAgent 人工介入(HITL)

1、核心原理:协同拦截与断点恢复

  • 原子拦截(借力 ReAct):

任务在团队中流转到某个 ReActAgent 时,若其试图调用敏感工具,会被 HITLInterceptor 捕捉。此时,底层 Agent 会向 TeamTrace 发出挂起信号。

  • 协作挂起(Pending):

TeamTrace 接收信号并进入 pending 状态,同时通过 FlowContext.stop() 冻结整个团队的协作链条,形成“协作断点”。

  • 精准恢复:

当人类回填决策后,再次调用 teamAgent.call(session)。系统通过 prepare() 重置状态,确保团队直接在那个“正在握着工具”的 Agent 节点上原位复活。

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 (resp.getTrace().isPending()) {
    // 此时会计的工作已记录在 trace 中,流程停在了出纳执行工具前
    HITLTask task = HITL.getPendingTask(session); 
    System.out.println("团队协作暂停,等待审批工具: " + task.getToolName());
}
  • 第三步:决策回填与团队唤醒
// 1. 人类提交决策(如:修改金额为 1000)
HITL.submit(session, "transfer", HITLDecision.approve().modifiedArgs("amount", 1000));

// 2. 团队原位恢复
// 此时 prepare() 会重置 finalAnswer,出纳 Agent 发现有 Decision,直接执行修正后的工具
TeamResponse respFinal = financeTeam.session(session).call();

4、协作闭环的优势

  • 精准定位断点:

由于借助了 ReAct 的拦截,断点精确发生在“工具执行前”。这意味着会计(Accountant)查余额的操作已经落库,恢复后不会重复查询,节省 Token。

  • 职责分离:

TeamAgent 负责把球传给谁,ReActAgent 负责球怎么踢。HITL 解决了“球踢到一半”需要人看一眼的问题。

  • 状态透明化:

通过 TeamTrace,人类可以追溯到是哪个 Agent 在哪一个步骤、因为哪一个参数被挂起的,提供了完整的协作链路审计。