How to implement agent planning and task decomposition
AI agent framework, LLM with reasoning capability
What this does
An AI agent that plans and decomposes tasks can handle multi-step objectives that would otherwise exceed the context window or require excessive prompting. This system generates structured sub-task graphs, executes sub-tasks with a ReAct loop, and triggers dynamic replanning when a sub-task fails.
Steps
Create a planner.py module containing a system prompt that instructs the LLM to produce structured decomposition. Define a JSON schema for the plan output with keys for goal, steps (each having id, description, depends_on, and tool), and an explicit instruction to only reference tools from the provided registry. The planner receives the user's task as input and outputs a list of steps that, if executed in dependency order, achieve the goal. Store this template in a file such as prompts/planner.md.
Create an agent.py module with a ReActAgent class that maintains internal state tracking completed_steps, pending_steps, and history of tool calls. The core loop reads the next step whose dependency conditions are satisfied, formats it as a tool call prompt, sends it to the LLM, and executes the returned tool. Append the tool result to history and mark the step as completed. Continue until the pending steps list is empty or the configured step limit is reached.
After each failed tool call, invoke the planner with the original goal, the current history, and an additional instruction prompting an updated plan. Parse the new plan and merge it into the agent's state by discarding steps already completed and replacing the remainder. Set a maximum replanning cap of 3 attempts per session in the agent's configuration to prevent infinite loops. Log each replanning event with a timestamp and the triggering error message. Build a lightweight visualization using graphviz that renders the plan as a directed acyclic graph before execution begins, with completed nodes shaded green and failed nodes shaded red. Save the graph to plan.dot and convert it to PNG for inspection.
Record the local run evidence. Save the exact command, runtime or package version, model name if applicable, and observed output so the result can be reproduced later.
Confirm the local starting state. Print the active binary, package version, model name, or configuration path before changing the workflow.
Run the smallest complete path. Execute the minimum command or script that proves the guide works end to end on the local machine.
Compare against expected output. Check the final line, status code, generated artifact, or model response against the verification section before expanding the setup.
Record the local run evidence. Save the exact command, runtime or package version, model name if applicable, and observed output so the result can be reproduced later.
Verification
Test the planning agent with a multi-step task such as extracting user comments from an API, counting how many contain the word "error," and sending a Slack alert if the count exceeds 5. Expected output: the planner returns a JSON plan containing at least 3 steps with correct dependency fields; the ReAct agent loop executes steps sequentially and updates completed steps for each one; a step failure triggers replanning with a new plan logged without repeating already-completed steps; the graphviz output shows a DAG with 3 or more nodes and correct dependency edges; the agent terminates within the configured step limit with all steps marked as completed.
Common failures
- Circular dependency in plan: A step depends on itself, causing the loop to never select it as executable. Validate the plan by performing a cycle detection pass before execution begins.
- Planner hallucinating unavailable tools: The LLM specifies a tool field that does not exist in the agent's registry. Maintain an explicit allow-list of valid tools and reject plans that reference unknown tools.
- Replanning exceeding context window: The full history appended to every replanning call causes the prompt to grow with each failure. Truncate history to the last 10 entries or summarize it before replanning.
- Step limit reached prematurely: A pipeline of dependent steps exhausts the step limit. Set the limit at
len(plan.steps) * 2 + 5as a safety margin and log a warning when 75% is consumed. - State inconsistency after replanning: The agent's internal state uses integers for step IDs, but the new plan uses different IDs. Normalize all step IDs to sequential integers starting from 0 after every plan generation.
Related guides
- Build a research agent that browses the web — research tasks decompose naturally into search, scrape, and synthesize sub-tasks.
- Set up agent-human collaboration workflows — human approval can be inserted as a special step in the task decomposition graph.