How to actually get better output from AI coding assistants
The patterns that separate productive AI-assisted development from expensive trial and error.
Most people treat AI coding assistants like a smarter autocomplete. Type a prompt, get some code, edit it until it works, repeat. And that works fine for small stuff: generating a utility function, explaining an unfamiliar API, drafting a quick test.
But when you try to use AI on real production work, things with actual constraints, team conventions, and code that has to survive contact with other engineers, that approach falls apart fast. The output is technically correct but doesn’t fit anywhere. You end up rewriting most of it anyway.
I’ve been reading through some of the most useful practical writing I’ve found on this topic, and I want to walk through three patterns that actually change the output quality in a meaningful way. Not theory. Patterns you can start using today.
Start with context, not prompts
Here’s a pattern I see constantly: engineers write detailed prompts but give the AI no context about where the code will live. No project structure. No team conventions. No architectural decisions. Just a description of the feature they want.
The AI fills in the blanks. And it’s good at that. But it fills them in with generic, statistically average choices, not your choices.
The fix is something called knowledge priming (or context engineering if you want to sound fancy). Before you start a session, you feed the AI the information it needs to make decisions that match your codebase.
This can be as simple as pasting your team’s style guide into the conversation. Or pointing the AI at a representative file from your codebase and saying “write new code that looks like this.” Or, and this is where it gets more structured, maintaining a document that lives in your repo and gets included in every AI session automatically.
The Encoding Team Standards piece from Martin Fowler’s site gets into exactly this. The idea is to make your team’s conventions explicit and machine-readable, so you’re not re-explaining them every session. Things like: how you name variables, how you handle errors, what packages you prefer, what patterns you avoid. Not a vague “we care about clean code.” Specific, concrete rules the AI can actually follow.
This matters more than most people realize. The AI isn’t being sloppy when it ignores your conventions. It genuinely doesn’t know them. Give it the information and the output quality shifts noticeably.
Build a harness before you build a feature
This one changed how I think about AI-assisted development entirely.
The instinct when working with a coding agent is to ask it to build the thing you need. But what usually happens is the agent generates something, you’re not sure if it’s right, you ask for changes, the changes break something else, and you spend more time debugging than you would have writing it yourself.
The pattern that actually works is to build the harness first.
A harness here isn’t a testing framework in the traditional sense. It’s a set of constraints (tests, type contracts, lint rules, example inputs and outputs) that define what correct looks like before any implementation exists. You give the agent something to run against. It can iterate on its own output, catch its own mistakes, and come back to you with something that already passes your criteria.
This is the core of what harness engineering describes. Instead of reviewing AI output by reading it and hoping you catch the bugs, you create an automated feedback mechanism. The agent fails fast, locally, on your constraints, not in production, not in code review.
Here’s what this looks like in practice. Say you’re asking an agent to implement a data transformation function. Before you write the prompt, you write:
- A few unit tests covering the expected behavior
- Type signatures that constrain the inputs and outputs
- Maybe a couple of edge cases you know are tricky
Then you give the agent the tests and tell it to make them pass. Not “build me a function that does X.” Give it something to aim at.
The difference in output quality is real. The agent has a ground truth to orient around. It stops guessing at what “correct” means and starts solving a specific, verifiable problem.
This also makes code review faster. When an agent’s output comes with passing tests, you’re not starting from scratch when evaluating it. You’re asking: are these tests sufficient? That’s a much smaller question.
Create a feedback loop, not a conversation
Most AI-assisted coding sessions look like a conversation. You ask for something, you get something, you give feedback, you get a revision. Back and forth.
That works. But it doesn’t scale, and it doesn’t improve over time. Every session starts from zero. Every mistake is one you have to catch yourself.
The Feedback Flywheel pattern is about turning that conversation into something self-improving. The idea is to capture the feedback you’re giving the AI (the corrections, the style notes, the “no, not like that” moments) and encode them back into the context the AI starts with next time.
So say you’re working with an agent and it keeps generating code with a pattern you don’t use. You correct it. That correction disappears when the session ends. But if you take that correction and add it to your team standards document, it’s part of the context the next session starts with. You stopped correcting the same mistake.
Over time, this compounds. Your AI sessions get progressively less corrective work, because the common mistakes are already ruled out before the session begins. The flywheel is slow at first (encoding one convention at a time is tedious) but it pays back quickly.
The practical steps for this are roughly:
1. Run a session, collect corrections and feedback
2. Group the feedback into categories (naming, patterns, architecture, style)
3. Rewrite the corrections as rules, not commentary: “use X” not “avoid Y because...”
4. Add those rules to a shared context document that every session gets
This is also how teams start sharing AI productivity gains. If one engineer figures out a better prompt structure or catches a common mistake pattern, it shouldn’t stay in their head. It should go into the shared context, where everyone benefits automatically.
A note on what these patterns have in common
Looking at all three, the thread is the same: friction reduction through upfront investment.
Knowledge priming requires writing down your conventions explicitly. Harness engineering requires writing tests before implementation. The feedback flywheel requires capturing corrections and updating shared context. None of these feel productive in the moment. They all slow down the first session.
But they’re the difference between AI assistance that compounds and AI assistance that plateaus.
The engineers I’ve seen get the most out of these tools aren’t the ones with the cleverest prompts. They’re the ones treating the AI’s working environment with the same care they’d treat their own. Good tooling, good constraints, good feedback mechanisms.
The AI isn’t going to ask for any of this. It will work with whatever you give it. The question is whether what you give it is enough for it to do good work.
Where to start
If you’re not doing any of this yet, pick one:
Easiest: Write a short conventions document for your project. Three to five specific rules the AI should follow. Paste it at the start of every session for a week and notice what changes.
Higher impact: Before your next feature task, write two or three tests that describe the expected behavior. Use those as the prompt. See if you spend less time revising.
Long game: After your next AI session, write down the corrections you made. Find the most common one. Turn it into a rule in your conventions document.
None of this requires new tools. It’s a shift in how you set up the work before the AI touches it.
That’s the whole idea. AI coding assistants are powerful, but they’re not magic. They’re tools that reflect the quality of their inputs. Make the inputs better and the outputs follow.

