AI-Sized Tasks

Breaking Work into AI-Sized Tasks

Reviewed by Juan Pablo Lorandi, CTO for Azumo

AI coding agents do their best work on small, bounded tasks: one objective, a clear file or module boundary, explicit constraints, expected tests, known dependencies and a rollback path. A broad ticket like "Build billing settings" works for an experienced developer, but it leads an agent to guess at layout, data model and business rules. Decompose features into tasks an agent can complete and a reviewer can verify on their own.

Traditional sprint planning breaks work into tickets sized for human developers working over several days. A typical ticket might read: "Build billing settings." That ticket assumes the developer will explore the problem space, make design decisions, implement across multiple files, write tests and self-review, all within a loosely bounded scope. Human developers handle this ambiguity well because they can use judgment at each step.

AI coding assistants handle it poorly. An agent given "build billing settings" will produce something, probably a full billing settings page with assumptions about layout, data model, validation rules, payment method handling and error states. Each assumption may be reasonable on its own, but together they produce a feature that reflects the AI's training data more than your product's actual requirements.

The fix is not to avoid AI on complex features. It is to decompose work differently. AI rewards smaller, sharper tasks: the better the boundary, the better the output.

Human-Sized Tasks vs. AI-Sized Tasks

The difference between a human-sized task and an AI-sized task is not mainly about effort. It is about scope clarity and independence.

A human-sized task can afford to be broad because the developer will decompose it mentally, make decisions along the way and adjust based on what they discover. "Build billing settings" is enough for an experienced developer who knows the codebase and can work out the details.

An AI-sized task needs to be narrow because the agent will execute exactly what it is told. "Add billing address validation to the existing billing settings form, using the current form pattern, without changing payment method logic" is an AI-sized task. It has one objective, a clear module boundary, explicit constraints about what not to change and an implied testing scope.

The distinction matters because AI agents are reliable at bounded work and unreliable at unbounded work. Given a clear function to implement, specific inputs and outputs, an existing pattern to follow and explicit constraints, an AI agent will produce clean, testable code that fits the system. Given a broad mandate with room for interpretation, it will produce code that solves a version of the problem that may not be your version.

The Recommended Task Pattern

Each AI-sized task should include these elements:

One objective. The task should accomplish a single, identifiable thing. Not "build the settings page" but "add the address form component." Not "implement search" but "add keyword filtering to the existing product list query."

A clear file or module boundary. Where possible, the task should name which files or modules the agent should modify. This prevents unintended changes to unrelated parts of the codebase and makes code review faster because the reviewer knows exactly where to look.

Explicit constraints. What should the agent not change? What patterns should it follow? What existing interfaces should it preserve? Constraints are often more important than instructions because they stop the AI from optimizing locally in ways that break the system globally.

Expected tests. What tests should accompany the change? Specify the type (unit, integration, end-to-end), the scenarios to cover and the testing framework to use. Without this, AI agents will either skip tests or write tests using conventions that do not match the project.

Known dependencies. Does this task depend on another task being completed first? Does it share data models, API contracts or UI components with other work in progress? Making dependencies explicit prevents merge conflicts and duplicated implementations.

A rollback path. How would the team undo this change if it causes problems? For small, bounded changes, the rollback is usually just reverting the commit. Stating it explicitly forces the team to confirm that the change is, in fact, reversible.

Where AI Works Well

AI coding assistants are most effective on tasks that have clear inputs and outputs, follow established patterns in the codebase and can be verified with automated tests. Specifically:

Isolated, well-defined changes. Adding a new field to an existing form, implementing a new API endpoint that follows the pattern of existing endpoints, or adding validation logic with clear business rules. These tasks have bounded scope and deterministic success criteria.

Repetitive patterns. If the codebase has ten API endpoints that all follow the same controller-service-repository pattern, AI will generate the eleventh reliably. Pattern replication is where AI saves the most time relative to manual development.

Boilerplate and scaffolding. Configuration files, build scripts, Docker configurations, database migration templates and other structural code that follows well-documented conventions. The time saved here is real and the risk of errors is low.

Test generation. Given a function with clear inputs and outputs, AI can generate test suites covering happy paths, edge cases and error conditions. This is one of the highest-value uses of AI because most teams underinvest in testing, and AI can close the gap quickly. Our chapter on test-first development with AI goes further.

Migrations and refactors with clear constraints. Renaming a variable across a codebase, converting callback-based code to async/await, updating API calls to a new version, or migrating database schemas with clear before/after mappings. These tasks are tedious for humans and reliable for AI, provided the constraints are explicit.

Codebase navigation and comprehension. Understanding how a feature works, tracing data flow across modules or explaining the purpose of legacy code. AI agents with codebase access do these investigative tasks well.

Where AI Is Riskier

Some categories of work consistently produce poor outcomes when delegated to AI agents without significant human oversight:

Broad architectural changes. Decisions about system boundaries, service decomposition, data ownership, caching strategies or scaling approaches require understanding the business context, operational constraints and long-term maintenance implications. AI can generate options, but it should not make these decisions by default.

Vague product decisions. "Make the dashboard more useful" or "improve the onboarding flow" are product problems, not engineering tasks. AI will interpret them as code changes, producing modifications that may or may not address the underlying user need.

Cross-system behavior. Changes that span multiple services, databases and message queues introduce complexity that AI agents handle inconsistently. The agent may produce a working change in one service while creating incompatibilities in another.

Security-sensitive flows. Authentication, authorization, payment processing, handling of personally identifiable information and encryption are areas where AI-generated code frequently introduces vulnerabilities, and AI-authored code shows higher security vulnerability rates than human-written code. These areas require human design, human review and targeted security testing.

Changes with weak test coverage. If the existing code has no tests, adding AI-generated changes is particularly risky because there is no automated way to verify that the change did not break existing behavior. The first AI-sized task in an untested area should often be "add tests for the existing behavior," not "change the behavior."

The Three Tracks of Estimation

When decomposing work into AI-sized tasks, it helps to think of each feature as three types of work, each with different estimation characteristics.

Generation work is the AI-assisted implementation: writing new code, creating new components, building new endpoints. This is fast but volatile. AI can generate a working implementation in hours, but the output needs validation. Estimating generation work from pre-AI baselines will overestimate the time needed.

Verification work includes tests, code review, security checks and design validation. In AI-assisted development, this becomes the critical path. Verification takes longer when the reviewer did not write the code, because understanding AI-generated logic takes the same analytical effort as understanding code written by a colleague you have never worked with.

Integration work includes merging into the broader system, resolving conflicts with parallel work, validating data contracts, ensuring operational readiness and confirming that the change works in staging and production. This is where surprises live. Integration problems are rarely visible until the code meets the real system.

The common planning failure is to estimate only generation work and assume verification and integration will take the time they always did. In practice, AI-assisted development often cuts generation time sharply while keeping verification and integration time constant, or even increasing it, because the higher volume of generated code creates more surface area to review and integrate.

Each track should have separate estimation, separate owners and a separate definition of done. A feature is not complete when the code is generated. It is complete when the code is verified and integrated. The same split shapes what a project costs; see how Azumo prices custom software.

Decomposition in Practice

Here is a practical example of how a feature-level requirement might be decomposed into AI-sized tasks.

Feature: "Users should be able to reset their passwords via email."

AI-sized tasks:

  1. Add a "Forgot Password" link to the login form, using the existing link styling, linking to a new /forgot-password route. No backend changes.
  2. Create the /forgot-password page with an email input field, using the existing form component pattern. Submit action calls POST /api/auth/forgot-password. Handle loading state and error display.
  3. Implement the POST /api/auth/forgot-password endpoint. Validate email format. Look up the user. Generate a time-limited reset token (30-minute expiry). Store the token hash in the database. Return 200 regardless of whether the email exists (prevent user enumeration). Do not send the email yet; that is a separate task.
  4. Create the password reset email template using the existing email template pattern. Include the reset link with token. Include an expiry warning.
  5. Implement the email sending service call from the forgot-password endpoint, using the existing email service. Add rate limiting: maximum 3 reset requests per email per hour.
  6. Create the /reset-password page. Accept the token from the URL. Validate the token (not expired, not already used). Show a password input with a confirmation field. Submit calls POST /api/auth/reset-password.
  7. Implement the POST /api/auth/reset-password endpoint. Validate the token. Validate that the password meets requirements (minimum 8 characters, existing password policy). Hash the new password. Invalidate the token. Return success or a specific error.
  8. Add unit tests for token generation, validation and expiry logic. Add integration tests for the full reset flow. Add a test for rate limiting. Add a test for user enumeration prevention.

Each task has one objective, touches a bounded set of files, includes explicit constraints and can be verified independently. Tasks 1–7 can be executed by an AI agent with high confidence. Task 8 can also be AI-generated, but a person should review it carefully to make sure the test scenarios reflect real security requirements.

Getting Started

The easiest way to adopt AI-sized task decomposition is to start with your next sprint planning session. Take the largest ticket in the backlog and break it into tasks using the pattern above. Then ask: could an AI agent execute each of these tasks independently, given access to the codebase and the context files? If the answer is yes, the decomposition is good. If the answer is "it depends on what the agent assumes," the task needs more explicit constraints.

As a custom software development company, we build this into planning: our engineering managers and tech leads decompose work into AI-sized tasks as a standard step. In the Azumo SDLC, the feature workflow puts a plan between the spec and the build, and a person approves that plan before the agent writes code. Each verified task becomes one commit on a feature branch, and work missing a test goes back to build.

This practice has two benefits beyond AI efficiency. First, it makes code review faster because each pull request is small and focused. Second, it makes progress more visible because the team completes and merges tasks throughout the sprint instead of delivering large, monolithic pull requests at the end. Whether or not AI is involved, smaller and sharper tasks produce better outcomes.

Related Chapters