跳到主要内容

推理与思考模型

Open WebUI 对表现出“思考”或“推理”行为的模型(如 DeepSeek R1、OpenAI o1 等)提供了一流的原生支持。这些模型通常会在输出最终答案之前,在内部生成思维链(Chains of Thought)。

思考标签的工作原理

当模型生成推理内容时,它通常会将该内容包裹在特定的 XML 标签中(例如 <think>...</think><thought>...</thought>)。

Open WebUI 会自动:

  1. 检测模型输出流中的这些标签。
  2. 提取标签之间的内容。
  3. 渲染提取到的内容到一个可折叠的 UI 元素中,该元素被标记为“思考(Thought)”或“正在思考(Thinking)”。

这样既能保持主对话界面的整洁,同时又允许您查看模型的内部处理过程。

reasoning_tags 参数

您可以使用 reasoning_tags 参数自定义 Open WebUI 应该识别哪些标签。这可以在每次对话每个模型的维度上进行设置。

默认标签

默认情况下,Open WebUI 会识别几种常见的推理标签对:

  • <think>, </think>
  • <thinking>, </thinking>
  • <reason>, </reason>
  • <reasoning>, </reasoning>
  • <thought>, </thought>
  • <|begin_of_thought|>, <|end_of_thought|>

自定义

如果您的模型使用不同的标签,您可以在 reasoning_tags 参数中提供一个标签对列表。每个标签对都是一个由开始标签和结束标签组成的元组或列表。

配置与行为

  • 从 Payload 中移除reasoning_tags 参数本身是 Open WebUI 特有的控制项,在发送给 LLM 后端(OpenAI, Ollama 等)之前会从 Payload 中移除。这确保了与不识别此参数的提供商的兼容性。
  • 对话历史:推理内容会保留在对话历史中,并在轮次之间发送回模型。在构建后续请求的消息时,Open WebUI 会使用其原始标签(如 <think>...</think>)对推理内容进行序列化,并将其包含在 assistant 消息的 content 字段中。这使模型能够在整个对话中“记住”其先前的推理步骤。
  • UI 渲染:在内部,推理块使用专门的 UI 组件进行处理和渲染。在保存或导出时,它们可能会被表示为 HTML 的 <details type="reasoning"> 标签。

Open WebUI 设置

Open WebUI 提供了几个内置设置来配置推理模型的行为。这些设置可以在以下位置找到:

  • 侧边栏的 对话控制(Chat Controls)高级参数(Advanced Parameters) —— 每次对话的设置
  • 工作区(Workspace)模型(Models)编辑模型(Edit Model)高级参数(Advanced Parameters) —— 每个模型的设置(仅限管理员)
  • 管理员面板(Admin Panel)设置(Settings)模型(Models) → 选择一个模型 → 高级参数(Advanced Parameters) —— 另一个每个模型设置的位置

推理标签设置

此设置控制 Open WebUI 如何解析和显示思考/推理块:

选项描述
默认(Default)使用系统默认行为
已启用(Enabled)显式启用推理标签检测,使用默认的 <think>...</think> 标签
已禁用(Disabled)完全关闭推理标签检测
自定义(Custom)允许您指定自定义的开始和结束标签

使用自定义标签

如果您的模型使用非标准的推理标签(例如 <reasoning>...</reasoning>[思考]...[/思考]),请选择 自定义(Custom) 并输入:

  • 开始标签(Start Tag):开始标签(例如 <reasoning>
  • 结束标签(End Tag):结束标签(例如 </reasoning>

这适用于:

  • 具有本地化思考标签的模型
  • 具有独特标签格式的自定义微调模型
  • 使用 XML 风格推理标记的模型

think (Ollama)

此 Ollama 特有的设置可以启用或禁用模型内置的推理功能:

选项描述
默认(Default)使用 Ollama 的默认行为
开启(On)显式为模型启用思考模式
关闭(Off)禁用思考模式
备注

此设置会将 think 参数直接发送给 Ollama。它与 Open WebUI 如何解析回复是分开的 —— 您可能同时需要此设置以及正确的推理标签配置才能获得完整体验。

推理力度(Reasoning Effort)

对于支持可变推理深度(如某些 API 提供商)的模型,此设置控制模型在推理上付出的力度:

  • 常见值:low, medium, high
  • 某些提供商接受数字值
信息

推理力度(Reasoning Effort)仅适用于来自支持此参数的特定提供商的模型。它对本地 Ollama 模型没有影响。


推理与工具调用的交织(Interleaved Thinking)

当模型在单轮对话中使用原生函数调用(工具使用)时,Open WebUI 会保留推理内容,并将其发送回 API,以便在该轮次的后续调用中使用。这实现了真正的“推理与工具调用交织”,其中:

  1. 模型生成推理 → 进行工具调用
  2. 工具执行并返回结果
  3. 模型接收到:原始消息 + 先前的推理 + 工具调用 + 工具结果
  4. 模型继续推理 → 可能会进行更多工具调用或提供最终答案
  5. 重复该过程直到该轮对话完成

工作原理

在多步骤工具调用轮次中,Open WebUI 会:

  1. 从模型的响应中捕获推理内容(通过 delta 中的 reasoning_contentreasoningthinking 字段)
  2. 将其与工具调用一起存储在内容块中
  3. 在构建下一次 API 调用的消息时,使用其原始标签(例如 <think>...</think>)对推理进行序列化
  4. 将序列化后的内容包含在 assistant 消息的 content 字段中

这确保了模型在同一轮次内决定后续操作时,能够访问其先前的思考过程。

推理内容如何被发送回去

存在两条并行的路径,适用哪一条取决于前一轮的推理内容是如何被捕获的 —— 而不取决于您发送到的提供商。

路径 1 —— 嵌入在 content 中的推理内容(大多数提供商的默认行为)

当模型在其内容中内联以 <think>…</think>(或任何其他配置的标签对)的形式流式传输推理时,Open WebUI 会将这些标签保留为 message.content 的一部分。在下一轮中,该消息会被逐字转发给 LLM,保留所有标签。没有任何内容被丢弃,也不需要特定于提供商的处理。这可能是您已经在使用的路径 —— 它也是上面 推理与工具调用的交织 部分所描述的路径。

路径 2 —— 捕获到结构化 output 数组中的推理内容

如果上游流发出了 reasoning_content / reasoning / thinking 的 delta(而不是文本标签)—— 这对于 OpenAI o 系列DeepSeek 官方 API、启用了推理的 llama.cpp 或带 --reasoning-parser 标志的 Ollama 来说非常典型 —— Open WebUI 会将这些 delta 捕获到 assistant 消息的 output 数组中的独立 reasoning 项中。显示的 content 仅包含一个用于 UI 的 <details type="reasoning"> 块;而结构化形式保留在 output 中。

当该消息被重放到 LLM(在工具调用循环中或在下一轮用户对话中)时,Open WebUI 会从 output 重建它,而不是转发渲染后的 content。用于重建推理的格式取决于连接的 Provider 设置管理员设置 → 连接 → OpenAI → 提供商 下拉菜单 —— 选项有 DefaultAzure OpenAIllama.cpp;Ollama 连接会自动检测):

连接 Provider重建推理的格式
Ollama(自动检测)包裹在 content 内的标签中:<think>…</think>
llama.cppassistant 消息上的顶级 reasoning_content 字段
Default / Azure OpenAI推理内容在重建的消息中被忽略(Omitted)

选择“在默认/严格模式下忽略”是深思熟虑的:OpenAI、Azure OpenAI、Vertex AI 和类似的 Chat Completions APIs 会拒绝包含未知字段的 assistant 消息,并且它们不希望在下一次调用时回传它们自己的推理内容(它们在 Responses API 中通过 previous_response_id 在状态端管理连贯性,或者根本不需要它)。Pipe 函数和过滤器可以在需要时以特定于提供商的形式重新注入推理。

对于 Ollama,重建后的消息类似于:

{
  "role": "assistant",
  "content": "<think>Let me search for the current weather data...</think>",
  "tool_calls": [...]
}

对于 llama.cpp 连接,它类似于:

{
  "role": "assistant",
  "content": "",
  "reasoning_content": "Let me search for the current weather data...",
  "tool_calls": [...]
}

提供商兼容性

提供商类型路径 1(content 中的标签)路径 2(结构化 output
内联发出 <think> 标签的 OpenAI 兼容 APIs(通过 Ollama 的 DeepSeek-R1、带推理解析器的 Qwen3 等)✅ 自动往返。不适用
Ollama(连接自动标记为 ollama✅ 往返。✅ 在 content 中重建为 <think>…</think>
llama.cpp(连接 Provider 设置为 llama.cpp✅ 如果模型使用标签,支持往返。✅ 重建为 reasoning_content 字段。
OpenAI o 系列(Responses API)不适用 —— o 系列不暴露推理文本。⚠️ 推理连贯性由 previous_response_id 处理,而不是通过重新发送内容。
OpenAI / Azure / Vertex AI (Chat Completions, Provider Default)✅ 标签以文本形式通过 —— 大多数严格的提供商都容许它们。⚠️ 重建时忽略结构化推理(如果需要,请使用 pipe/filter 重新注入)。
Anthropic(extended thinking 深度思考)⚠️ 标签有效,但原生 API 期望 {"type": "thinking"} 块以实现真正的深度思考 —— 请使用 pipe function❌ 原生不支持。

重要注意事项

  • 检测逻辑未改变。 从输入流中检测推理内容的方式与以往完全相同 —— 路径 1 使用 <think> 样式的标签匹配,路径 2 使用 reasoning_content / reasoning / thinking delta。这里添加的提供商感知行为仅控制在重放消息时如何重建路径 2 的推理内容。
  • 轮内和轮际使用相同的逻辑。 无论 Open WebUI 是在多步骤工具调用循环中发送消息,还是为新的用户轮次构建 Payload,都适用相同的重建规则。
  • 大多数用户处于路径 1。 内联发出 <think> 标签的模型(Ollama 上的 DeepSeek-R1 系列、Qwen3、MiniMax M2.5 等)将其推理保留在 content 中,并继续在没有做任何提供商配置的情况下进行往返。

流式与非流式

流式模式(默认)

在流式模式下(stream: true),Open WebUI 会在 Token 到达时对其进行处理,并可以实时检测推理块。这通常在没有额外配置的情况下也能工作得很好。

非流式模式

在非流式模式下(stream: false),整个响应会一次性返回。这是大多数解析问题发生的地方,因为:

  1. 响应作为一个单一的文本块到达
  2. 没有推理解析器,就没有后处理来分离 <think> 内容
  3. 原始响应会按原样显示
重要

如果您使用非流式请求(通过 API 或某些特定配置),推理解析器对于正确分离思考块至关重要


API 使用

在通过推理模型使用 Open WebUI API 时:

{
  "model": "qwen3:32b",
  "messages": [
    {"role": "user", "content": "Solve: What is 234 * 567?"}
  ],
  "stream": true
}

建议: 使用 "stream": true 以获得最可靠的推理块解析。


问题排查

思考内容与最终答案合并

症状: 使用推理模型时,整个响应(包括 <think>...</think> 块)都作为最终答案显示,而不是被分离到隐藏/可折叠的思考部分。

错误显示的示例:

<think>
Okay, the user wants a code snippet for a sticky header using CSS and JavaScript.
Let me think about how to approach this.
...
I think that's a solid approach. Let me write the code now.
</think>

Here's a complete code snippet that demonstrates a sticky header using CSS and JavaScript...

预期行为: 思考内容应该是隐藏或可折叠的,仅最终答案可见。

针对 Ollama 用户

最常见的原因是 Ollama 没有配置正确的推理解析器(reasoning parser)。运行 Ollama 时,您需要指定 --reasoning-parser 标志以启用对思考块的正确解析。

步骤 1:配置推理解析器

启动 Ollama 时,添加 --reasoning-parser 标志:

# 针对 DeepSeek-R1 风格的推理(推荐用于大多数模型)
ollama serve --reasoning-parser deepseek_r1

# 备用解析器(如果上述解析器对您的模型不起作用)
ollama serve --reasoning-parser qwen3
ollama serve --reasoning-parser deepseek_v3
推荐的解析器

对于大多数推理模型,包括 Qwen3 和 DeepSeek 变体,请使用 --reasoning-parser deepseek_r1。此解析器处理大多数推理模型使用的标准 <think>...</think> 格式。

步骤 2:重启 Ollama

添加标志后,重启 Ollama 服务:

# 停止 Ollama
# 在 Linux/macOS 上:
pkill ollama

# 在 Windows 上 (PowerShell):
Stop-Process -Name ollama -Force

# 带着推理解析器启动
ollama serve --reasoning-parser deepseek_r1

步骤 3:在 Open WebUI 中验证

  1. 前往 Open WebUI 并与您的推理模型开始新的对话
  2. 提出一个需要推理的问题(例如,数学题或逻辑谜题)
  3. 响应现在应该在一个可折叠的部分中显示思考内容

可用的推理解析器

解析器描述使用场景
deepseek_r1DeepSeek R1 格式大多数推理模型,包括 Qwen3
deepseek_v3DeepSeek V3 格式某些 DeepSeek 变体
qwen3Qwen3 特有格式如果 deepseek_r1 对 Qwen 不起作用

问题排查清单

1. 验证 Ollama 是否带推理解析器运行

检查 Ollama 启动时是否带了正确的标志:

# 检查 Ollama 进程
ps aux | grep ollama
# 或在 Windows 上:
Get-Process -Name ollama | Format-List *

在命令行参数中寻找 --reasoning-parser

2. 检查模型兼容性

并非所有模型都以相同的格式输出推理。请查看您的模型文档以验证:

  • 它使用什么标签来包裹思考内容(例如 <think><reasoning> 等)
  • 它是否需要特定的 Prompt 来启用思考模式

3. 测试启用流式传输

如果非流式传输不起作用,请尝试在您的对话中启用流式传输:

  1. 前往 对话控制(Chat Controls)(侧边栏)
  2. 确保已启用流式传输(这是默认设置)
  3. 再次测试模型

4. 检查 Open WebUI 版本

确保您运行的是最新版本的 Open WebUI,因为对推理模型的支持在不断改进:

docker pull ghcr.io/open-webui/open-webui:main

5. 验证模型回复格式

直接使用 Ollama CLI 检查您的模型输出什么格式:

ollama run your-model:tag "Explain step by step: What is 15 + 27?"

在输出中寻找 <think> 标签。如果它们不存在,模型可能需要特定的系统 Prompt 来启用思考模式。

工具调用之间推理丢失

症状: 工具调用完成后,模型似乎“忘记”了它之前在想什么。

可能的原因:

  1. 模型没有以被捕获的格式输出推理(reasoning_contentreasoningthinking delta 字段)
  2. 模型使用基于文本的思考标签,这些标签没有被解析为推理块

解决方案: 检查您的模型是否通过以下方式输出推理:

  • 结构化 delta 字段(reasoning_contentreasoningthinking
  • Open WebUI 检测的基于文本的标签(确保启用了推理标签检测)

Anthropic Extended Thinking 无法与工具调用配合使用

症状: 在启用了 extended thinking 的情况下使用 Anthropic 的 Claude 模型,但工具调用失败并报错:

Expected `thinking` or `redacted_thinking`, but found `text`. When `thinking` is enabled, 
a final `assistant` message must start with a thinking block.

原因: 这是一个根本性的架构差异。Open WebUI 遵循 OpenAI Chat Completions API 标准,原生不支持 Anthropic 的专有 API 格式。Anthropic 的 extended thinking 需要包含 {"type": "thinking"}{"type": "redacted_thinking"} 的结构化内容块,这些是 Anthropic 特有的格式,在 OpenAI 标准中并不存在。

Open WebUI 在消息内容字段内将推理序列化为被标签包裹的文本(例如 <think>...</think>)。这适用于 OpenAI 兼容的 API,但不满足 Anthropic 对结构化思考块的要求。

为什么 Open WebUI 不原生支持此格式:

在不同的提供商之间,没有标准的方法来将推理内容存储为 API Payload 的一部分。如果 Open WebUI 实现了对某个提供商格式的支持,它可能会破坏许多其他推理提供商的现有部署。鉴于 Open WebUI 支持广泛的后端,我们遵循 OpenAI Completions API 作为通用标准。有关此架构决定的更多详细信息,请参阅我们的 关于协议支持的 FAQ

权宜之计:

  1. 使用 Pipe 函数:创建一个自定义的 pipe function,在向 Anthropic API 发送请求之前,将 Open WebUI 基于文本的思考格式转换为 Anthropic 的结构化思考块。

  2. 禁用 Extended Thinking:如果您在工具调用工作流中不需要思考过程,请将其禁用以避免格式不匹配。

备注

此限制专门适用于将 Anthropic 的 extended thinking 与工具调用结合使用。Extended thinking 在没有工具调用时可以工作,工具调用在没有 extended thinking 时也可以工作 —— 只有在通过 Anthropic API 同时使用这两个功能时才会发生此问题。

有状态推理模型(GPT-5.2 等)

症状: 使用隐藏其推理的模型(有状态/内部推理),且推理内容未被保留。

原因: 一些较新的模型(如 GPT-5.2)将推理保留在内部,并不在 API 响应中暴露。Open WebUI 只能保留模型实际返回的推理内容。

行为: 如果模型返回的是推理摘要而不是完整的推理内容,那么被保留并发送回去的将是该摘要。


常见问题解答

为什么思考块显示为原始文本?

如果模型使用的标签不在默认列表中,并且未在 reasoning_tags 中进行配置,Open WebUI 将把它们视为普通文本。您可以通过在“模型设置”或“对话控制”中将正确的标签添加到 reasoning_tags 参数来解决此问题。

模型能看到它自己的思考吗?

是的。 推理内容会在以下两种场景中被保留并发送回模型:

  • 在同一轮对话中(工具调用期间)是的。当模型进行工具调用时,Open WebUI 会保留推理内容并将其作为 assistant 消息的一部分发送回 API。这使模型能够保持关于它在进行工具调用时在想什么的上下文。

  • 跨不同轮次是的。在构建后续请求的消息时,Open WebUI 会使用其原始标签(例如 <think>...</think>)对前几轮的推理内容进行序列化,并将其包含在 assistant 消息的 content 字段中。这允许模型在整个对话中引用其先前的推理。

在工具调用期间推理内容是如何发送的?

当涉及工具调用时,推理会被序列化为带原始标签的文本,并包含在 assistant 消息的 content 字段中。例如:

<think>Let me search for the current weather...</think>

这种基于文本的格式适用于大多数 OpenAI 兼容的提供商。然而,某些提供商(如 Anthropic)可能期望特定格式的结构化思考内容块 —— Open WebUI 目前使用基于文本的序列化,而不是特定于提供商的结构化格式。

This content is for informational purposes only and does not constitute a warranty, guarantee, or contractual commitment. Open WebUI is provided "as is." See your license for applicable terms.