import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.hook.hip.HumanInTheLoopHook;
import com.alibaba.cloud.ai.graph.agent.hook.hip.ToolConfig;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import com.alibaba.cloud.ai.graph.NodeOutput;
import com.alibaba.cloud.ai.graph.action.InterruptionMetadata;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
public class HumanInTheLoopExample {
public static void main(String[] args) throws Exception {
// 1. 配置检查点
MemorySaver memorySaver = new MemorySaver();
// 2. 创建人工介入Hook
HumanInTheLoopHook humanInTheLoopHook = HumanInTheLoopHook.builder()
.approvalOn("poem", ToolConfig.builder()
.description("请确认诗歌创作操作")
.build())
.build();
// 3. 创建Agent
ReactAgent agent = ReactAgent.builder()
.name("poet_agent")
.model(chatModel)
.tools(List.of(poetToolCallback))
.hooks(List.of(humanInTheLoopHook))
.saver(memorySaver)
.build();
String threadId = "user-session-001";
RunnableConfig config = RunnableConfig.builder()
.threadId(threadId)
.build();
// 4. 第一次调用 - 触发中断
System.out.println("=== 第一次调用:期望中断 ===");
Optional<NodeOutput> result = agent.invokeAndGetOutput(
"帮我写一首100字左右的诗",
config
);
// 5. 检查中断并处理
if (result.isPresent() && result.get() instanceof InterruptionMetadata) {
InterruptionMetadata interruptionMetadata = (InterruptionMetadata) result.get();
System.out.println("检测到中断,需要人工审批");
List<InterruptionMetadata.ToolFeedback> toolFeedbacks =
interruptionMetadata.toolFeedbacks();
for (InterruptionMetadata.ToolFeedback feedback : toolFeedbacks) {
System.out.println("工具: " + feedback.getName());
System.out.println("参数: " + feedback.getArguments());
System.out.println("描述: " + feedback.getDescription());
}
// 6. 模拟人工决策(这里选择批准)
InterruptionMetadata.Builder feedbackBuilder = InterruptionMetadata.builder()
.nodeId(interruptionMetadata.node())
.state(interruptionMetadata.state());
toolFeedbacks.forEach(toolFeedback -> {
InterruptionMetadata.ToolFeedback approvedFeedback =
InterruptionMetadata.ToolFeedback.builder(toolFeedback)
.result(InterruptionMetadata.ToolFeedback.FeedbackResult.APPROVED)
.build();
feedbackBuilder.addToolFeedback(approvedFeedback);
});
InterruptionMetadata approvalMetadata = feedbackBuilder.build();
// 7. 第二次调用 - 使用人工反馈恢复执行
System.out.println("
=== 第二次调用:使用批准决策恢复 ===");
RunnableConfig resumeConfig = RunnableConfig.builder()
.threadId(threadId)
.addMetadata(RunnableConfig.HUMAN_FEEDBACK_METADATA_KEY, approvalMetadata)
.build();
Optional<NodeOutput> finalResult = agent.invokeAndGetOutput("", resumeConfig);
if (finalResult.isPresent()) {
System.out.println("执行完成");
System.out.println("最终结果: " + finalResult.get());
}
}
}
}
本文整理自 Spring AI Alibaba 官方文档《人工介入》:https://java2ai.com/docs/frameworks/agent-framework/advanced/human-in-the-loop

AI项目博客






