AIApril 21, 20264 min read
Context Is the Real Prompt
USAMA DARWASHI

I spent my first few months with AI coding assistants doing what everyone did in 2023: collecting prompt incantations. "Act as a senior engineer." "Think step by step." "Be concise." Some of it helped at the margins. None of it fixed the actual problem, which was that the code coming back was competent, generic, and wrong for my codebase in a dozen small ways. Wrong error shapes. Wrong naming. A UserService that would have been fine in a tutorial and would never survive review.
The fix, it turned out, had almost nothing to do with how I phrased the request. It had everything to do with what the model could see when it answered.
The model writes for the codebase it can see
A large language model with an empty context window doesn't write bad code. It writes the statistical average of every codebase it was trained on. Ask for "an endpoint that returns operator metrics" with no context and you get the median of ten thousand blog posts: a generic controller, a DTO invented on the spot, exceptions swallowed in a try/catch, pagination bolted on however the model felt like it that day.
Your codebase is not the median. Mine certainly aren't. The Indicators platform I built for telecom operators in Oman had a strict contract for how validation errors were shaped, because the operators' own systems parsed those responses programmatically. Change the shape and you break someone else's integration. No amount of "act as a senior engineer" communicates that. Pasting the error handler and the contract does, instantly.
A model without your context doesn't write bad code. It writes someone else's good code.
Once that clicked, I mostly stopped tweaking prompts and started treating every request as a context problem: what does the model need to see to produce code that would pass review here, in this repo, this week?
What actually goes in the window
What I load before asking for anything non-trivial, roughly in order of leverage:
- Two or three examples of similar existing code. This is the strongest lever by far. A paragraph saying "follow our error handling conventions" does almost nothing. One handler that does it right does almost everything.
- The real interfaces it must touch. The actual entity, the actual repository signature, the actual Angular service. Pasted or opened, never described from memory. Described interfaces drift; real ones don't.
- Constraints stated as facts, not preferences. "We're on PostgreSQL 14." "Angular with standalone components, no NgModules." "This runs inside Docker with 512MB, don't buffer the whole export in memory." Facts get respected. Vague wishes get averaged away.
- A conventions file that lives in the repo. Naming, layering, how we do migrations, what we log and what we never log. Written once, loaded every session.
- The anti-patterns, with reasons. "Don't add a caching layer here; this table changes every five minutes and we've been burned before." Models take a stated reason seriously in a way they don't take a bare rule.
Notice what's missing: adjectives. Nothing about being an expert, nothing about thinking carefully. The model's competence was never the bottleneck. Its visibility was.
Treat it like a new hire, not an oracle
The mental model that made this stick for me: an AI assistant is a very fast engineer on their first day, every day. When I led development on Sabr, the TRA's analytics platform, our conventions weren't decoration. Most of them were scar tissue from real incidents. A new engineer absorbed them through the onboarding doc, code review, and reading neighboring code. The model has to absorb them the same way, except it starts from zero every session, so the onboarding has to be cheap and repeatable.
That reframing changes the daily workflow:
- Small, scoped asks against files that are already open, instead of "build the feature" against an empty window.
- The conventions doc gets updated the moment the model makes a mistake a new hire would also make. If the assistant got it wrong, the docs were wrong or missing, and the next engineer would have hit the same gap.
- Review the diff, not the vibe. Context gets you code that fits; it doesn't get you code that's correct.
That second point is the part I didn't expect. Six years in, the discipline of feeding context to a model has made me better at writing things down for humans. The model is a brutal, instant test of whether your conventions actually live in the repo or only in your head. If it can't infer the rule from what's written, neither can the person you hire next month.
Prompt engineering optimizes the question. Context engineering optimizes what the answer is allowed to be built from. Only one of those scales past a demo.