LangGraph Agents

Course Content

LangGraph Agents

7 sections · 49 lessons

How do you implement agent-to-agent handoffs and shared state safely?


Card EMI ping-pongtriagecardsloansEMI is aloan productit is on a cardEleven handoffs before the recursion limit; now a cap of 3 routes to a human.
Two agents that each defer to the other will loop forever unless the handoff count lives in state.

What you need to know

A handoff tool

Python
from langchain.tools import tool, ToolRuntimefrom langchain_core.messages import ToolMessagefrom langgraph.types import Command@tooldef transfer_to_billing(reason: str, runtime: ToolRuntime) -> Command:    """Hand the customer to the billing agent. Use for charges and refunds."""    last_ai = runtime.state["messages"][-1]          # the message with this tool call    done = ToolMessage(f"Transferred to billing: {reason}", tool_call_id=runtime.tool_call_id)    return Command(goto="billing", graph=Command.PARENT,                   update={"messages": [last_ai, done], "handoffs": 1})

The parent graph has triage and billing as nodes (each a create_agent), with destinations=("billing",) on triage so the diagram shows the hop. handoffs uses an operator.add reducer. The update includes the AI message with the tool call and its ToolMessage, so the billing agent's history stays valid.

Safety rules

  • Key ownership — write down which agent may write which key; only billing writes refund_decision.
  • Reducers for shared keys — findings: Annotated[list, operator.add], so parallel agents do not overwrite each other.
  • Brief, not transcript — hand over {"task": ..., "customer_id": ..., "facts": [...]}; the next agent should not inherit the last one's confusion.
  • Audit — record sender, reason and a timestamp.
  • Cap handoffs — two agents can pass a case back and forth forever. A counter in state (handoffs >= 4 goes to a human) plus recursion_limit.
  • Permissions travel with the role — the billing agent's refund tool checks the customer id from the runtime context, not from the message.

A real-life example

A bank's support system has triage, cards and loans agents. A customer asked about "EMI on my credit card purchase". cards handed to loans ("EMI is a loan product"); loans handed back ("it is on a card"). This looped 11 times before the recursion limit stopped it. The fix: a handoffs counter with a cap of 3 that routes to a human, a rule that an agent cannot hand back to the agent that just handed to it, and a clearer description on transfer_to_cards that includes "card EMI conversions". Ping-pong cases went from 2% to near zero.

Follow-up questions to expect

  • "Handoffs or a supervisor?" — Handoffs suit conversations where the active specialist talks directly to the user; a supervisor suits tasks where one agent must combine the results.
  • "What if the next agent needs the conversation?" — Pass a summary plus the last user message, not the full history with tool calls.
  • "How do you test handoffs?" — Scripted conversations with fake models that assert which agent handles each turn.