一键导入
deepagents-hitl
Implementing human-in-the-loop approval workflows with interrupt_on parameter for sensitive tool operations in Deep Agents.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Implementing human-in-the-loop approval workflows with interrupt_on parameter for sensitive tool operations in Deep Agents.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
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.
| name | deepagents-hitl |
| description | Implementing human-in-the-loop approval workflows with interrupt_on parameter for sensitive tool operations in Deep Agents. |
| language | python |
Human-in-the-Loop (HITL) middleware adds human oversight to tool calls. When the agent proposes a sensitive action, execution pauses for human decision:
Requires LangGraph's persistence (checkpointer) to save state during interrupts.
| Use HITL When | Skip HITL When |
|---|---|
| High-stakes operations (DB writes, deployments) | Read-only operations |
| Compliance requires human oversight | Fully automated workflows |
| Expensive API calls need verification | Low-cost operations |
| Learning agent behavior | Trusted, tested operations |
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
agent = create_deep_agent(
interrupt_on={
"write_file": True, # All decisions allowed (approve/edit/reject)
"execute_sql": {"allowed_decisions": ["approve", "reject"]}, # No editing
"read_file": False, # No interrupts
},
checkpointer=MemorySaver() # REQUIRED for interrupts
)
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import MemorySaver
agent = create_agent(
model="gpt-4",
tools=[write_file_tool, execute_sql_tool, read_data_tool],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
"write_file": True,
"execute_sql": {"allowed_decisions": ["approve", "reject"]},
"read_data": False,
},
description_prefix="Tool execution pending approval",
),
],
checkpointer=MemorySaver(),
)
| Tool Type | Interrupt Config | Allowed Decisions | Use Case |
|---|---|---|---|
| Destructive | True | approve, edit, reject | write_file, delete_record |
| Critical | {"allowed_decisions": ["approve", "reject"]} | approve, reject only | deploy_code, execute_sql |
| Safe | False | none | read_file, get_weather |
| Expensive | True | approve, edit, reject | call_paid_api |
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
agent = create_deep_agent(
interrupt_on={"write_file": True},
checkpointer=MemorySaver()
)
# Initial invocation
config = {"configurable": {"thread_id": "session-1"}}
result = agent.invoke({
"messages": [{"role": "user", "content": "Write deployment config to /config/prod.yaml"}]
}, config=config)
# Execution pauses - check for interrupts
state = agent.get_state(config)
if state.next: # Has interrupts
for interrupt in state.tasks:
print(f"Interrupt: {interrupt}")
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
from langchain.schema import Command
agent = create_deep_agent(
interrupt_on={"write_file": True},
checkpointer=MemorySaver()
)
config = {"configurable": {"thread_id": "session-1"}}
# Step 1: Agent proposes write_file
result = agent.invoke({
"messages": [{"role": "user", "content": "Write config to /prod.yaml"}]
}, config=config)
# Step 2: Get interrupts
state = agent.get_state(config)
interrupt = state.tasks[0] # First interrupt
# Step 3: Approve
agent.update_state(
config,
{
"messages": [
Command(
resume={
"decisions": [{"type": "approve"}]
}
)
]
}
)
# Step 4: Continue execution
result = agent.invoke(None, config=config)
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
from langchain.schema import Command
agent = create_deep_agent(
interrupt_on={"execute_sql": True},
checkpointer=MemorySaver()
)
config = {"configurable": {"thread_id": "session-1"}}
# Agent proposes SQL
result = agent.invoke({
"messages": [{"role": "user", "content": "Delete old records from users table"}]
}, config=config)
# Get interrupt details
state = agent.get_state(config)
interrupt = state.tasks[0]
print(f"Proposed SQL: {interrupt.value['action_requests'][0]['args']}")
# Edit the SQL query
agent.update_state(
config,
{
"messages": [
Command(
resume={
"decisions": [{
"type": "edit",
"args": {
"query": "DELETE FROM users WHERE last_login < '2020-01-01' LIMIT 100"
}
}]
}
)
]
}
)
# Continue with edited query
result = agent.invoke(None, config=config)
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
from langchain.schema import Command
agent = create_deep_agent(
interrupt_on={"deploy_code": True},
checkpointer=MemorySaver()
)
config = {"configurable": {"thread_id": "session-1"}}
result = agent.invoke({
"messages": [{"role": "user", "content": "Deploy to production"}]
}, config=config)
# Reject deployment
agent.update_state(
config,
{
"messages": [
Command(
resume={
"decisions": [{
"type": "reject",
"message": "Tests haven't passed yet. Run tests first."
}]
}
)
]
}
)
# Agent receives rejection feedback and can try alternative approach
result = agent.invoke(None, config=config)
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import MemorySaver
agent = create_agent(
model="gpt-4",
tools=[deploy_tool, send_email_tool],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
"deploy_to_prod": {
"allowed_decisions": ["approve", "reject"],
"description": "🚨 PRODUCTION DEPLOYMENT requires approval"
},
"send_email": {
"description": "📧 Email draft ready for review"
},
},
),
],
checkpointer=MemorySaver(),
)
✅ Which tools require approval ✅ Allowed decision types per tool ✅ Custom interrupt descriptions ✅ Checkpointer implementation ✅ Interrupt handling logic
❌ The HITL protocol (approve/edit/reject structure) ❌ Skip checkpointer requirement ❌ Interrupt without saving state ❌ Have subagents interrupt without main checkpointer
# ❌ This will error
agent = create_deep_agent(
interrupt_on={"write_file": True}
)
# ✅ Must provide checkpointer
agent = create_deep_agent(
interrupt_on={"write_file": True},
checkpointer=MemorySaver()
)
# ❌ Can't resume without thread_id
agent.invoke({"messages": [...]})
agent.update_state(...) # Which thread?
# ✅ Use consistent thread_id
config = {"configurable": {"thread_id": "session-1"}}
agent.invoke({...}, config=config)
agent.update_state(config, ...)
# Interrupts don't happen mid-invoke()
# They happen between invoke() calls
# Step 1: invoke() -> interrupt occurs
result = agent.invoke({...}, config=config)
# Step 2: Check state for interrupts
state = agent.get_state(config)
if state.next: # Has interrupts
# Handle interrupts
# Step 3: Resume with decision
agent.update_state(config, {...})
result = agent.invoke(None, config=config)
# ❌ Edited args must match tool schema
agent.update_state(config, {
"messages": [Command(resume={
"decisions": [{
"type": "edit",
"args": {"wrong_param": "value"} # Tool doesn't have this param
}]
})]
})
# ✅ Use correct parameter names from tool schema