Lesson 04 · Structure · 13 min
Conditional routing
A router reads one field of state and picks an edge. That is the whole mechanism, and it is what turns a pipeline into a graph: the same input can now take different paths, and which path it took is recorded rather than inferred.
Two properties are worth designing for from the start. Always provide a default edge, because a router with no match is a dead end and dead ends are the most common way a graph fails silently. And keep the routing value constrained — this lab's classifier is limited to five words, so the router matches on a small closed set rather than on free text.
You will often need to route more than once. In this lab, shipping and refund questions share a lookup, then diverge: a delivery question needs no policy, a refund does. Rather than duplicating the lookup on both branches, the graph routes again after it.
classify -> route
route[returns|billing|shipping] -> extract_order -> lookup -> route_again
route_again[shipping] -> reply_shipping
route_again[default] -> read_policy -> reply_refund
route[default] -> reply_generalWhile this course was being written, the first version of that graph had one chain after the lookup, so shipping questions fell through the refund path and reply_shipping was unreachable. Nothing errored — every run produced a plausible answer by the wrong route. Unreachable nodes are worth checking for explicitly.
Checkpoint
Find two messages that share a node early and diverge later.