Possible issue: completion-only output may contain </think> without a preceding <think> due to chat template prefill

#62
by molujia - opened

Hello. I would like to report and clarify a behavior in the current chat_template of Qwen/Qwen3.6-35B-A3B.

When using the default generation template, the generated completion may contain reasoning text followed by </think>, but the completion itself does not contain the opening <think> tag. After inspecting the template, I understand that this happens because the opening <think> tag is pre-filled into the prompt by the chat template, rather than generated by the model.

This is not necessarily a model generation bug. However, I think it may be an unintuitive and potentially problematic template/API behavior, because many downstream users and parsers only see the newly generated completion, not the full prompt + completion sequence.

Relevant part of the chat template

The relevant part is:

{%- if add_generation_prompt %}
    {{- '<|im_start|>assistant\n' }}
    {%- if enable_thinking is defined and enable_thinking is false %}
        {{- '<think>\n\n</think>\n\n' }}
    {%- else %}
        {{- '<think>\n' }}
    {%- endif %}
{%- endif %}

My understanding is:

enable_thinking=False
    -> the prompt is pre-filled with an empty thinking block:
       <think>

       </think>

    -> the model is expected to continue directly with the final answer.

enable_thinking undefined or True
    -> the prompt is pre-filled with:
       <think>

    -> the model starts generation inside the thinking block, then later generates:
       reasoning content
       </think>
       final answer

Therefore, when only the generated suffix is decoded, the visible completion may look like:

I need to analyze the problem first...
...
</think>

Final answer...

instead of:

<think>
I need to analyze the problem first...
...
</think>

Final answer...

Observed behavior

In common usage, the generated text is often decoded with something like:

generated = processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])

That means only the newly generated tokens are returned or displayed.

Since <think>\n was already part of the input prompt, it is not included in generated. But </think> is generated by the model, so it appears in the completion.

As a result, the completion-only output can contain a closing </think> tag without a corresponding opening <think> tag.

Could this be problematic?

I am not entirely sure, but it may be worth discussing
I understand that the model itself still works as intended. However, this behavior may still cause some practical issues for downstream users:

  1. Downstream parsers may fail.
    Many parsers expect reasoning to be enclosed by a complete ... pair. If the generated completion lacks , such parsers may fail to detect or remove the reasoning section.

  2. Reasoning content may be leaked unexpectedly.
    If an application removes reasoning only by searching for ..., it may not remove anything when the opening tag is missing. The reasoning text before may then be shown to end users.

  3. The output format is unintuitive.
    Users generally expect a model that uses XML-like tags to either output both the opening and closing tags, or output neither. Seeing only in the completion is surprising unless one knows that the opening tag was pre-filled in the prompt.

  4. Most importantly: it can be confusing.
    Some users, myself included, may spend a non-trivial amount of time wondering whether the model simply forgot to output . Speaking from experience, I spent two hours chasing this exact mystery before realizing that the opening tag had been pre-filled into the prompt.

My interpretation

My current interpretation is:

  • Default thinking is effectively enabled unless enable_thinking=False is explicitly passed.
  • The model is not “forgetting” to output <think>.
  • Instead, the chat template has already inserted <think> into the prompt.
  • Therefore, the model only needs to generate the reasoning content and the closing </think> tag.
  • This behavior is consistent with the current template design, but it may be surprising and fragile for users who process completion-only outputs.

So I am not sure whether this should be classified as a model bug. It may be better described as a chat-template design issue, documentation issue, or API interoperability issue.

Question

Is it intentional that, under the default enable_thinking behavior, completion-only output may contain </think> without <think>?

If this is intentional, could the documentation explicitly warn users that:

<think> may be part of the prompt rather than part of the generated completion.

And that users who decode only newly generated tokens may see reasoning text followed by </think> without an opening <think>?

Sign up or log in to comment