用 Anthropic SDK 接入 MiniMax:官方推荐的接法

2026-08-25

数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。

MiniMax 在「前置准备」这一页里,把 Anthropic SDK 明确写成了推荐接法:装官方 anthropic 包,把 ANTHROPIC_BASE_URL 指到 MiniMax 的 /anthropic 路径,Key 照填,client.messages.create() 就能调 M 系列模型。三行配置本身没什么难度,真正会绊人的是另外三件事——响应里的 content 是一个内容块列表而不是字符串,多轮 Function Call 必须把上一轮完整的 content 原样塞回历史,以及一部分 Anthropic 原生参数在这边是被”忽略”而不是被”报错”。这篇就按官方文档的顺序,把这条链路从配环境变量一直走到看报错。

装 SDK 和配环境变量:真正需要动的只有两个

官方给的安装命令,Python 侧是 pip install anthropic,Node.js 侧是 npm install @anthropic-ai/sdk——都是 Anthropic 自家的官方 SDK,MiniMax 没有另外包一层。

接下来是两个环境变量:

export ANTHROPIC_BASE_URL=https://api.minimaxi.com/anthropic
export ANTHROPIC_API_KEY=<你的 API Key>

这里有个细节值得盯一眼:ANTHROPIC_BASE_URL 填到 /anthropic 为止,而实际的接口路径在 OpenAPI 里写的是 POST /anthropic/v1/messages。也就是说 /v1/messages 那一段是 SDK 自己拼上去的,你不用(也不该)把它写进 base url 里。同一份文档里另外列了 OpenAI 兼容形态用的是 OPENAI_BASE_URL=https://api.minimaxi.com/v1,AI SDK 形态用的是 MINIMAX_API_KEY——三套变量名各管各的,混着配是新手最常见的翻车点。

鉴权上官方提供了两条通道:一条是 Authorization: Bearer <API_KEY>,另一条是 Anthropic 生态习惯的 x-api-key: <API_KEY>。文档里明确写了两点:官方推荐用 Authorization: Bearer 这条;如果两个头同时存在,服务端会优先采用 Authorization。这条规则在排查”我明明换了 Key 怎么还是老的”这类问题时特别有用——很可能是某个中间层偷偷塞了另一个头。

Key 本身也分两种。按量付费的 Key 在「接口密钥 > 创建新的 API Key」里创建;Token Plan 的订阅 Key 在「订阅管理 > Token Plan」里查看。官方特别提示了订阅 Key 的一个反直觉之处:它可以在付费资源可用之前就已经存在,只有当账号真正拥有 Token Plan 席位或者积分权限之后才能实际调用资源。所以拿到一串 Key 不等于能跑通,先确认资源侧的状态。

企业侧还有一条要提前想清楚的:官方建议用主账号加子账号的形式管理,子账号数量暂时不设限制,但子账号和主账号享用相同的使用权益与速率限制,API 消耗共享、统一结算,子账号没有查看和管理支付的权限。换句话说,子账号是权限隔离,不是配额隔离——想给不同团队分限额,靠拆子账号是达不到目的的。Key 的分发与轮换策略可以参考API Key 的安全管理里的通用做法。

第一次调用:返回的 content 是块列表,不是一段文字

官方 quickstart 给的最小示例是这样的:

import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
    model="MiniMax-M3",
    max_tokens=1000,
    system="You are a helpful assistant.",
    messages=[
        {"role": "user", "content": [{"type": "text", "text": "Hi, how are you?"}]},
    ],
)

for block in message.content:
    if block.type == "thinking":
        print(block.thinking)
    elif block.type == "text":
        print(block.text)

注意最后那个循环。官方示例没有直接 print(message.content),而是遍历每一个 block 判断 type——因为在 Anthropic 兼容格式里,响应的 content 是一个内容块数组。按 OpenAPI 的 ResponseContentBlock 定义,模型侧可能输出三类块:text(文本内容)、tool_use(模型发起工具调用)、thinking(模型的思考过程)。文档同时写明,响应里不会出现 imagevideotool_resultmid_conv_system 这几类块,它们只在请求方向上使用。

与之配套的是 stop_reason,官方给的枚举有三个取值:end_turn 表示模型自然结束,max_tokens 表示撞到了长度上限,tool_use 表示模型请求调用工具。这三个值应该成为你解析逻辑的第一个分支,而不是事后补的兜底。尤其是 max_tokens:文档在 max_tokens 参数说明里写了,超过上限的内容会被截断,如果生成因 length 原因中断,应该尝试调高这个值。M3 与 M2.x 系列的推荐值和上限不同,具体数值以官方文档当前版本为准。

thinking 参数:M3 默认关着,M2.x 关不掉

这是 MiniMax 这套兼容接口里设计得比较特别的一处。官方文档的说明是:

  • MiniMax-M3,省略 thinking 参数时默认关闭思考,响应不会包含 thinking 块;
  • thinking: {"type": "adaptive"} 显式开启,对 M3 而言 adaptive 等同于开启 thinking;
  • thinking: {"type": "disabled"} 显式保持关闭;
  • 对 M2.x 系列模型,thinking 无法关闭——即便你传了 disabled,thinking 仍然保持开启。

thinking.type 的枚举官方只列了 disabledadaptive 两个值。这意味着如果你是从别家迁过来、习惯用预算数值控制思考长度的写法,在这里是接不上的。

还有一个更隐蔽的点:当响应里出现 thinking 块时,块上会带一个 signature 字段。官方明确要求,后续轮次中应当把这些块原样保留,尤其是在工具调用对话里;signature 在多轮续写时需要原样回带。也就是说 thinking 不是纯展示用的调试信息,它是会话状态的一部分。很多人写日志时顺手把 thinking 过滤掉了,多轮场景下就会出问题。

多轮 Function Call:官方专门用一节强调”完整回带”

文档在「特别注意」一节里写得很直白:在多轮 Function Call 对话中,必须将完整的模型返回(即 assistant 消息)添加到对话历史,以保持思维链的连续性。具体两条:

  • 把完整的 response.content(包含 thinking / text / tool_use 等所有块)添加到消息历史;
  • response.content 是一个列表,包含多种类型的内容块,必须完整回传。

实现上常见的错法是只把 tool_use 那一块挑出来回带,或者只回带文本部分。按官方这条说明,这两种做法都不对。

工具定义这一侧也有限制需要提前知道。Tool 结构里必填的是 nameinput_schemadescription 可选,另外可以挂 cache_control。而 tool_choice 的说明写着”仅支持 auto 和 none”——如果你的编排逻辑依赖强制指定某个工具,这套兼容接口目前接不住,需要在应用层自己收敛。

工具执行结果通过 tool_result 块回传,tool_use_id 对应上一轮 tool_use 块的 ID,content 可以是字符串,也可以是 text / image 内容块数组。另外请求方向还有一个 mid_conv_system 块类型,用途是”对话中途插入的系统指令”——这是标准 Anthropic 格式里没有的扩展,需要在对话中途改变模型行为时可以留意。

哪些参数会被忽略:不是报错,是静默丢弃

这一节的信息密度最高,也最容易被忽略。官方的兼容性说明列了两类参数,一类”完全支持”,一类”忽略”。被明确标为忽略的有这几个:top_kstop_sequencesmcp_serverscontext_managementcontainer

“忽略”的含义是请求不会失败,参数就是不生效。这比直接报错难查得多——你以为 stop_sequences 在截断输出,实际上它压根没被读。从 Claude 生态迁过来的代码尤其要过一遍这张单子,把依赖这几个参数的逻辑改到应用层实现。迁移时的其他检查项可以对照换厂商迁移清单一起过。

标注为完全支持的包括 modelmax_tokensstreamsystemtemperaturetool_choicetoolstop_pthinkingmetadataservice_tier。其中几个值得单独说:

  • temperature 有官方规定的取值范围,文档在警告框里写明超出范围会返回错误,同时给了推荐取值。具体范围与推荐值以官方文档当前版本为准。
  • top_p 是核采样参数,官方注明 M3 与 M2.x 系列的默认值不同——如果你跨模型复用同一份请求模板又没有显式传这个参数,实际行为会跟着模型变。默认值同样以官方文档当前版本为准。
  • metadata 里可以传 user_id。官方的建议是:to-C 业务传入 user_id,便于按终端用户聚合限流和计费分析。这一条属于花五分钟就能省掉后面很多麻烦的设计,做多租户的话第一天就该加上。
  • service_tier 控制请求准入层级,官方给的枚举是 standardpriority,省略时使用 standard。文档说明 priority 会确保请求获得优先准入,使其排在其他请求之前处理,从而带来更快响应并减少失败;代价是按高于 standard 的价格计费,具体计费比例与单价见官方定价页。

messages 被标为”部分支持”,原因在下一节。

多模态只有 M3 吃得下

官方对 messages 的支持状态写的是部分支持,理由很具体:MiniMax-M3 支持文本、图片、视频、工具调用、工具结果和 thinking 内容块;M2.7、M2.5、M2.1 和 M2 系列仅支持文本与工具调用相关内容块,不支持图片和视频输入。这条在文档里出现了三次(兼容性表、字段表、页尾警告框),可见踩的人不少。

具体到格式,官方列出的图片格式是 JPEG、PNG、GIF、WEBP,视频格式是 MP4、AVI、MOV、MKV。MOV 有一个容易踩的坑单独写在了 MIME Type 一栏:用 URL 传入时,对象存储侧要把 Content-Type 设为 video/quicktime;而 base64 编码传入时,要用 video/mov,即 data:video/mov;base64,<编码内容>。同一种格式两种写法,配错了就是一个 400。

大小上有官方规定的上限:URL 或 base64 方式传入时,视频、图片、请求体各有各的上限,超了会命中 413 request_too_large。更大的视频要先走 Files API 上传拿到 file_id,再以 mm_file://{file_id} 的形式引用,这条路径的上限比直传更宽。具体数值以官方文档为准。

两个影响 token 花费的参数也在这一层:图片和视频块的 source.detaillowdefaulthigh 三档,官方给了每档单张图片的粗略 token 用量区间,并强调实际用量取决于图片尺寸和内容;视频块的 fps 控制抽帧频率,官方的说明是取值越高对画面变化越敏感但 token 花费高、速度慢,取值越低则花费少、对画面变化迟钝。这两个参数就是多模态场景下账单的主要旋钮——想控成本,先调它们,再考虑换模型。

上下文窗口方面,官方文档给 MiniMax-M3 标注的是 100 万 token,M2.x 系列是另一个量级,以官方文档为准;这个数字本身别硬记,它随版本更新。

算钱和排查:usage 四个字段、count_tokens、request_id

usage 结构官方定义了四个字段:input_tokensoutput_tokenscache_creation_input_tokens(创建 prompt cache 的输入 token 数)、cache_read_input_tokens(命中 prompt cache 的输入 token 数)。后两个字段是判断缓存到底有没有生效的唯一客观依据——不看它们,缓存优化就是在盲调。缓存本身怎么计费可以先看缓存计费的通用机制

流式场景下 usage 出现在两个地方:message_start 事件里带一份,message_delta 事件里再带一份。做用量统计时要想清楚以哪一份为准,否则容易重复计数。流式事件类型官方列的枚举是 message_startpingcontent_block_startcontent_block_deltacontent_block_stopmessage_deltamessage_stop;增量类型有 text_deltathinking_deltasignature_delta 三种。

调用前想预估的话,Anthropic 兼容接口也支持 POST /anthropic/v1/messages/count_tokens,官方说明是可用于 MiniMax-M3 调用前预估输入 token 用量,不会生成模型输出。多模态请求想知道一张图到底吃掉多少 token,这个端点比任何估算表都准。

报错侧,官方统一用 HTTP 状态码加 JSON body,body 里除了 error.type 还有一个 request_id——这是排查问题时唯一能递给官方技术支持的凭据,日志里必须落。error.type 的枚举官方列了八个:invalid_request_errorauthentication_errorpermission_errornot_found_errorrequest_too_largerate_limit_errorapi_erroroverloaded_error,分别对应 400、401、403、404、413、429、500、529。

其中两个值得单独记:529 的描述是”上游模型过载,可重试”,属于官方点名可以重试的一类;429 的描述是触发 RPM/TPM/连接数等限流,注意这里除了常见的两个维度还多了”连接数”,流式长连接开太多也可能撞上。429 的退避策略可以参考429 的通用处理方式

还有一条只有读 OpenAPI 才看得到的说明:流式过程中出现错误时,会以 event: error 这个 SSE 事件下发,body 结构和非流式一致;客户端应当在收到 error 后停止读取并清理本次会话状态。很多流式客户端只处理了正常事件类型,遇到 error 事件时既没停读也没清状态,表现就是一次失败之后后面全乱套。

最后:三个最容易栽的地方

第一,content 当字符串用。这是从 OpenAI 兼容格式过来的人最常犯的错,写出来的代码在纯文本场景能跑通,一开 thinking 或者一带工具调用就崩。

第二,多轮里没有把 assistant 的 content 完整回带。官方专门开了一节写这件事,说明它就是高频事故点。thinking 块和它的 signature 一起原样带回去,别做任何”清洗”。

第三,把被忽略的参数当成生效的参数。top_kstop_sequencesmcp_serverscontext_managementcontainer 这五个传了也白传,而且不报错。接入完成后,建议专门 grep 一遍代码里这几个参数名,确认没有业务逻辑依赖它们。

配置本身十分钟就能跑通,剩下的时间都花在这三件事上,反而是值的。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。