6.0 KiB
Workflow Graphs
In ADK 2.0, workflows are represented as directed graphs where execution flows from node to node along defined edges. This guide explains the core concepts of nodes, edges, and graphs, how to define them, and the validation rules enforced by the framework.
Introduction
A workflow graph defines the execution plan for your multi-step agent interactions. It specifies:
- What tasks to run (Nodes).
- The order of execution (Edges).
- How data flows and how branches fork or merge.
The graph structure is compiled and validated when you instantiate the Workflow class.
Core Concepts
Nodes (NodeLike)
A node represents a single unit of execution in the workflow. In ADK, you can use several types of objects as nodes (collectively referred to as NodeLike):
- Python Functions: Sync or async functions (and generators) decorated with
@node. They are automatically wrapped in aFunctionNode. - Agents:
LlmAgentinstances (typically insingle_turnmode). They are automatically wrapped in an internal_LlmAgentWrapper. - Tools:
BaseToolinstances. They are wrapped in aToolNode. - Workflows: A
Workflowis itself aBaseNodeand can be nested as a child node in another workflow. START: A special sentinel node that marks the entry point of the workflow. Every graph must have exactly one edge starting fromSTART.
Edges (Edge)
An edge defines a transition from a source node (from_node) to a destination node (to_node).
Unconditional Edges
By default, edges are unconditional. When the source node completes, execution immediately transitions to the destination node.
Conditional Edges (Routing)
An edge can be associated with one or more routes (a string, integer, or boolean). The edge is only followed if the source node explicitly emits a matching route.
To emit a route, the source node must yield an Event(route="my_route") (or return/yield an object that maps to that route).
Default Route
You can define a fallback edge using DEFAULT_ROUTE (imported as from google.adk.workflow import DEFAULT_ROUTE or using "__DEFAULT__"). This edge is followed if the source node emits a route, but no specific conditional edge matches it.
Defining the Graph (Syntax)
You define the graph structure by passing a list of edges to the Workflow constructor. ADK supports two syntax styles:
1. Chain Tuples (Recommended)
Chain tuples provide a concise way to define sequential, parallel, and conditional transitions using Python tuples.
-
Sequential Chain:
edges=[ (START, step_a, step_b, step_c), ]This defines:
START -> step_a -> step_b -> step_c. -
Parallel Fan-Out: Use a tuple of nodes to split execution into parallel branches.
edges=[ (START, step_a, (step_b, step_c)), ]This defines:
START -> step_a, and thenstep_a -> step_bANDstep_a -> step_cin parallel. -
Conditional Routing: Use a dictionary (Routing Map) to define conditional branches.
from google.adk.workflow import DEFAULT_ROUTE edges=[ (START, step_a, { "success": step_b, "failure": step_c, DEFAULT_ROUTE: fallback_step, }), ]If
step_ayieldsEvent(route="success"), it goes tostep_b. If it yields"failure", it goes tostep_c. Any other route goes tofallback_step.
2. Explicit Edge Objects
For complex graphs or when you prefer explicit declarations, you can use Edge objects:
from google.adk.workflow import Edge, START
edges=[
Edge(from_node=START, to_node=step_a),
Edge(from_node=step_a, to_node=step_b, route="success"),
Edge(from_node=step_a, to_node=step_c, route="failure"),
]
Graph Validation
When a Workflow is initialized, it builds an internal Graph representation and runs validate_graph() to catch structural errors early. The following rules are strictly enforced:
1. Unique Node Names
All distinct node objects in the graph must have unique names.
- Error: If you have two different function nodes named
process_data, validation will fail. - Solution: Ensure unique names, or reuse the exact same object instance if you want to route back to the same node.
2. Single START Entry Point
The graph must contain the START node, and START must not have any incoming edges.
- Error: A graph without
STARTor with an edge pointing back toSTARTwill fail validation.
3. Connectivity (Reachability)
All nodes in the graph must be reachable from the START node.
- Error: If you define a node but do not connect it to the rest of the graph, validation will fail.
4. No Duplicate Edges
You cannot define duplicate edges between the same two nodes.
- Error:
Edge(from_node=A, to_node=B)andEdge(from_node=A, to_node=B)in the same list will fail.
5. Default Route Constraints
- A node can have at most one outgoing
DEFAULT_ROUTEedge. DEFAULT_ROUTEcannot be combined with other routes in a list (e.g.,route=["success", DEFAULT_ROUTE]is invalid).
6. No Unconditional Cycles
The graph must not contain cycles consisting entirely of unconditional edges (edges with no route).
- Allowed: Conditional loops are allowed (e.g.,
A -> B -> AwhereB -> Ais conditional on a route). - Forbidden: Unconditional loops (
A -> B -> Awith no routes) are rejected to prevent infinite execution loops.
7. Static Schema Matching
If a node defines an output_schema and its successor defines an input_schema, they must match exactly.
- Error: Schema mismatch on transition edges will fail validation.
8. Chat Agent Wiring
LlmAgent instances configured with mode='chat' are only allowed to follow the START node.
- Reason: Chat-mode agents manage their own conversational history and cannot consume direct inputs from preceding nodes in a workflow chain. For sequential steps, use
mode='single_turn'.