
How to Write Good Prompts: Pin AI Output with Context Design
Give people the same model and the first place results diverge is the prompt. Here's why a prompt is context design, not an incantation, and why the limits of a single shot called for the next stage.
A prompt is context design, not a magic spell. How to enforce LLM output formats with structured output, pin down shifting results, and where prompts fail.
A prompt isn't a magic spell; it's the context design you lay down for the model. Everyone starts the same way with LLMs. You open a chat window and type what you want. Yet with the same model and the same screen, results vary widely from person to person. The first fork in the road is the prompt.
> Part 1 of the "Evolution of LLM use" series. ① Prompting · ② Vibe coding · ③ Agents · ④ Harness engineering · ⑤ Open models. We walk step by step through how the way people work with LLMs has changed.

People often mistake prompting for "finding the magic spell," collecting phrases like "write it this way and it works." But what actually decides the result isn't a spell; it's the design of the context you lay down for the model. Prompting is the very first stage of working with LLMs and, in fact, the smallest unit of context engineering.
What this series covers
| Part | Topic | Core idea |
|---|---|---|
| ① | Prompting | Reduce the variance in results with context design |
| ② | Vibe coding | State your intent and code comes out, but verification is missing |
| ③ | Agents | The model uses tools on its own and iterates while watching results |
| ④ | Harness engineering | Design the execution and verification environment that wraps the agent |
| ⑤ | Open models | Expand to models you can self-host and tune |
A prompt is context design, not an incantation
A vague one-liner gets a vague result. "Write a post on this topic" leaves the model too much freedom. Tone, length, and format are all decided by the model on the fly, so it comes out different every time.
A good prompt reduces the blanks the model has to guess. What, for whom, in what format, and what to avoid: fill in these four ahead of time and the variance in results drops sharply. Even with the same model.
Enforce the structure and results stabilize
Asking for a format in the prompt often isn't enough. Even if you say "give it to me as JSON," sometimes an explanation gets prepended or line breaks wobble, and the code that parses it keeps breaking.
So in practice, you don't ask for the format; you enforce it. Pin the output schema with Anthropic's tool_use [1] or OpenAI's function calling [2], and the model must answer only in that structure. This is the same pattern we use in our card news generation pipeline.
# (1) Vague prompt: the format wobbles every time
resp = await client.messages.create(
model="claude-opus-4-8",
messages=[{"role": "user", "content": "Make 6 slides on this topic"}],
)
text = resp.content[0].text # preambles and line breaks vary -> parsing breaks
# (2) Pin the schema with tool_use: it must answer only in this structure
tools = [{
"name": "emit_slides",
"input_schema": {
"type": "object",
"properties": {
"slides": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {"type": "string"},
"body": {"type": "string"},
},
"required": ["title", "body"],
},
},
},
"required": ["slides"],
},
}]
resp = await client.messages.create(
model="claude-opus-4-8",
tools=tools,
tool_choice={"type": "tool", "name": "emit_slides"}, # must call this tool
messages=[{"role": "user", "content": prompt}],
)
slides = resp.content[0].input["slides"] # verified structure: no parsing needed
① and ② use the same model and the same topic. The only difference is whether you designed the output. With ②, parsing errors disappear, and empty values and wrong fields are filtered at the schema stage. It's the moment you start treating a prompt not as "writing" but as an interface.
Give references too, so it sounds like you
Even with structure in place, tone is a separate problem. The model doesn't know "our brand tone." So instead of explaining it in words, include a few examples that actually performed well. This is called few-shot. Two real examples convey tone far more precisely than ten lines explaining "this is our tone."
Go a step further, and instead of attaching examples by hand each time, define your brand context once and attach it automatically in front of the prompt. In our pipeline we manage this as a memory block, so blog posts, card news, and detail pages all inherit the same tone context. The prompt turns from a one-off sentence into reusable context.
But there are places a single prompt can't reach
By this point, prompting alone takes you pretty far. But prompts have three structural limits.
- No state (stateless): One request and one response are all there is. The model doesn't know what it just did or whether it actually worked.
- No tools (toolless): It can't run code, read files, or check results. It only answers from its head.
- No verification: When it's wrong, it doesn't know it's wrong. Checking and fixing is entirely the human's job.
These three limits called for the next stage. The idea of "instead of writing it all at once, let the model write code, run it, and fix it" is vibe coding, and "let the model use tools on its own and iterate while watching results" is agents.
In short
Prompting is the first way of working with LLMs and is still the foundation under every stage. The key isn't a magic spell but context design: reduce the blanks, enforce the structure, and give references. That alone gets you a completely different level of stability from the same model.
But a single prompt has no state, no tools, and no verification. In the next part, we cover the approach that first shook up these limits: vibe coding.
For related reading, see What is vibe coding? Its limits and the AI code verification loop, What is an AI agent? Permissions and approval gates when the model runs its own loop, and What is first-party data? How to use it in marketing after third-party cookies.
Frequently asked questions
Are prompt engineering and context engineering different things?
Prompting is the very first stage of working with LLMs and, in fact, the smallest unit of context engineering. Filling in what, for whom, in what format, and what to avoid ahead of time is context design.
How is tool_use different from just asking for "give it to me as JSON"?
"Give it to me as JSON" is a request, so sometimes an explanation gets prepended or line breaks wobble and parsing breaks. tool_use and function calling enforce an output schema, so the model must answer only in that structure, and empty values or wrong fields are filtered at the schema stage.
How many few-shot examples are right?
What matters is less a set number than whether the examples show the real tone. As the post puts it, two examples that actually performed well convey tone far more precisely than ten lines explaining "this is our tone."
References
Summary
- Prompting isn't a magic spell; it's designing the context you lay down for the model.
- Fill in what, for whom, in what format, and what to avoid, and the variance in results drops.
- Formats become stable only when you enforce them with structured output like tool_use, not when you ask nicely.
- Prompts have no state, no tools, and no verification, and those limits called for vibe coding and agents.
Why TRAIL Labs works this way
How a researcher-founder grounds measurement and recommendations, and how the three products relate to the company, is laid out on the about page, and how we work day to day is written up separately.
More posts

TRAIL Labs joins the Google for Startups Cloud Program
TRAIL Labs has joined the Google for Startups Cloud Program, gaining cloud credits and support to run our AI-search measurement and content engine at scale.

TRAIL Labs has joined the NVIDIA Inception program
TRAIL Labs has joined the NVIDIA Inception program, gaining compute, technical resources, and a network to grow our AI-search measurement and content engine.

Is AI search visibility enough? Why we changed our question
AI search visibility is countable, but more of it doesn't mean your accurate information reached the answer. What measurement and three papers taught us.
Keep reading on this topic
- Defending Against RAG Hallucinations: Types and LimitsRAG retrieves outside documents to ground answers, yet hallucinations still arise in retrieval and generation. Types, defenses, and limits of automated checks.
- Design principles for a GEO data AI agentDesign principles for a GEO data AI agent: text parsing vs. structured tool calls, blocking irreversible actions, and why skipping evals is risky.
- Open-Weight vs. API Models: Own a Domain Model with HermesOwn the model instead of renting it: why open weights, open vs. API models, Nous Research Hermes 4.3, its function-calling standard, and the data flywheel.
This post is part of the TRAIL Labs category, which collects all 19 posts on the topic. See all posts in TRAIL Labs