AI项目博客
记录 AI 工程实践与大模型应用

Spring AI Alibaba 36|人工介入 · 完整示例

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

赞(0)
未经允许不得转载:AI项目博客 » Spring AI Alibaba 36|人工介入 · 完整示例

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册