[控场AI]
· 10 分钟阅读· 5,388 字

MiniMax M3.1 Flash迁移实战:修复2013错误与思考模式调优

MiniMax M3.1 Flash迁移实战:修复2013错误与思考模式调优

M2.x 退役迁移 M3.1 Flash 实测:三类故障、成本激增与 Agent 集成要点。

MiniMax M2.5/M2.7 将于 11 月 18 日退役,团队被迫迁移到 M3.1 Flash,而这次迁移并不平滑。作者基于实测梳理了三类问题:Chat Completions 发送 thinking disabled 会返回 HTTP 400(错误码 2013),因为该模型 always thinks,只接受 adaptive;其他各种「关思考」写法全部静默失败,返回 200 却仍在推理,只能靠检查 reasoning_tokens 判断;省略 effort 时默认跑在 max,同一 bug 修复任务消耗 6364 推理 tokens、56 秒,成本约为 low 设置的 10 倍。文章还给出 Claude Code、Codex CLI、OpenCode 的接入方式与 OpenCode 的 effort 变体变通方案,提示 cache_control 不被支持、图片 URL 拉取失败同样触发 2013,建议改用 base64,并列出若干尚未验证的边界。核心结论是:返回 200 不等于配置生效,必须显式设置 effort、核对 reasoning_tokens 并重跑评测。

MiniMax M2.5 和 M2.7 将于 11 月 18 日正式退役,许多团队正被迫迁移到 M3.1 Flash。这次迁移并不平滑:我们把 M2.x 风格的请求发往 M3.1 Flash,遇到了三类问题——一个显式的 400 错误、若干静默失败,以及默认思考强度带来的成本飙升。本文基于实测数据,梳理错误成因、修复方法以及 Agent 集成中的坑。

MiniMax M3.1 Flash 迁移问题概览

为什么现在必须关注迁移

MiniMax 已宣布 M2.5 和 M2.7(含 -highspeed 变体)于 11 月 18 日退役。自 10 月 19 日起,这两个系列已对新用户关闭。根据 MiniMax 官方模型页面的说明,在 M Plan 和 Token Plan广告 下命名这两个模型的请求,实际上会被 M3.1 Flash 以旧名称服务;按量付费的调用则会在退役日之后彻底停止。

这意味着,如果你的日志里还写着 M2.7,背后的模型可能已经换了:上下文从 204,800 变为 1M,top_p 从 0.9 变为 0.95,思考模式默认跑在 max。官方明确建议重新跑一遍评测——这不是可选项,而是必须做的迁移动作。

错误 2013:"requires adaptive thinking" 的复现与修复

最直接的报错来自 Chat Completions 接口。当我们发送 thinking: {"type": "disabled"} 时,返回 HTTP 400:

"invalid params, model \"MiniMax-M3.1-Flash\" requires adaptive thinking; 
thinking.type=\"disabled\" (including reasoning.effort=none) is not allowed (2013)"

问题根源在于模型能力差异。MiniMax 的 Messages API 文档写明该模型「always thinks」,thinking.type 如果发送,必须是 adaptive。为 M3 编写的代码之所以会踩坑,是因为 M3 可以关闭思考。一些框架将模型归类为非推理模型,默认发送「关闭思考」,结果每一次调用都失败——kodus-ai 和 9router-go 项目都报告了同样的问题。

修复方式很直接:要么移除 thinking 字段,要么发送 {"type": "adaptive"}。如果想加快速度,应降低 effort 而非关闭思考:

resp = client.chat.completions.create(
    model="minimax-m3.1-flash",
    reasoning_effort="low",   # low | medium | high | xhigh | max; 省略 = max
    max_tokens=32768,         # 思考 token 计入此上限
    messages=[{"role": "user", "content": "..."}],
)

自适应思考(adaptive thinking) 是 MiniMax 在 M3 系列引入的推理控制模式:模型自行决定何时推理、推理多深,调用方不再拥有「关闭思考」的开关。与之相对的是早期 M2.x 采用的显式开关(thinking.type: enabled/disabled),开发者可以完全跳过推理阶段以换取延迟和成本。M3.1 Flash 属于「always thinks」模型,thinking.type 只接受 adaptive 或不发送,这意味着控制粒度从「开/关」变成了「强度高低」。这一变化与 Anthropic 在 Claude 3.7+ 上推行的 extended thinking、OpenAI 的 reasoning effort 分级是同一趋势:厂商逐渐把推理视为模型固有能力而非可选插件,接口层面只暴露预算调节。理解这一点很关键——迁移时任何试图「完全关掉思考」的代码路径都会失效,正确做法是改用 reasoning_effort 这类强度参数,并把思考 token 纳入 max_tokens 和成本预算的核算范围。

reasoning_tokens 是响应 usage 字段中用于统计内部推理消耗的子项,它与可见输出 token 分开计量,但通常按输出价格计费。由于推理内容默认不回传正文,只看 content 无法判断模型是否真的「没思考」——这正是静默失败的根源。建议在集成层统一解析 usage.completion_tokens_details.reasoning_tokens(或对应字段),为每次调用打点;当该值异常偏高时告警,可及早发现 effort 未透传、配置被覆盖等问题。在 Agent 循环中,还应把 reasoning_tokens 累加进单步成本,否则很容易低估整条工作流的开销。

静默失败:返回 200 但行为不符合预期

比 400 更隐蔽的是那些返回 200 却「不听话」的请求。我们实测了多种「关闭思考」的写法,结果如下:

请求方式实际行为
Messages + thinking disabled仍然思考:短谜题消耗 469–622 tokens
Chat + reasoning_effort none仍然思考:265–372 tokens
Chat + reasoning_effort minimal仍然思考
省略 effort以 max 强度运行
max_tokens 设为 64finish_reason 为 length,回答被截断
cache_control 块不支持,缓存是自动的
service_tier不支持,无 Priority 层级

只有 Chat Completions 配合 thinking: {"type": "disabled"} 才会产生 400,其余「关思考」的尝试全部静默失败。对迁移团队来说,这意味着不能靠「没报错」判断配置生效,必须在响应里检查 reasoning_tokens。

成本实测:默认 max 强度贵 7 倍

effort 设置直接决定了迁移后的账单。我们用一个包含两个 bug 的 Python 函数修复任务做基准,对照 215 个隐藏测试,每种设置跑三次:

设置平均推理 tokens平均耗时单次修复成本
省略 effort(max)6,36456 秒$0.0045
effort = low5919.5 秒$0.0006

所有运行都通过了测试。按 AIHubMix 的定价(输入 $0.165、输出 $0.66、缓存读取 $0.0165 每 1M tokens),默认设置下思考 token 占输出的 95%(6,364 / 6,673)。换句话说,一个小 bug 修复的思考成本是低强度设置的 10 倍以上,耗时接近 6 倍。如果 Agent 每一步工具调用前都思考,这个差距会被放大到整个工作流。

Agent 与编码工具集成要点

在 Agent 场景下,M3.1 Flash 有几个需要留意的行为特征。首先,它在每次工具调用前都会推理,即便在 low 设置下,短工具步骤也要 2–7 秒。其次,它严格遵循指令——早期测试者评价「速度惊人,但需要清晰具体的指令,否则太懒」,因此显式的停止条件和验证步骤很关键。

协议支持方面,我们实测了三种主流工具:

工具协议通过 AIHubMix 可用Effort 字段
Claude CodeAnthropic Messages是output_config.effort
Codex CLIOpenAI Responses是reasoning.effort
OpenCodeOpenAI-compatible是reasoning_effort

OpenCode 存在已知问题(issue #54801,v2.0.27 复现):它无法为该模型解析 effort 变体。变通方法是在 opencode.json 中声明五个变体,每个设置 reasoning_effort,注意不要加 none。

Claude Code 的配置大致如下:

export ANTHROPIC_BASE_URL="https://aihubmix.com"
export ANTHROPIC_AUTH_TOKEN="$AIHUBMIX_API_KEY"
export ANTHROPIC_MODEL="minimax-m3.1-flash"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="minimax-m3.1-flash"

建议做一个约 15 分钟的冒烟测试:给 Agent 一个带已知 bug 和失败测试的临时目录,要求「先跑测试、修复 bug、再跑测试并展示输出」。通过标准是修复前后都运行了测试、最终变绿、经历数轮交互且没有 400。在用量日志中,minimax-m3.1-flash 请求应显示 reasoning tokens;如果每轮接近一分钟,说明 effort 设置没传递到模型。

冒烟测试(smoke test) 是迁移场景中的低成本验证手段:用最小但具备完整链路特征的用例,快速确认配置、鉴权、协议适配和关键行为是否符合预期,而不追求覆盖率。针对本次迁移,冒烟用例需要同时覆盖三件事——协议能否连通(无 400)、effort 是否真正下传(日志中 reasoning_tokens 合理)、Agent 能否完成多轮工具调用闭环(测试变绿)。它之所以重要,是因为本次迁移的多数故障是静默的:返回 200 的请求可能正以 max 强度运行,账单和延迟问题要到生产流量放大后才暴露。建议把冒烟脚本纳入 CI,在模型版本、base URL 或环境变量变更时自动执行,并在输出中固化 reasoning_tokens 与端到端耗时两个指标,形成可对比的基线。

其他需要注意的细节

上下文窗口:MiniMax API 上是 1,000,000 tokens,但 MiniMax Code 客户端默认 512K「以平衡体验与成本」,API 本身没有窗口参数。

缓存:cache_control 在 M3.1 Flash(以及 M3)上不支持。M2.7 曾按每 1M tokens $0.375 计费显式缓存写入。我们发送的每个请求(包括第一个)都有约 175–195 个 prompt tokens 来自缓存,看起来是 MiniMax 侧固定的前言部分。

图片上传的 2013:同一个错误码也可能来自图片 URL 拉取失败。upload.wikimedia.org 的图片 URL 报 400,而 base64 图片或来自其他主机的 URL 返回 200。MiniMax 未文档化此场景,我们的解读是上游无法抓取图片。建议统一使用 data:image/png;base64,… 格式,并在搜索日志前先读完整错误消息。

未能验证的边界

诚实地说,有几个问题我们没能给出确定答案:Claude Code 的 effort 设置是否真的以 output_config.effort 传递给非 Claude 模型,文档没有说明,如果没有传递,模型会跑在 max;强制工具调用(tool_choice required/any)虽然被 AIHubMix 接受且工具确实被调用,但 MiniMax 只文档化了 auto,不能依赖这一行为;剥离 thinking 块对长工具循环的影响,我们只测试了一次短往返;以及 11 月 18 日之后 AIHubMix 自己的 minimax-m2.7 路由会怎样,官方没有说明。所有计时数据来自每种设置三次运行,微小差异应视为噪声。

迁移到 M3.1 Flash 的核心教训是:不要假设「返回 200」等于配置生效。显式设置 effort、检查 reasoning_tokens、重跑评测,才能避免账单和延迟的意外。

#MiniMax M3.1 Flash#requires adaptive thinking#错误 2013#MiniMax 迁移#reasoning_effort#AIHubMix#Claude Code 配置#思考模式成本
分享:

相关推荐