Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧩 MiMo Proxy 操作说明

Node.js License

MiMo Proxy 是一个面向 MiMoCode 的轻量 OpenAI 兼容代理。推荐使用 Responses API;对于只支持 Chat Completions 的中转站,代理也能修补流中不完整的 tool_calls,作为兼容回退。

本文档按实际操作顺序说明如何安装、替换不同中转站、配置 MiMoCode、验证连接和排查错误。

📌 适用场景

当中转站返回下面这种分阶段工具调用时:

{
  "index": 0,
  "type": "function"
}

MiMoCode 可能因为当前 SSE 帧缺少 function 对象而校验失败:

choices[0].delta.tool_calls[0].function
Invalid input: expected object, received undefined

代理会把当前片段修补为:

{
  "index": 0,
  "type": "function",
  "function": {}
}

代理不会猜测函数名或参数,后续 SSE 帧仍可继续提供 namearguments

🗺️ 工作方式

MiMoCode
   |
   | OpenAI-compatible request + API Key
   v
MiMo Proxy  http://127.0.0.1:3000
   |
   | Chat SSE 修补 / Responses 原样透传
   v
任意兼容中转站

本地支持以下请求路径:

MiMoCode 请求路径 转发目标 处理方式
/chat/completions UPSTREAM_URL 修补 Chat SSE
/v1/chat/completions UPSTREAM_URL 修补 Chat SSE
/responses RESPONSES_UPSTREAM_URL 原样透传
/v1/responses RESPONSES_UPSTREAM_URL 原样透传

✅ 中转站兼容性检查

替换中转站前,先从其文档或控制台确认以下信息:

检查项 要求 示例
Responses API 推荐,优先确认并提供完整接口地址 https://relay.example.com/v1/responses
Chat Completions 可选,仅在中转站不支持 Responses 时作为回退 https://relay.example.com/v1/chat/completions
鉴权方式 支持 Authorization: Bearer <API_KEY> 大多数 OpenAI 兼容站点均支持
流式格式 使用 text/event-streamdata: 事件 Chat 流式响应
模型名称 必须与中转站实际模型 ID 完全一致 gpt-5.6-sol

💡 网页上的“API 地址”有时只是域名,有时已经包含 /v1。本项目需要的是完整接口 URL,不要只凭界面名称猜路径。

⚡ 快速开始

1. 环境要求

  • Node.js 18 或更高版本
  • pnpm 10 或兼容版本
  • 一个 OpenAI 兼容中转站及其 API Key

检查版本:

node --version
pnpm --version

2. 下载并安装

git clone git@github.com:maycode0-0/mimo-proxy.git
cd mimo-proxy
pnpm install --frozen-lockfile

3. 配置中转站

Windows PowerShell

$env:UPSTREAM_URL = 'https://relay.example.com/v1/chat/completions'
$env:RESPONSES_UPSTREAM_URL = 'https://relay.example.com/v1/responses'
$env:HOST = '127.0.0.1'
$env:PORT = '3000'

Linux / macOS

export UPSTREAM_URL='https://relay.example.com/v1/chat/completions'
export RESPONSES_UPSTREAM_URL='https://relay.example.com/v1/responses'
export HOST='127.0.0.1'
export PORT='3000'

⚠️ 项目没有加载 dotenv。直接创建 .env 文件不会自动生效,请在启动进程的 Shell、进程管理器或系统服务中设置环境变量。

4. 启动代理

pnpm start

启动成功:

Proxy listening on 127.0.0.1:3000

如果没有设置 HOST,默认输出为:

Proxy listening on 0.0.0.0:3000

5. 验证本地服务

curl.exe -i http://127.0.0.1:3000/v1/responses

预期结果为 405 Method Not Allowed,并包含:

Allow: POST

这表示本地代理已经运行。它不是上游调用失败,测试使用了 GET,而模型接口只接受 POST。

🔄 替换不同中转站

代码中只有 RouterTeam 是默认值,运行时可以通过环境变量切换到任何兼容站点,无需修改 proxy.js

场景 A:中转站同时支持 Chat 和 Responses(推荐)

这是最完整的配置:

$env:UPSTREAM_URL = 'https://relay.example.com/v1/chat/completions'
$env:RESPONSES_UPSTREAM_URL = 'https://relay.example.com/v1/responses'
pnpm start

建议始终显式填写两个地址,并在 MiMoCode 中优先使用 Responses API。即使两个接口在同一域名,也能避免中转站使用特殊路径前缀时推导错误。

场景 B:中转站只支持 Chat Completions(兼容回退)

只配置 Chat 地址:

$env:UPSTREAM_URL = 'https://relay.example.com/v1/chat/completions'
Remove-Item Env:RESPONSES_UPSTREAM_URL -ErrorAction SilentlyContinue
pnpm start

同时在 MiMoCode provider 中指定 OpenAI Compatible SDK:

{
  "provider": {
    "openai-any-router": {
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "http://127.0.0.1:3000",
        "apiKey": "<YOUR_API_KEY>"
      },
      "models": {
        "your-model-id": {
          "name": "Your Model"
        }
      }
    }
  }
}

这样 MiMoCode 会走 Chat Completions,不会请求中转站未实现的 Responses API。

场景 C:接口带自定义路径前缀

有些站点的接口不是标准根路径,例如:

https://relay.example.com/openai/v1/chat/completions
https://relay.example.com/openai/v1/responses

必须分别配置完整地址:

$env:UPSTREAM_URL = 'https://relay.example.com/openai/v1/chat/completions'
$env:RESPONSES_UPSTREAM_URL = 'https://relay.example.com/openai/v1/responses'
pnpm start

如果省略 RESPONSES_UPSTREAM_URL,代理会根据 Chat 地址的域名推导标准路径 /v1/responses。推导结果不会保留 /openai 前缀,因此自定义路径必须显式配置。

场景 D:RouterTeam 多入口切换

RouterTeam 提供多个入口时,可以任选网络质量较好的一个,并确保两个接口使用同一入口。

# CF 代理线路
$env:UPSTREAM_URL = 'https://ai.router.team/v1/chat/completions'
$env:RESPONSES_UPSTREAM_URL = 'https://ai.router.team/v1/responses'

# 或中国大陆优化线路
# $env:UPSTREAM_URL = 'https://cn2.router.team/v1/chat/completions'
# $env:RESPONSES_UPSTREAM_URL = 'https://cn2.router.team/v1/responses'

# 或美国直连线路
# $env:UPSTREAM_URL = 'https://api.router.team/v1/chat/completions'
# $env:RESPONSES_UPSTREAM_URL = 'https://api.router.team/v1/responses'

pnpm start

⚙️ MiMoCode 推荐配置

编辑配置文件:

~/.config/mimocode/mimocode.jsonc

推荐使用 OpenAI provider,通过 Responses API 调用中转站:

{
  "$schema": "https://mimo.xiaomi.com/mimocode/config.json",
  "model": "openai-any-router/your-model-id",
  "provider": {
    "openai-any-router": {
      "npm": "@ai-sdk/openai",
      "options": {
        "baseURL": "http://127.0.0.1:3000",
        "apiKey": "<YOUR_API_KEY>",
        "timeout": 90000
      },
      "models": {
        "your-model-id": {
          "name": "Your Model",
          "tool_call": true
        }
      }
    }
  }
}

替换以下占位值:

占位值 替换内容
<YOUR_API_KEY> 中转站生成的 API Key
your-model-id 中转站提供的真实模型 ID
Your Model MiMoCode 界面显示名称,可自定义

@ai-sdk/openai 默认使用 Responses API。仅当中转站没有实现 Responses API 时,才改用场景 B 中的 @ai-sdk/openai-compatible,回退到 Chat Completions。

MiMoCode 会把 API Key 放入请求的 Authorization 头,代理只转发该请求头,不需要在代理项目中保存 Key。

修改配置后,建议退出并重新启动 MiMoCode,避免旧 provider 配置仍在内存中。

🎛️ 环境变量参考

变量 默认值 说明
UPSTREAM_URL https://cn2.router.team/v1/chat/completions 完整 Chat Completions 接口 URL
RESPONSES_UPSTREAM_URL 根据 Chat 地址推导同域 /v1/responses 完整 Responses API 接口 URL
UPSTREAM_TIMEOUT_MS 90000 上游请求超时,单位毫秒
REQUEST_BODY_LIMIT 10mb 请求体大小上限
HOST 0.0.0.0 本地监听地址
PORT 3000 本地监听端口

环境变量只在当前 Shell 会话和它启动的子进程中生效。关闭终端后需要重新设置,或交给 PM2、systemd、Docker 等进程管理方式持久化。

🧭 推荐操作流程

  1. 优先确认中转站支持 Responses API,并复制 Responses 的完整接口地址。
  2. 确认需要使用的模型 ID,不要使用仅用于显示的别名。
  3. 在启动代理的 Shell 中设置 RESPONSES_UPSTREAM_URL;如需兼容回退,再设置 UPSTREAM_URL
  4. 启动代理并用 GET 请求确认本地端口返回 405。
  5. 在 MiMoCode 中把 baseURL 指向本地代理。
  6. 新建 MiMoCode 会话,先发送简单文本验证流式输出。
  7. 再执行一次会触发工具调用的任务,确认 Responses 工具调用正常。

🔍 常见问题

Not Found

按顺序检查:

  1. MiMoCode 的 baseURL 是否为 http://127.0.0.1:3000
  2. 是否运行了最新代理,而不是仍占用端口的旧进程。
  3. RESPONSES_UPSTREAM_URL 是否包含完整的 /responses 路径。
  4. 中转站是否真的支持 /responses。不支持时才使用 Chat Compatible provider。
  5. 中转站是否要求额外路径前缀,并显式设置了两个上游地址。

401 Unauthorizedinvalid_api_key

  • 检查 API Key 是否属于当前中转站。
  • 检查 Key 是否启用、过期或被限制分组。
  • 确认 MiMoCode provider 的 apiKey 已更新,并重启 MiMoCode。

model_not_found 或模型不可用

  • 使用中转站 API 文档中的真实模型 ID。
  • 检查 Key 所属分组是否有该模型权限。
  • 模型显示名称可以自定义,但配置对象的 key 必须与请求模型一致。

Type validation failed,缺少 tool_calls[].function

  • 确认 MiMoCode 请求经过本地代理,而不是直接访问中转站。
  • 确认已重启代理并加载最新代码。
  • 查看返回内容是否为 Chat Completions SSE,Responses API 不使用这套修补格式。

null is not an object (evaluating error.message)

旧版代理可能向成功事件加入了 error: null。最新版本会删除空错误哨兵,同时保留真实错误对象。

EADDRINUSE: address already in use

端口已被旧代理或其他程序占用。更换端口:

$env:PORT = '3001'
pnpm start

同时把 MiMoCode 的 baseURL 改为:

http://127.0.0.1:3001

504 Upstream request timed out

  • 切换中转站线路。
  • 增大 UPSTREAM_TIMEOUT_MS
  • 检查中转站服务状态和模型排队情况。
$env:UPSTREAM_TIMEOUT_MS = '180000'
pnpm start

🔐 安全提示

  • 仅本机使用时设置 HOST=127.0.0.1
  • 默认 HOST=0.0.0.0 会允许局域网设备访问。
  • 不要把代理直接暴露到公网,它没有身份验证、限流或 TLS 终止。
  • 不要把真实 API Key 写入仓库、Issue、日志或截图。
  • 代理只转发必要请求头,不主动记录 Authorization 内容。

🧪 测试与开发

安装依赖:

pnpm install --frozen-lockfile

运行语法检查和完整回归测试:

pnpm check

测试覆盖:

  • 非流式错误状态、响应头和正文透传
  • error 清理与真实错误保留
  • 超过 Express 默认 100KB 的请求体
  • 分片 CRLF SSE 与最后一个未闭合事件
  • Chat 和 Responses 的路径别名
  • 无正文的 204 响应
  • 非 POST 方法拒绝
  • 上游断开后的结构化 502

🧠 修补原理

MiMoCode 使用联合类型校验成功响应与错误响应。当成功流中的 tool_call.function 暂时缺失时,成功分支校验失败;错误分支也会因为没有顶层 error 而失败。

这不表示成功响应需要添加 error: null。正确处理方式是:

  • 缺少 tool_call.function 时补 {}
  • errornullundefined 时删除该字段。
  • error 为真实对象时保持不变。

一个空对象解决类型问题,一个空错误对象则会制造新问题。区别不大,也就差一次崩溃。🙂

📁 项目结构

.
├── proxy.js             # Express 代理与 SSE 修补逻辑
├── test/
│   └── proxy.test.js    # 本地伪上游回归测试
├── package.json
├── pnpm-lock.yaml
├── LICENSE
└── README.md

📄 License

本项目基于 MIT License 开源。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages