🔌 在 Claude Code 框架下完整释放 MiniMax-M3 能力的本地代理
补齐 6 大 Anthropic 协议短板,让第三方模型在 Claude Code 中跑得跟原生一样稳。
📖 完整文档已上线:https://mars535821089-ops.github.io/MiniMax-claude-proxy/latest/ (mkdocs + Material 主题 + 中文搜索)
Claude Code 客户端默认是为 Anthropic Claude 设计的,依赖一批 Anthropic 独家的协议特性。 MiniMax-M3 通过"Anthropic 兼容"接口接进来时,这批特性多数不工作,导致: 工具调用失败、PDF 看不到、长任务被切断、subagent 出错报告。
本项目是一个本地代理,嵌在 Claude Code 和 MiniMax-M3 之间,把这些 Anthropic 特性 全部在本地重新实现或绕过掉,对客户端保持完全透明。
| # | Anthropic 独有能力 | 没代理时的影响 | 本代理怎么做 |
|---|---|---|---|
| ① | Prompt Caching (cache_control) |
长会话烧 token、Skill 反复重传 | SQLite 持久化前缀缓存 + cache_control 剥离 + 响应级 KV 缓存 + usage 占位回填 |
| ② | Extended Thinking | Plan 模式 / 深度推理失效 | system 注入 <thinking> 引导 + 流式标签拆分回填为 thinking block |
| ③ | 复杂 tool_use schema | TodoWrite/Edit 工具参数出错 | 递归展开 $ref、拍平 oneOf/anyOf、响应后还原嵌套 |
| ④ | 多模态 | 图/PDF 看不到 | 图片自动缩放、PDF→文本+关键页转图、URL→base64 拉取 |
| ⑤ | 长输出 SSE 稳定性 | 长任务被代理切断 | 15s 心跳 ping + tool_use 整块缓冲 + cache usage 占位注入 + event_id 续传 |
| ⑥ | Server-side Tools (web_search/code_execution/bash) | 工具不可用 | 本地实现 DuckDuckGo 搜索 + subprocess 沙箱 + 拦截 round-2 回灌答案 |
flowchart LR
CC["<b>Claude Code</b><br/>Anthropic SDK"]
Proxy["<b>MiniMax-Claude-Proxy</b>"]
Upstream["<b>MiniMax-M3</b><br/>/anthropic API"]
DB[("SQLite<br/>cache.db")]
CC -- "POST /v1/messages<br/>(SSE stream)" --> Proxy
subgraph PRE["前置 pipeline"]
direction TB
P1["model_mapping<br/>(claude-* → MiniMax-M3)"]
P2["cache_control_strip"]
P3["thinking.preprocess<br/>(注入 system)"]
P4["schema.preprocess<br/>(拍平 $ref/oneOf)"]
P5["ssr_tools.preprocess<br/>(翻译为普通工具)"]
P6["multimodal.preprocess<br/>(图片/PDF)"]
P7["cache.touch_prefix<br/>(注入 usage 占位)"]
P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7
end
subgraph POST["后置 pipeline"]
direction TB
Q1["thinking.stream_transformer<br/>(拆标签)"]
Q2["sse.wrap<br/>(心跳+tool_use 缓冲+占位)"]
Q3["schema.postprocess<br/>(嵌套还原)"]
Q4["ssr_tools.execute<br/>(本地工具+回灌)"]
Q1 --> Q2 --> Q3 --> Q4
end
Proxy -- "请求" --> PRE
PRE -- "清洗后 payload" --> Upstream
Upstream -- "SSE/JSON 响应" --> POST
POST -- "客户端透明<br/>(cache_control/thinking/schema 都还原)" --> CC
PRE -.读/写.-> DB
POST -.读/写.-> DB
classDef upstream fill:#fef3c7,stroke:#d97706,color:#000
classDef proxy fill:#dbeafe,stroke:#1d4ed8,color:#000
classDef store fill:#f3e8ff,stroke:#7c3aed,color:#000
class Upstream upstream
class Proxy proxy
class DB store
flowchart LR
subgraph Front["📥 请求进入"]
A1["① 缓存命中?<br/>查 SQLite prefix"]
A2["② thinking 标签<br/>注入 system"]
A3["③ schema 拍平<br/>oneOf/anyOf → flat"]
A4["④ 多模态预处理<br/>图片缩放/PDF 拆页"]
A5["⑤ 模型重映射<br/>claude-* → MiniMax-M3"]
A6["⑥ SSR 工具翻译<br/>web_search 改普通 tool"]
end
subgraph Back["📤 响应回传"]
B1["① 用量占位回填<br/>cache_*/read tokens"]
B2["② thinking 块拆分<br/>标签 → thinking block"]
B3["③ 嵌套还原<br/>flat → 原始 oneOf 结构"]
B4["④ 媒体直出<br/>(已是 base64)"]
B5["⑤ 模型 ID 一致"]
B6["⑥ SSR 工具执行<br/>本地实现 + round-2 回灌"]
end
Front --> Up["🚀 上游<br/>MiniMax-M3"] --> Back
| 场景 | 首次请求 | 二次请求(命中) | 提速 |
|---|---|---|---|
| 简单中文问答 | ~2.17s | 0.01s | 🚀 217× |
| Prompt Caching 同一会话 | 2.10s | 0.01s | 210× |
| 复杂 tool_use schema | 1.85s | 0.01s | 185× |
数据来自 MILESTONES.md 真上游回归测试,2026-06-12。
tests/test_basic.py::test_strip_cache_control_recursive PASSED [ 4%]
tests/test_basic.py::test_thinking_inject_system PASSED [ 9%]
tests/test_basic.py::test_thinking_split_text_block PASSED [ 14%]
tests/test_basic.py::test_schema_flatten_oneof PASSED [ 19%]
tests/test_basic.py::test_schema_reconcile_string_to_object PASSED [ 23%]
tests/test_basic.py::test_ssr_tools_translate_web_search PASSED [ 28%]
tests/test_basic.py::test_encode_sse_basic PASSED [ 33%]
tests/test_basic.py::test_sse_stabilizer_buffers_tool_use PASSED [ 38%]
tests/test_e2e.py::test_e2e_health PASSED [ 42%]
tests/test_e2e.py::test_e2e_count_tokens PASSED [ 47%]
tests/test_e2e.py::test_e2e_basic_non_stream PASSED [ 52%]
tests/test_e2e.py::test_e2e_cache_control_stripped PASSED [ 57%]
tests/test_e2e.py::test_e2e_thinking_injected PASSED [ 61%]
tests/test_e2e.py::test_e2e_schema_oneof_flattened PASSED [ 66%]
tests/test_e2e.py::test_e2e_ssr_tool_translated PASSED [ 71%]
tests/test_e2e.py::test_e2e_cache_hit_second_call PASSED [ 76%]
tests/test_e2e.py::test_e2e_cache_hit_with_claude_model_mapping PASSED [ 80%]
tests/test_e2e.py::test_e2e_streaming_basic PASSED [ 85%]
tests/test_e2e.py::test_e2e_streaming_tool_use_buffered PASSED [ 90%]
tests/test_e2e.py::test_e2e_ssr_tool_round2_executes PASSED [ 95%]
tests/test_e2e.py::test_e2e_usage_cache_placeholder PASSED [100%]
======================= 21 passed, 2 warnings in 13.92s ========================
- Python 3.10+(推荐 3.12)
- MiniMax-M3 API Key(申请地址)
- 可选:
git用于克隆,curl用于测试
git clone https://github.com/Mars535821089-ops/MiniMax-claude-proxy.git
cd MiniMax-claude-proxy
bash scripts/install.shinstall.sh 会做:
- 创建
.venv虚拟环境 - 安装
requirements.txt全部依赖 - 拷贝
config.yaml.example→config.yaml - 创建
~/.MiniMax-claude-proxy/launch.sh启动器
编辑 config.yaml:
upstream:
base_url: "https://api.minimaxi.com/anthropic"
api_key: "sk-cp-填入您的真实key"
model_id: "MiniMax-M3"🛡️
proxy启动时强制校验 API Key:必须是 ASCII,且不能是占位文本。
bash scripts/start.sh
# → INFO MiniMax-claude-proxy v0.1.0 listening on 127.0.0.1:8787临时(关终端就失效):
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787
export ANTHROPIC_API_KEY=any-non-empty
export ANTHROPIC_MODEL=MiniMax-M3
claude永久(写入 ~/.zshrc 或 ~/.bashrc):
echo 'export ANTHROPIC_BASE_URL=http://127.0.0.1:8787' >> ~/.zshrc
echo 'export ANTHROPIC_API_KEY=any-non-empty' >> ~/.zshrc
echo 'export ANTHROPIC_MODEL=MiniMax-M3' >> ~/.zshrc
source ~/.zshrc启动 claude,所有请求会经过代理,6 大块功能自动激活。
# 健康检查
curl http://127.0.0.1:8787/v1/health
# 发个简单消息
curl -X POST http://127.0.0.1:8787/v1/messages \
-H "x-api-key: any" -H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"MiniMax-M3","max_tokens":100,
"messages":[{"role":"user","content":"你好"}]}'config.yaml 全部配置项有中文注释。常用调优:
| 想做的事 | 怎么改 |
|---|---|
| 缓存命中更激进 | cache.strategy: prefix + 调大 default_ttl |
| 关掉 thinking 引导(节省 token) | thinking.enabled: false |
| 换搜索后端为 Serper | server_side_tools.web_search.backend: serper + export SERPER_API_KEY=... |
| 代码执行更宽松 | server_side_tools.code_execution.timeout: 60 |
| PDF 只抽文本不转图 | multimodal.pdf.strategy: text |
| SSE 心跳更频繁 | server.sse_ping_interval: 5 |
| 把 claude-opus-4-6 映射到不同 MiniMax 模型 | 编辑 model_mapping |
环境变量覆盖(无需改配置文件):
| 变量 | 作用 |
|---|---|
MINIMAX_API_KEY |
覆盖 upstream.api_key |
MINIMAX_BASE_URL |
覆盖 upstream.base_url |
MINIMAX_PROXY_HOST |
覆盖 server.host |
MINIMAX_PROXY_PORT |
覆盖 server.port |
MINIMAX_PROXY_CONFIG |
自定义 yaml 路径 |
SERPER_API_KEY |
web_search 选 serper 后端时需要 |
| 路径 | 方法 | 说明 |
|---|---|---|
/ |
GET | 服务信息 |
/v1/health |
GET | 详细健康检查 |
/v1/messages |
POST | Anthropic Messages API 兼容主端点(支持流式 + 非流式) |
/v1/messages/count_tokens |
POST | token 估算(避免 Claude Code 404) |
source .venv/bin/activate
pip install pytest pytest-asyncio
pytest tests/ -v应输出 21 passed(8 单元 + 13 E2E)。
bash scripts/dev.sh# 单元
pytest tests/test_basic.py -v
# E2E(用 mock 上游,无需真 API Key)
pytest tests/test_e2e.py -v# 1. 填好 config.yaml
# 2. 启动
bash scripts/start.sh
# 3. 发请求
curl -X POST http://127.0.0.1:8787/v1/messages \
-H "x-api-key: any" -H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"MiniMax-M3","max_tokens":100,
"messages":[{"role":"user","content":"用一句话介绍 Python"}]}'请看 CONTRIBUTING.md。
| 场景 | 推荐 |
|---|---|
| 个人 macOS + 临时用 | nohup bash scripts/start.sh & |
| 个人 macOS + 每天用 | launchd (见 Wiki) |
| 多机 / 团队 | Docker (见 Dockerfile) |
| Linux 服务器 | systemd |
详细的 launchd / Docker / systemd 配置见 docs/deploy.md。
| 症状 | 排查 |
|---|---|
启动报 upstream.api_key 含非 ASCII 字符 |
把 config.yaml 的 key 换成真 ASCII key(以 sk-cp- 开头) |
| Claude Code 报 401 | 检查 ANTHROPIC_API_KEY 是否非空(仅作占位,代理不校验) |
代理日志 upstream 401 |
检查 config.yaml 的 upstream.api_key |
| 长任务卡住 | 把 server.sse_ping_interval 调小(默认 15s) |
| tool_use 参数错乱 | 把 schema.flatten_oneof: false 试试 |
| PDF 加载失败 | pip install pymupdf 验证;或改 multimodal.pdf.strategy: text |
| 缓存不命中 | 检查 sqlite:sqlite3 ~/.MiniMax-claude-proxy/cache.db 查行数 |
| 端口被占 | lsof -i :8787 找进程;改 server.port |
在 MacBook M1 + 本地 127.0.0.1 测试(真上游回归,非 mock):
xychart-beta
title "二次请求命中缓存耗时(毫秒)"
x-axis ["首次", "二次命中", "schema 命中", "tool_use 命中"]
y-axis "耗时 (ms)" 0 --> 2200
bar [2170, 10, 10, 10]
| 场景 | 首次 | 二次(命中缓存) | 提速 |
|---|---|---|---|
| 简单中文问答 | ~2.17s | 0.01s | 217× |
| 流式输出 | 取决于上游 | 流式常驻 1 个心跳 ping | — |
| 100 KB 上传 | ~3.5s | 取决于上游 | — |
| Prompt Caching 同一会话 | 2.10s | 0.01s | 210× |
| 复杂 tool_use schema | 1.85s | 0.01s | 185× |
提示:本代理不会让模型变快,它只让协议层不拖后腿。
欢迎 PR / Issue / Discussion!请看 CONTRIBUTING.md。
特别欢迎:
- 🐛 Good first issues
- 📝 翻译改进
- 🌐 新增 web_search / code_execution 后端
本项目不收集任何用户数据。所有流量都走您的本地进程和您配置的上游 API。
- 日志仅记录在本地 stdout(不发送任何地方)
- SQLite 缓存文件位于
~/.MiniMax-claude-proxy/cache.db(您自己控制) - API Key 绝不会被代理转发到 MiniMax 之外的任何地方
详见 SECURITY.md。
如果这个项目对您有帮助,欢迎给个 ⭐ 鼓励一下!
MIT © 2026 The MiniMax-Claude-Proxy Authors
- Anthropic - Claude Code 客户端 + Messages API 协议
- MiniMax - MiniMax-M3 模型
- FastAPI / httpx / PyMuPDF / DuckDuckGo 等开源项目
Made with ❤️ by the open-source community


