format is ignored when think is disabled for qwen3.5 series

用户通过 Ollama 的 API 调用 Qwen 3.5 系列模型(例如 qwen3.5:35b-a3b ),在使用 Python SDK 的 client.chat() 函数时,将 think 参数设为 False ,同时设置了 format='json' 期望输出 JSON 格式。但模型返回的

快速结论:当通过 think=False 禁用思考过程后,format='json' 或结构化输出会被 Ollama 忽略,模型返回纯文本而非 JSON。优先检查你使用的 Ollama 版本是否低于 0.21.1,以及模型是否属于 qwen3.5 或 qwen3.6 系列。

问题场景

用户通过 Ollama 的 API 调用 Qwen 3.5 系列模型(例如 qwen3.5:35b-a3b),在使用 Python SDK 的 client.chat() 函数时,将 think 参数设为 False,同时设置了 format='json' 期望输出 JSON 格式。但模型返回的却是普通文本,无视 format 指令。

报错原文

# think = False, format = 'json' 时,期望返回 JSON,实际返回普通文本
response = client.chat(
    model = 'qwen3.5:35b-a3b',
    messages=[{'role': 'user', 'content': 'why is the sky blue'}],
    think=False,
    format='json',
    options={
        'temperature': 0
    }
)
# 实际返回:
# "The sky appears blue due to a phenomenon called **Rayleigh scattering**..."
# 而非 JSON 对象

原因分析

可能原因:Ollama 在实现思考(thinking)功能时,期望模型输出中显式出现 </think> 结束标记后,才会应用 format 的概率掩码(probability masking)来控制输出格式。然而 Qwen 3.5 系列通过 chat template 注入了一个空的 <think>\n\n</think>\n\n 片段来禁用思考(方法 3:模板控制),这个 </think> 是由模板直接拼接的,模型本身并未输出该终止符。因此 Ollama 始终等待模型输出 </think>,但永远等不到,format 掩码也就永远不会被激活。

该行为与 gemma4 系列类似,但 Gemma4 的修复(#15678)在 v0.21.1 中仅作用于 gemma4,并未涵盖 Qwen 3.5/3.6 系列。Ollama 会检查模型的能力标志(CapabilityThinking)来决定是否启动这种 anticipating 行为。

环境排查

  • 确认 Ollama 版本:在终端运行 ollama --version。已知 v0.17.6 ~ v0.21.0 受影响,v0.21.1 以上可能部分修复。
  • 确认模型家族:是否使用的是 Qwen 3.5、Qwen 3.6、gemma4 或其他通过模板注入空 <think> 来控制思考的模型。
  • 确认 thinkformat 组合:单独使用 think=True + format='json' 时是否正常?单独使用 think=True/False + format=None 是否正常?
  • 确认使用的模型是否带有 CapabilityThinking 标志:部分第三方模型(如 frob/qwen3.5-instruct)可能没有此标志,因此不受影响。

解决步骤

  1. 升级 Ollama 至最新版(≥ v0.21.1),并检查该版本是否包含针对 Qwen 3.5/3.6 的修复。注意:v0.21.1 仅修复了 gemma4 的问题(#15678),Qwen 系列修复可能会在后续版本中合入。
  2. 作为临时工作区:创建一个自定义模型,移除其 CapabilityThinking 标志。可使用以下方法:
    # 1. 创建一个 Modelfile,使用原始基础模型
    FROM qwen3.5:35b-a3b
    # 2. 不需要修改模板,仅通过 Modelfile 的 PARAMETER 或修改模板来避免 Ollama 的 thinking 检测
    # 3. 然后使用 ollama create 创建新模型
    ollama create my-no-think-qwen -f ./Modelfile
    
  3. 优先尝试 PR #15901:如果你有能力编译 Ollama,可以尝试合并该 PR 中的改动,该 PR 专门针对此问题进行修复。
  4. 检查性能基准测试:社区用户 @Orbiter 提供了一个基准测试文件 project-euler-llm-benchmark/benchmark.json,可以用来对比 format 在 think disable/enable 下的表现。

验证方法

重复以下 Python 测试,确认修复后 think=False + format='json' 返回的内容是否符合 JSON 格式:

response = client.chat(
    model='qwen3.5:35b-a3b',
    messages=[{'role': 'user', 'content': 'why is the sky blue'}],
    think=False,
    format='json',
    options={'temperature': 0}
)
print(response['message']['content'])
# 修复后应输出类似:{"answer":"The sky is blue due to Rayleigh scattering..."}
print('IS JSON?', type(json.loads(response['message']['content'])))

如果打印结果返回的是 JSON 对象而非普通文本,则问题已解决。也建议对 qwen3.6 和 gemma4 模型做同样的验证。

参考来源

ollama/ollama #14645

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 15401

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注