Debugging LLM Failures With Logits: A Practical Workflow
Learn a practical workflow for debugging LLM failures using logits and logprobs—inspect decision margins, diagnose failure modes, and improve reliability.
Why LLM Failures Hide in the Logits
When an LLM produces a bad answer, the string you see is the end of a long decision chain, not the decision itself. By the time text reaches your logs, the model has already collapsed thousands of competing token probabilities into one path. Debugging that final string is like diagnosing a bridge failure by looking at a photo of the wreckage: you can see that it fell, but not which bolt sheared first.
Logits are the raw material of that collapse. They are the pre-softmax scores the model assigns to every token in its vocabulary at each generation step. Before a token is sampled, the model has already ranked its options and assigned them relative weights. Those weights are where the diagnostic signal lives.
What Logits Actually Tell You
A logit is an unbounded real number. Run it through softmax and you get a probability over the vocabulary. The gap between the top token and its runner-up — the decision margin — tells you how committed the model was. Expressed as a difference of log-probabilities, the margin is in nats (natural log units); a margin of ~2.3 nats corresponds to the top token being roughly 10× more likely than the runner-up, and ~4.6 nats to roughly 100×. Confident predictions often show margins of a few nats; genuinely ambiguous positions sit under ~0.5 nats, where the top two candidates are within ~1.6× of each other. Neither the margin nor the ordering is visible in the decoded string.
Two properties matter for debugging:
- Logprobs are computed before sampling controls. Temperature scaling, top-p, and top-k truncation are applied after the raw distribution is produced. The numbers you inspect are the model's unmodified belief, not the distribution the token was actually drawn from. This is why a low temperature can make the output look deterministic while the underlying margin stays razor-thin — and why lowering temperature does not fix a tie.
- API coverage is real but capped. Many major inference APIs now expose top-k logprobs per generated token (commonly capped at the top 5 or 20), and open-weight deployments via vLLM or similar give you the full distribution. That means practitioners can inspect not just what the model chose but how close the alternatives were. (Related: how to read logprobs from an inference API)
Why Output-Only Debugging Falls Short
String-level debugging conflates distinct root causes. A wrong answer from a high-confidence token points to a knowledge or data gap. The same wrong answer from a coin-flip token points to ambiguity or prompt underspecification. The fixes are completely different, but the output text looks identical.
For engineering leaders, the business case is straightforward: reliability improves when teams can see decision margins, not just decoded strings. Teams that instrument logits catch regressions earlier, route uncertain outputs to review, and stop chasing sampling noise as if it were a defect.
A Practical Logit Debugging Workflow
You can run this workflow on any failing trace in under an hour. It works with API-exposed top-k logprobs or full distributions from self-hosted models.
Step 1 — Capture Logits at the Failure Boundary
Find the exact token position where the failure originates. If the model outputs invalid JSON, don't log the whole response — locate the first token that diverges from a valid parse and capture logprobs from that position forward. If the model gives a wrong fact, find the token that carries the incorrect entity or number.
Request top-k logprobs (k=5 to 20 is usually enough) at generation time and store them keyed to the trace. Logprobs must be captured during inference: they cannot be recovered from stored output text alone. For self-hosted models you can often reconstruct them by re-running inference with a fixed seed and the same sampling parameters, but for closed APIs the moment is gone if you didn't log it. (See: logging and observability patterns for LLM inference)
Step 2 — Inspect the Top-K Distribution
Print the candidates and their probabilities at the failure position. What you're looking for is the shape of the distribution:
- Steep drop-off: the model was certain. If it's wrong, you have a knowledge problem.
- Flat plateau: the top few candidates are near-equal. You have an ambiguity or formatting problem.
- Multi-cluster split: two or more distinct groups of candidates (e.g., a cluster of content tokens vs. a cluster of format tokens such as
{,", or a label). This is the signature of structured-output breakdowns — the model is torn between what to say and how to format it. Note that a top-5 view often hides the second cluster; request a higher k or full distributions when diagnosing format failures.
Step 3 — Compare Confidence to Correctness
The final step turns a single trace into a calibration dataset. Across many traces, plot the softmax probability of the chosen token against whether that token was actually correct. Miscalibration shows up as a gap between confidence and accuracy — the model says 0.95 and is right 70% of the time.
Two practical cautions:
- You need labels. Token-level correctness requires a reference or a judge, and labeling is the expensive part. Start with a task where correctness is mechanically checkable (schema validity, numeric match, entity match) before expanding to open-ended generation.
- Token correctness ≠ sequence correctness. A response can be right overall while containing a low-confidence token, or wrong overall despite every token being locally confident. Report both, and use expected calibration error (ECE) alongside the reliability diagram to summarize the gap in one number. Bin your probabilities carefully — ECE is sensitive to bin count, so fix the binning scheme before comparing runs.
Repeat this per task type. A model can be well-calibrated on summarization and badly calibrated on numeric extraction in the same deployment. Those two facts imply different interventions. (Related: building a calibration curve for LLM confidence scores)
A single logprob trace tells you why one generation failed. A confidence-versus-correctness curve tells you how much to trust the system as a whole.
Diagnosing Common Failure Modes
Most production failures fall into four logit signatures. Learning to recognize them shortens triage dramatically.
Confident and Wrong: Overconfidence Bugs
The model assigns high probability (0.9+) to an incorrect token. There's no hesitation to exploit — the model is simply wrong and sure of it. This almost always traces to a data or knowledge gap: stale training data, a missing retrieval document, or a domain the model never saw.
Don't treat this as sampling noise. Lowering temperature won't help, because the model isn't fluctuating — the raw distribution already favors the wrong token, and sampling controls only reshape a distribution that is already skewed. The fixes are retrieval augmentation, grounding the prompt in authoritative context, or fine-tuning on the missing domain. (See: retrieval-augmented generation to close knowledge gaps)
Low-Margin Ties and Near-Misses
The top two or three candidates sit within a small fraction of a nat of each other. The model is genuinely torn. Common causes: underspecified prompts, conflicting instructions, or ambiguous input. "Summarize this" with no length or format guidance produces ties between a one-line summary and a paragraph.
The diagnostic value here is that ties are actionable. Tighten the prompt, add a format example, or resolve the conflicting instruction. Re-run and watch the margin widen — that widening is your proof the fix worked. (Related: prompt engineering techniques for reducing ambiguity)
Structured Output Breakdowns
Invalid JSON is the most common structured output failure, and the logits usually show why. At the position where the schema breaks, you typically see a multi-cluster split: one cluster of tokens that would continue valid syntax and another of tokens that carry the model's intended content. The model "wants" to emit a value but the format tokens are competing with it.
The fixes follow from the signature. Constrained decoding (grammar- or schema-based) eliminates the format cluster entirely by masking invalid tokens at each step. If you can't constrain decoding, few-shot examples that show the exact schema, or a two-pass approach (generate content, then format), both work. What doesn't work is re-prompting with "please return valid JSON" — that addresses the symptom, not the competing distribution.
Silent Degradation: Drift in the Margins
The fourth signature doesn't produce a wrong answer at all — it produces a less confident right answer. Margins on a previously stable task narrow over time without any change to output text. This is the earliest visible sign of model drift (a provider model update, a retrieval corpus change, or a prompt edit upstream), and it's exactly the regression that output-only monitoring misses until failures surface. Track the mean margin per task as a leading indicator; alert when it moves beyond its historical band.
Operationalizing Logit Debugging
Three practices turn this workflow from a debugging trick into a reliability program:
- Log logprobs by default, sampled if cost-sensitive. Store top-k logprobs for every production trace (or a statistically representative sample). The cost is small relative to the value of being able to reconstruct a failure after the fact.
- Route on margin, not just on output. Send low-margin generations to human review or a stronger model. This is a cheap, high-precision uncertainty gate that requires no extra model.
- Treat calibration as a monitored metric. Recompute the confidence-versus-correctness curve on a fixed cadence and after every model or prompt change. A widening gap is a regression signal before it becomes an incident.
The decoded string tells you what the model said. The logits tell you how sure it was — and that distinction is where debugging speed and production reliability actually come from.