> ## Documentation Index
> Fetch the complete documentation index at: https://agent.minimaxi.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent 的 BYOK 模型配置指南

> 指导 Agent 配置自定义模型，并在 macOS 和 Windows 上通过 curl 验证真实回复。

<div className="code-docs">
  通过应用界面添加模型，请参阅[自定义模型 / BYOK](/docs/code/account/byok)。

  本文供用户的 Agent 配置 MiniMax Code 桌面应用的自定义模型，并通过 curl 确认供应商能够返回真实回复。

  更新日期：2026-09-16。不同应用版本的配置格式可能有所差异；若实际配置与本文不一致，请先确认当前版本支持的配置方式。

  ## 1. 配置前先确认这些信息

  | 信息       | 如何确定                                                                           |
  | -------- | ------------------------------------------------------------------------------ |
  | 目标应用     | 确认用户当前使用的桌面应用及其数据目录，避免修改其他安装或账户的配置                                             |
  | 供应商接口地址  | 使用用户提供或供应商文档确认的 Base URL，保留必要的网关路径前缀                                           |
  | API 格式   | 明确选择 `anthropic-messages`、`openai-completions` 或 `openai-responses`；不能仅凭模型名称推断 |
  | API Key  | 使用用户指定的真实密钥或沿用已有密钥；不要把掩码当作密钥                                                   |
  | 模型 ID    | 使用该供应商接受的精确 ID；显示名不能代替模型 ID                                                    |
  | 上下文与输出上限 | 使用该模型、该接口实际支持的数值；未知时先确认，不把表单默认值当作模型能力                                          |
  | 推理与附件能力  | 只声明已确认支持的档位和输入类型；未知时不添加这些可选能力                                                  |
  | 配置目的     | 区分“新增可选模型”“切换当前会话”和“修改全局默认”；新增配置不自动授权后两项                                       |

  供应商支持某个模型，不代表它同时支持三种协议、所有推理档位或所有附件类型。缺少必要连接信息时先向用户补齐，不能猜一个值并宣称配置完成。

  ## 2. 找到正确的配置入口

  先从桌面应用提供的信息或用户确认的信息中确定当前应用的数据目录。无法确认时先向用户询问，不猜测配置文件位置。

  macOS 配置文件位于 `<dataDir>/config.yaml`，Windows 为 `<dataDir>\config.yaml`，其中 `<dataDir>` 为实际数据目录。YAML 字段与三种协议的 JSON 请求体在两个平台相同，命令行语法按下文分别使用。自定义安装或启动配置可能改变目录，不能一律假定为 `~/.minimax/config.yaml`。

  编辑前读取并备份原文件。只修改目标供应商的配置，保留其他字段、供应商和模型；避免同时在应用中保存设置，不要直接覆盖整份文件。

  沿用已有密钥时保留原值，不用掩码、空字符串或占位符替换。不要在对话、日志或分享的配置中展示真实密钥和敏感请求头。

  写入后重新读取文件，检查改动是否正确，并在桌面应用中确认模型可用。若应用没有加载新配置，应在用户允许的时机重启应用再验证，不能仅凭文件落盘判断已生效。

  ## 3. 配置文件的正确结构

  自定义供应商写在 `custom_provider` 下。不要写入托管模型的 `provider` 树，也不要把自定义模型写进 `minimax_api`。

  以下是一个完整供应商条目的模板，供合并到已有配置中使用。`example.invalid`、`REPLACE_WITH_REAL_API_KEY`、`REPLACE_WITH_EXACT_MODEL_ID` 都是占位符，不能原样保存为可用配置。`32000`、`2048` 仅用于展示数值字段格式，必须按供应商能力替换。

  ```yaml theme={null}
  custom_provider:
    my-gateway:
      name: "My Gateway"
      kind: custom
      enabled: true
      api: openai-completions
      options:
        baseURL: "https://example.invalid/v1"
        apiKey: "REPLACE_WITH_REAL_API_KEY"
      models:
        "REPLACE_WITH_EXACT_MODEL_ID":
          name: "My Model"
          enabled: true
          limit:
            context: 32000
            output: 2048
          modalities:
            input: [text]
            output: [text]
  ```

  字段规则：

  * `my-gateway` 是供应商配置键；新建时使用不冲突的简单键，后续改显示名只改 `name`。不要使用 `minimax`、`minimax_api`、`openai-codex`、`provider`、`custom_provider` 等保留名称。
  * `api` 位于供应商层，值必须是本指南列出的协议之一。不要用 `openai`、`anthropic` 等品牌名代替。
  * `baseURL` 的大小写固定，并位于 `options` 内；API Key 也位于 `options.apiKey`。
  * `models` 是以真实模型 ID 为键的字典，不是数组。模型 ID 可以包含 `/`，保留供应商给出的完整值。
  * `limit.context` 和 `limit.output` 是正整数 Token 数，不是 `128K`、`1M` 等字符串。上下文和最大输出是不同参数。
  * 不要因为模型支持推理，就自动写 `high`、`max` 等档位；也不要因为名字像多模态模型，就自动声明图片、视频或 PDF。
  * 需要工具调用时，先确认上游支持；文件字段为模型下的 `tool_call: true`，并用真实工具请求验证。声明字段不等于供应商已经实现能力。
  * YAML 字符串建议加引号。不要假定 `${API_KEY}` 会自动展开；`apiKey` 中需要填写实际密钥。

  ### 三种协议如何配置地址

  | `api`                | 推荐填写的 Base URL 形态                       | 连通性请求目标                    |
  | -------------------- | --------------------------------------- | -------------------------- |
  | `anthropic-messages` | `https://example.invalid`，或供应商指定的兼容接口前缀 | `<规范化后的 base>/v1/messages` |
  | `openai-completions` | `https://example.invalid/v1`            | `<base>/chat/completions`  |
  | `openai-responses`   | `https://example.invalid/v1`            | `<base>/responses`         |

  同一配置模板可用于三种协议，但必须同时替换 `api` 和相应地址。OpenAI 风格的 `/v1` 不会凭空补齐，供应商要求 `/v1` 时需要包含它。Messages 会规范化末尾的 `/v1`、`/messages` 或 `/v1/messages`；不要自己反复拼接这些后缀。网关已有的 `/proxy/anthropic` 等前缀不能随意删除。

  优先保存供应商文档提供的接口基地址，不使用带临时认证参数的完整生成 URL。连接测试后核对最终 Endpoint；HTTP 404 可能是路径错误，也可能是模型不存在，需结合清理后的错误判断。

  ### 自定义请求头

  确有需要时，添加到 `options.headers`：

  ```yaml theme={null}
  options:
    headers:
      X-Project-Id: "REPLACE_WITH_PROJECT_ID"
  ```

  这是对已有 `options` 的补充，不能替换掉其中的 `baseURL` 和 `apiKey`。请求头名称不区分大小写，禁止同时配置 `Authorization` 与 `authorization`。显式值会覆盖同名协议默认值，因此不要无理由手写 `Authorization`、`x-api-key` 或 `content-type`。

  ## 4. 需要思考档位或附件能力时再添加

  确认模型支持推理且供应商接受相应档位后，可在文件中的模型条目下增加：

  ```yaml theme={null}
  reasoning: true
  thinking:
    effortOptions: [low, medium, high]
  ```

  这只是字段结构示例，三个值并不适用于所有模型。`effortOptions` 保存可选集合；不要把当前会话选择写成配置中的 `thinking.effort`。普通自定义模型没有会话覆盖时取集合中间项，偶数取靠后一项。

  普通非关闭档位通常按协议发送原值：Messages 使用 `output_config.effort`，Completions 使用 `reasoning_effort`，Responses 使用 `reasoning.effort`。`off`、`none` 是关闭值，有专门映射，不能假设全部字符串原样透传。某些模型另有适配，不能通过更换供应商显示名改变协议。

  自定义 MiniMax-M3 如果确认支持二态思考，可配置 `effortOptions: ["off", "on"]`。注意 YAML 中给 `off`、`on` 加引号。运行时按以下方式发送：

  | 协议                     | `on`                       | `off`                    |
  | ---------------------- | -------------------------- | ------------------------ |
  | Messages / Completions | `thinking.type=adaptive`   | `thinking.type=disabled` |
  | Responses              | `reasoning.effort=minimal` | `reasoning.effort=none`  |

  附件能力写在模型的 `modalities.input`，保留 `text`，只追加已确认的 `image`、`pdf`、`video`、`audio`；输出仍使用 `[text]`。文本连接测试不会验证附件或工具调用，必须分别验证需要使用的能力。

  ## 5. 配置完成后组装 curl，确认模型真实返回

  保存后重新读取目标供应商配置，以**实际保存的值**组装一次生成请求，不使用另一个供应商、另一个模型或临时替换的密钥。不要只请求 `/models`：模型列表成功不能证明模型能够生成回复。

  ### 5.1 从配置提取请求参数

  | 请求内容         | 配置来源                                          |
  | ------------ | --------------------------------------------- |
  | 协议           | 供应商的 `api`                                    |
  | 请求地址         | `options.baseURL` 按第 3 节规则规范化后拼接生成 Endpoint   |
  | 密钥           | `options.apiKey`，必须为真实值，不能使用掩码                |
  | 自定义 Header   | `options.headers`；若模型条目也有 `headers`，同名项以模型层为准 |
  | 请求中的 `model` | `models` 下目标条目的真实键名，不使用显示名                    |
  | 输出上限         | 目标模型的 `limit.output`                          |
  | 思考参数         | 已配置的档位集合，按第 4 节转换成对应协议字段                      |

  先检查配置语法、供应商与模型的启用状态，确认其他模型没有被误删。随后构造与该配置一致的请求。不要为让测试通过而擅自缩小输出上限、删除自定义 Header 或换一个档位；确需修改时，应修正配置并用保存后的值重测。

  API Key 默认不含 `Bearer ` 前缀，由认证 Header 添加。默认请求头如下，自定义 Header 按名称大小写无关地覆盖它们；同名项最终只保留一份：

  | 协议                      | 默认请求头                                                                                   |
  | ----------------------- | --------------------------------------------------------------------------------------- |
  | Messages                | `Content-Type: application/json`、`x-api-key: <API Key>`、`anthropic-version: 2023-06-01` |
  | Completions / Responses | `Content-Type: application/json`、`Authorization: Bearer <API Key>`                      |

  ### 5.2 生成请求体

  下面三份是 JSON 模板，Agent 按保存的 `api` 只选一份。将 `REPLACE_WITH_EXACT_MODEL_ID` 替换为真实模型 ID，将示例 `2048` 替换为已保存的 `limit.output` 正整数。使用 JSON 序列化器生成文件，不把未转义的模型 ID 或其他字符串直接拼进 shell 命令。

  **Anthropic Messages**，地址为规范化后的 `<base>/v1/messages`：

  ```json theme={null}
  {
    "model": "REPLACE_WITH_EXACT_MODEL_ID",
    "max_tokens": 2048,
    "stream": false,
    "messages": [{"role": "user", "content": "请只回复 BYOK_OK"}]
  }
  ```

  **OpenAI Chat Completions**，地址为规范化后的 `<base>/chat/completions`：

  ```json theme={null}
  {
    "model": "REPLACE_WITH_EXACT_MODEL_ID",
    "max_tokens": 2048,
    "stream": false,
    "messages": [{"role": "user", "content": "请只回复 BYOK_OK"}]
  }
  ```

  **OpenAI Responses**，地址为规范化后的 `<base>/responses`：

  ```json theme={null}
  {
    "model": "REPLACE_WITH_EXACT_MODEL_ID",
    "max_output_tokens": 2048,
    "stream": false,
    "input": "请只回复 BYOK_OK"
  }
  ```

  这些基础模板未加入思考参数。若保存了 `effortOptions`，应为每个档位分别生成请求体并验证，按第 4 节添加普通档位字段或 M3 on/off 字段。没有档位时不凭空添加。某个档位失败后继续记录其他档位结果，但不能把整组配置报告为全部通过。

  ### 5.3 执行 curl

  两个平台都使用请求文件传递 JSON，避免命令行引号和中文编码差异。先准备以下内容：

  * 完整 Endpoint，以及按前文规则合并的请求头，每行 `名称: 值`，名称和值不得包含换行字符。
  * 按第 5.2 节填好的请求体，保存为 UTF-8 无 BOM 的 JSON。
  * 真实密钥只写入本次临时 Header 文件，不写进对话或可分享的命令。

  **macOS：使用终端的 sh / zsh。**

  先创建仅当前用户可读写的临时目录：

  ```sh theme={null}
  umask 077
  BYOK_CHECK_DIR="$(mktemp -d)"
  ```

  Agent 将合并后的完整请求头写入 `$BYOK_CHECK_DIR/headers.txt`（每行 `名称: 值`），将选定并填好的请求体写入 `$BYOK_CHECK_DIR/request.json`。真实密钥只进入受限的 Header 文件，不写进对话或可分享的命令。Header 名称和值不得包含换行字符。

  将 `BYOK_URL` 设置为从当前配置得到的完整 Endpoint，然后执行：

  ```sh theme={null}
  BYOK_HTTP_STATUS="$(curl --silent --show-error \
    --connect-timeout 10 \
    --max-time 90 \
    --request POST \
    --url "$BYOK_URL" \
    --header "@$BYOK_CHECK_DIR/headers.txt" \
    --data-binary "@$BYOK_CHECK_DIR/request.json" \
    --output "$BYOK_CHECK_DIR/response.json" \
    --write-out '%{http_code}')"
  BYOK_CURL_EXIT=$?
  printf 'curl_exit=%s http_status=%s\n' "$BYOK_CURL_EXIT" "$BYOK_HTTP_STATUS"
  ```

  **Windows：使用 Windows PowerShell 5.1 或 PowerShell 7，不使用 cmd。**

  先确认系统提供 `curl.exe`。以下命令明确调用该程序，避免 Windows PowerShell 的 `curl` 别名被解释成其他命令：

  ```powershell theme={null}
  $null = Get-Command curl.exe -ErrorAction Stop
  $BYOK_CHECK_DIR = Join-Path ([System.IO.Path]::GetTempPath()) ("byok-check-" + [guid]::NewGuid().ToString('N'))
  $null = New-Item -ItemType Directory -Path $BYOK_CHECK_DIR -ErrorAction Stop
  ```

  使用当前用户的临时目录，不使用共享目录。Agent 按实际配置设置 `$BYOK_URL`，将合并后的 Header 行放入字符串数组 `$ByokHeaderLines`，将第 5.2 节的请求体构造成 `$ByokBody` 对象。不要在输出中打印这两个变量。使用下列方式写文件，避免 PowerShell 5.1 的默认重定向编码和 UTF-8 BOM：

  ```powershell theme={null}
  $ByokUtf8 = [System.Text.UTF8Encoding]::new($false)
  $ByokHeaderPath = Join-Path $BYOK_CHECK_DIR 'headers.txt'
  $ByokRequestPath = Join-Path $BYOK_CHECK_DIR 'request.json'
  $ByokResponsePath = Join-Path $BYOK_CHECK_DIR 'response.json'
  $ByokRequestJson = ConvertTo-Json -InputObject $ByokBody -Depth 20 -Compress
  [System.IO.File]::WriteAllText($ByokHeaderPath, ($ByokHeaderLines -join "`r`n") + "`r`n", $ByokUtf8)
  [System.IO.File]::WriteAllText($ByokRequestPath, $ByokRequestJson, $ByokUtf8)
  ```

  用参数数组执行 curl，路径包含空格时也不需要手工拼接引号：

  ```powershell theme={null}
  $ByokCurlArgs = @(
    '--silent', '--show-error',
    '--connect-timeout', '10',
    '--max-time', '90',
    '--request', 'POST',
    '--url', $BYOK_URL,
    '--header', ('@' + $ByokHeaderPath),
    '--data-binary', ('@' + $ByokRequestPath),
    '--output', $ByokResponsePath,
    '--write-out', '%{http_code}'
  )
  $BYOK_HTTP_STATUS = & curl.exe @ByokCurlArgs
  $BYOK_CURL_EXIT = $LASTEXITCODE
  Write-Output ("curl_exit={0} http_status={1}" -f $BYOK_CURL_EXIT, $BYOK_HTTP_STATUS)
  ```

  `$LASTEXITCODE` 必须在 curl 后立即保存。不要用 PowerShell 的 `$?` 代替 curl 的数值退出码。

  读取响应时显式指定 UTF-8，再按第 5.4 节检查错误和助手正文：

  ```powershell theme={null}
  $ByokResponseText = [System.IO.File]::ReadAllText($ByokResponsePath, [System.Text.Encoding]::UTF8)
  $ByokResponse = ConvertFrom-Json -InputObject $ByokResponseText -ErrorAction Stop
  ```

  若 curl 未生成响应文件或 JSON 解析失败，保留对应错误，不按成功处理。读取原始错误时也须先脱敏再展示。

  不添加 `-k` 跳过证书校验，不开启 `-v` 输出认证头，也不自动跟随重定向到另一主机。保留错误响应体供本地分析，展示前清理其中可能包含的密钥、Header 值和认证信息。

  ### 5.4 如何判定通过

  必须同时满足以下条件，才能报告“该配置已收到真实模型回复”：

  1. `BYOK_CURL_EXIT=0`，HTTP 状态为 2xx，响应体可解析为 JSON。
  2. 没有上游 `error`，也没有 `base_resp.status_code` 非零等业务错误；返回 HTML、空对象或空正文均不算通过。
  3. 在对应协议的助手正文位置找到非空文本，不能只看到请求 ID、usage 或思考内容：

  | 协议          | 检查的模型正文                                                                                      |
  | ----------- | -------------------------------------------------------------------------------------------- |
  | Messages    | `content` 数组中 `type="text"` 项的 `text`                                                        |
  | Completions | `choices` 中 `message.content` 的文本；若为内容块则提取其文本块                                               |
  | Responses   | `output` 中 `type="message"`、`role="assistant"` 项的 `content`，提取 `type="output_text"` 的 `text` |

  期望回复包含 `BYOK_OK`。模型返回其他非空正文时，可以确认已收到回复，但应如实记录未按指定文案回答，不伪造成功输出。不要只查 Responses SDK 的 `output_text` 便利字段，原始 HTTP JSON 通常要从 `output` 数组提取。

  同时检查完成状态：Messages 的 `stop_reason=max_tokens`、Completions 的 `finish_reason=length`、Responses 的 `status=incomplete/failed` 或 `incomplete_details` 表示输出截断或未完成，应记录原因，不能报告完整验证通过。只有思考内容而没有助手正文时，排查输出预算、推理档位和协议适配。

  多模型、多档位配置应逐项记录结果，不能用一个模型或一个档位成功代表全部成功。超时、429、认证失败等保留原始错误归因；不要自动换托管模型兜底。

  ### 5.5 验证后向用户交付什么

  报告配置位置、供应商、模型 ID、协议与脱敏 Endpoint、测试档位、HTTP 状态及一小段实际回复；失败时给出清理后的错误和需要修正的配置字段。验证结束后删除本次临时文件，尤其是含真实密钥的 `headers.txt`。

  curl 成功证明这组地址、认证、模型和请求参数能够直接从供应商获得回复；仍需在桌面确认配置已加载。它不证明完整 Agent 对话、工具调用或附件能力都可用。只有实际执行了请求并读到正文才报告“已验证”；如果只生成了 curl，明确写“待执行”。

  保存本身不触发测试，测试缓存也不阻止选择模型，因此不能以“已保存”或“可选择”代替上述真实请求验证。

  ## 6. 常见错误及处理

  | 现象              | 优先检查                                                   |
  | --------------- | ------------------------------------------------------ |
  | 文件已保存，模型不出现     | 是否改错 dataDir；供应商和模型是否启用；是否写在 custom\_provider；运行时是否已加载 |
  | 401 / 403       | 密钥是否属于该供应商、是否是掩码或未展开的占位符；自定义 Header 是否覆盖认证；账户是否有权限     |
  | 404             | API 格式与 Base URL 是否匹配；是否遗漏 /v1 或丢失网关前缀；模型 ID 是否存在      |
  | 推理档位报错          | effort 是否在最终模型的支持集合内；是否误带旧模型档位；是否误把 M3 on/off 当普通档位    |
  | 输出 Token 或上下文超限 | 是否把 256K / 128K 的表单默认值当作实际能力；context/output 是否填反       |
  | 文本成功，附件或工具失败    | 能力声明是否真实；协议和供应商是否支持该输入或工具格式                            |
  | 测试失败但仍能选择       | 这是测试状态仅供诊断的行为；处理上游错误，不伪造成功记录                           |

  BYOK 请求失败时，应保留所选供应商并返回错误。不要静默改成 Token Plan、托管模型或另一个供应商。也不要通过禁用校验、扩大窗口或改写未知字段掩盖上游错误。
</div>
