Track D: Graph workflows
Track D builds conditional-branch graph workflows with routing and join nodes. You verify correct branch execution order through graph trace events, not only final output text.
Goal
Build a conditional-branch graph workflow with routing and a join node. Verify correct branch execution order via trace metadata (GraphNodeStarted, GraphNodeCompleted).
Prerequisites
| Item | Required |
|---|---|
| Track A | Linear workflow familiarity |
| Python SDK | Built |
| Provider | Stub default |
| Primary examples | Graph routing example |
| Scripts | parallel_search.py, reflection_loop.py |
| Guide | Graph workflows |
Postgres optional for embedded SDK; required for server recovery paths. Graph resume from checkpoint is partial (Graph recovery resume).
Step 1: Parallel fan-out and join
Run the canonical join sample:
Study wiring:
Step 2: Conditional loop (optional second exercise)
Observe max_iterations(3) guarding the revise-to-draft loop.
Step 3: Extract graph trace order
For parallel search, both search_web and search_docs should appear before the final synthesize completion. Order between parallel branches may vary; join ensures synthesize waits for both.
Step 4: Verification checklist
| Check | Expected |
|---|---|
result.status | completed |
GraphNodeStarted | One entry per executed node (plus iterations in loop sample) |
| Join behavior | synthesize after both search nodes in parallel exercise |
WorkflowCompleted | Present |
max_iterations | Loop sample does not exceed guard |
Expected output
run_id=<uuid> steps=<n>
Pass criteria are structural: graph events and join ordering, not exact LLM text.
Trace events you should see
| Event kind | When |
|---|---|
WorkflowStarted | Graph run begins |
GraphNodeStarted | Each node starts |
GraphNodeCompleted | Each node finishes |
StepStarted / StepCompleted | Per underlying step |
WorkflowCompleted | Success |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Synthesize runs early | Join misconfigured | Use .join_node("synthesize", ["search_web", "search_docs"]) |
| Loop never exits | Condition always matches | Add terminating edge with to=None |
| Missing graph events | graph=True omitted | Set on Workflow constructor |
| Exceeded iterations error | Guard too low | Increase max_iterations or fix routing |
What you learned
Track D covers scheduler semantics: entry nodes, conditional edges, parallel fan-out, join preconditions, and iteration guards. These patterns underpin support routers and multi-branch automation in production.
Next tracks
| Track | Focus |
|---|---|
| E | HITL and external callbacks |
| Level 2 cert | Graph plus RAG plus HITL combined workflow |