ed@edheltzel: ~/log/context-window-is-an-interface
ed@edheltzel:~/log$ cat context-window-is-an-interface.md

The context window is an application interface

If the last post was “the model names a step,” this one is “you decide what tokens it sees when it names that step.” Dex Horthy’s factors 2 and 3 are the same idea at two layers: own the prompt, own the context window. Hamel Husain said the prompt version first, in Your AI Product Needs Evals: do not outsource the only interface you have.

This is still a reading of 12-factor agents (content CC BY-SA 4.0).

Prompts are source, not config

The black-box pattern looks friendly:

Agent(role, goal, personality, tools) + Task(instructions) -> result

It also hides the tokens. When the model does the wrong thing, you cannot tell whether the framework stuffed a system prompt you would never have written. Horthy’s fix is boring: the next-step function is a prompt template in your repo. You can diff it, test it, and change it after a real failure.

BAML is one way to keep that template typed. A string template is another. The tool does not matter. Seeing every instruction you send does.

What you get back is not vibes. You can eval a prompt like any other function. You can try role tricks that a framework will not expose. You can stop pretending “the agent” is a person and start treating it as a function from thread text to a next step.

Chat messages are a default, not a requirement

Factor 3 is the part people skip because the SDK already has messages: [{role, content}]. That format is fine until it is not. An LLM is a stateless function. The window is the whole argument. History, tool results, RAG, memory, and the question “what is the next step” are all just tokens you chose to include.

Horthy’s example packs the thread into one user message: current user request, then event history, then “what should the next step be?” XML-ish tags, YAML, whatever. The point is not the markup. The point is you can drop, fold, or rewrite events before they hit the model. Stored history and model-facing context are not the same object.

Two months after the guide landed, “context engineering” became the phrase. Karpathy and others said out loud what factor 3 already assumed: you are building the input. If you only append OpenAI-style messages forever, you will ship the SDK’s attention pattern, not yours.

What I actually keep

  • Prompt text lives in the repo, next to the code that parses the reply.
  • Event log is durable. Context is a projection of that log.
  • When quality drops, I inspect the window, not the model’s personality.

Prev: your agent does not need to own the workflow. Next: an agent should be able to stop and come back.