Skip to content

Planning and Task Decomposition

Why have a plan at all?

An agentic loop does not always need an explicit plan. For many tasks, this is enough:

observe
  ↓
choose next action
  ↓
act
  ↓
observe again

But when a task contains several dependent steps, longer execution, or explicit dependencies, a plan helps the runtime make progress toward the whole goal rather than only choosing locally useful next actions.

For example:

Goal:
Fix the failing payment test and open a PR.

Possible plan:
1. inspect failing test
2. inspect payment implementation
3. identify root cause
4. modify code
5. run targeted tests
6. run relevant regression tests
7. summarize change
8. open PR

The plan is not the truth itself.

A plan is an execution hypothesis for how the goal may be reached. New environment observations may invalidate it.

Goal vs plan vs state

Treat these as three separate concepts:

Goal
  = what we want to achieve

Plan
  = current idea of how to get there

Execution State
  = what has actually happened and what is true now

For example:

Goal:
production incident root cause identified

Plan:
1. query error rate
2. inspect recent deployment
3. inspect logs

State:
step 1 complete
error rate elevated
no deployment in last 24h

Step 2 may still exist in the plan, but the observation may already make it irrelevant.

So:

plan ≠ canonical state

Runtime state is authoritative; the plan is mutable.

Plan-first vs reactive execution

Plan-first

The runtime creates a plan before execution:

Goal
 ↓
Create plan
 ↓
Execute step 1
 ↓
Execute step 2
 ↓
...

Useful when:

  • there are several clear subtasks,
  • dependencies exist,
  • execution is long-running,
  • approval requires showing planned actions upfront,
  • steps are expensive or risky,
  • progress should be visible to the user.

Its weakness is that plans can become stale.

Reactive execution

The model chooses only the next action from current observations:

Goal + current state
       ↓
choose next action
       ↓
new state
       ↓
choose next action

This can work well for short, uncertain, or rapidly changing environments.

Incident diagnosis is a common example: we may not know in advance which logs matter.

Short-horizon planning

Often a good compromise:

plan next 2–4 meaningful steps
        ↓
execute
        ↓
observe
        ↓
revise local plan

There is little value in predicting twenty steps ahead when the third observation may change the direction completely.

Task decomposition

A large goal can be divided into smaller subgoals.

For example:

Goal:
Prepare a safe production release.

Subgoals:
├── validate build
├── evaluate test state
├── inspect release risk
├── prepare deployment plan
└── obtain approval

A good subtask usually has:

  • a clear responsibility,
  • an observable completion condition,
  • minimal hidden state dependency,
  • a structured result usable by later steps.

Weak decomposition:

1. think about release
2. think more
3. decide what to do

Better:

1. read CI result
2. identify failed required checks
3. inspect release diff risk
4. return release-readiness assessment

When should decomposition stop?

Over-decomposition adds overhead.

For a goal such as:

read current deployment version

we do not need:

1. decide to read deployment
2. find deployment tool
3. call deployment tool
4. inspect response
5. extract version

If a capability already exists as a well-defined tool or skill, use it as an atomic step.

A natural decomposition boundary often appears where a stable reusable capability already exists.

Dependency graph

Not every plan is a simple list.

For example:

        build
       /     \
  unit tests  static analysis
       \     /
      package
         ↓
      approval
         ↓
      deploy

This is closer to a DAG than a linear checklist.

Possible representation:

{
  "steps": [
    {"id": "build", "depends_on": []},
    {"id": "tests", "depends_on": ["build"]},
    {"id": "scan", "depends_on": ["build"]},
    {"id": "deploy", "depends_on": ["tests", "scan", "approval"]}
  ]
}

The runtime can deterministically determine which step is eligible next.

The LLM does not need to rediscover dependency semantics every iteration.

Plan as a typed artifact

In production, a plan is often better as structured state than as free text.

For example:

{
  "goal": "Fix failing payment test",
  "steps": [
    {
      "id": "inspect_test",
      "description": "Read failing test and failure output",
      "status": "PENDING",
      "depends_on": []
    },
    {
      "id": "inspect_code",
      "description": "Read relevant payment implementation",
      "status": "PENDING",
      "depends_on": ["inspect_test"]
    }
  ]
}

This allows the runtime to:

  • store progress,
  • checkpoint,
  • resume,
  • validate dependencies,
  • audit changes,
  • display plan diffs.

Plan generation vs plan validation

The model can propose a plan, while the runtime validates it.

For example:

Model proposes:
1. inspect production DB
2. delete suspicious row
3. restart service

Runtime policy says:

production DB write → forbidden
restart production service → approval required

So:

LLM plan proposal
      ↓
policy / capability validation
      ↓
accepted executable plan

A plan cannot bypass tool authorization.

Replanning

Replanning is needed when new observations invalidate the current plan.

Typical triggers:

Assumption invalidated

Plan assumes recent deployment caused incident.
Observation: no deployment happened.

→ choose another diagnostic direction.

Step impossible

Required repository is unavailable.

→ fallback or human escalation.

Goal changed

User: "Don't fix it yet, only explain the cause."

→ remove mutation steps.

Better path discovered

A single failing config value explains all symptoms.

→ skip remaining exploratory steps.

Replanning should not always regenerate the entire plan

Weak:

every observation
      ↓
regenerate entire 20-step plan

This is:

  • expensive,
  • unstable,
  • hard to audit,
  • unnecessarily disruptive to unaffected plan sections.

Local repair may be better:

step 4 failed
 ↓
replace step 4 with 4a + 4b
 ↓
keep unaffected steps

Plan fixation

The opposite failure mode is rigidly following a stale plan.

Plan says: query deployment logs
Observation says: service never deployed
Runtime: query deployment logs anyway

This is plan fixation.

Plans should always be interpreted in light of current environment evidence.

Coding-agent example

User:

Fix the flaky retry test.

Initial plan:

1. run failing test repeatedly
2. inspect test code
3. inspect retry implementation
4. identify race/timing dependency
5. patch
6. rerun repeated test
7. run related suite

Observation after step 1:

Failure only occurs with parallel test execution.

Replan:

1. inspect shared mutable test fixture
2. inspect test isolation
3. patch fixture lifecycle
4. rerun parallel suite

The loop is not intelligent because it predicted everything upfront. It is useful because it can change the plan based on evidence.

Deterministic workflow vs model-generated plan

If the process is already known:

validate → approval → deploy → verify

do not ask an LLM to reinvent it every run.

That is a workflow.

Agentic planning is most valuable when:

  • the next action is not known in advance,
  • semantic investigation is required,
  • environment feedback changes the direction.

A strong hybrid can be:

Deterministic release workflow
        │
        ├── build
        ├── tests
        ├── agentic risk-analysis island
        ├── approval
        └── deploy

Anti-pattern: plan as a chain-of-thought database

The runtime does not need to store long internal reasoning transcripts as “the plan”.

Store operationally useful state instead:

- explicit goal
- planned step
- dependency
- status
- evidence
- short decision rationale when audit requires it

Execution reproducibility should not depend on hidden reasoning transcripts.

Takeaways

  • Goal, plan, and canonical execution state are different artifacts.
  • A plan is a mutable execution hypothesis, not authoritative truth.
  • For stable known processes, deterministic workflows are better than regenerated agent plans.
  • In uncertain environments, short-horizon planning is often better than long upfront planning.
  • Task decomposition is useful while it creates meaningful, measurable subgoals.
  • Dependencies should be explicit runtime data where useful.
  • New observations can invalidate a plan; replanning should be evidence-driven.
  • Avoid both over-planning and plan fixation.
  • The runtime must validate capabilities, permissions, and risk boundaries in the plan.
  • Plans should be checkpointable and auditable artifacts, not implicit model memory.