Skip to content

使用 MiniMax 的 thinking 和 reasoning_split

MiniMax 的接入重点是分别处理当前请求的 thinking 开关、推理内容返回形态,以及工具调用后的完整 assistant 消息。MiniMax M3 使用 thinking.type 控制当前请求是否思考,reasoning_split 只控制 thinking 返回在哪里。

区分 thinking 开关和返回形态

MiniMax M3 支持以下 thinking 设置:

  • 省略 thinking 时,默认开启 adaptive thinking。
  • 设置 thinking: {"type": "adaptive"} 时,显式开启 adaptive thinking。
  • 设置 thinking: {"type": "disabled"} 时,关闭思考并直接回答。

MiniMax M2.x 无法关闭 thinking。对 M2.x 传入 thinking.type: "disabled" 时,不要假设 thinking 已关闭。

reasoning_split 不会开启或关闭 thinking,只改变返回形态:

  • 设置 reasoning_split: true 时,推理内容和最终回答拆分返回。MiniMax M3 的非流式响应可能只包含 reasoning_content;流式响应可能同时包含 reasoning_contentreasoning_details 增量。应用必须允许任一字段缺失。
  • 不启用 split 或设置 reasoning_split: false 时,推理内容可能出现在 content 的原生 <think> 片段中。

如果不向用户展示推理,请在展示层过滤。需要继续多轮对话或工具调用时,保留服务端返回的完整 assistant 消息,不要从历史消息中删除或改写推理字段。

开启 M3 adaptive thinking 并读取 split 响应

以下 Python 示例显式开启 adaptive thinking 和 split 模式。展示推理内容时,优先读取 reasoning_content,并把 reasoning_details 作为兼容回退,避免同时展示两个字段中的重复内容。

language-python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["API_KEY"],
    base_url="https://cloud.infini-ai.com/maas/v1",
)

response = client.chat.completions.create(
    model="minimax-m3",
    messages=[{"role": "user", "content": "What is 17 * 23? Give only the final answer."}],
    max_completion_tokens=512,
    extra_body={
        "thinking": {"type": "adaptive"},
        "reasoning_split": True,
    },
)

message = response.choices[0].message
reasoning_content = getattr(message, "reasoning_content", None)
reasoning_details = getattr(message, "reasoning_details", None)

if reasoning_content:
    print(reasoning_content)
elif reasoning_details:
    print(reasoning_details)

print(message.content)

如果 reasoning_details 为空,不要立即判定请求失败。先读取 reasoning_content;如果两个字段都为空,再检查本次请求是否关闭了 thinking、这次回复是否只包含最终答案,以及是否使用了 split 模式。

用 curl 验证 M3 请求体

先用 curl 确认 thinkingreasoning_split 和生成长度字段已经传入。运行前先在当前终端设置 API_KEY 环境变量。以下命令适用于 bash/zsh 等 POSIX 风格 Shell(macOS/Linux、WSL、Git Bash)。如果使用 Windows PowerShell 或 CMD,请按对应 Shell 的语法调整命令。

language-shell
curl --request POST \
  --url "https://cloud.infini-ai.com/maas/v1/chat/completions" \
  --header "Accept: application/json, text/event-stream" \
  --header "Authorization: Bearer $API_KEY" \
  --header "Content-Type: application/json" \
  --data-raw '{
    "model": "minimax-m3",
    "messages": [
      {
        "role": "user",
        "content": "What is 17 * 23? Give only the final answer."
      }
    ],
    "thinking": {"type": "adaptive"},
    "reasoning_split": true,
    "max_completion_tokens": 512
  }'

终端录制

用 curl 验证 MiniMax reasoning_split

在演示库中打开

适用于验证 MiniMax 推理拆分字段是否按预期传入。

MiniMax M3 新接入建议使用 max_completion_tokens。不要同时设置 max_tokensmax_completion_tokens;如果响应以 finish_reason: "length" 结束,应把结果视为不完整输出,并在模型允许范围内提高上限。

关闭 M3 思考

如果业务请求只需要最终答案,可对 MiniMax M3 设置:

language-python
extra_body = {
    "thinking": {"type": "disabled"},
    "reasoning_split": True,
}

此时 reasoning_contentreasoning_details<think> 都可能缺失,这是正常结果。reasoning_split 仍只控制返回形态,不会重新开启 thinking。该关闭方式只适用于 MiniMax M3;不要套用到 MiniMax M2.x。

保留 <think> 内容所在的完整 assistant 消息

未启用 split 时,MiniMax 可能把原生 <think> 内容放在 content 中。此时不要在历史消息里删除 <think> 片段后再回传,因为这会改变模型看到的历史。

language-python
assistant_message = response.choices[0].message.model_dump(exclude_none=True)
messages.append(assistant_message)

如果需要面向用户隐藏 <think>,应在展示层过滤;不要改写要继续传给模型的历史消息。

工具调用后回传完整 assistant 消息

工具调用流程中,MiniMax M3 的非流式 assistant 消息可能包含 reasoning_contenttool_calls;流式重建后的消息还可能同时包含 reasoning_details。不要只挑选其中一个推理字段。回传 assistant 消息时保留服务端实际返回的完整结构,再追加 tool 结果。

以下代码假设 tool_call_response 是已经返回 tool_calls 的第一轮响应:

language-python
assistant_message = tool_call_response.choices[0].message.model_dump(exclude_none=True)
messages.append(assistant_message)
messages.append(
    {
        "role": "tool",
        "tool_call_id": assistant_message["tool_calls"][0]["id"],
        "content": '{"weather": "Sunny"}',
    }
)

如果应用框架要求把 SDK 对象转成 dict,请确保 contenttool_callsreasoning_contentreasoning_details 等扩展字段没有被过滤。字段没有返回时保持缺失,不要补写空字符串或空数组。

按增量处理 reasoning_details

reasoning_details 是对象数组,不是纯字符串。流式响应中,同一 idindex 可能分多次返回不同的 text 片段。应用应按到达顺序保留对象,或按到达顺序拼接其中的 text;不要按 index 覆盖前一个片段。

language-python
stream = client.chat.completions.create(
    model="minimax-m3",
    messages=[{"role": "user", "content": "What is 17 * 23? Give only the final answer."}],
    max_completion_tokens=512,
    stream=True,
    extra_body={
        "thinking": {"type": "adaptive"},
        "reasoning_split": True,
    },
)

reasoning_detail_parts = []

for chunk in stream:
    if not chunk.choices:
        continue

    delta = chunk.choices[0].delta
    for detail in getattr(delta, "reasoning_details", None) or []:
        text = detail.get("text") if isinstance(detail, dict) else getattr(detail, "text", None)
        if text:
            reasoning_detail_parts.append(text)

reasoning_details_text = "".join(reasoning_detail_parts)

展示时可优先使用完整的 reasoning_content,仅在该字段缺失时使用拼接后的 reasoning_details。继续工具调用或多轮对话时,应保留并回传模型实际返回的全部字段,而不是只回传展示用文本。