[PR #2477] [rfc] langgraph: add agent node wrapper and handoff tools #2732

Closed
opened 2026-02-20 17:47:28 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langchain-ai/langgraph/pull/2477

State: closed
Merged: No


This change introduces few building blocks for multi-agent:

  • make_agent_node - a wrapper around create_react_agent that returns a graph node function
    • allows users to define custom input/output processing functions (handle what information is passed to/from agent as well as handle different state schemas). by default all of the message history is shared by all of the agents via messages (each agent receives full message history and and adds its internal history to the full history). TBD if this is the best default
    • handles handoff tools that return GraphCommand.goto and returns a GraphCommand.goto to dynamically route to a different node (agent)
    • handles state updates from tools when a tool in subgraph agent wants to update parent state
  • AgentRouterState (TBD on name, would love to improve) -- react agent state + active node (node) for routing on follow-up interactions
  • add_entrypoint_router - helper that adds the agent nodes to the StateGraph and adds a top-level entrypoint router based on the active node in the state. TBD if this can be replaced with human-in-the-loop
  • ToolNode is now aware of tools returning GraphCommand and can apply state updates from GraphCommand.update. this allows general support for tools that can update state (only internal to the graph)
  • handoff - a shorthand that helps create tools that return GraphCommand with goto and update

Basic usage:

from langgraph.prebuilt.handoff import handoff
from langgraph.graph import StateGraph, GraphCommand, START, END

# define handoff tools
bob_tool = handoff(goto="bob", tool_message="Transferred to Bob", name="transfer_to_bob", description="Transfer to Bob")
alice_tool = handoff(goto="alice", tool_message="Transferred to Alice", name="transfer_to_alice", description="Transfer to Alice")

# define agent nodes
alice = make_agent_node(model, [add, bob_tool], state_schema=AgentRouterState, state_modifier="You're Alice.", output_processor=keep_last_message_as_human)
bob = make_agent_node(model, [multiply, alice_tool], state_schema=AgentRouterState, state_modifier="You're Bob.", output_processor=keep_last_message_as_human)

# define graph
builder = StateGraph(AgentRouterState)
add_entrypoint_router(builder, route_to=[("alice", alice), ("bob", bob)], default_start_node="alice")
memory = MemorySaver()
graph = builder.compile(checkpointer=memory)

# pass control between the agents
config = {"configurable": {"thread_id": "1"}}
for chunk in graph.stream({"messages": [("user", "hi! transfer me to bob")]}, config):
    ...
for chunk in graph.stream({"messages": [("user", "back to alice please")]}, config):
    ...

Here are some usage examples:

**Original Pull Request:** https://github.com/langchain-ai/langgraph/pull/2477 **State:** closed **Merged:** No --- This change introduces few building blocks for multi-agent: * `make_agent_node` - a wrapper around `create_react_agent` that returns a graph node function * allows users to define custom input/output processing functions (handle what information is passed to/from agent as well as handle different state schemas). by default all of the message history is shared by all of the agents via `messages` (each agent receives full message history and and adds its internal history to the full history). TBD if this is the best default * handles handoff tools that return `GraphCommand.goto` and returns a `GraphCommand.goto` to dynamically route to a different node (agent) * handles state updates from tools when a tool in subgraph agent wants to update parent state * `AgentRouterState` (TBD on name, would love to improve) -- react agent state + active node (`node`) for routing on follow-up interactions * `add_entrypoint_router` - helper that adds the agent nodes to the `StateGraph` and adds a top-level entrypoint router based on the active node in the state. TBD if this can be replaced with human-in-the-loop * `ToolNode` is now aware of tools returning `GraphCommand` and can apply state updates from `GraphCommand.update`. this allows general support for tools that can update state (only internal to the graph) * `handoff` - a shorthand that helps create tools that return `GraphCommand` with `goto` and `update` Basic usage: ```python from langgraph.prebuilt.handoff import handoff from langgraph.graph import StateGraph, GraphCommand, START, END # define handoff tools bob_tool = handoff(goto="bob", tool_message="Transferred to Bob", name="transfer_to_bob", description="Transfer to Bob") alice_tool = handoff(goto="alice", tool_message="Transferred to Alice", name="transfer_to_alice", description="Transfer to Alice") # define agent nodes alice = make_agent_node(model, [add, bob_tool], state_schema=AgentRouterState, state_modifier="You're Alice.", output_processor=keep_last_message_as_human) bob = make_agent_node(model, [multiply, alice_tool], state_schema=AgentRouterState, state_modifier="You're Bob.", output_processor=keep_last_message_as_human) # define graph builder = StateGraph(AgentRouterState) add_entrypoint_router(builder, route_to=[("alice", alice), ("bob", bob)], default_start_node="alice") memory = MemorySaver() graph = builder.compile(checkpointer=memory) # pass control between the agents config = {"configurable": {"thread_id": "1"}} for chunk in graph.stream({"messages": [("user", "hi! transfer me to bob")]}, config): ... for chunk in graph.stream({"messages": [("user", "back to alice please")]}, config): ... ``` Here are some usage examples: * basic usage examples: https://github.com/langchain-ai/langgraph/blob/vb/prebuilt-agent-components/examples/multi_agent/experimental/simple_multi_agent_examples.ipynb * hierarchical agent tutorial: https://github.com/langchain-ai/langgraph/blob/vb/prebuilt-agent-components/examples/multi_agent/experimental/hierarchical_agent_teams.ipynb * customer support example: https://github.com/langchain-ai/langgraph/blob/vb/prebuilt-agent-components/examples/multi_agent/experimental/customer_support.ipynb
yindo added the pull-request label 2026-02-20 17:47:28 -05:00
yindo closed this issue 2026-02-20 17:47:28 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#2732