Graph-based agent workflow
Modeling an agent application as a directed graph of typed nodes joined by conditional edges, run by a scheduler that owns concurrency, state persistence, and pause/resume — instead of expressing control flow ad-hoc in the agent loop. The design ADK Go 2.0 is built around (and Python ADK 2.0 before it). Its load-bearing claim: “a graph is an agent” — a graph runs on the same runtime as a single agent, so declarative multi-step orchestration and single-agent execution are one mechanism, not two.
Nodes
ADK ships a spread of node constructors, so the graph can hold ordinary code, models, and tools as peers:
- Function / emitting-function — wrap a typed Go function (input/output schemas inferred via
generics); the emitting variant adds an
emitcallback to stream events or request a human pause without a dynamic node. - Agent / tool — embed an existing
agent.Agent(incl.LlmAgent) or turn atool.Toolinto a graph step. - Join — a fan-in barrier that waits for all predecessors.
- Dynamic — decides execution order at runtime in plain Go (call
RunNode(...)per child), for loops, conditionals, accumulation, or fan-out across a runtime-sized list. - Workflow — compose a sub-workflow as a single node (nested graphs).
- Parallel workers / state-bound — concurrent processing across a list; pull session values into typed structs via tags.
Edges and routing
Edges carry routing conditions; a node emits a routing value and the matching edge fires — StringRoute,
IntRoute, BoolRoute, MultiRoute, Default. One mechanism expresses sequential chains, conditional
routers, fan-out/fan-in, nested sub-graphs, and loops. Because an LLM agent can emit the routing value,
a model can steer the path (classify a user message) while the graph keeps execution reliable and
resumable — the reliability sits in the runtime, the judgment in the model.
Reliability the runtime provides
The point of the graph is that the scheduler, not the prompt, owns robustness:
- Retries — per-node exponential backoff with jitter (default 5 attempts, 1s initial, 60s cap, 2×).
- Timeouts — per node. Concurrency caps — graph-wide via
WithMaxConcurrency(n). - Isolation — parallel branches run in isolation scopes so their histories don’t contaminate each
other (
WithRunID,WithIsolationScope). - Durable pause/resume — a node can pause for human input and the workflow waits in session state, resuming across process restarts by scanning session history.
Relation to the other orchestration shape
This is the declarative cousin of orchestrator-worker fan-out: fan-out is a main agent imperatively spawning subagents; a graph names the branch/join/loop structure up front and hands execution to a scheduler. They compose — an agent node inside a graph can itself fan out — and both serve the wiki’s structure-over-capability thesis: the model supplies judgment at nodes, the graph supplies the reliability the model can’t.
Related
adk-go-2 · adk · agent-orchestration · durable-agents · a2a-protocol · agentic-coding-harness