We increasingly talk about software development with AI as though it were one practice.
It is not.
A developer asking a model to explain a function, someone building an application by conversational prompting, a team giving an agent a detailed specification, and an autonomous engineering system that can plan, edit, test, repair, and open a pull request are all using AI. But they are not using the same development pattern.
That distinction matters because the right way to use AI changes with the complexity, reversibility, risk, and uncertainty of the task.
This article presents a practical working taxonomy of AI software development patterns. These labels are not an official industry standard, and they should not be treated as a rigid maturity ladder. They are a way to reason more precisely about how much information, verification, and autonomy we give an AI system.
AI Development Is a Spectrum, Not One Mode
At one end, AI behaves like an assistant. A human remains in control of nearly every engineering decision.
At the other end, an engineering agent can interpret a goal, plan work, modify multiple files, run tools, observe failures, repair its own implementation, and continue until a stopping condition is reached.
Between those ends are several useful patterns:
- AI assisted development
- Conversational development
- Vibe coding
- Intent driven development
- Context driven development
- Spec driven development
- Test or eval driven AI development
- Agentic development
- Multi-agent development
- Autonomous engineering
The sequence is useful for explanation, but it is not a scorecard. A prototype may legitimately use vibe coding while a small production change may be better handled with an explicit specification and one model call. More autonomy is not automatically more sophisticated engineering.
1. AI Assisted Development
AI assisted development is the broadest and most familiar pattern.
The developer remains the primary driver. AI helps with bounded activities such as:
- code completion
- explaining unfamiliar code
- generating a function or test
- suggesting a refactor
- writing documentation
- finding likely causes of an error
The important characteristic is not the product being used. It is the control model.
The human decomposes the work, decides what to ask for, evaluates each result, and performs or approves the important actions.
This pattern is useful when the developer already understands the task and wants leverage rather than delegation.
2. Conversational Development
Conversational development moves from isolated suggestions to an ongoing dialogue about the software.
A developer might ask for a feature, review the result, point out a problem, clarify the requirement, ask for another change, and continue until the implementation is acceptable.
The conversation itself becomes part of the development interface.
This is more interactive than traditional completion, but the human still provides most of the orchestration. The model does not necessarily have durable repository context, a formal specification, or authority to independently execute a long workflow.
Conversational development works well for exploratory changes, learning, debugging, and collaborative design. Its weakness is that important decisions can remain trapped in the conversation instead of becoming durable repository knowledge.
3. Vibe Coding
Vibe coding is an intentionally loose development style.
The developer describes what they want in natural language, lets the model infer many implementation details, observes the result, and steers by feel rather than by a complete specification.
A typical request might be:
Add a small cache here so repeated reads are faster. Keep the existing API behavior.
The model has substantial freedom to decide what "small cache" means, how expiry should work, how data should be copied, what happens at boundary conditions, and which implementation strategy to use.
That freedom is not inherently bad. It can be extremely productive for prototypes, disposable experiments, internal tools, and low risk work.
The risk appears when requirements contain subtle correctness properties that are obvious to neither the model nor the reviewer.
In ADP-001, vibe generated implementations handled most visible cache behavior correctly but consistently missed mutation safety. The lesson was not that vibe coding always fails. It was that loosely represented requirements can leave repeatable correctness gaps.
4. Intent Driven Development
Intent driven development starts by making the desired outcome clearer without fully prescribing the implementation.
Instead of only saying what feature to add, the developer explains why it exists, what outcome matters, and which constraints should guide the solution.
For example:
Reduce repeated backend reads for the same client while preserving client isolation and existing API behavior. The cache should never allow stale writes to remain visible.
This gives the model a stronger decision frame than a vibe request while preserving implementation flexibility.
Intent is especially useful when there are multiple technically valid solutions and the model needs to understand the purpose behind the change.
But intent is not a specification.
Intent describes the outcome and priorities. A specification defines the behavior that must be true.
5. Context Driven Development
Context driven development gives the AI durable knowledge about the environment in which the change must live.
That context may include:
- repository instructions
- architecture documentation
- coding standards
- approved and prohibited dependencies
- domain terminology
- service boundaries
- testing conventions
- security and operational expectations
The goal is to stop making the model rediscover the same engineering rules in every conversation.
This is the foundation of an AI ready repository.
Context answers questions such as:
How does this codebase expect software to be engineered?
It does not necessarily answer:
Exactly what must this feature do?
That is why context and specification should complement each other rather than compete.
6. Spec Driven Development
Spec driven development makes the required behavior explicit before generation.
A useful specification may define:
- inputs and outputs
- behavioral rules
- boundary conditions
- error behavior
- compatibility requirements
- concurrency expectations
- allowed dependencies
- acceptance criteria
A specification should constrain what must be true without unnecessarily dictating every line of implementation.
This distinction is important. A good spec does not eliminate engineering judgment. It makes correctness less dependent on the model guessing unstated requirements.
In the constraint dense phase of ADP-001, the spec treatment passed all ten replicated runs while vibe and intent passed none of the complete evaluator suites. That is evidence for that task and model, not a universal law, but it illustrates why explicit behavioral information becomes more valuable as constraint density rises.
7. Test or Eval Driven AI Development
Test or eval driven AI development treats executable feedback as part of the development contract.
The AI does not only receive prose. It can produce or run an implementation against observable checks such as:
- unit tests
- integration tests
- type checking
- linting
- security policies
- performance thresholds
- model evaluations
- runtime contract checks
This matters because not all engineering knowledge can be represented perfectly in advance.
A compiler, runtime, service, or test environment can reveal facts that were missing or ambiguous in the original prompt.
Specifications describe expected reality. Verification lets the AI encounter reality.
Verification becomes especially powerful when paired with an agent that can respond to what it observes.
8. Agentic Development
Agentic development changes the control loop.
Instead of waiting for a human to manually issue every next instruction, an agent can pursue a bounded engineering objective through multiple actions.
A coding agent may:
- inspect the repository
- form a plan
- edit several files
- run tests or other tools
- observe failures
- repair the implementation
- repeat until a success or stopping condition
The defining characteristic is not simply that the AI writes more code. It is that the system has a loop connecting reasoning, action, observation, and another action.
That loop introduces new engineering questions:
- Which tools may the agent use?
- What can it modify?
- What evidence determines success?
- How many repair attempts are allowed?
- When should it stop and ask a human?
ADP-001 found that autonomy itself did not help when the static information already produced a correct first attempt. It became useful when runtime feedback contained information the initial prompt did not.
9. Multi-Agent Development
Multi-agent development distributes engineering work across multiple AI roles or agents.
One possible arrangement is:
- a planner analyzes the change
- an implementation agent writes code
- a test agent creates or runs verification
- a reviewer agent critiques the implementation
- a governance agent checks policy or risk
The potential benefit is specialization and independent review.
The danger is believing that multiplying agents automatically multiplies intelligence or reliability.
If all agents receive the same incomplete information, share the same blind spot, or simply agree with one another, the system may create additional cost without adding independent evidence.
Multi-agent design should therefore focus on role separation, information boundaries, independent verification, and clear ownership of decisions rather than the number of agents.
10. Autonomous Engineering
Autonomous engineering is the far end of the spectrum.
Here the system can take a broader engineering objective and perform a substantial workflow with limited human intervention.
Depending on the environment, that could include understanding an issue, inspecting architecture, planning changes, modifying code, creating tests, running validation, repairing failures, preparing documentation, and proposing a pull request.
Autonomous does not need to mean uncontrolled.
In serious engineering systems, greater autonomy should usually be paired with stronger boundaries:
- scoped permissions
- explicit policy
- observable validation
- bounded retry and token budgets
- human approval for consequential actions
- audit evidence
The goal is not to remove humans from engineering. It is to decide which parts of the engineering loop can be delegated safely and which decisions still require human judgment or independent authority.
Intent, Context, Spec, Verification, and Autonomy Are Different
Many discussions become confusing because these concepts are treated as competing methodologies.
They are better understood as separate dimensions.
| Dimension | Question it answers |
|---|---|
| Intent | What outcome are we trying to achieve, and why? |
| Context | What does this repository and organization expect? |
| Specification | What behavior must be true? |
| Verification | How will we know whether reality matches the expectation? |
| Autonomy | How much can the system do and repair without another human instruction? |
A strong engineering workflow may use all five.
For example, an agent can receive product intent, load repository context, implement against an explicit specification, run tests and policy checks, then use a bounded repair loop before escalating to a person.
That is more useful than arguing whether development should be "spec driven" or "agentic."
How the Patterns Compare
| Pattern | Human orchestration | Requirement structure | AI autonomy | Best fit |
|---|---|---|---|---|
| AI assisted | Very high | Low to medium | Low | Everyday coding assistance |
| Conversational | High | Evolves in dialogue | Low | Exploration, debugging, learning |
| Vibe | Medium | Loose | Low to medium | Prototypes and reversible work |
| Intent driven | Medium | Outcome focused | Low to medium | Problems with multiple valid implementations |
| Context driven | Medium | Repository rules are durable | Low to medium | Work inside established codebases |
| Spec driven | Medium | Explicit behavior | Low to medium | Constraint dense or higher risk changes |
| Test/eval driven | Medium | Executable acceptance signals | Medium | Work requiring objective validation |
| Agentic | Lower per action | Usually structured | High within bounds | Multi-step changes with observable feedback |
| Multi-agent | Lower per action | Structured by roles | High | Specialized planning, implementation, review |
| Autonomous engineering | Supervisory | Must be strong | Very high within governance | Broad repeatable workflows with reliable controls |
How to Choose the Right Pattern
I would not begin by asking, "How autonomous can we make this?"
I would begin with the work.
Use a lightweight pattern when:
- the task is small
- the change is easy to inspect
- failure is cheap and reversible
- the developer already understands the system
AI assisted, conversational, or even vibe coding may be perfectly reasonable.
Add context and specification when:
- the codebase has important conventions
- the feature has subtle boundary behavior
- multiple constraints must hold simultaneously
- a superficially working solution can still be incorrect
Add verification and agentic repair when:
- the task requires several coordinated actions
- runtime behavior contains information not available in advance
- tests and tools expose useful failure signals
- repair can be bounded safely
Consider multi-agent or broader autonomy when:
- role separation creates genuinely independent analysis or review
- the workflow is repeatable enough to automate
- tool permissions and stopping conditions are well defined
- the system can produce evidence that humans can audit
Do Not Turn This Into a Maturity Ladder
There is a temptation to draw a staircase from vibe coding to autonomous engineering and assume every organization should climb it.
That would be the wrong lesson.
The best development pattern is the least complicated one that provides enough reliability for the task.
A senior engineer using conversational AI for a five line refactor is not "less mature" than a team using a multi-agent system. They may simply be choosing the appropriate control model.
Likewise, deploying an autonomous coding agent on a poorly specified, weakly tested repository is not advanced engineering. It is automation placed on top of ambiguity.
Autonomy amplifies the quality of the environment around it.
What the Experiments Add
This taxonomy explains the development patterns. The companion article From Vibe Coding to Agentic Development: What Actually Improves AI Generated Software? examines several of them experimentally.
The ADP-001 lab found three especially useful signals on the tested tasks:
- simple tasks could hide differences between development methods
- explicit behavioral information mattered more as constraint density increased
- runtime feedback and repair opportunity helped some failing implementations, but additional retries eventually showed diminishing returns
That leads to a more useful way to think about AI engineering.
Do not choose a method because its label sounds more advanced.
Decide how much information the model needs, how much reality it can observe, and how much bounded autonomy the task can safely justify.
The Direction of AI Engineering
The progression in AI software development is not simply from better autocomplete to agents that write more code.
The deeper change is that software engineering is gaining a programmable reasoning and execution layer.
That means repositories, specifications, tests, policies, architecture documentation, and runtime signals are becoming inputs to automated engineering decisions.
The organizations that use this well will not necessarily be the ones with the most autonomous agents.
They will be the ones that make engineering intent clear, context durable, behavior testable, feedback observable, and autonomy appropriately bounded.
Explore this topic
Part of the AI Native Engineering topic collection.