为了简化人工介入的处理,你可以创建实用方法:
public class HITLHelper {
/**
* 批准所有工具调用
*/
public static InterruptionMetadata approveAll(InterruptionMetadata interruptionMetadata) {
InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
.nodeId(interruptionMetadata.node())
.state(interruptionMetadata.state());
interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
builder.addToolFeedback(
InterruptionMetadata.ToolFeedback.builder(toolFeedback)
.result(InterruptionMetadata.ToolFeedback.FeedbackResult.APPROVED)
.build()
);
});
return builder.build();
}
/**
* 拒绝所有工具调用
*/
public static InterruptionMetadata rejectAll(
InterruptionMetadata interruptionMetadata,
String reason) {
InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
.nodeId(interruptionMetadata.node())
.state(interruptionMetadata.state());
interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
builder.addToolFeedback(
InterruptionMetadata.ToolFeedback.builder(toolFeedback)
.result(InterruptionMetadata.ToolFeedback.FeedbackResult.REJECTED)
.description(reason)
.build()
);
});
return builder.build();
}
/**
* 编辑特定工具的参数
*/
public static InterruptionMetadata editTool(
InterruptionMetadata interruptionMetadata,
String toolName,
String newArguments) {
InterruptionMetadata.Builder builder = InterruptionMetadata.builder()
.nodeId(interruptionMetadata.node())
.state(interruptionMetadata.state());
interruptionMetadata.toolFeedbacks().forEach(toolFeedback -> {
if (toolFeedback.getName().equals(toolName)) {
builder.addToolFeedback(
InterruptionMetadata.ToolFeedback.builder(toolFeedback)
.arguments(newArguments)
.result(InterruptionMetadata.ToolFeedback.FeedbackResult.EDITED)
.build()
);
} else {
builder.addToolFeedback(
InterruptionMetadata.ToolFeedback.builder(toolFeedback)
.result(InterruptionMetadata.ToolFeedback.FeedbackResult.APPROVED)
.build()
);
}
});
return builder.build();
}
}
// 使用示例
InterruptionMetadata approvalMetadata = HITLHelper.approveAll(interruptionMetadata);
InterruptionMetadata rejectMetadata = HITLHelper.rejectAll(interruptionMetadata, "操作不安全");
InterruptionMetadata editMetadata = HITLHelper.editTool(
interruptionMetadata,
"execute_sql",
"{"query": "SELECT * FROM records LIMIT 10"}"
);
- 始终使用检查点: 人工介入需要检查点机制来保存和恢复状态
- 提供清晰的描述: 在 ToolConfig 中提供清晰的描述,帮助审查者理解操作
- 保守编辑: 编辑工具参数时,尽量保持最小更改
- 处理所有工具反馈: 确保为每个需要审查的工具调用提供决策
- 使用相同的 threadId: 恢复执行时必须使用相同的线程 ID
- 考虑超时: 实现超时机制以处理长时间未响应的人工审批
- Hooks – 了解 Hook 机制
- Interceptors – 了解 Interceptor 机制
- Memory – 检查点和持久化
- Agents – Agent 基础概念
本文整理自 Spring AI Alibaba 官方文档《人工介入》:https://java2ai.com/docs/frameworks/agent-framework/advanced/human-in-the-loop

AI项目博客






