用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tomevault-io/skills-registry --skill deepagents-hitl命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | deepagents-hitl |
| description | 在 Deep Agents 中实现人工审批工作流,使用 interruptOn 参数对敏感工具操作进行人工干预。 Use when this capability is needed. |
| metadata | {"author":"evanfang0054"} |
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 |
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" } };
// 步骤 1:调用(触发中断)
let result = await agent.invoke({
messages: [{ role: "user", content: "将配置写入 /prod.yaml" }]
}, config);
// 步骤 2:检查中断
const state = await agent.getState(config);
if (state.next) {
const interrupt = state.tasks[0];
console.log("中断:", interrupt);
}
// 步骤 3:批准
await agent.updateState(config, {
messages: [
new Command({
: {
: [{ : }]
}
})
]
});
result = agent.(, config);
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);
// 编辑 SQL
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);
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);
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(),
});
✅ 哪些工具需要审批 ✅ 每个工具允许的决策类型 ✅ 自定义中断描述 ✅ Checkpointer 实现
❌ HITL 协议结构 ❌ 跳过 checkpointer 要求 ❌ 中断时不保存状态
// ❌ 错误
await createDeepAgent({ interruptOn: { write_file: true } });
// ✅ 必须提供 checkpointer
await createDeepAgent({
interruptOn: { write_file: true },
checkpointer: new MemorySaver()
});
// ❌ 没有 thread_id 无法恢复
await agent.invoke({...});
await agent.updateState(...); // 哪个会话?
// ✅ 使用一致的 thread_id
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({...}, config);
await agent.updateState(config, ...);
// 中断发生在 invoke() 调用之间
// 步骤 1: invoke() -> 中断
await agent.invoke({...}, config);
// 步骤 2: 检查状态
const state = await agent.getState(config);
if (state.next) {
// 处理中断
}
// 步骤 3: 恢复
await agent.updateState(config, {...});
await agent.invoke(null, config);
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
基于 SOC 职业分类