LangGraph Approval Flows

LangGraph knows how to pause.
KiLu decides why.

interrupt() is not a policy.
Without a separate authority layer, you hardcode pauses or trust the model.
Add a deterministic ALLOW / REQUIRE_CONFIRM / BLOCK outcome to your human-in-the-loop workflows.

Graph State Reaches Tool Node KiLu ALLOW  |  REQUIRE_CONFIRM  |  BLOCK Execute / interrupt() / Fail
KiLu LangGraph Approval Demo

interrupt() is an API, not a decision layer.

Building Human-in-the-Loop workflows in LangGraph usually means hardcoding nodes to pause execution, or relying on the model to "ask for permission" before doing something dangerous.

Hardcoded pauses

Interrupting at fixed nodes causes fatigue. Every action requires human eyes, regardless of relative risk.

Model-driven requests

Prompting the model to ask the user creates risk. If the model bypasses the prompt, execution happens.

No audit trail

Resuming the graph state doesn't generate durable receipts of who approved what action at what specific time.

A deterministic decision layer.

ALLOW

The node executes automatically. No graph interruption needed. Record generated.

REQUIRE_CONFIRM

KiLu signals the graph to interrupt(). Execution pauses for explicit human review.

BLOCK

Fails fast without user fatigue. Policy violation recorded as evidence.

Decoupling execution from routing.

Keep your graph focused on agent logic. Let KiLu handle authorization.

Before
Graph logic mixes execution flow and authorization
Static interruption rules
Manual state patching
After
Graph handles flow, KiLu handles decision
Dynamic, policy-driven interruptions
Clean separation of concerns
Python — before / after
# before — hardcoding interruptions
workflow.add_node("sensitive_tool", sensitive_tool_node)
workflow.add_edge("agent", "sensitive_tool")
workflow.compile(interrupt_before=["sensitive_tool"])

# after — KiLu decides if interrupt() is needed
def safe_tool_node(state):
    decision = kilu.check_intent(action="tool.execute")
    if decision.outcome == "REQUIRE_CONFIRM":
        interrupt("Approval needed")
    elif decision.outcome == "BLOCK":
        raise PolicyViolation()
    
    return run_tool()

LangGraph execution paths

Approach What it does What it misses
interrupt_before Pauses at specific nodes Rigid. Pauses even for safe args
Prompt routing Model calls "ask_user" tool Not authoritative. Model can bypass
Custom IF/ELSE logic Evaluates state dynamically Messy graph, hard to audit
KiLu integration Decides based on external policy Clean graph, durable receipts

Common questions

No. You trigger an `interrupt()` inside your node function or conditionally block navigation based on the KiLu decision. State preservation works exactly as intended by LangGraph.
No. You just wrap the execution phase of your tool nodes to evaluate a KiLu decision before calling the underlying system.
Start with one LangGraph node →