methodologyAug 7, 2026·7 min read

Design First, Then Build: A Better AI Dev Workflow

By Jonathan Stocco, Founder

The Scenario Every Developer Recognizes

It is mid-2026, and you have a feature to ship. You open ChatGPT or Claude, type something like "build me a function that parses webhook payloads and routes them to the right handler," and wait. The model returns something plausible. You paste it in, run it, and it almost works. So you prompt again: "fix the edge case where the payload is missing the event key." Another round. Then another. Forty-five minutes later, you have code that functions, but you also have a conversation thread that looks like a debugging session rather than a build session. You never actually described what you were building. You just started building it.

This is the default mode for most developers using AI coding assistants in 2026, and it is expensive. According to McKinsey's State of AI in 2024 report (source), organizations that adopt structured design and planning approaches before implementing AI tools report higher success rates and better integration outcomes compared to those using ad-hoc implementation strategies. The pattern holds at the individual developer level too. Jumping straight into prompting skips the step that makes prompting useful: knowing precisely what you want before you ask for it.

The fix is not a better model. It is a different sequence.

What Design-First Actually Means in Practice

Design-first means producing a written artifact that describes your system before you write a single prompt asking an AI to build it. Not a full technical document. A tight, structured description of inputs, outputs, constraints, and edge cases. Think of it as the brief you would hand to a contractor before they start work. The contractor analogy is useful because it reframes the relationship: you are not collaborating with the model in real time, you are commissioning it with a clear scope.

Here is what that looks like concretely. Instead of opening Google Gemini and typing "help me build a webhook router," you spend ten minutes writing this first:

  • Input: JSON payload from a third-party service, always containing event_type (string) and payload (object). Occasionally missing metadata.
  • Output: Routed function call based on event_type value. Return a structured error object if the type is unrecognized.
  • Constraints: No external dependencies. Must handle missing metadata gracefully without throwing. Response time under 50ms.
  • Edge cases: Empty payload object, null event_type, unknown event types not in the routing table.

Now your first prompt to the model is not a question. It is a commission. "Here is the full specification. Build the router function." The model has everything it needs to produce something close to final on the first pass. You are not iterating on what to build. You are reviewing what was built.

The before/after difference is not subtle. In the ad-hoc approach, the first several exchanges are spent clarifying scope that you could have defined yourself in ten minutes. In the design-first approach, those exchanges become code review. The model's output quality does not change. What changes is how much of its output you can actually use.

This matters especially for constraint-heavy requirements. I learned this the hard way building output validation into one of our pipelines. We spent a week trying to get a classifier to output exactly three sentences. The prompt said "EXACTLY 3 sentences. Not 2, not 4. Three." It still wrote four. The fix was not better instructions. It was stronger constraint language: "CRITICAL: This is a hard technical constraint enforced by automated validation. If you write 4, the output will be rejected. Count your sentences before outputting." LLMs do not treat polite instructions the same as system constraints. Every system prompt we write now uses emphatic constraint blocks for hard output requirements. Had we designed the output format before prompting, we would have caught this distinction before burning a week on it.

One honest caveat: design-first is not the right approach for every task. When you are genuinely exploring a problem space and do not yet know what the output should look like, open-ended prompting is the correct tool. The design-first method pays off when requirements are knowable in advance. If you are prototyping something speculative, forcing a written brief before prompting adds friction without adding clarity. Know which mode you are in before you start.

Building the Workflow: Three Phases That Actually Stick

The workflow breaks into three phases. Each one is short. Together they replace the sprawling, reactive prompt sessions that eat developer time.

Phase 1: Write the brief (10 minutes). Before opening any AI tool, write down inputs, outputs, constraints, and edge cases in plain text. Use bullet points. Do not write prose. The goal is a document you could hand to another developer and have them understand the scope without asking follow-up questions. If you cannot write it clearly, you do not understand it clearly yet. That is useful information before you start prompting.

Phase 2: Commission, do not converse (first prompt). Paste the full brief into your first message. Do not ask the model to "help you think through" the problem. Ask it to build the thing. The distinction matters because conversational prompting invites the model to ask clarifying questions, which puts you back in the reactive loop. A commission prompt signals that the scope is closed. Google Gemini handles this particularly well for design-to-build pipelines because its context window accommodates detailed briefs without degrading output quality on the implementation itself.

Phase 3: Review against the brief, not against your intuition (iteration). When the model returns code, check it against your written brief point by point. Does it handle the missing metadata case? Does it return the right error object for unknown types? This is a structured review, not a vibe check. When you find a gap, your follow-up prompt references the brief directly: "The brief specifies the response time must be under 50ms. The current implementation calls an external API on every request. Revise to eliminate that dependency." The model now has a concrete target, not a vague complaint.

This three-phase process is repeatable. It works for a single function, a full service, or an automation pipeline. We use a version of it when building n8n workflow blueprints, including the Jira Sprint Risk Analyzer. Before writing a single node, we document what data enters the pipeline, what the output format must be, and which failure states need explicit handling. The result is a build that requires far fewer mid-construction corrections. If you want to see how that translates into a working pipeline, the setup guide walks through the full implementation.

The broader principle applies to any system where an AI model is doing structured work. If you are curious how this connects to more complex orchestration patterns, the piece on why specialized agents outperform monolithic AI systems covers the same design discipline applied to multi-agent builds.

One more structural note: the design-first approach surfaces integration problems early. When you write down your constraints before prompting, you often discover that two requirements conflict, or that an edge case you assumed was rare is actually the common path. Catching that in a ten-minute brief is cheaper than catching it after the model has already generated 200 lines of code you now need to throw away. This is what ForgeWorkflows calls agentic logic applied upstream: the reasoning work happens before the build, not during it.

What We'd Do Differently

We would version the brief alongside the code. Right now, most developers write a brief, use it once, and discard it. Treating the brief as a versioned artifact, committed to the same repository as the code it produced, creates a record of why the system was built the way it was. Six months later, when a requirement changes, you have the original constraints in front of you instead of reverse-engineering intent from the implementation.

We would build a constraint library before starting any new project. Across multiple builds, certain constraint patterns recur: output format requirements, error handling conventions, latency thresholds. Maintaining a reusable library of constraint blocks, the kind we now use in every system prompt for hard output requirements, would cut brief-writing time significantly and reduce the chance of missing a constraint class entirely.

We would apply this discipline to prompt templates, not just code generation. The design-first method works equally well for any repeatable AI task: classification prompts, summarization pipelines, routing logic. We came to this late. If you are building anything that runs more than a few times, write the brief first, every time.

Get Jira Sprint Risk Analyzer

$199

View Blueprint

Related Articles