6.2.4 · D4AI Agents & Tool Use

Exercises — Planning and task decomposition

2,192 words10 min readBack to topic

Before we start, one reminder of the two symbols we will lean on again and again:


Level 1 — Recognition

Exercise 1.1

Match each strategy to its one-line description: (a) Hierarchical planning (b) Forward chaining (c) Backward chaining. Descriptions: (i) start at the goal, find what preconditions it needs; (ii) start at the current state, keep applying actions until the goal appears; (iii) recursively split a goal into subgoals, then into primitive actions.

Recall Solution

(a)–(iii): hierarchical planning is top-down recursion (goal → subgoals → primitives). (b)–(ii): forward chaining pushes from the present state forward. (c)–(i): backward chaining pulls from the goal backward to the needed preconditions. Memory hook: Hierarchical splits, Forward pushes, Backward pulls.

Exercise 1.2

An agent must answer "Who directed the film that won Best Picture the year the iPhone launched?" It first searches the iPhone launch year, then searches Best Picture for that year, then the director. Which chaining direction is this, and why?

Recall Solution

This is backward chaining. The final thing we want (the director) sits at the end; but we cannot search for it directly because the year is unknown. So we reason backward from the goal: "to name the director I need the film; to name the film I need the year." We resolve the deepest missing precondition (year) first, then walk back up. See 5.3.02-Chain-of-thought-prompting for the reasoning trace that makes this order explicit.


Level 2 — Application

Exercise 2.1

An agent has actions per step and a plan of depth . Compute the naive search size .

Recall Solution

Naive search explores every path of length , and at each of the steps there are choices, so the count is :

Exercise 2.2

Now decompose the same goal into independent subgoals, each of depth . Using , compute the decomposed cost and the speedup .

Recall Solution

Each subgoal is its own little search of depth , costing paths. We do of them, and because they are independent we add (not multiply) their costs: Speedup: The million-path problem became a 300-path problem — a factor of ~3300 saved. See the figure: the tall exponential bar collapses to a sliver.

Figure — Planning and task decomposition

Exercise 2.3

Redo the cost with (so ). Which gives the smaller search here, or ? Is "bigger always better"?

Recall Solution

For : , so paths. For : paths (from Ex. 2.2). So wins here. The reason: the exponent shrinks fast as grows, and the exponential shrinkage beats the linear growth in front. But "bigger is always better" is false in the real world — see the L2 trap: each split adds a real LM-call / tool-I/O overhead the formula ignores.


Level 3 — Analysis

Exercise 3.1

Goal: "Summarize paper X and compare it to paper Y." Subtasks: fetch X, fetch Y, summarize X, summarize Y, compare summaries. Draw the dependency graph and give a valid execution order that maximizes parallelism.

Recall Solution

Dependencies: needs ; needs ; needs both and . and depend on nothing. A topological sort (an ordering where every arrow points forward) that also runs independent tasks together: The symbol means "run at the same time." Three waves instead of five sequential steps. See the DAG figure — colored bars mark the three waves.

Figure — Planning and task decomposition

Exercise 3.2

If each task takes 1 time-unit and you have unlimited workers, how long does the plan in 3.1 take? How long if you (wrongly) run everything sequentially? What is the critical path?

Recall Solution

With unlimited workers, wall-clock time = length of the critical path = the longest chain of dependent tasks. That chain is (or ), length 3. Sequential run touches all 5 tasks one after another: 5 time-units. So parallel = 3, sequential = 5. You cannot beat 3 no matter how many workers, because can only start after its inputs finish.


Level 4 — Synthesis

Exercise 4.1

Write a ReAct trace (Thought / Action / Observation / Answer) for: "Which is larger by population, the Greater Tokyo Area or the New York metro area, and by roughly how much?" State why each Thought precedes its Action.

Recall Solution
Thought: I need Tokyo's metro population — specify metro, not city proper.
Action: search("Greater Tokyo Area population")
Observation: ~37 million
Thought: Now I need the comparable NY figure — metro area again, same boundary type.
Action: search("New York metropolitan area population")
Observation: ~19.5 million
Thought: Subtract to get the gap: 37 - 19.5 = 17.5 million.
Answer: Greater Tokyo (~37M) is larger by ~17.5M — about 90% larger than NY metro (~19.5M).

Each Thought names the current subgoal so the following Action is grounded — it fetches exactly the missing fact instead of random tool spam. Note the unit discipline: comparing metro to metro (never city-proper Tokyo ~14M to metro NY) keeps the comparison meaningful. Percentage: .

Exercise 4.2

Design an HTN plan for "Prepare coffee" with two methods, and write the state-check that selects between them. Then give the primitive action list the agent runs when state.has_grinder = False.

Recall Solution
Task: PrepareCoffee
  Method 1 (requires state.has_grinder = True):
      [BoilWater, GrindBeans, Brew]
  Method 2 (requires state.has_grinder = False):
      [BoilWater, UseInstantCoffee]
Selector: if state.has_grinder: use Method 1 else: use Method 2

With has_grinder = False, the selector picks Method 2, and the primitive actions executed are: Checking the state before committing guarantees the plan is feasible given current resources — otherwise the agent would try to grind beans it cannot grind.


Level 5 — Mastery

Exercise 5.1

An agent solves a depth- task with branching . It can decompose into independent subgoals, but each subgoal also costs a fixed overhead of path-equivalents (LM call + tool I/O). The total cost model is Compute , , , . Which is optimal, and what does the overhead term teach us?

Recall Solution

Here .

  • Optimal is (cost 260). Beyond the exponential search term is already tiny, so the linear overhead takes over and total cost rises again at . This is the mathematical face of the L2 trap: there is a sweet spot, not a "more is always better." See the U-shaped curve.
Figure — Planning and task decomposition

Exercise 5.2

Combine everything: sketch a full agent loop for "Fetch two papers, summarize each, compare them, and if any fetch fails, replan." Name the concepts used at each stage and the vault topics they connect to.

Recall Solution
  1. Decompose the goal into the DAG (task decomposition — parent topic).
  2. Schedule by topological sort into 3 waves (dependency analysis, Ex. 3.1).
  3. Ground each step with tools: fetch = API call, summarize = LM call — tool-augmented reasoning (6.2.01-Tool-augmented-LMs), interleaved ReAct-style so each Thought sets the subgoal.
  4. Verify each output (did the fetch return a paper?) — LM-Modulo generate-then-check.
  5. Replan on failure: if throws "not found," regenerate that branch (e.g. switch API to Scholar) without touching — failure isolation.
  6. Optionally remember partial results so a retry does not re-fetch what already succeeded (6.2.05-Memory-in-agents); split truly independent fetches across cooperating agents (6.2.03-Multi-agent-systems).

Recall Quick self-check ladder

Naive search for ::: Decomposed with ::: Critical-path length of the summarize-and-compare DAG ::: 3 Optimal in Ex. 5.1 (with overhead ) ::: , cost 260 Direction of planning when you unroll a goal's preconditions ::: backward chaining