Evaluating and Iterating on LLM Outputs

Develop a systematic approach to diagnosing bad LLM outputs — distinguishing prompt failures from model limitations — and learn the iteration loop that moves from a rough first response to a reliable one.

Estimated time
~12 min
Difficulty
intermediate
Sources
5 sources

In the previous lesson, “Temperature, Top-p, and the Knobs That Matter,” you worked through a standing-desk example to see how temperature=0.1 produces safe-but-generic copy while temperature=0.9 produces a memorable line — and how raising it to 1.8 collapses into noise. You now have control over how the model samples. This lesson is about what to do when the output still isn’t right.

You ran the prompt. The output came back. It’s not what you wanted. Now what? Most practitioners do the same thing: rewrite the prompt, hope for better, repeat until frustration sets in. The problem isn’t the prompt — it’s the absence of a diagnostic before the rewrite.

The two kinds of bad output

Before changing anything, you need to know why the output is wrong. There are exactly two reasons an LLM gives you a bad answer:

  1. Prompt failure — the model had the capability, but you didn’t give it enough signal to use it. This is fixable by rewriting the prompt.
  2. Model limitation — the model genuinely cannot do what you’re asking, regardless of how you phrase it. Rewriting the prompt won’t help.

Conflating these two is the source of most “prompt engineering rabbit holes.” Practitioners spend hours rephrasing a request the model is fundamentally incapable of answering. The right move — change the architecture, use retrieval, switch models — never gets tried because the diagnosis was wrong.

The same symptom, two different causes

Symptom: the model gives you an outdated answer about a current event.

  • If the event happened before the model’s training cutoff, and the model is simply getting the facts wrong — this is likely a prompt failure: try adding a few-shot example or grounding context in the prompt.
  • If the event happened after the training cutoff — this is a model limitation: no prompt will give the model knowledge it doesn’t have. You need retrieval-augmented generation (RAG) or a search tool.

Same symptom. Completely different fix.

The five most common prompt failures, in order of frequency:

  1. Missing role or goal — the model doesn’t know who it’s answering for or what a good answer looks like
  2. Unspecified output format — the model defaults to prose when you need JSON, or vice versa
  3. No examples — a complex output structure isn’t learnable from description alone
  4. Ambiguous scope — “summarize” means nothing without a target length and audience
  5. No grounding constraints — the model invents plausible-sounding details because nothing told it not to

The most common model limitations:

  • Knowledge cutoff — no live information after training
  • Arithmetic and reasoning over large numbers — LLMs are poor calculators
  • Long-context faithfulness degradation — in very long prompts, the model loses track of facts stated early on [Lost in the Middle: How Language Models Use Long Contexts]
  • Data coverage gaps — rare languages, niche domain knowledge, and fictional constructed languages (like the Klingon example)
Read each prompt and response pair. Decide: is this fixable with a better prompt, or is it a genuine model limitation?

Check your understanding

A model confidently summarizes a legal document but includes a clause that doesn't exist in the original. What kind of failure is this most likely to be?

The iteration loop

Once you’ve diagnosed what is wrong, you apply a structured loop — not trial and error:

Prompt iteration loop def.

A four-step cycle: (1) Observe the failure and record the exact input/output pair. (2) Hypothesize a single cause. (3) Change exactly one thing in the prompt. (4) Compare the new output against the old, across all known test cases — not just the failing one.

The discipline of “change exactly one thing” is crucial. If you rewrite the role, add an example, and change the output format all at once, and the output improves, you have no idea which change did it. Next time you hit a different problem, you have no transferable knowledge. Worse: two of those changes may be helping while the third is quietly introducing a new failure.

The one-at-a-time rule

Every experienced prompt engineer has a story about a prompt that “got worse” after a rewrite that felt like an improvement. Almost always, it’s because multiple changes were made simultaneously. One change helped; another broke something else. The rule: touch one variable per iteration.

The iteration loop in action — watch how three sequential prompt improvements turn a useless first response into a production-ready output:

Notice the progression in the widget: the prompt moved from vague instruction → role + goal → format contract → grounding rules. Each step is a response to a specific diagnosed failure, not a gut-feel rewrite.

The techniques from the prompting fundamentals lesson — system messages, few-shot examples, chain-of-thought, output fences — are the building blocks you reach for. The iteration loop is the process for knowing which block to reach for and when. [Chain-of-Thought Prompting Elicits Reasoning in Large Language Models]

Check your understanding

You change the output format instruction and the grounding rule in the same iteration. The output improves. What's the problem?

Where the model genuinely can't go

Not everything is a prompt failure. Knowing where model limitations live prevents wasted iteration.

Common misconception

With the right prompt, an LLM can do anything a human expert can.

What's actually true

LLMs are pattern-completion engines trained on text. They’re remarkably capable within that scope — but some things genuinely require real-time data, persistent memory, external computation, or specialized training data that doesn’t exist. Recognizing these limits early is a competitive advantage, not a concession.

Knowledge cutoff. Models have a hard training cutoff. Asking for current stock prices, yesterday’s news, or a just-published paper will produce either a refusal or confident hallucination. The fix is always architectural: retrieval, search tools, or API integration — not a better prompt.

Arithmetic and exact computation. LLMs calculate by pattern-matching, not by executing arithmetic. They are unreliable beyond simple single-digit operations. [Measuring Mathematical Problem Solving With the MATH Dataset] For any calculation that matters, send the expression to a calculator tool and have the model interpret the result — not compute it.

Long-context faithfulness. Counterintuitively, models often do worse on facts stated early in a very long prompt. The model attends more reliably to recent context. Strategies: put critical instructions at both the top and the bottom, and break long documents into smaller chunks if possible.

Rare languages and domains. A model trained on 99% English text will produce unreliable output in languages with sparse training data. The same applies to highly specialized domains — esoteric legal systems, rare programming languages, niche scientific fields — where the training corpus is thin.

Prompt failure Model limitation
Root cause Missing signal: role, format, examples, constraintsModel lacks the data or capability entirely
Diagnosis Model produces something plausible but wrong-shapedModel refuses, hallucinates with high confidence, or degrades consistently
Fix Rewrite the prompt — add the missing pieceChange the architecture: RAG, tools, fine-tuning, or a different model
Example Model returns prose when you needed JSONModel asked for live weather data or post-cutoff news
How to tell them apart — and what to do about each

Check your understanding

You ask an LLM to compute compound interest on a $10,000 investment at 7% for 30 years. It returns $76,123. The correct answer is $76,122.55. Should you iterate on the prompt?

Building a regression harness

Here is the surprising consequence of systematic iteration: every test case you accumulate — every input/output pair you’ve verified — is an asset. Without a harness, fixing one case silently breaks another. With a harness, you know immediately.

The pattern is simple:

  1. Every time you confirm a prompt works correctly on an input, record that input/output pair as a test case.
  2. Every time you iterate the prompt, run all existing test cases against the new version.
  3. A regression (previously-passing case now failing) is a stopping signal — the change introduced a hidden trade-off.

This is not sophisticated engineering. It’s a text file with input, expected, and actual columns. The discipline is in running it every single iteration.

Switch between Prompt v1 and Prompt v2, then click 'Run suite' to see which cases pass and fail. Prompt v2 fixes case 3 — but look at what it does to the rest.
Show a minimal test harness structure (TypeScript)
// test-prompt.ts — a minimal harness, no framework needed
type TestCase = {
  input: string;
  expected: string;  // the string the output should contain
};

const cases: TestCase[] = [
  { input: "I love this product!", expected: "POSITIVE" },
  { input: "Arrived broken.",       expected: "NEGATIVE" },
  { input: "When does it ship?",    expected: "NEUTRAL"  },
];

async function runSuite(prompt: string) {
  let pass = 0;
  for (const tc of cases) {
    const output = await callModel(prompt.replace("{{input}}", tc.input));
    const ok = output.includes(tc.expected);
    console.log(`${ok ? "✓" : "✗"} [${tc.expected}]  got: ${output.trim()}`);
    if (ok) pass++;
  }
  console.log(`\n${pass}/${cases.length} passing`);
}

The callModel function is wherever you route your API call — Anthropic, OpenAI, or local. The harness structure is the same regardless.

Seed with edge cases first

The hardest test cases — ambiguous sentiment, empty input, foreign language, very long text — are the ones that expose hidden failures earliest. Seed your harness with these before you have the easy cases exactly right.

Check your understanding

You fix a failing test case by adding an instruction. You run only that case and it passes. Is the prompt ready to ship?

Check your understandingQ 1 / 5

You ask an LLM for the current CEO of a company. It confidently names someone who left three years ago. What is this?