Bird
Raised Fist0
LangChainframework~10 mins

Human-in-the-loop with LangGraph in LangChain - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Human-in-the-loop with LangGraph
Start: User Input
LangGraph Receives Input
LangGraph Processes Input & Generates Query
Human Review & Feedback
Approve
Execute Query
Back to Human Review
Return Results
End
The flow starts with user input, LangGraph processes it, then a human reviews and approves or requests changes before execution and returning results.
Execution Sample
LangChain
from typing import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver

class State(TypedDict):
    input: str
    query: str
    results: str | None

def generate_query(state: State) -> State:
    state["query"] = "SELECT * FROM sales WHERE date > DATE_SUB(NOW(), INTERVAL 1 MONTH)"
    return state

def execute_query(state: State) -> State:
    state["results"] = f"Results from executing: {state['query']}"
    return state

workflow = StateGraph(State)
workflow.add_node("generate", generate_query)
workflow.add_node("execute", execute_query)
workflow.set_entry_point("generate")
workflow.add_edge("generate", "execute")
workflow.add_edge("execute", END)

app = workflow.compile(checkpointer=MemorySaver(), interrupt_before=["execute"])

config = {"configurable": {"thread_id": "1"}}
app.invoke({"input": "Find recent sales data"}, config)

# Human review
state = app.get_state(config).values
query = state["query"]
if human_approves(query):
    results = app.invoke(None, config)["results"]
This code shows LangGraph processing input to generate a query, interrupting for human approval via get_state/update if needed, then resuming execution with invoke(None).
Execution Table
StepActionInput/StateOutput/StateNotes
1Receive user input'Find recent sales data'Input storedUser input captured by LangGraph
2Process inputInput storedGenerated query: 'SELECT * FROM sales WHERE date > DATE_SUB(NOW(), INTERVAL 1 MONTH)'LangGraph creates query from input
3Human reviewGenerated queryApproved or modification requestedHuman checks query via app.get_state(config)
4If approvedApproved queryExecute queryResume with app.invoke(None, config)
5If modification requestedModification feedbackQuery updatedLangGraph updates via app.update_state(config, updates)
6Return resultsQuery executedResults returned to userFinal output delivered
7EndResults returnedProcess completeCycle ends
💡 Process ends after results are returned and user is satisfied.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 5Final
user_inputNone'Find recent sales data''Find recent sales data''Find recent sales data''Find recent sales data'
queryNone'SELECT * FROM sales WHERE date > DATE_SUB(NOW(), INTERVAL 1 MONTH)''Approved' or 'Needs change''Updated query if changed''Final approved query'
resultsNoneNoneNoneNone'Query results data'
Key Moments - 3 Insights
Why does the human need to review the query before execution?
Because LangGraph generates queries automatically, human review ensures the query matches the user's intent and avoids errors, as shown in step 3 of the execution_table.
What happens if the human requests a change to the query?
The query is updated based on feedback and sent back for review again, creating a loop between steps 3 and 5 until approval, as seen in the execution_table rows 3 and 5.
Why is the process considered 'human-in-the-loop'?
Because a human actively participates in reviewing and approving or modifying the automated query before execution, ensuring accuracy and control, demonstrated by the decision branch after step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the output after step 2?
AUser input stored
BResults returned to user
CGenerated query: 'SELECT * FROM sales WHERE date > DATE_SUB(NOW(), INTERVAL 1 MONTH)'
DQuery executed
💡 Hint
Check the 'Output/State' column for step 2 in the execution_table.
At which step does the human decide to approve or request changes?
AStep 3
BStep 2
CStep 1
DStep 4
💡 Hint
Look at the 'Action' column in the execution_table where human review happens.
If the human requests a change, which step updates the query?
AStep 4
BStep 5
CStep 6
DStep 7
💡 Hint
Refer to the 'Action' and 'Output/State' columns for step 5 in the execution_table.
Concept Snapshot
Human-in-the-loop with LangGraph:
- User inputs request
- LangGraph generates query
- Human reviews and approves or requests changes
- Approved query executes
- Results returned
- Loop continues until satisfied
Full Transcript
This visual execution trace shows how LangGraph works with a human in the loop. First, the user inputs a request. LangGraph processes this input and generates a query. Then, a human reviews the query to ensure it matches the intent. If approved, the query executes and results are returned. If changes are needed, the human requests modifications, and LangGraph updates the query. This loop continues until the human approves the final query, ensuring accuracy and control over automated query generation.

Practice

(1/5)
1. What is the main purpose of using Human-in-the-loop with LangGraph?
easy
A. To combine AI processing steps with human feedback for better results
B. To replace human input entirely with AI automation
C. To create static AI models without any human interaction
D. To speed up AI training by skipping validation steps

Solution

  1. Step 1: Understand Human-in-the-loop concept

    Human-in-the-loop means AI and humans work together, where humans check or improve AI outputs.
  2. Step 2: Role of LangGraph in this context

    LangGraph helps build flows that connect AI steps with human feedback nodes to improve results.
  3. Final Answer:

    To combine AI processing steps with human feedback for better results -> Option A
  4. Quick Check:

    Human-in-the-loop = AI + human feedback [OK]
Hint: Human-in-the-loop means AI plus human checks [OK]
Common Mistakes:
  • Thinking it removes human input
  • Assuming it only automates AI without feedback
  • Confusing it with fully automated AI pipelines
2. Which of the following is the correct way to add a human feedback node in a LangGraph flow?
easy
A. flow.create_human('review')
B. flow.add_human('review')
C. flow.add_node(HumanNode(name='review'))
D. flow.insert_human_node('review')

Solution

  1. Step 1: Recall LangGraph syntax for adding nodes

    LangGraph uses flow.add_node() method to add nodes, including human nodes.
  2. Step 2: Identify correct human node creation

    HumanNode is the class representing human feedback nodes, so flow.add_node(HumanNode(name='review')) is correct.
  3. Final Answer:

    flow.add_node(HumanNode(name='review')) -> Option C
  4. Quick Check:

    Use add_node with HumanNode class [OK]
Hint: Use add_node with HumanNode to add human steps [OK]
Common Mistakes:
  • Using non-existent methods like add_human or insert_human_node
  • Forgetting to instantiate HumanNode class
  • Passing string directly without node wrapper
3. Given this LangGraph flow snippet:
flow.add_node(AINode(name='generate'))
flow.add_node(HumanNode(name='check'))
flow.connect('generate', 'check')
result = flow.run(input='Hello')
What will happen when flow.run is called?
medium
A. The flow runs human node first, then AI node
B. The flow runs only the AI node and skips the human node
C. The flow throws an error because human nodes cannot be connected
D. The AI node generates output, then the human node requests feedback before continuing

Solution

  1. Step 1: Analyze flow node order and connections

    The AI node 'generate' runs first, then its output is passed to the human node 'check' via connect.
  2. Step 2: Understand human node behavior in flow.run

    HumanNode pauses for human feedback before continuing, so the flow waits for human input after AI output.
  3. Final Answer:

    The AI node generates output, then the human node requests feedback before continuing -> Option D
  4. Quick Check:

    AI runs first, then human feedback [OK]
Hint: AI node runs before connected human node in flow [OK]
Common Mistakes:
  • Assuming human nodes are skipped automatically
  • Thinking human nodes run before AI nodes
  • Believing human nodes cause errors when connected
4. You wrote this code snippet:
flow.add_node(HumanNode('review'))
flow.connect('review', 'generate')
But it throws an error. What is the likely cause?
medium
A. HumanNode must be instantiated with a named argument like name='review'
B. You cannot connect a human node to an AI node
C. The connect method requires node objects, not strings
D. HumanNode cannot be added to LangGraph flows

Solution

  1. Step 1: Check HumanNode instantiation syntax

    HumanNode requires named argument 'name', so HumanNode('review') is invalid syntax.
  2. Step 2: Confirm connection method accepts node names as strings

    Connecting nodes by their names as strings is valid, so error is not from connect method usage.
  3. Final Answer:

    HumanNode must be instantiated with a named argument like name='review' -> Option A
  4. Quick Check:

    HumanNode needs name= argument [OK]
Hint: HumanNode requires name= parameter when created [OK]
Common Mistakes:
  • Passing positional argument instead of named argument
  • Assuming connect only accepts node objects
  • Thinking human nodes cannot be connected
5. You want to build a LangGraph flow where AI generates text, a human reviews and edits it, then AI summarizes the final text. Which flow setup correctly implements this?
hard
A. flow.add_node(AINode(name='generate')) flow.add_node(AINode(name='summarize')) flow.add_node(HumanNode(name='review')) flow.connect('generate', 'summarize') flow.connect('summarize', 'review')
B. flow.add_node(AINode(name='generate')) flow.add_node(HumanNode(name='review')) flow.add_node(AINode(name='summarize')) flow.connect('generate', 'review') flow.connect('review', 'summarize')
C. flow.add_node(HumanNode(name='review')) flow.add_node(AINode(name='generate')) flow.add_node(AINode(name='summarize')) flow.connect('review', 'generate') flow.connect('generate', 'summarize')
D. flow.add_node(AINode(name='generate')) flow.add_node(HumanNode(name='review')) flow.add_node(AINode(name='summarize')) flow.connect('review', 'generate') flow.connect('summarize', 'review')

Solution

  1. Step 1: Identify correct node order for the flow

    The flow should be AI generate -> human review/edit -> AI summarize final text.
  2. Step 2: Check connections match the desired order

    flow.add_node(AINode(name='generate')) flow.add_node(HumanNode(name='review')) flow.add_node(AINode(name='summarize')) flow.connect('generate', 'review') flow.connect('review', 'summarize') connects 'generate' to 'review', then 'review' to 'summarize', matching the required sequence.
  3. Final Answer:

    AI generate, then human review, then AI summarize with correct connections -> Option B
  4. Quick Check:

    Correct node order and connections = flow.add_node(AINode(name='generate')) flow.add_node(HumanNode(name='review')) flow.add_node(AINode(name='summarize')) flow.connect('generate', 'review') flow.connect('review', 'summarize') [OK]
Hint: Connect nodes in logical order: AI -> Human -> AI [OK]
Common Mistakes:
  • Placing human node before AI generate
  • Connecting nodes in wrong sequence
  • Skipping human review step