While developing an application using LangGraph, I wanted to implement a human-in-the-loop feature using LangGraph’s interrupt mechanism.
My setup includes a main graph and a subgraph, and both contain one interrupt for human feedback.
Below is the code I’m using to compile the graphs:
from langgraph.graph import StateGraph, START, END
# --- Part 1: Build the Response Agent Subgraph ---
# Initialize a new state graph with our defined `State` schema.
agent_builder = StateGraph(State)
# Add nodes for LLM call and interrupt handling.
agent_builder.add_node("llm_call", llm_call)
agent_builder.add_node("interrupt_handler", interrupt_handler)
# Define graph flow: start → llm_call
agent_builder.add_edge(START, "llm_call")
# Add conditional branching:
# If continuation is needed, go to interrupt_handler; otherwise, end.
agent_builder.add_conditional_edges(
"llm_call",
should_continue,
{
"interrupt_handler": "interrupt_handler",
END: END,
},
)
# After handling an interrupt, resume LLM call.
agent_builder.add_edge("interrupt_handler", "llm_call")
# Compile the subgraph.
response_agent = agent_builder.compile()
# --- Part 2: Build the Overall Workflow ---
# Initialize the main graph with input schema `StateInput`.
overall_workflow = (
StateGraph(State, input=StateInput)
.add_node("triage_router", triage_router)
.add_node("triage_interrupt_handler", triage_interrupt_handler)
.add_node("response_agent", response_agent)
.add_edge(START, "triage_router")
.add_edge("triage_router", "triage_interrupt_handler")
.add_edge("triage_interrupt_handler", "response_agent")
)
# Compile the full workflow graph.
email_assistant = overall_workflow.compile()
In this setup, I have two interrupt nodes:
-
"triage_interrupt_handler"in the main graph -
"interrupt_handler"in the subgraph
When I call graph.invoke(), I expect the graph to pause execution at the first interrupt (triage_interrupt_handler).
However, instead, the graph triggers both interrupts simultaneously, even though execution should stop after the first interrupt.
Could you help me understand why both interrupts are being scheduled and what I might be doing wrong?