Workshop

MiniMax M3 实战:1M 上下文 + 稀疏注意力的开源编码模型怎么用

3 min read ·

💡 一句话总结:M3 真正的工程价值不在「又一个能打的开源模型」,而在 1M 上下文 + 低成本 API 让「把整个代码库交给模型」从理论变成日常操作。本文给你四段直接能跑的代码。

一、M3 是什么,为什么值得动手

2026 年 6 月 1 日,上海 MiniMax 发布了 M3。和发布会上一堆跑分相比,对开发者真正重要的是三件事:

定位很清楚——对标编码与 agentic 场景的前沿能力,但用开源权重和低成本把门槛打下来。下面直接进代码。

二、5 分钟调通 M3

M3 的 API 兼容 OpenAI 协议,最快的方式是通过 OpenRouter(已上线 minimax/minimax-m3),或官方平台。用官方 Python SDK 即可:

from openai import OpenAI

# 方式 A:OpenRouter(多模型聚合,免去单独申请)
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="YOUR_OPENROUTER_KEY",
)

resp = client.chat.completions.create(
    model="minimax/minimax-m3",
    messages=[
        {"role": "system", "content": "你是一个严谨的代码审查助手。"},
        {"role": "user", "content": "用 Python 写一个带指数退避的 HTTP 重试装饰器,要求支持 jitter。"},
    ],
    temperature=0.2,
)
print(resp.choices[0].message.content)

切换到官方端点只需要改 base_urlapi_key,模型名换成官方约定的标识(以官方文档为准)。其余调用方式完全一致。

三、把整个代码库塞进 1M 上下文

这是 M3 最有杀伤力的用法。传统做法是 RAG 检索片段,但片段化会丢掉跨文件的调用关系。有了 1M 上下文,可以把一个中型仓库整体喂进去做全局推理:

import os
from pathlib import Path
from openai import OpenAI

client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_KEY"])

def pack_repo(root: str, exts=(".py", ".ts", ".go"), max_chars=2_800_000):
    """把仓库打平成带路径标注的单个字符串,粗略控制在 1M token 量级。"""
    chunks, total = [], 0
    for p in sorted(Path(root).rglob("*")):
        if p.suffix not in exts or p.is_dir():
            continue
        if any(seg in p.parts for seg in ("node_modules", ".git", "dist")):
            continue
        text = p.read_text(encoding="utf-8", errors="ignore")
        block = f"\n\n===== FILE: {p} =====\n{text}"
        if total + len(block) > max_chars:
            break
        chunks.append(block)
        total += len(block)
    return "".join(chunks), total

repo_text, size = pack_repo("./my-service")
print(f"打包字符数:{size}")

resp = client.chat.completions.create(
    model="minimax/minimax-m3",
    messages=[
        {"role": "system", "content": "你看到的是一个完整代码库,回答时必须给出涉及的文件路径。"},
        {"role": "user", "content": f"{repo_text}\n\n问题:用户登录态在哪些文件里被校验?有没有重复实现可以合并?"},
    ],
    temperature=0.1,
)
print(resp.choices[0].message.content)

⚠️ 注意max_chars 到 token 的换算很粗糙——中文/代码大约 1 token ≈ 2–3 字符,英文代码更接近 4 字符。打包前最好用 tiktoken 或官方 tokenizer 精确计数,避免超限被截断。

实测体感:跨文件的「这个函数在哪被调用」「这两处逻辑能不能合并」这类问题,整库精读明显优于 RAG 片段,因为模型能看到完整的调用链。

四、一个带工具调用的 agentic 循环

M3 主打 agentic,下面是一个最小可用的工具调用循环(function calling 协议同样兼容 OpenAI):

import json
from openai import OpenAI

client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key="YOUR_KEY")

tools = [{
    "type": "function",
    "function": {
        "name": "run_shell",
        "description": "在沙箱里执行一条 shell 命令并返回 stdout",
        "parameters": {
            "type": "object",
            "properties": {"cmd": {"type": "string"}},
            "required": ["cmd"],
        },
    },
}]

def run_shell(cmd: str) -> str:
    import subprocess
    # 生产中务必放进容器/沙箱并加白名单,这里仅示意
    return subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=20).stdout[:4000]

messages = [{"role": "user", "content": "统计当前目录下有多少个 Python 文件,并告诉我最大的那个。"}]

for _ in range(6):  # 限制最大轮数,防止失控
    resp = client.chat.completions.create(
        model="minimax/minimax-m3", messages=messages, tools=tools, temperature=0,
    )
    msg = resp.choices[0].message
    messages.append(msg)
    if not msg.tool_calls:
        print(msg.content)
        break
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = run_shell(args["cmd"])
        messages.append({
            "role": "tool", "tool_call_id": call.id, "content": result,
        })

关键工程点:一定要设最大轮数上限工具沙箱。agentic 模型失控时会反复调用工具,没有 for _ in range(6) 这种硬上限,一次任务可能烧掉大量 token。

五、自部署:显存与吞吐怎么估

M3 是 MoE,总参数大、激活参数小。自部署时显存主要被三块吃掉:全部专家权重、1M token 的 KV cache、运行时缓冲。粗略经验:

如果没有多卡环境,最务实的方案是:日常短请求走量化小模型,只在真正需要百万上下文时调 API 或临时拉起自部署实例。

六、五个避坑清单

  1. token 计数别拍脑袋:1M 上下文很容易被「字符数估算」坑,务必用真实 tokenizer 计数后再发请求。
  2. 长上下文 ≠ 免费午餐:每次塞满 1M token,成本和延迟都线性上涨,能 RAG 粗筛就先粗筛。
  3. agentic 循环必须设硬上限:最大轮数 + 工具超时 + token 预算,三者缺一不可。
  4. computer use 要人在环:发布初期可靠性有限,生产环境务必加动作确认和回滚。
  5. 量化先小流量灰度:INT4 在编码长链推理上偶尔会崩,上线前用你自己的真实任务集回归一遍,别只信公开跑分。

M3 的意义在于把「整库级别的代码理解」和「低成本 agentic」同时拉到了开源可及的范围。先用 API 把上面四段代码跑通,再决定要不要上自部署——这是性价比最高的上手路径。

Frequently asked questions

MSA(MiniMax Sparse Attention)和普通稀疏注意力有什么不一样?
传统稀疏注意力(如滑窗、块稀疏)靠固定的稀疏模式裁剪计算,长距离依赖容易丢。MSA 的思路是让稀疏模式可学习——模型自己决定每个 query 关注哪些 key 块,再配合分层的注意力路由,在 1M token 下把注意力计算量压到接近线性,同时尽量保留关键的长程关联。官方技术报告里它的长上下文召回(needle-in-haystack 类测试)在 512K 以上仍然稳定。代价是实现复杂、对 KV cache 管理要求高,自部署时这部分最容易出性能问题。
M3 是真开源还是只是开放权重?能商用吗?
M3 走的是「开放权重(open-weight)」路线——发布模型权重供下载和自部署,但训练代码和数据集不完全公开。这和 Apache 2.0 的「开源」严格意义上有区别。商用许可以官方 HuggingFace 仓库的 LICENSE 为准,发布初期建议先看清楚月活/营收阈值条款(很多国产开源模型对超大体量商用有额外约定)。如果只是内部工具或中小规模产品,自部署一般没有障碍。
1M 上下文是不是意味着我可以不做 RAG 了?
不是。1M 上下文解决的是「单次任务需要看很多相关文件」的场景,比如让模型理解一个中型代码库再改 bug。但它不替代 RAG:一是成本,把 1M token 全塞进去每次请求都很贵,RAG 只取相关片段更划算;二是召回,超长上下文里模型对中段信息的利用率仍低于检索命中的片段。实践中最优解往往是 RAG 粗筛 + 长上下文精读的混合:检索把候选从百万行压到几万 token,再交给 M3 做深度推理。
M3 的 computer use(桌面操作)能力实际可用吗?
M3 原生支持把屏幕截图作为视觉输入并输出鼠标/键盘动作,这让它可以驱动 GUI 自动化。但和所有 computer-use 模型一样,发布初期的可靠性远未到无人值守级别——简单表单填写、固定流程点击能跑,复杂多步任务仍需要人在环校验和重试机制。建议把它当成「能看懂屏幕的 agent 后端」,前面套一层动作确认和超时回滚,而不是直接放权操作生产环境。
自部署 M3 需要什么硬件?买不起 H100 怎么办?
M3 是 MoE 架构,总参数大但激活参数小,显存主要被全部专家权重和 1M KV cache 吃掉。全精度自部署需要多卡 H100/H200 级别。预算有限的三条路:一是用量化版(INT4/FP8),显存可降到原来的 1/3 到 1/2,质量损失在编码任务上通常可接受;二是直接用 OpenRouter / 官方 API,省去运维;三是只在需要 1M 上下文时才走自部署,日常短上下文请求用更小的 M2.5 或量化模型分流。
// next.txt ›

Some outbound links in this post are affiliate links — see disclosure.