Zenaique

Explain what gen_ai.response.finish_reasons captures and why it is a list

Flashcard·Easy·4.0 · 0·~30s·Asked atDoordashMphasisUniphore
Attempt it
TL;DR

It records why each completion stopped (stop, length, tool_calls, content_filter, etc.) as a list because a single request can return multiple completions (n>1), each with its own finish reason.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Picture a printer that can print several copies of a document at once. After the job, you want to know whether each copy finished cleanly, ran out of paper, was cancelled by the operator, or got pulled because the content was flagged. One field cannot tell you what happened to all the copies at once. You need a list, one entry per copy. A finish_reasons attribute on an LLM call is the same idea: one entry per completion the model returned, each telling you whether that particular completion ended cleanly, hit the token limit, was redirected into a tool call, or got blocked by a safety filter.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Finish reasons are the cheapest LLM telemetry by far. The attribute is one string per completion, populated by the provider on every response, and it tells you in a single value whether the model finished cleanly, hit its token cap, decided to call a tool, or got blocked by safety filtering. Dashboards built on this single attribute catch most of the LLM-specific regressions a production system will see.

The interview question is checking whether you understand both what the attribute means and why it has the shape it has. The list shape is the part that trips people up; it exists for a real reason, and missing that reason signals a candidate who has not handled the n parameter in production.

The values and what each one means

The OpenTelemetry GenAI semantic conventions standardize finish_reasons on a small canonical set:

  • stop, the model emitted its end of turn token or hit a configured stop sequence. Clean finish; the output is complete.
  • length, the model hit max_tokens before finishing. The output is truncated, almost always mid-sentence. Two flavors: configuration too tight (the max_tokens cap is below what this prompt needs) or output-runaway (the model started looping or wandering).
  • tool_calls, the model emitted one or more tool invocations and stopped to wait for the tool results. This is the normal exit for the planning step of an agent loop, NOT a failure. The next turn will be a tool-result message followed by another model invocation.
  • content_filter, a safety system intervened to block all or part of the output. Distinct from the model's own refusal because it is applied by infrastructure after generation, not produced by the model itself.
  • error, an upstream error stopped generation. Rare on the response object; usually surfaces as an HTTP error instead.

Provider-specific values exist and need normalization. Anthropic emits end_turn, max_tokens, stop_sequence, and tool_use. Google emits STOP, MAX_TOKENS, SAFETY, RECITATION, OTHER. The instrumentation library (OpenLLMetry, Langfuse, vendor SDKs) maps these into the OTel canonical set so dashboards work across providers. Skipping the normalization step is the most common mistake when wiring this up by hand.

Why it is a list
Production patterns for alerting and triage
The common mistakes that bite in production
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.

Real products, models, and research that use this idea.

  • OpenTelemetry GenAI semantic conventions in 2026 define gen_ai.response.finish_reasons as an array of strings, with the canonical values standardized.
  • OpenAI's GPT-5.5 chat-completions API still emits a finish_reason per choice in the choices array; instrumentation libraries normalize it to the OTel list shape.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QHow do you distinguish a model-side refusal from a provider-side content_filter block?
A

Model refusal: finish_reason is 'stop' and the output text contains a refusal pattern. Content_filter block: finish_reason is 'content_filter' and the output is empty or replaced with a filter message. Different remediations: refusal means prompt engineering, filter block means the provider's safety policy.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Filtering only on finish_reason = 'stop' as success. A 'tool_calls' finish is the normal exit when the model wanted to call a tool, not a failure.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • Why finish_reasons is a list rather than a single string

  • The canonical OTel values and what each one means

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Describe how end user thumbs up/down should flow back onto a trace
Flashcard·Easy