| name | deepagents-hitl |
| description | 在 Deep Agents 中实现人工审批工作流,使用 interruptOn 参数对敏感工具操作进行人工干预。 |
| language | js |
deepagents-hitl (JavaScript/TypeScript)
概述
HITL 中间件为工具调用添加人工监督。执行暂停以等待人工决策:批准、编辑或拒绝。
需要 checkpointer 在中断期间保存状态。
基本设置
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const agent = await createDeepAgent({
interruptOn: {
write_file: true,
execute_sql: { allowedDecisions: ["approve", "reject"] },
read_file: false,
},
checkpointer: new MemorySaver()
});
决策表
| 工具类型 | 配置 | 决策 | 使用场景 |
|---|
| 破坏性 | true | 批准/编辑/拒绝 | write_file、delete |
| 关键 | {allowedDecisions: [...]} | 仅批准/拒绝 | deploy、SQL |
| 安全 | false | 无 | read_file |
代码示例
示例 1:基本审批
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
import { Command } from "@langchain/langgraph";
const agent = await createDeepAgent({
interruptOn: { write_file: true },
checkpointer: new MemorySaver()
});
const config = { configurable: { thread_id: "session-1" } };
let result = await agent.invoke({
messages: [{ role: "user", content: "将配置写入 /prod.yaml" }]
}, config);
const state = await agent.getState(config);
if (state.next) {
const interrupt = state.tasks[0];
console.log("中断:", interrupt);
}
await agent.updateState(config, {
messages: [
new Command({
resume: {
decisions: [{ type: "approve" }]
}
})
]
});
result = await agent.invoke(null, config);
示例 2:执行前编辑
const agent = await createDeepAgent({
interruptOn: { execute_sql: true },
checkpointer: new MemorySaver()
});
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({
messages: [{ role: "user", content: "删除旧用户" }]
}, config);
await agent.updateState(config, {
messages: [
new Command({
resume: {
decisions: [{
type: "edit",
args: {
query: "DELETE FROM users WHERE last_login < '2020-01-01' LIMIT 100"
}
}]
}
})
]
});
await agent.invoke(null, config);
示例 3:拒绝并提供反馈
const agent = await createDeepAgent({
interruptOn: { deploy_code: true },
checkpointer: new MemorySaver()
});
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({
messages: [{ role: "user", content: "部署到生产环境" }]
}, config);
await agent.updateState(config, {
messages: [
new Command({
resume: {
decisions: [{
type: "reject",
message: "测试尚未通过"
}]
}
})
]
});
await agent.invoke(null, config);
示例 4:自定义中间件
import { createAgent, humanInTheLoopMiddleware } from "langchain";
import { MemorySaver } from "@langchain/langgraph";
const agent = createAgent({
model: "gpt-4",
tools: [deployTool, sendEmailTool],
middleware: [
humanInTheLoopMiddleware({
interruptOn: {
deploy_to_prod: {
allowedDecisions: ["approve", "reject"],
description: "🚨 生产环境部署需要审批"
},
send_email: {
description: "📧 邮件草稿已准备好审核"
},
},
}),
],
checkpointer: new MemorySaver(),
});
边界
Agent 可以配置的内容
✅ 哪些工具需要审批
✅ 每个工具允许的决策类型
✅ 自定义中断描述
✅ Checkpointer 实现
Agent 不能配置的内容
❌ HITL 协议结构
❌ 跳过 checkpointer 要求
❌ 中断时不保存状态
注意事项
1. Checkpointer 是必需的
await createDeepAgent({ interruptOn: { write_file: true } });
await createDeepAgent({
interruptOn: { write_file: true },
checkpointer: new MemorySaver()
});
2. 需要 Thread ID
await agent.invoke({...});
await agent.updateState(...);
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({...}, config);
await agent.updateState(config, ...);
3. 在调用之间检查状态
await agent.invoke({...}, config);
const state = await agent.getState(config);
if (state.next) {
}
await agent.updateState(config, {...});
await agent.invoke(null, config);
完整文档