Back to Blog
    The Prompting Series · Part 2 of 4
    CodingPromptingDeveloper Tools

    How to Prompt AI for Code That Actually Works

    The gap between AI that writes bugs and AI that writes shippable code is almost entirely in the prompt. Six habits that close it.

    June 15, 20268 min read
    Code on a laptop screen, representing prompting AI for programming

    Models are genuinely good at code now. They still fail constantly — not because they can't write the function, but because they're guessing at everything you didn't tell them. Good coding prompts remove the guessing.

    Context is the whole game

    The number one cause of bad AI code is missing context. The model invents a language version, a framework, a data shape — and it invents wrong. Front-load the facts:

    • Language and version (“TypeScript 5.4, strict mode”)
    • Framework and version (“Next.js 14 App Router, not Pages”)
    • Constraints (“no new dependencies,” “must run in a Deno edge function”)
    • The actual surrounding code, not a paraphrase of it

    Weak prompt

    Write a function to cache API responses.

    Stronger prompt

    In a Next.js 14 App Router project (TypeScript, strict), write a helper that caches fetch responses in memory for 60s. No external deps. It’ll be called from server components. Here’s the existing fetch call: [paste].

    Define the contract: inputs, outputs, edge cases

    Describe the function like you'd describe it to a contractor who bills by the surprise. What goes in, what comes out, and what happens at the edges:

    PromptInputs: an array of orders, each { id, total, status }. Output: total revenue of orders with status “paid,” rounded to cents. Edge cases: empty array → 0; missing total → treat as 0; never return NaN. Include the type signature.

    Naming the edge cases up front does two things: you get correct code the first time, and you force yourself to actually decide what should happen — which is usually where the real bug was hiding anyway.

    Ask for assumptions and tests, not just code

    A model will happily hand you confident code built on a wrong assumption. Make it surface the assumptions before you trust the output:

    PromptBefore writing the code, list every assumption you're making about the data and the environment. Then write the function. Then write three test cases, including one edge case you think I might have missed.

    The tests aren't just for coverage — they're how you find out whether the model understood the task. If its test cases don't match what you meant, the code won't either, and you caught it in ten seconds instead of in production.

    Takeaway: “List your assumptions, then write the code, then write tests” catches more bugs than any single instruction.

    Debug by pasting the error, not “it broke”

    “It doesn't work” forces the model to guess what went wrong, and it'll often rewrite the whole thing to dodge a one-line fix. Give it what a good bug report gives a teammate:

    • The exact error message and stack trace
    • What you expected vs. what happened
    • The relevant code and the input that triggered it
    • What you've already tried

    Weak prompt

    This function is broken, fix it.

    Stronger prompt

    This throws “TypeError: cannot read properties of undefined (reading id)” on line 12 when the input array is empty. Expected: return []. Here’s the function and the failing input: [paste]. Give me the minimal fix, not a rewrite.

    Have a second model review the code

    The model that wrote the code is the worst reviewer of it — it shares its own blind spots and tends to defend its choices. A different model reads the same code cold and catches the off-by-one, the unhandled null, the SQL injection, the race condition.

    PromptYou're a senior engineer reviewing this in a PR. Find real bugs, security issues, and edge cases the author missed. Rank them by severity. Don't rewrite it — just tell me what's wrong.

    Running “write” and “review” across two different models is one of the highest-value habits in AI-assisted coding. It's the whole idea behind a draft → critique → fact-check flow — AskOnce runs it across models so the reviewer isn't the author.

    Keep it on a short leash

    The failure mode of AI coding is asking for too much at once: “build the whole feature.” You get 200 lines you didn't read, one of which is quietly wrong. Work in small, verifiable steps:

    • One function or one file at a time
    • Run it before asking for the next piece
    • When it goes sideways, start a fresh chat instead of fighting a polluted context

    You're the one who has to maintain the code. Prompt so that you understand every line before it ships — the goal is leverage, not a black box.

    Let one model write and another review.

    AskOnce runs your coding prompt through multiple models at once — so the reviewer isn't the author, and bugs surface before they ship.

    Try AskOnce Free