Applied Intelligence
Module 11: Skills, Hooks, and Automation

Task Decomposition Strategies

From prompts to workflows

Earlier modules covered decomposition as a technique for managing agent work: breaking large requests into smaller pieces that an agent handles sequentially. Automation workflows require a different perspective. Tasks must be decomposed not just for single-agent comprehension but for orchestration across multiple agents, handling dependencies, and aggregating results.

The shift is from "how do I structure this request?" to "how do I structure this workflow?" Single-session decomposition happens within a conversation. Workflow decomposition happens before any agent starts.

Static versus dynamic decomposition

Static decomposition defines the task breakdown before execution. Every subtask, dependency, and sequence is known upfront. The workflow proceeds through predetermined steps.

# Static decomposition in a CI/CD workflow
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  deploy:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - run: npm run deploy

Static decomposition works well for:

  • Well-understood, repetitive processes
  • Compliance workflows requiring auditability
  • Data pipelines with fixed stages
  • Any scenario where the task structure is predictable

The limitation is rigidity: static workflows cannot adapt when intermediate results reveal unexpected requirements.

Dynamic decomposition adapts the breakdown during execution. An orchestrating agent analyzes results from early tasks and spawns new subtasks accordingly.

Main agent receives: "Fix all security vulnerabilities in dependencies"

Step 1: Run security audit
        → Discovers 3 critical, 12 high, 47 medium vulnerabilities

Step 2: Dynamically decompose based on audit results
        → Subtask A: Update 3 critical packages (spawn agent)
        → Subtask B: Update 12 high packages (spawn agent)
        → Subtask C: Assess 47 medium packages for false positives (spawn agent)

Step 3: Aggregate results, identify remaining issues
        → If breaking changes detected, spawn additional compatibility subtasks

Dynamic decomposition works well when:

  • Optimal task breakdown depends on intermediate findings
  • The problem space has unknown dimensions
  • Error recovery requires adaptive re-planning

The trade-off is complexity: dynamic systems require more sophisticated orchestration logic and have less predictable resource consumption.

Production systems often combine both approaches. Static decomposition handles the overall workflow structure while dynamic decomposition handles adaptation within specific phases.

The granularity problem

Decomposition improves parallelism but adds coordination overhead. Finding the right granularity is where most teams struggle.

Over-decomposition symptoms:

  • Tasks finish faster than they can be coordinated
  • Agents spend more time on handoffs than execution
  • Subtasks lack sufficient context to operate independently
  • Error rates increase as context fragments across many agents

A security audit decomposed into "check dependency A," "check dependency B," and so on for 200 dependencies creates 200 coordination points. A single agent running the full audit produces results faster with fewer failure modes.

Under-decomposition symptoms:

  • Single tasks run for hours without checkpoints
  • Failures require full restarts rather than partial recovery
  • Parallelism opportunities go unused
  • Context windows exhaust before completion

A full application migration handled as one task provides no visibility, no partial progress, and no parallel acceleration.

Calibration guidelines:

These thresholds are approximate—actual boundaries depend on task complexity and team context:

Task complexitySuggested subtasksRationale
Trivial (< 30 min)NoneOverhead exceeds benefit
Small (30 min - 2 hr)2-3Natural checkpoints
Medium (2-8 hr)4-8Balance parallelism and coordination
Large (8+ hr)8-15Need visibility and recovery points
MassiveDecompose into medium tasks firstAvoid single orchestration layer spanning dozens of subtasks

Each subtask should be:

  • Specific enough that the agent knows exactly what to do
  • Achievable with available tools and context
  • Ordered so later steps can build on earlier completions
  • Independent enough that failure in one does not cascade to all

Dependency graphs

Complex workflows have task dependencies: Task B cannot start until Task A completes. Modeling these dependencies as a directed acyclic graph (DAG) enables systematic orchestration.

Why dependency graphs matter

┌─────────┐     ┌─────────┐
│ Schema  │────→│ Backend │────┐
└─────────┘     └─────────┘    │

┌─────────┐     ┌─────────┐  ┌─────────┐
│  Tests  │────→│  Docs   │  │ Deploy  │
└─────────┘     └─────────┘  └─────────┘

┌─────────┐     ┌─────────┐    │
│ Config  │────→│Frontend │────┘
└─────────┘     └─────────┘

The graph reveals:

  • Parallelism opportunities: Schema and Config can run simultaneously
  • Critical path: The longest dependency chain determines minimum completion time
  • Failure boundaries: If Backend fails, Deploy blocks but Docs remains unaffected

Dependency types:

TypeDescriptionExample
Data dependencyTask B requires Task A's outputAPI tests need API implementation
Control dependencyTask B cannot start until Task A completesDeploy waits for all tests
Resource dependencyTasks compete for shared resourcesDatabase migrations serialize

Modeling dependencies in orchestration

CrewAI uses explicit context declarations:

research_task = Task(
    description="Research authentication patterns",
    agent=researcher
)

implementation_task = Task(
    description="Implement authentication",
    agent=developer,
    context=[research_task]  # Explicit dependency
)

Claude Code's task system uses blockedBy relationships:

Task 1: Schema migration [status: in_progress]
Task 2: API implementation [blockedBy: Task 1]
Task 3: Frontend updates [blockedBy: Task 1]
Task 4: Integration tests [blockedBy: Task 2, Task 3]

When Task 1 completes, Tasks 2 and 3 unblock automatically. Task 4 waits for both.

Critical path identification

The critical path is the longest weighted path through the dependency graph. Optimizing tasks off the critical path has zero impact on total completion time.

If schema migration (2 hours) blocks backend (4 hours) which blocks deploy (1 hour), the critical path is 7 hours. Speeding up frontend work from 3 hours to 1 hour does not reduce total time—frontend is not on the critical path.

Focus optimization effort on critical path tasks. Parallelize everything else.

Sequential versus parallel execution

Not every workflow benefits from parallelism. The decision depends on task characteristics.

When to parallelize:

  • Tasks have no data dependencies
  • Each task has sufficient context to operate independently
  • Results merge without conflicts
  • Resource constraints permit concurrent execution

When to stay sequential:

  • Each task depends on prior results
  • Shared state would conflict under parallel access
  • Debugging requires deterministic execution order
  • The task naturally involves iteration and refinement

Hybrid patterns:

Most workflows combine sequential and parallel phases:

Phase 1: Research (sequential)
   └── Agent explores codebase, builds understanding

Phase 2: Implementation (parallel)
   ├── Agent A: Backend changes
   ├── Agent B: Frontend changes
   └── Agent C: Test updates

Phase 3: Integration (sequential)
   └── Agent combines changes, resolves conflicts

Phase 4: Verification (parallel)
   ├── Agent A: Run unit tests
   ├── Agent B: Run integration tests
   └── Agent C: Run security scans

Phase 5: Deploy (sequential)
   └── Agent deploys to staging, then production

The pattern alternates: converge for decisions that require unified context, then diverge for independent execution.

A useful heuristic: if you can sketch the workflow as columns rather than a single line, parallelization helps. If everything must happen in strict sequence, parallelism adds overhead without benefit.

Result aggregation

Parallel agents produce parallel outputs. The orchestration layer must aggregate these results coherently.

Fan-out/fan-in pattern:

                    ┌── Agent A: Security audit ──┐
                    │                             │
Orchestrator ───────┼── Agent B: Performance audit──────→ Synthesizer
                    │                             │
                    └── Agent C: Style audit ─────┘

The synthesizer agent receives outputs from all parallel agents and produces a unified result. Each agent writes to distinct keys in shared state; the synthesizer reads all keys.

Conflict resolution strategies:

When parallel agents produce contradictory outputs:

StrategyDescriptionBest for
Majority votingMost common answer winsClassification, yes/no decisions
Confidence weightingHigher-confidence outputs dominateQuantitative assessments
Human escalationRoute conflicts to developerHigh-stakes decisions
SynthesisAgent combines perspectivesComplementary partial answers

In practice, majority voting provides most of the gains with minimal complexity. Ensembles larger than five to seven agents typically see diminishing returns, with diversity mattering more than count.

Quality filtering:

Before aggregation, filter agent outputs:

def aggregate_results(agent_outputs):
    # Filter low-quality outputs
    valid_outputs = [
        output for output in agent_outputs
        if output.confidence > 0.7
        and output.completed_successfully
        and not output.contains_errors
    ]

    # Aggregate remaining outputs
    return synthesize(valid_outputs)

An output that fails validation should not contaminate the aggregated result.

Partial failure handling:

Parallel execution means some agents may fail while others succeed. Design aggregation to handle incomplete results:

  • Require all: Fail the workflow if any agent fails
  • Require majority: Proceed if most agents succeed
  • Best effort: Use whatever results are available
  • Weighted quorum: Proceed if critical agents succeed

The choice depends on task requirements. A security audit might require all checks to pass. A code review might proceed with best-effort aggregation if one reviewer agent times out.

Decomposition anti-patterns

Certain decomposition approaches reliably fail.

Vague subtasks:

# Bad decomposition
Subtask 1: Do the research
Subtask 2: Implement the feature
Subtask 3: Test it

Each subtask lacks actionable specificity. Agents need concrete scope, not general direction.

Wrong ordering:

# Bad decomposition
Subtask 1: Write integration tests
Subtask 2: Define the API interface
Subtask 3: Implement the API

Integration tests cannot be written before the interface exists. Dependencies must inform ordering.

Missing steps:

# Bad decomposition
Subtask 1: Add new endpoint
Subtask 2: Deploy to production

Where is validation? Error handling? Documentation? Incomplete decomposition creates gaps that surface during execution.

Responsibility blending:

# Bad decomposition
Subtask 1: Generate code and tests and documentation

Combining conceptually distinct tasks in one subtask prevents the separation of concerns that makes agent work reliable. Code generation, test generation, and documentation are separate tasks with different validation criteria.

Practical decomposition process

When facing a complex task:

  1. Identify natural boundaries: What parts of the codebase are involved? What layers of the stack?

  2. Map dependencies: Which parts must complete before others can start? Which can run in parallel?

  3. Calibrate granularity: Is each subtask specific and achievable? Is the total count manageable?

  4. Assign ownership: Each subtask should have clear scope that does not overlap with others.

  5. Define interfaces: What does each subtask produce? What does the next subtask consume?

  6. Plan for failure: How does partial completion affect the workflow? Can failed subtasks retry independently?

A 20-minute decomposition conversation that produces a clear dependency graph saves hours of debugging confused agent output later. Skip this step, and you'll spend that time anyway—just in less pleasant circumstances.

On this page