ワンクリックで
deepagents-hitl
Implementing human-in-the-loop approval workflows with interruptOn parameter for sensitive tool operations in Deep Agents.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Implementing human-in-the-loop approval workflows with interruptOn parameter for sensitive tool operations in Deep Agents.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Using the Deep Agents CLI - terminal interface, persistent memory with AGENTS.md, project conventions, skills directories, and CLI commands.
Understanding Deep Agents framework - what they are, how to create them with createDeepAgent, and the agent harness architecture with built-in middleware for planning, filesystems, and subagents.
Creating and using custom skills with progressive disclosure, SKILL.md format, and the Agent Skills protocol in Deep Agents.
Using the Deep Agents CLI - terminal interface, persistent memory with AGENTS.md, project conventions, skills directories, and CLI commands.
Using FilesystemMiddleware with virtual filesystems, backends (State, Store, Filesystem, Composite), and context management for Deep Agents.
Using FilesystemMiddleware with virtual filesystems, backends (State, Store, Filesystem, Composite), and context management for Deep Agents.
SOC 職業分類に基づく
| name | deepagents-hitl |
| description | Implementing human-in-the-loop approval workflows with interruptOn parameter for sensitive tool operations in Deep Agents. |
| language | js |
HITL middleware adds human oversight to tool calls. Execution pauses for human decision: approve, edit, or reject.
Requires checkpointer to save state during interrupts.
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
const agent = await createDeepAgent({
interruptOn: {
write_file: true, // All decisions allowed
execute_sql: { allowedDecisions: ["approve", "reject"] }, // No editing
read_file: false, // No interrupts
},
checkpointer: new MemorySaver() // REQUIRED
});
| Tool Type | Config | Decisions | Use Case |
|---|---|---|---|
| Destructive | true | approve/edit/reject | write_file, delete |
| Critical | {allowedDecisions: [...]} | approve/reject only | deploy, SQL |
| Safe | false | none | 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" } };
// Step 1: Invoke (triggers interrupt)
let result = await agent.invoke({
messages: [{ role: "user", content: "Write config to /prod.yaml" }]
}, config);
// Step 2: Check for interrupts
const state = await agent.getState(config);
if (state.next) {
const interrupt = state.tasks[0];
console.log("Interrupt:", interrupt);
}
// Step 3: Approve
await agent.updateState(config, {
messages: [
new Command({
resume: {
decisions: [{ type: "approve" }]
}
})
]
});
// Step 4: Continue
result = await agent.invoke(null, config);
const agent = await createDeepAgent({
interruptOn: { execute_sql: true },
checkpointer: new MemorySaver()
});
const config = { configurable: { thread_id: "session-1" } };
// Invoke
await agent.invoke({
messages: [{ role: "user", content: "Delete old users" }]
}, config);
// Edit 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"
}
}]
}
})
]
});
// Continue
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: "Deploy to production" }]
}, config);
// Reject
await agent.updateState(config, {
messages: [
new Command({
resume: {
decisions: [{
type: "reject",
message: "Tests haven't passed yet"
}]
}
})
]
});
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: "🚨 PRODUCTION DEPLOYMENT requires approval"
},
send_email: {
description: "📧 Email draft ready for review"
},
},
}),
],
checkpointer: new MemorySaver(),
});
✅ Which tools require approval
✅ Allowed decision types per tool
✅ Custom interrupt descriptions
✅ Checkpointer implementation
❌ HITL protocol structure
❌ Skip checkpointer requirement
❌ Interrupt without saving state
// ❌ Error
await createDeepAgent({ interruptOn: { write_file: true } });
// ✅ Must provide checkpointer
await createDeepAgent({
interruptOn: { write_file: true },
checkpointer: new MemorySaver()
});
// ❌ Can't resume without thread_id
await agent.invoke({...});
await agent.updateState(...); // Which thread?
// ✅ Use consistent thread_id
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({...}, config);
await agent.updateState(config, ...);
// Interrupts happen between invoke() calls
// Step 1: invoke() -> interrupt
await agent.invoke({...}, config);
// Step 2: Check state
const state = await agent.getState(config);
if (state.next) {
// Handle interrupts
}
// Step 3: Resume
await agent.updateState(config, {...});
await agent.invoke(null, config);