A travel assistant may need to answer questions about attractions and check room availability. Routing gives each request to the right specialist instead of asking one component to handle both jobs. A router examines the request, chooses from a limited set of paths, and hands control to the selected retriever or agent. Unlike a controller-worker workflow, it does not assign a sequence of subtasks. section 12.2 section 5.1.1
The destination and the handoff are separate decisions:
- Define the choices. A query router can choose a tourist-information vector store or an accommodation-booking database; an agent router can choose the corresponding specialist agents. section 10.6.2 section 12.2.1
- Classify the request. Describe each destination in the prompt and constrain the LLM response with a typed output model, rather than parsing free-form text. section 10.6.2 section 12.2.1
- Dispatch using the returned choice. A retriever chooser looks up the selected chain; a LangGraph router node returns a Command whose goto value selects the agent node. section 10.6.2 section 12.2.2
Routing need not use an LLM. In a LangGraph conditional edge, a router function can inspect state and return a string matching a configured option: for example, return "search_more" when fewer than three results exist, or "write_report" otherwise. The destination names and graph configuration must agree. section 5.6
One request, one specialist
“What are the main attractions in St Ives?” goes to the travel-information agent; “Are there any rooms available in Penzance this weekend?” goes to the accommodation-booking agent. In this graph, the chosen agent answers and execution ends. The handoff does not itself create a multi-step collaboration. section 12.2.4 section 12.2.3
Listing 12.3 Router agent node
def router_agent_node(state: AgentState) -> Command[AgentType]: """Router node: decides which agent should handle the user query.""" messages = state["messages"] #1 last_msg = messages[-1] if messages else None #2 if isinstance(last_msg, HumanMessage): #3 user_input = last_msg.content #4 … router_messages = [ #5 … …SystemMessage(content=ROUTER_SYSTEM_PROMPT), … …HumanMessage(content=user_input) … ] router_response = llm_router.invoke( … …router_messages) #6 … agent_name = router_response.agent.value #7 … return Command(update=state, … …goto=agent_name) #8 return Command(update=state, … goto=AgentType.travel_info_agent) #9
The router node reads the latest message, asks for a typed agent choice, and uses Command to hand off the state to that agent. section 12.2.2
Treat classification as a decision worth checking. Give the router explicit criteria for ambiguous requests, define a default route or ask for clarification when confidence is low, and test its choices against labeled queries. LangSmith traces show which agent received a request. A guardrail can also reject an out-of-scope question before it reaches any specialist, sending it through a refusal path to END. section 12.4 section 14.2.1





















