Lab 01 — Multi-Mode Agent Runtime (ReAct / ReWOO / Plan-Execute)
Phase 01 · Lab 01 · Phase README · Warmup
The problem
Phase 00 gave you the arithmetic of ReAct-vs-ReWOO (quadratic vs linear tokens). Now build all three orchestration strategies for real, behind one runtime, with the LLM injected as a deterministic policy so you can see the tradeoff in the trace:
- ReAct — reason → act → observe, interleaved. One LLM call per step. Adaptive.
- ReWOO — plan the whole task (1 call) → execute tools without the LLM (variable substitution) → solve (1 call). Exactly two LLM calls. Cheap; not adaptive.
- Plan-execute-replan — plan, execute, and re-plan on failure (bounded). Adaptive recovery without ReAct's per-step cost.
The Trace counts llm_calls and tool_calls, so a test proves ReWOO makes two LLM calls
where ReAct makes N — Phase 00's lesson, empirically.
What you build
| Piece | What it does |
|---|---|
ToolRegistry.dispatch | runs a tool; never raises — failures become ToolError observations |
parse_react_step | ReAct text → Action | FinalAnswer; malformed → ValueError |
run_react | the interleaved loop with a max_steps guard; llm_calls == steps |
parse_plan + substitute | a JSON plan → PlanSteps; wire #E1 outputs into later inputs (type-preserving) |
run_rewoo | plan → execute (no LLM) → solve; 2 LLM calls regardless of plan length |
run_plan_execute | execute a plan, re-plan on failure with the error in context |
run | the facade that dispatches by mode |
File map
| File | Role |
|---|---|
lab.py | your implementation (fill the # TODOs) |
solution.py | reference + a worked example that runs the same task in all three modes |
test_lab.py | 18 tests: parsing, the loop, the guard, errors-as-observations, the 2-vs-N call proof, replan recovery |
requirements.txt | pytest only |
Run it
pytest test_lab.py -v # your lab.py (red until you implement)
LAB_MODULE=solution pytest test_lab.py -v # the reference (green)
python solution.py # the three-mode worked example
Success criteria
-
You can explain why
run_reactrecordsllm_calls == stepsandrun_rewoorecordsllm_calls == 2, and connect that to Phase 00's quadratic-vs-linear cost. -
Your
dispatchturns every tool failure into aToolErrorobservation — the loop never crashes on a bad tool call. -
substitutepreserves anintfor an exact#E1reference (so the next tool gets a number, not a string) and raises on an unresolved reference. -
run_plan_executerecovers from a bad first plan by re-planning with the failure in context, and stops atmax_replans. -
All 18 tests pass under both
labandsolution.
How this maps to the real stack
- ReAct is the loop inside the OpenAI Agents SDK
Runner, a LangGraph ReAct node, and LangChain'sAgentExecutor. Yourparse_react_stepis the framework's tool-call parser; yourmax_stepsis its recursion/iteration limit. - ReWOO is the plan-and-execute / LLMCompiler family — LangGraph ships a plan-execute
template; your
#E1substitution is exactly their variable-passing between plan steps. - Plan-execute-replan is what production "planner" agents actually do (LangGraph's
plan-execute with a re-plan edge, ADK's
LoopAgentaround a planner). The bounded replan is the reliability lever from Phase 00 §5 made concrete. - Injecting the policy is how real teams unit-test agents: record/replay fixtures,
FakeLLM, VCR-style cassettes. Correctness that doesn't depend on the model being right is the craft.
Limits. A real planner is an LLM whose plan quality varies; real tools are async and can fail transiently (retries/backoff live in Phase 08); real ReAct parsing must handle native tool-call JSON, not just the text format (Phase 02). The control flow, though, is exactly this.
Extensions (your own machine)
- Add token accounting to each
Step(word-count stand-in) and print the ReAct-vs-ReWOO token totals for a 10-step task — reproduce Phase 00's cost curve empirically. - Add a parallel ReWOO executor: independent plan steps (no
#Edependency between them) run concurrently; latency becomes the max of a group, not the sum. - Wire a real model behind the
Policyinterface (one function swap) and run the same three modes against a live LLM; compare traces.
Interview / resume signal
"Built a multi-strategy agent runtime — ReAct (interleaved), ReWOO (plan-execute with variable substitution), and plan-execute-replan — behind one interface with an injected, deterministic model, and proved the ReAct-quadratic vs ReWOO-linear LLM-call tradeoff in the execution trace. Errors are structured observations, so the loop survives bad tool calls."