How to Write Good Prompts: Pin AI Output with Context Design

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.

By · Fred KimUpdated
PromptingLLMtool useStructured output

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.

Moving from a stage where a vague one-line prompt produces uneven results to prompt engineering that stabilizes results by designing context, structure, and references

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

PartTopicCore idea
①PromptingReduce the variance in results with context design
②Vibe codingState your intent and code comes out, but verification is missing
③AgentsThe model uses tools on its own and iterates while watching results
④Harness engineeringDesign the execution and verification environment that wraps the agent
⑤Open modelsExpand 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.

A vague one-line prompt produces output whose format and quality wobble, while designing in context, a schema, and references produces verified structured output

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

  1. [1]Anthropic, "Tool use with Claude" official documentation
  2. [2]OpenAI, "Function calling" official guide

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

Keep reading on this topic

This post is part of the TRAIL Labs category, which collects all 19 posts on the topic. See all posts in TRAIL Labs