Skip to content

Getting good results from AI coding assistants

Give context, work in small steps, verify with tests — a workflow that makes AI-written code something you can trust.

PracticalDevelopers

17 minAs of Oct 2026

By the end of this guide

  • Write requests with a goal, constraints and a definition of done, so the assistant stops changing the wrong things.
  • Have it write a test that reproduces the bug first, so you can judge its fix objectively.
  • Know what to ask when it reviews code, and what to check yourself.
Illustration of a code editor beside an AI chat panel with a task checklist and a terminal showing passing tests
Illustration: AI Ping

Who this is for

  • Developers who find AI coding tools hit-or-miss
  • Teams evaluating AI coding tools

What you need

  • An AI coding tool (editor plugin or terminal agent)
  • A project where you can run tests

Step by step

  1. State the goal, constraints and definition of done

    Instead of "fix login," say what's broken, what must not change, and how you'll know it's done. Include relevant file paths and the full error message.

    The same task, asked vaguely and specifically
    ItemVagueSpecific
    GoalFix loginFix password reset emails being sent twice
    Scope(none)src/auth/reset.ts, src/mail/send.ts
    Constraints(none)Don't change the email template or the public API
    Done when(none)One email per reset request; existing tests pass
    Example prompt
    Goal: fix password reset emails being sent twice
    Files: src/auth/reset.ts, src/mail/send.ts
    Constraints: don't change the email template or the public API
    Done when: one email per reset request, and existing tests pass
  2. Ask in small steps

    Hand over a whole feature and you'll get a change too big to review. Split the work into reviewable pieces — usually a few files at a time.

    One bug, split into reviewable steps
    StepAsk forDone when
    1A test that reproduces the bugThe test fails
    2Fix the cause of the duplicate sendNew and existing tests pass
    3Handle two simultaneous requestsA concurrent-request test passes
    4Tidy logs and commentsChanges stay within the two files
    Example prompt
    Don't change any code yet. First show me a plan that splits this into easy-to-review steps, with how to check each step is done.
  3. Have it write the test first

    For a bug, ask for a test that reproduces it, confirm the test fails, then ask for the fix. Now you have an objective way to judge the change.

    Example prompt
    Before changing anything, write a test that reproduces the duplicate reset email. It should fail against the current code.
    Example AI reply

    Here's a test that sends one reset request and counts the emails sent. Rename the helpers to match your project. Against the current code it should fail, because two emails go out.

    Example code
    test("sends exactly one email per reset request", async () => { const mailer = createFakeMailer(); await requestPasswordReset("[email protected]", { mailer }); expect(mailer.sent).toHaveLength(1); });

    Check it

    • Run it and confirm it fails with something like "expected 1, received 2." If it passes from the start, it isn't reproducing the bug.
    • After the fix, this test and all the existing ones must pass.
  4. Let it review, but make the call yourself

    When the change is done, ask it to look for missed cases and security problems. The final judgment — and the decision to ship — stays with you.

    Example prompt
    Review the change you just made. Pay particular attention to two requests arriving at once and to the email send failing.
    Example AI reply

    Two places need attention.

    1) If two requests arrive at once, both can see "no email sent yet" and send one each. Add a constraint that stops the same request being recorded twice, such as a unique key.

    2) A failed send is still recorded as sent. Record it only after the send succeeds, or roll the record back on failure, so the user can try again.

    Check it

    • Don't take the findings on trust: turn each case into a test and see whether it actually reproduces.
    • Changes that touch security, payments or personal data get a human review as well.

Common mistakes

  • Pasting files that contain API keys or passwords
  • Handing over work too large to review
  • Merging because it "seems to work," without tests

References

Keep learning

  • How-to guide14 min

    Your first LLM API call: from key to response

    Using the Claude API as the example: keep your API key safe, send a first request from Python, and read the answer, the stop reason and the token usage.

    BeginnerDevelopers
  • How-to guide15 min

    Get structured (JSON) output from an LLM

    Instead of asking for JSON and hoping, define the shape as a schema and get responses your code can use directly. Worked through with a customer-message classifier.

    PracticalDevelopers
  • How-to guide15 min

    Cut API costs with prompt caching

    Cache the long instructions and documents you resend with every request, and their input cost drops sharply. Using a support bot built on a manual, here's how to place the cache point and check that it works.

    PracticalDevelopers