Context engineering is the work of curating exactly what a model sees before it answers: the real files, the actual constraints, and the one example that shows the shape you want. A sharper prompt helps a little. Feeding the model the right context is what changes the output.
For a long stretch I kept tuning wording and getting small gains. The lever was somewhere else. Once I started treating the model like a new engineer joining the team, handing it the real repo and the file that shows how we do things here, the quality jumped. This is the habit I use now and the specific moves that make it repeatable. If you read one section, read the one on cutting noise.
Why context beats wording
The model is not short on intelligence. It is short on information about your specific problem. When an answer comes back generic, it is usually because the input was generic.
Think about how you brief a capable engineer who just joined. You do not hand them a cleverly phrased sentence and hope. You point them at the repo, the ticket, the constraint that makes this problem yours. The model works the same way. Its output is a function of what it can see in the window, and wording is a thin slice of that.
I test this constantly. Take a vague prompt with rich context against a beautifully worded prompt with thin context. The rich-context version wins almost every time. Phrasing sets the tone and the task. Context sets the ceiling on how correct the answer can be.
So the first question I ask is no longer ‘how do I say this better’. It is ‘what does the model still not know that I do’. That one reframe changes where the effort goes.
Give it the real files
Do not describe your code. Paste it. A summary of a function is lossy, and the model fills the gaps with the average of everything it has seen, which is exactly the generic output you are trying to avoid.
When I want a change to a module, I give the model the actual file, the types it depends on, and one caller that uses it. That is usually enough for it to match the existing patterns instead of inventing new ones. When I want a bug fixed, I paste the failing test and the real stack trace, never my paraphrase of them.
The same holds outside code. Writing a landing page? Give it the real product notes and a page you consider good, not an abstract description of your tone. Answering a support question? Give it the actual docs, not your memory of them.
Real artifacts carry detail you would never think to mention. Variable names, edge cases, the odd comment that explains a past decision. That detail is the difference between an answer that fits your system and one that merely sounds right.
Cut the noise
More context is not automatically better. Every irrelevant file you paste competes for the model’s attention and pulls the answer toward things that do not matter. A window stuffed with three tangential modules produces worse work than a tight window with the one that counts.
My rule: include what the model needs to be correct, and nothing that is merely related. Before I send, I reread the context as if I were the model and ask what each piece is doing. If a file is there because it felt safer to include it, it comes out.
Watch for stale context too. In a long session the earlier messages still sit in the window, and a decision you reversed twenty minutes ago is still shaping answers. When a thread starts drifting, I open a fresh one and paste only the current state. A clean, small window beats a large one full of history the model has to guess its way through.
Order the window like a briefing
Position matters. Models weight the start and the end of the context more heavily than the middle, so where you put something changes how much it counts.
I structure the window like a good briefing. The task and the hard constraints go near the top, so they frame everything that follows. The reference material sits in the middle. The specific instruction, the thing I actually want done right now, goes last, closest to where the model starts writing. When I have non-negotiables, a required library, an output format, a thing it must never do, I state them at both ends rather than burying them once in the middle.
This is not superstition. Move the same instruction from the middle to the end and you can watch adherence go up. If an important rule keeps getting ignored, it is often not that the model missed it. It is that the rule was sitting in the low-attention part of the window.
One example beats a page of rules
When I catch myself writing a long list of rules to describe an output, that is the signal to stop and show one worked example instead.
Rules describe the target from the outside and leave room for interpretation. An example is the target. Give the model one commit message in the format you want, one function written in your style, one email with the structure you like, and it infers the pattern faster and more faithfully than a paragraph of instructions ever manages.
This is the highest-leverage move in the whole habit. One good example usually replaces a dozen rules and outperforms them, because it carries the tone, the structure, and the small conventions all at once. Rules cannot capture those without becoming a specification longer than the work itself.
When one example is not enough, I add a second that covers a different case. Two contrasting examples pin down the boundaries far better than piling on more prose.
Build a repeatable context habit
Curating context by hand every time is slow, so I turned it into something reusable.
For any recurring task I keep a small context template: a note of which files to pull, the constraints that always apply, and one canonical example. Starting a new session becomes assembly rather than invention. Many tools now let you persist this in a project instruction file, a saved prompt, or a system message, and that is where these templates live.
A few habits keep it sharp. When an answer is wrong, I fix the context before I touch the wording, since the context is usually the real cause. When an answer is great, I note what was in the window so I can reproduce it. And I reread my standing context now and then, because a constraint that was true last month may be quietly steering answers wrong today.
Treat context as an artifact you maintain, the same way you maintain code. That is the shift. The prompt is the last mile. The context is the road.

Old library accession ledgers, a running catalog of exactly what a collection holds.
Figure: Met Museum library accession books, 1881-1969 (CC0). Hero: Wooden Card Catalog by MarkBuckawicki (CC0).
Field notes from the build, in your inbox
I write these as I go: the context habits, the small workflow changes, the things that actually moved the needle on shipping. If that is useful, subscribe and the next one lands in your inbox. No cadence promises, just what I learn while building.