Cheat sheets

Agent Planning: Workflows, HTN, Plan-Execute

Pick a workflow, an HTN or evolutionary planner, or a replanning executor. Stdlib Python from the lessons.

  • Concepts and terms
  • Tasks and commands
  • Annotated code
  • Diagrams
  • Comparisons
  • Defaults and numbers
  • Troubleshooting
  • Questions and tips

Source

Pick a planner#

FactorWorkflowHTN + ChatHTNAlphaEvolveReAct / ReWOO
Who decidesEngineersSymbolic layerEvaluator selectsThe model
GuaranteeBounded step countProvable soundnessBest plan by fitnessNo formal guarantees
NeedsSteps you can enumerateOperator schemaMachine-checkable fitnessLLM in the loop
FitsPredictable, compliance-boundScheduling, policy-boundCompiler optimizationOpen-ended research
LLM roleCalls on fixed code pathsFallback decompositionProposes mutationsPicks each step

Five workflow patterns in code#

TaskCode
Prompt chaining: output N is input N+1prompt_chain(input_text, llm, steps)
Routing: classify, then dispatchroute(input_text, classifier, handlers)
Parallelization: N runs, majority voteparallel_vote(prompt, llm, n=5)
Orchestrator-workers: pick specialistsorchestrator_workers(task, workers, synth)
Evaluator-optimizer: loop until PASSevaluator_optimizer(task, proposer, evaluator, max_iter=5)
Unknown route labelhandlers.get("default") gives "escalate to human"
Run all five demospython3 code/main.py

Evidence plan waves#

depends_ondepends_onprocesscontractwave 1, review contractprocessimplementationwave 2, unittestprocessdocswave 2, check_links.pyprocessintegrationwave 3, acceptance gatedepends_ondepends_onprocesscontractwave 1, review contractprocessimplementationwave 2, unittestprocessdocswave 2, check_links.pyprocessintegrationwave 3, acceptance gate

Run a replanning agent#

agent = PlanExecuteAgent(
planner=make_deterministic_planner(fail_step_id=2, recovery="route_around"),
executor=executor,(tool_name, args) -> result, raises ToolFailure
max_steps=12, max_replans=5,both budgets are hard
)
res = agent.run("ship the report")
res.status, res.reason"completed" and "goal_met"
res.revisionslist of PlanDiff
r.to_dict()revision, removed, added, revised
Step(2, "transform", {"mode": "v2"}, "computed via fallback")

HTN planner with LLM fallback#

op = Operator("open_editor", ("logged_in",), ("editor_open",))
m = Method("ship_change_m1", "ship_change", ("logged_in",),
("open_editor", "write_tests", "run_tests", "open_pr"))
planner = HTNPlanner(operators=operators, methods=methods, llm=llm)
plan = planner.plan("ship_change", {"logged_in"})list of operators or None
planner.cached_methodsLLM decompositions kept for the next call
planner.llm.calls0 new calls on a cache hit

Defaults#

SettingDefaultNote
max_steps12All step executions, replans included
max_replans5Planner calls after the first plan
max_depth12HTN recursion limit, then None
max_iter5Evaluator-optimizer rounds
n5Voters in parallel_vote
generations12Evolutionary demo, keep top 3 of 6

Plan-execute executor#

1Plannerplanner(goal, history, None) returns the firstplan. Event plan.commit.2Executorruns plan[cursor] through the dispatcher. Eventsstep.start and step.end.3Executoron success, append to history and move thecursor to the next step.4Executoron an exception, store step.error and setlast_error.5Budget checkreplans_used >= self.max_replans returns failedwith replan_budget.6Plannerplanner(goal, history, last_error) gives a newplan. Event plan.draft.7Executoremits plan.diff, commits the new plan and setscursor = 0.8Executorthe last step succeeds. Event session.completewith goal_met.

Planning terms#

Operator
primitive action with preconditions and effects.
Method
a way to break a compound task into subtasks, with preconditions.
ChatHTN
the symbolic planner asks the LLM when no method matches.
Fitness function
deterministic, machine-checkable score over outputs.
Augmented LLM
LLM plus search, tools and memory. The atomic unit.
expected_outcome
planner's success condition. The executor does not enforce it.
Replan
hand the error to the planner. This turns a script into an agent.

Failures and fixes#

SymptomCauseFix
failed, reason replan_budgetPlanner returns the same broken planFeed last_error and route around it
failed, reason step_budgetReplans add steps past max_stepsShorter plans or reuse history
failed, reason no_planPlanner returned []Add a recovery plan for that error
dependency cycle among:Items wait on each otherResolve the disagreement behind it
has no repository evidenceItem has empty evidenceCite a repository fact
has no proof commandEmpty proofGive one exact check
HTN soundness collapsesNo precondition/effect schemasValidate LLM output against operators
Evolution does not convergeLLM asked if the code is betterUse a deterministic, fast evaluator

Commands#

CommandWhat it does
python3 code/main.pyRuns the lesson demo and prints the trace
python3 -m unittest discover code/tests -vRuns the evidence plan tests
outputs/evidence-plan.jsonWritten by lesson 44, status ready or blocked

Questions#

Workflow or agent?
Workflow when you can enumerate the steps. Agent when the next step depends on the last result.
Why cap replans and steps?
A capped replan fails faster with a clearer reason.
Why is ChatHTN sound?
LLM output enters only as candidate decompositions. The schema rejects invalid ones.
Which steps run together?
Steps in the same wave. Integration waits for both branches.

Tips#

  • Start with direct API calls. Reach for ReAct or ReWOO before HTN.
  • Define the contract before its implementations.
  • Give each work item an id, change, evidence, dependencies and proof.
  • Emit a plan diff on each revision. Do not rewrite the plan silently.
  • Store the plan next to the work, not in chat checkboxes.