Spring AI Alibaba 人工介入实战|Human-in-the-Loop 让 AI 更可靠

张开发
2026/4/7 12:35:25 15 分钟阅读

分享文章

Spring AI Alibaba 人工介入实战|Human-in-the-Loop 让 AI 更可靠
引言在构建AI智能体应用时我们经常面临一个关键挑战如何让AI在执行某些敏感操作前获得人工确认Spring AI Alibaba框架提供了强大的人工介入Human-in-the-Loop机制让开发者能够精确控制AI工具的执行流程在关键节点引入人工审批环节。本文将通过一个完整的实战示例详细介绍如何在Spring AI Alibaba应用中实现人工介入功能。什么是人工介入人工介入是一种机制它允许AI智能体在执行特定工具前暂停执行等待人工审批后再继续。这种机制特别适用于敏感操作如数据删除、资金转账等内容生成如文章发布、诗歌创作等需要质量把控的场景权限控制某些需要特定权限才能执行的操作审计要求需要记录人工决策过程的场景实战示例诗歌创作的人工审批让我们通过一个具体的例子来理解人工介入Hook的使用。这个示例展示了如何让AI在创作诗歌前获得人工确认。1. 项目依赖配置首先确保你的项目中包含了Spring AI Alibaba相关依赖dependencies !-- Spring AI Alibaba Agent Framework -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-agent-framework/artifactId version1.1.2.0/version /dependency !-- DashScope ChatModel 支持如果使用其他模型请跳转 Spring AI 文档选择对应的 starter -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId version1.1.2.0/version /dependency /dependencies2. 代码实现解析步骤1构建AI模型// 构建DashScope API对象 DashScopeApi dashScopeApi DashScopeApi.builder() .apiKey(System.getenv(AliQwen_API)) .build(); // 创建聊天模型 ChatModel chatModel DashScopeChatModel.builder() .dashScopeApi(dashScopeApi) .build();步骤2配置工具public class PoetTool implements BiFunctionString, ToolContext, String { public int count 0; public PoetTool() { } Override public String apply( ToolParam(description The original user query that triggered this tool call) String originalUserQuery, ToolContext toolContext) { count; System.out.println(Poet tool called : originalUserQuery); return 在城市的缝隙里 \n 一束光悄悄发芽 \n 穿过钢筋水泥的沉默 \n 在风中轻轻说话。 \n \n 夜色如墨却不再黑 \n 星星点亮了每一个角落 \n 我站在时间的边缘 \n 等一朵云轻轻落下; } public static ToolCallback createPoetToolCallback() { return FunctionToolCallback.builder(poem, new PoetTool()) .description(用来写诗的工具) .inputType(String.class) .build(); } public static ToolCallback createPoetToolCallback(String name, PoetTool poetTool) { return FunctionToolCallback.builder(name, poetTool) .description(用来写诗的工具) .inputType(String.class) .build(); } }步骤3构建带有Hook的智能体// 这里我们配置了poem工具需要人工审批并提供了审批时的描述信息。 MapString, ToolConfig approvalOn Map.of( poem, ToolConfig.builder() .description(请确认诗歌工具执行) .build() ); ReactAgent agent ReactAgent.builder() .name(single_agent) .model(chatModel) .saver(new MemorySaver()) // 使用内存保存状态 .tools(List.of(createPoetToolCallback())) // 添加诗歌创作工具 .hooks(HumanInTheLoopHook.builder() .approvalOn(approvalOn) // 添加人工介入Hook .build()) .outputKey(article) .build();步骤4创建会话配置String threadId user-session-001; RunnableConfig config RunnableConfig.builder() .threadId(threadId) .build();步骤5执行并处理中断// 第一次调用 - 触发中断 OptionalNodeOutput result agent.invokeAndGetOutput( 帮我写一首100字左右的诗, config ); // 检查是否触发中断 if (result.isPresent() result.get() instanceof InterruptionMetadata) { InterruptionMetadata interruptionMetadata (InterruptionMetadata) result.get(); System.out.println(检测到中断需要人工审批); // 获取工具反馈信息 ListInterruptionMetadata.ToolFeedback toolFeedbacks interruptionMetadata.toolFeedbacks(); for (InterruptionMetadata.ToolFeedback feedback : toolFeedbacks) { System.out.println(id: feedback.getId()); System.out.println(工具: feedback.getName()); System.out.println(参数: feedback.getArguments()); System.out.println(描述: feedback.getDescription()); } // 模拟人工决策批准 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(); // 使用人工反馈恢复执行 RunnableConfig resumeConfig RunnableConfig.builder() .threadId(threadId) .addMetadata(RunnableConfig.HUMAN_FEEDBACK_METADATA_KEY, approvalMetadata) .build(); OptionalNodeOutput finalResult agent.invokeAndGetOutput(, resumeConfig); if (finalResult.isPresent()) { System.out.println(执行完成); // 因为创建智能体的时候指定了outputKey所以这里我们直接获取 Object article finalResult.get().state().data().get(article); System.out.println(最终结果: article); } }3. 执行流程分析这个示例的执行流程如下触发阶段用户请求AI创作诗歌中断阶段AI检测到poem工具需要人工审批暂停执行审批阶段系统展示工具信息等待人工决策恢复阶段人工批准后AI继续执行并生成诗歌完成阶段返回最终结果高级特性多工具审批你可以为多个工具配置审批MapString, ToolConfig approvalOn Map.of( poem, ToolConfig.builder().description(诗歌创作工具).build(), delete, ToolConfig.builder().description(数据删除工具).build(), publish, ToolConfig.builder().description(内容发布工具).build() );审批结果类型支持多种审批结果APPROVED批准执行REJECTED拒绝执行MODIFIED修改参数后执行最佳实践1. 明确审批策略只为真正需要人工确认的工具配置审批提供清晰的审批描述信息考虑审批的时效性2. 用户体验优化提供友好的审批界面支持批量审批操作记录审批历史便于审计3. 错误处理try { OptionalNodeOutput result agent.invokeAndGetOutput(request, config); // 处理中断和结果 } catch (GraphRunnerException e) { // 处理执行异常 log.error(智能体执行失败, e); }4. 状态管理// 使用合适的Saver .saver(new MemorySaver()) // 内存存储适合开发测试 .saver(new RedisSaver()) // Redis存储适合生产环境 .saver(new DatabaseSaver()) // 数据库存储适合需要持久化的场景5. 执行结果拓展

更多文章