What the model actually sees: context engineering for reusable AI work
A practical guide to deciding what goes into a model call, in what order and at what size, built on a real trace of what one app was actually sending.
- Engineering & Data
- Strategy & Operations
- Kind
- Guide
- Min read
- 08
- Sections
- 08
- Library records
- 02
On this page8 sections
Most prompt problems are context problems that nobody has looked at. You wrote a good instruction, but you have never read the full text the model receives once your tool has wrapped it in a role, a method, some files, the conversation so far and your request.
So read it. Print the assembled request for one ordinary run and go through it line by line. The rest of this guide is about what you will probably find, and how to arrange it so the model gets what it needs and little else.
A real trace
In October 2026 we audited the AI layer of the MyPromptVerse app and traced, from the code, what one real run sent to the model. The request was five words: "say hello in five words". Here is what the model received.
- A 2,678-character system prompt (about 670 tokens) for a 23-character question. A lean equivalent would be around 25 tokens.
- A playbook instruction for a different job. The app had silently attached the first available playbook, which said "Turn the user's notes into a concise product feature specification", so a greeting was treated as notes for a spec.
- Knowledge listed by name only. The operator block said "Knowledge: Product Spec PRD" with no content, so the model was told about material it could not see.
- Empty rows. "Constraints: Not provided", "No knowledge records selected", "No files attached". Each one is a line the model reads and tries to account for.
- The user's text twice, once inside a "Structured user input" block and again as the user message.
- Text describing things that did not exist: an "Execution contract", an orchestration plan with "5 child runs", an approval policy and a tool policy, in a run that was one model call with no tools.
- A cache-hostile order. History sat between stable blocks, and the last block, a cost estimate, changed on every run.
- Our own bookkeeping in the history. Earlier assistant turns were replayed with their title, summary and a "Run details" section (routing mode, operator ids), so the model re-read our metadata on every follow-up.
- Truncation that kept the head. Long earlier answers were cut at a character limit from the end, so the conclusions went and the preamble stayed.
None of this came from a bad instruction. Each block made sense to whoever added it, and nobody had read the whole thing as the model does.
One more finding is worth knowing before you start trimming. That run used 5,325 tokens and took about 30 seconds, and the system prompt was only about an eighth of the tokens. Most of the rest was almost certainly hidden reasoning on a model whose reasoning effort nobody had set (the app did not yet record the exact split). Cleaning up context is worth doing, but check reasoning effort and output caps first if the goal is speed or cost.
The layers, and where each one lives
Every model call is a stack of layers with different owners and different rates of change. Keeping them apart is what lets you change one without breaking another. Here is the stack, with where each layer lives in the Studio.
| Layer | Studio home | Example | Change rate | Who changes it |
|---|---|---|---|---|
| Operating rules | Operator | Role, audience, boundaries, quality bar | Slow | Owner of the role |
| Method | Playbook | Inputs, instruction, required output sections, rubric | Medium | Domain lead |
| Grounding material | Knowledge | Brand rules, product facts, support policy | Medium | Project team |
| Task input | Prompt variables | {{notes}}, {{page_copy}}, {{ticket}} | Every run | Requester |
| Conversation so far | Thread history | Earlier answers in this thread | During the thread | Nobody edits it; the system trims it |
| Provenance | Run record | Blocks sent, token costs, validation status, reviewer decision | Written once per run | The system writes it; people read it |
Two notes on honesty. In MPV today a real run is one model call with one Operator and one Playbook, and Knowledge is attached whole rather than retrieved. Retrieved evidence would be a seventh layer between Knowledge and the task input; we have designed it but not built it.
Who should be able to change this, and how soon
When you are unsure where something belongs, ask: who should be able to change this, and how soon must the change reach new runs?
- A rule that only the role owner should touch, and that can wait for a review, goes in the Operator.
- A step or required section that a domain lead revises a few times a quarter goes in the Playbook.
- A price, a plan name or a policy clause that the project team must be able to fix today goes in Knowledge, never inside the Operator text.
- Anything that differs per request is a variable, filled at run time.
Updating a product fact should not mean editing a role. Changing an output section should not quietly change which sources are allowed.
Three ways context goes wrong
The trace above shows all three.
- Dilution. The rule that matters is buried under text that does not. Empty rows, duplicated input and fictional execution contracts are pure dilution.
- Collision. Two layers disagree and nothing says which wins. A greeting meeting a spec-writing playbook is a collision: the input says one thing, the method says another, and the model has to guess.
- Staleness. An old fact reads as current. Replayed history is the usual source, along with Knowledge nobody has reviewed since launch.
Fix each at its layer. A collision between the request and the Playbook goes away when Playbooks are attached only to requests they fit. Adding "ignore the playbook if irrelevant" to the Operator leaves the collision in place and adds one more line of dilution.
Order: static first, volatile last
Providers that cache prompts reuse the longest prefix that is byte-for-byte identical to an earlier request. Anything that changes early in the prompt invalidates everything after it. So put the stable layers first and the volatile ones last, and keep the stable bytes identical between runs.
1. Operator stable across every run of this role
2. Playbook stable across every run of this method
3. Knowledge stable within a project, long documents in tagged blocks
4. Thread history grows, but append-only
5. Task input the variables for this run, tagged
6. Task the question or instruction, last
This order also matches current provider guidance on long inputs: role, constraints and format at the top, long material in tagged blocks before the task, and the specific task or question at the end.
Things that break caching without anyone noticing:
- timestamps, run ids or cost estimates inside the system prompt;
- rebuilding the history block in a different form each turn;
- the same Knowledge source serialised with different whitespace or field order;
- a "current date" line at the top instead of near the task.
If the model genuinely needs a value such as today's date, put it with the task input.
Give every layer a budget
A context window is a ceiling, and nothing makes you fill it. Decide a token budget per layer, measured with the model's own tokeniser rather than estimated from characters.
| Layer | Budget approach |
|---|---|
| Operator | Small and fixed. A sentence or two of role plus the rules that need a reason. |
| Playbook | Fixed per playbook. Measure it once and alert when an edit grows it. |
| Knowledge | A cap per source. Over the cap, include a summary or the relevant sections with a visible "trimmed" marker. |
| Thread history | A window in tokens. Keep the tail of long turns, send only the answer text, and summarise older turns once and reuse the summary. |
| Task input | Whatever the request needs, but reject or flag inputs far beyond normal. |
Then allocate by priority: required blocks are never dropped, optional ones are trimmed lowest priority first, and the run record says what was trimmed. A quiet truncation is worse than a short context, because nobody can see what the model did not get.
For a sense of scale, the redesign target for "say hello in five words" in a plain chat with no Operator or Playbook is 25 to 60 tokens of system prompt, against the 670 it was sending.
Retrieval: start plain
When Knowledge outgrows what you can attach whole, you need to select from it. Start with the simplest thing that can work.
- Attach whole, under a cap. Most project knowledge is small. If it fits the budget, include it and skip retrieval.
- Full-text search. Search the sources for the request's terms and include the top passages with their source names. If your sources already sit in Postgres, its built-in full-text search needs no new infrastructure.
- Embeddings, only when recall is demonstrably poor. Collect requests where full-text search missed a passage a person would have found. If that list is long and real, add semantic search. Do not add it because it sounds like the proper way.
Whichever stage you are at, write down the approved sources, which source wins when two disagree, how fresh each must be, and what the model should do when nothing relevant comes back. "Say the information is not in the provided material" is a better default than a confident guess.
The run record
Store what was sent as a list of blocks, not one opaque string: each block's name, token cost, a hash of the static ones, what was trimmed, and which Knowledge sources were included. When an output is wrong you can then tell a model failure from missing context, a stale source or the wrong Playbook, and you can diff two runs instead of rereading them.
The record does not need the model's private reasoning. It needs provenance: what went in, in what order, and at what size.
Before you rewrite another instruction
- Print the full request for one real run and read it.
- Delete empty rows and anything sent twice.
- Remove text about features, tools or steps that do not exist in this run.
- Check that every Knowledge item named is also included.
- Move each piece to the layer whose owner should change it.
- Order the layers static first, volatile last, with the task at the end.
- Set token budgets and record what gets trimmed.
- Set reasoning effort deliberately.
- Add retrieval only when attaching whole no longer fits, and embeddings only when plain search is shown to miss.
From the Library
Read next
- 01Prompt, Playbook, Operator, Knowledge: what goes whereThe four kinds of reusable AI setup, what belongs in each, and how they map to saved prompts, SKILL.md, Claude Projects and custom GPTs. Includes how to tell when a prompt you keep reusing should become a Playbook.
- 02Prompt testing: how to know if your prompt is goodA practical way to test a prompt or Playbook: a small realistic test set, an anchored rubric, pinned model settings, budgets as assertions and a diagnosis of which layer failed.
- 03Human review is not a failure modeHow to design human review as a deliberate stage of an AI workflow: where the gates go, what reviewers see, and what their decisions should teach the system.
Newsletter
The next note, by email.
Guides, analysis and build log entries as they are published, plus new Library records. Occasional, practical, easy to leave.