How I code with AI agents (spec-driven development)
An opinionated guide to writing code with AI agents like Claude Code.
Hey there đ,
Hereâs a pattern youâll recognise: You tell an AI agent to âadd authentication to the app.â It starts coding immediately. An hour later, youâre undoing decisions you never asked for.
Complex code you didnât ask for. Password reset flows you didnât need. New dependencies you explicitly avoid. The agent was trying to help. It just had no idea what you actually wanted.
The fix isnât better prompting. Itâs a different workflow entirely.
This post breaks down spec-driven development - the practice of defining a specification before letting an agent execute. Iâll show you exactly what goes in a spec, how it differs from other documents you might write, and a step-by-step workflow I use every day.
What Is Spec-Driven Development?
Spec-driven development is simple: instead of prompting first and figuring things out as you go, you define a specification up front. A short markdown document that describes what youâre building, constraints, relevant context, and a list of tasks to complete.
When you tell an AI agent to âadd authentication,â there are dozens of decisions to make. Token expiration. Storage approach. Error handling. Library choices. If you donât specify, the agent guesses. And guesses compound.
Even though agents like Claude Code can write plans, ask clarifying questions, and resume sessions, youâll still want to own the spec yourself. A plan Claude generates lives in a conversation. A spec lives in your repo - a markdown file you can review, edit, version control, and hand to any other agent or teammate. And writing the spec yourself forces you to make decisions rather than just review the agentâs choices.
The Three Documents (and Why Theyâre Different)
I see people conflating PRDs, design docs, and specs constantly. They serve different purposes.
Product Requirements Document (PRD): For humans; product managers, stakeholders. Covers what weâre building and why. Business value, user stories, success metrics. This is a debate document.
Technical Design Document: For engineers. Covers how weâre building it. Architecture decisions, scalability considerations, security implications. Also debated and reviewed.
AI Spec: For agents. This is an execution document - not a debate, a plan. It translates decisions from the PRD and design doc into something an agent can act on.
In practice, you donât always write all three. For a small feature, you might skip straight to a spec. For a large initiative, youâd have a PRD that spawns multiple design docs, each spawning multiple specs. The spec is always the final translation layer before code.
Anatomy of a Good Spec
A spec has four parts:
1. Why (Brief Context)
Keep this short. One or two sentences about the problem youâre solving. This helps the agent make intelligent decisions if it encounters ambiguity.
2. What (Scope)
Define the boundaries. What features are you building? Be specific about implementation details the agent would otherwise guess about.
Example: âJWT-based auth with one-hour access tokens and seven-day refresh tokens. Users can register, login, and refresh tokens.â
3. Constraints (Boundaries)
This is where you prevent the agent from being too eager. What libraries to use. What patterns to follow. Whatâs explicitly out of scope.
Example: âUse bcrypt for password hashing. Store user data in Postgres via Prisma. Must not add new dependencies. Must not store tokens in the database. Out of scope: password reset, OAuth, email verification.â
4. Tasks (Discrete Work Units)
Break the work into small, verifiable chunks. Each task should specify what to build, which files to touch, and how to verify completion.
Example:
Task 1: Add user model to Prisma schema. Verify: npx prisma generate succeeds.
Task 2: Create registration endpoint. Verify: Test with curl, user appears in database.
Task 3: Create login endpoint. Verify: Returns valid JWT on correct credentials.
When Specs Go Wrong
Specs fail in two directions.
Over-specified: Youâve constrained the agent so tightly it canât solve the problem. Signs: the agent keeps asking for permission, or produces convoluted code to satisfy contradictory constraints. Fix: loosen constraints, focus on outcomes rather than implementation details.
Under-specified: The agent still has to guess. Signs: you review the code and find unexpected decisions - new files, different patterns, surprise dependencies. Fix: add the missing constraints. Each surprise is a constraint you forgot to write down.
The goal is a spec tight enough that the agent canât make decisions youâd disagree with, but loose enough that it can solve problems you didnât anticipate.
My Workflow
Itâs important to point out that this level of planning isnât always needed. If youâre fixing a simple bug, you likely donât need extensive planning. Just do it. If youâre working on something large that might split into many tasks or run over multiple sessions - write a spec.
Hereâs how I actually use specs day to day:
Step 1: Generate. I describe what I want to build to the agent and ask it to write a specânot implement the feature. I use a /spec command for this.
Step 2: Iterate. I review the spec carefully. The agent will make assumptions. I correct them, add constraints I forgot, remove scope creep. This is where I catch problems before they become code.
Step 3: Execute. I open a fresh session. I ask the agent to read the spec and implement Task 1. Review the code. Commit. Move to Task 2.
âRead <path to spec> and implement T1â
Step 4: Adapt. Review the code. Could it be improved? Maybe Task 3 reveals a flaw in the spec. I go back and update it. This isnât waterfall, itâs iterative. The spec is a living document.
The key insight: donât ask the same agent to plan the work and do the work. Planning and execution are different modes. An agent thatâs planning will think through edge cases. An agent thatâs executing will rush to ship.
Skip the Frameworks?
There are a lot of spec-driven development frameworks out there. OpenSpec. Kiro. GitHub Spec Kit. Iâve tried them.
To me, they felt like overkill.
They generate tons of files. They want you to define user stories in markdown. They add ceremony that slows you down without adding value.
Hereâs what you actually need: one slash command that acts as a meta-prompt to generate a spec.
> â/spec implement rate limiting in the API.
The power of spec-driven development isnât in the tooling. Itâs in the practice of thinking before prompting. A fancy framework wonât fix sloppy thinking. A simple markdown file that forces you to articulate constraints is probably enough.
Why This Creates Leverage
Spec-driven development isnât new. Software teams have always worked this way. PRD > Design doc > Task breakdown > Implementation. The only difference is weâre handing tasks to agents instead of other developers.
But hereâs what changes: an agent that executes well-defined specs can move faster than any human. The bottleneck shifts from implementation to specification. Your job becomes defining work clearly enough that an agent can execute it autonomously.
Final Thoughts
If youâre building anything non-trivial with AI agents, write a spec first. It prevents agents from guessing. It gives you control over implementation decisions. It produces higher-quality code.
Working incrementally - one task at a time, reviewed and committed - beats letting an agent generate 10,000 lines you have to untangle later. Match the specâs detail to the taskâs complexity. One liner? Just do it. Small feature? Short spec. Large feature? Detailed spec with many tasks.
Your job is to architect the work. The agentâs job is to build it.
PS: Watch the video here. It contains a link to all the templates I use:
Thanks for reading. Have an awesome week : )
P.S. If you want to go deeper on building AI systems, I run a community where we build agents hands-on: https://skool.com/aiengineer

