跳到主要内容
Router One

用一个 .qwen/.env 文件或一条 modelProviders 条目把 Qwen Code 接到 Router One

Qwen Code 是 Qwen 团队开源的终端编程 agent:读写文件、执行 shell 命令、循环调用工具;它最初基于 Gemini CLI,从 v0.1 起独立开发。它的 openai auth type 通过官方 OpenAI Node.js SDK 发送 Chat Completions 请求,指向 Router One 后就能用一把 Key 调用目录里在 /v1/chat/completions 上提供服务的所有聊天模型——GPT、Claude、Gemini、Grok 和 DeepSeek 系列——每一轮模型调用在 Dashboard → Logs 都有成本和延迟 Trace,而 agent 循环、工具执行、审批和会话仍留在 Qwen Code 本地。网关在中国大陆可直连,无需 VPN。本指南讲三变量的 .qwen/.env 配置、把多个目录模型放进 /model 选择器的 modelProviders 条目、两者同时存在时哪个值生效,以及怎样给一次会话定预算。

安装 Qwen Code 并单独建一把 Key

用 npm 安装需要 Node.js 22 或更新版本;README 还提供 Linux/macOS/Windows 的独立安装脚本和 Homebrew 包。安装后在项目目录里启动 qwen:首次运行会打开 /auth 菜单,其中 Custom Provider 选项面向 OpenAI 兼容端点,但本指南的两个文件不经过菜单也能完成同样的配置;随时可以用 /doctor 查看认证和环境检查。动手之前,先为 Qwen Code 单独创建一把设了 maxSpend 的 Router One Key:agent 会话每一轮模型调用、每次工具结果回传都是一次请求,这个上限就是硬性止损。Key 只写进下面的 .qwen/.env,不写进 settings.json。

terminal
npm install -g @qwen-code/qwen-code@latest
cd /path/to/your-project
qwen

把 Qwen Code 配置到 Router One base URL

在项目根目录创建 .qwen/.env,写入下面三个变量;这是 Qwen Code 文档推荐存放项目级密钥的文件,要排除在 git 之外。OPENAI_API_KEY 填 Router One Key——按身份验证文档的说法,只用环境变量时,正是导出 OPENAI_API_KEY 这一步选中了 OpenAI 兼容认证,provider 专属的变量名不会。OPENAI_BASE_URL 填带 /v1 的 https://api.router.one/v1:openai auth type 用这个值构造官方 OpenAI Node.js SDK 客户端,SDK 在它后面拼 /chat/completions,所以每一轮模型调用就是一个 POST /v1/chat/completions。OPENAI_MODEL(别名 QWEN_MODEL)填精确的目录模型 ID,它就是每次请求 model 字段的值;--model <id> 可以在单次会话里覆盖它。Qwen Code 只加载找到的第一个 .env 文件——从当前目录向上依次找 .qwen/.env 和 .env,找不到再回退到 ~/.qwen/.env 和 ~/.env——而且不会覆盖 shell 里已经导出的变量,所以 ~/.zshrc 里一个过期的 OPENAI_BASE_URL 会压过这个文件。这种形式创建的是文档所说的 Runtime Model:只有一个模型,选择器里没有条目;如果 qwen 仍然弹出 /auth 菜单,按下一节加上 security.auth.selectedType。启动 qwen,运行 /doctor,发一条简短提示,再到 Logs 里核对它的 Trace。文件内容如下,替换掉 Key 和模型 ID:

.qwen/.env
# <project>/.qwen/.env — the first .env file Qwen Code finds; keep it out of git
OPENAI_API_KEY=sk-your-router-one-key
OPENAI_BASE_URL=https://api.router.one/v1
OPENAI_MODEL=<exact-model-id-from-/models>

把 Router One 登记进 modelProviders,进入 /model 选择器

想在会话里切换多个目录模型,就把它们声明在 ~/.qwen/settings.json——这是文档推荐的用户级作用域,因为项目级设置会整体替换 modelProviders 对象而不是合并。键名 openai 就是 auth type,决定了传输方式;写错成 openai-custom 之类的键会被跳过并给出警告,它下面的模型不会出现在 /model 里。每个条目必须有 id,即作为 model 字段发送的精确目录 ID;name 只是选择器里的显示名;envKey 填保存 Key 的环境变量名——运行时读取 process.env[envKey],从不保存凭据本身——所以把 ROUTER_ONE_API_KEY=sk-your-router-one-key 写进 .qwen/.env 或 ~/.qwen/.env,或者直接 export;baseUrl 填同一个带 /v1 的地址,同一 auth type 内条目按 id 加 baseUrl 识别,重复的组合会被跳过。generationConfig 可选且封闭:选中 provider 模型时它的值整体生效,顶层 model.generationConfig 被忽略;源码里 timeout 默认 120000 毫秒、maxRetries 默认 3。security.auth.selectedType 设为 openai 后,qwen 启动不再弹 /auth 菜单,model.name 必须等于其中一个 id。运行中的会话会自动读取 modelProviders 的改动(重新打开 /model 即可);/model 和 /auth 会把 model.name 和 selectedType 写回定义了 modelProviders 的那个作用域。选中 provider 条目后,它的 baseUrl 和 envKey 优先于 --openai-base-url、OPENAI_BASE_URL 和 OPENAI_API_KEY。

~/.qwen/settings.json
{
  "modelProviders": {
    "openai": [
      {
        "id": "<exact-model-id-from-/models>",
        "name": "<在 /model 里显示的名字>",
        "envKey": "ROUTER_ONE_API_KEY",
        "baseUrl": "https://api.router.one/v1",
        "generationConfig": { "timeout": 120000, "maxRetries": 3 }
      },
      {
        "id": "<another-model-id-from-/models>",
        "envKey": "ROUTER_ONE_API_KEY",
        "baseUrl": "https://api.router.one/v1"
      }
    ]
  },
  "security": { "auth": { "selectedType": "openai" } },
  "model": { "name": "<exact-model-id-from-/models>" }
}

每个值填在哪里,怎么验证

Router One 需要的只有三个变量或一条 provider 条目;下表给出每个值,以及证明它已生效的检查方法。看实际请求最快的办法是 Qwen Code 自己的日志:打开 model.enableOpenAILogging(或加 --openai-logging 参数),每次请求和响应都会以 JSON 写到工作目录的 logs/openai 下。

Qwen Code 字段填什么怎么验证
.qwen/.env → OPENAI_BASE_URL,或 modelProviders.openai[].baseUrlhttps://api.router.one/v1404 not_found 且消息要求 base URL 以 /v1 结尾,说明少了 /v1;打开日志后,logs/openai 下的 JSON 会显示实际 URL
.qwen/.env → OPENAI_API_KEY,或 envKey 指定的那个变量为 Qwen Code 单独创建、设了 maxSpend 的 Router One Key第一次请求出现在 Logs 里这把 Key 名下;401 说明别的值生效了——shell export 压过 .env,而且只加载找到的第一个 .env 文件
.qwen/.env → OPENAI_MODEL(别名 QWEN_MODEL)、--model,或 modelProviders.openai[].id 与 model.name精确的目录模型 IDLogs 里每条 Trace 的模型与 /models 逐字一致;model.name 必须等于其中一个 id
modelProviders 的键名openai条目在 /model 里归在 openai 下;未知键名会被跳过并给出警告,它下面的模型不会出现
security.auth.selectedTypeopenaiqwen 启动不再弹 /auth 菜单;/doctor 显示认证检查;/model 和 /auth 会把这个字段写回
modelProviders → openai-responses(可选)只放模型详情页列出 POST /v1/responses 的 ID;这个传输会去掉 baseUrl 末尾的 /v1 再自行拼上 /v1/responses模型详情页列出 POST /v1/responses;其他 ID 会在调用任何模型之前收到 400 must be called via
model.enableOpenAILogging,或 --openai-logging排查期间设为 truelogs/openai 下的 JSON 文件显示每次请求的实际 URL、模型和请求体,可与 Logs 里的 Trace 对照

给一次 Qwen Code 会话定预算,并与 Logs 对账

在 Qwen Code 里一条提示很少只对应一次请求。每一轮模型调用是一次请求,agent 每回传一次工具结果又是一轮;model.maxToolCallsPerTurn 默认把一轮限制在 100 次工具调用,按自适应方式执行,硬性上限 1000;用 /model --fast、--compaction、--vision 指定的辅助模型也各自发请求。openai 传输还会把 timeout(默认 120000 毫秒)和 maxRetries(默认 3)传给 OpenAI SDK,每一次真正到达网关的尝试都是独立请求,有各自的 request_id 和费用。给 Qwen Code 单独一把设了 maxSpend 的 Key:会话触到上限会收到 HTTP 402 并停下,钱包和其他 Key 不受影响。客户端一侧,model.maxSessionTurns 和 model.sessionTokenLimit 限制对话长度;客户端取消的流会记为 HTTP 499 client_cancelled,只按已上报的用量计费。对账用 /stats model:它显示 Qwen Code 自己统计的分模型 token 用量和它自己的费用估算;Dashboard → Logs 才是逐请求的实际费用,带模型、tokens、成本、延迟、状态和 request_id;/stats export 可以把客户端这一侧导出为 CSV 或 JSON。Router One 只记录模型调用元数据;工具、审批、会话和子 agent 都在 Qwen Code 里运行。

Qwen Code 该填哪个模型 ID?

从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 Qwen Code 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key,并设置 maxSpend 消费上限。

Qwen Code 用的是哪种 API 协议?

OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。

在 trace 里验证 Qwen Code 的调用

先在 Qwen Code 发出一次简单文本请求,再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace:tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,先查客户端配置和网络,不能仅凭客户端报错认定是网关或上游故障。

常见问题

Qwen Code 能启动,但第一次请求报 404 或 401,实际用的是哪个 base URL 和哪把 Key?

生效的值按字段逐个决定,层级从高到低:/auth 里输入的值;选中的 modelProviders 条目(它的 baseUrl 和 env[envKey]);命令行参数 --openai-base-url 和 --openai-api-key;环境变量 OPENAI_BASE_URL 和 OPENAI_API_KEY——其中 shell export 压过 .env,而且只加载找到的第一个 .env 文件;最后才是已弃用的 security.auth.baseUrl 和 security.auth.apiKey。报 404 时先看 Logs 里的错误消息和 Qwen Code 自己 logs/openai JSON 里的请求 URL:openai auth type 在 base URL 后面拼 /chat/completions,所以 base URL 不带 /v1 就会得到 404 not_found,消息里要求 base URL 以 /v1 结尾;路径正确仍报 404,则指向模型 ID 或资源不存在,按 /models 核对 ID。报 401 说明到达网关的 Key 不是有效的 Router One Key:查 envKey 写的是哪个变量名——它填的是变量名而不是 Key 本身——再查是不是 shell export 或更早找到的 .env 文件提供了另一个值。打开 model.enableOpenAILogging 就能看到每次请求的实际 URL 和模型,报障时保留 Logs 里的 request_id。

Router One 的条目该用 openai 还是 openai-responses auth type?

用 openai。它通过 OpenAI Node.js SDK 发送 Chat Completions,而 /v1/chat/completions 服务目录里的所有聊天模型,所以同一种条目写法适用于任意当前 ID。openai-responses 是另一个 auth type,传输方式也不同:不经 SDK,直接用 HTTP/SSE 调用 /v1/responses,目的是通过 reasoning.encrypted_content 在多轮之间回放推理,用 reasoning.effort 而不是 extra_body.enable_thinking 控制推理强度。它的管线会去掉 baseUrl 末尾的 /v1 再自行拼上 /v1/responses,所以 https://api.router.one/v1 和 https://api.router.one 会解析成同一个地址。网关只对目前列出的 GPT 系列和 DeepSeek ID 原生提供 /v1/responses;其他 ID 发到这里会在调用任何模型之前收到 HTTP 400 invalid_request_error,消息为 model '<id>' must be called via …。两个 auth type 在 modelProviders 里保持为不同的键,只有模型详情页列出 POST /v1/responses 时才把它放到 openai-responses 下。

Qwen Code 能通过网关用哪些模型?

选用当前目录中同时支持 Qwen Code 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准;不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型,只证明模型发现成功,仍需验证实际调用。

能列出模型,但调用报 400 或 404,怎么办?

先记录实际请求路径和错误消息,再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配;404 可能是请求路径或资源不存在,不能直接判定模型下线。若错误提示 must be called via,按它指明的端点调整客户端 provider,或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。

中国大陆能直连吗?

能。网关在大陆可直连、无需 VPN,配置与全球环境完全一致。

报 401/402/403/429 怎么排查?

先到 Dashboard → Logs 核对请求及错误消息。401 查 Key 是否传入和有效;402 查钱包余额与 maxSpend;403 查 Key 权限和访问限制;429 查请求频率、token 限额及上游限流,按错误来源处理。保留 request_id,再按错误码速查页逐项排查。