Zed 接 OpenAI 兼容端点:settings.json 该怎么写

2026-08-07

在 Zed 里接一个 OpenAI 兼容端点,真正卡住人的通常不是 URL,而是模型不会自己冒出来——截至 2026-08-07 的官方文档,模型要你一条条手写进 available_models 数组里。 这一条如果没意识到,你会以为配置没生效、以为密钥错了,实际上只是那个数组是空的。

这篇只讲 Zed 这一家的配置结构,讲到逐个字段。想先横向看各家编辑器接自定义模型的差别,去看 编辑器接入自定义 API 的通用做法;想先弄明白”OpenAI 兼容端点”这个词到底指什么、请求长什么样,去看 OpenAI 兼容端点是什么;至于 Zed 的学生免费资格怎么回事,那是 Zed 学生免费 那篇的事,和本篇的自带端点配置是两码事。

一、先把两件事分开:能不能连上,和连上以后能不能干活

OpenAI 兼容端点,指的是一个第三方服务把自己的接口做成和 OpenAI 那套 HTTP 接口同样的形状——同样的路径、同样的请求体字段、同样的响应结构。客户端因此不用为每家单独写适配,换个 base URL 和密钥就能连过去。

但”连得上”只是第一层。第二层是这个模型有没有你要的能力,比如原生工具调用(function calling)——模型能按结构化格式说出”我要调用某个工具、参数是这些”,而不是靠正文里夹一段自定义标记让客户端去解析。编辑器里的 Agent 功能几乎都建立在这一层上。

这两件事在配置文件里体现为不同的字段,混在一起看就容易误判。下面按这个顺序拆。

二、language_models 那段结构,逐层拆开

Zed 官方文档给出的 settings.json 示例是这样的(以下代码块原样引用官方文档示例,截至 2026-08-07):

{
  "language_models": {
    "openai_compatible": {
      "my-provider": {
        "api_url": "https://example.com/v1",
        "available_models": [
          {
            "name": "my-model",
            "display_name": "My Model",
            "max_tokens": 128000
          }
        ]
      }
    }
  }
}

这段嵌套一共四层,每层各管一件事:

  1. language_models:settings.json 里管语言模型的顶层块。
  2. openai_compatible:这一类接入方式的分组。你要接的那家服务只要接口形状和 OpenAI 一致,就归这里。
  3. my-provider你自己起的 provider 名,它是这份配置的键,也是后面环境变量命名的依据,这一点第三节还会用到。
  4. provider 对象内部:api_urlavailable_models

按文档的字段含义,api_url 是自定义 base URL;available_models 是模型数组,每项含 name(模型标识)、display_name(界面显示名)、max_tokens(上下文窗口上限);另有 capabilities 对象控制能力开关(tools、images、parallel_tool_calls 等)。

上下文窗口,指模型单次推理能同时看到的 token 总量,历史消息、系统提示、当前文件片段都挤在这个额度里。max_tokens 在 Zed 这份文档里对应的就是这个上限值。

配置项(字段名逐字取自官方文档)它是什么填错时的排查方向(属协议层推理,非文档逐条说明)出处
language_modelssettings.json 中语言模型配置的顶层块层级写错,这段配置整体不被识别Zed configuration 文档
openai_compatibleOpenAI 兼容这一类接入方式的分组键放错分组,provider 不会按兼容模式解析Zed use-api-access 文档
my-provider你自定义的 provider 名(文档示例值)与环境变量命名不对应时,密钥读不到Zed use-api-access 文档
api_url自定义 base URL路径段缺失或多写,请求 URL 拼接后指向不存在的路径,通常表现为路径类错误Zed use-api-access 文档
available_models模型数组,Zed 里要手写数组为空,就没有可选模型Zed use-api-access 文档
name模型标识与服务端实际模型 ID 不一致,服务端会拒绝该模型名Zed use-api-access 文档
display_name界面显示名只影响你自己看到的名字Zed use-api-access 文档
max_tokens上下文窗口上限填得超过服务端真实上限,超出部分由服务端判定并报错;填得过小则可用上下文被你自己压窄Zed use-api-access 文档
capabilities能力开关对象(tools、images、parallel_tool_calls 等)与模型实际支持的能力不一致时,相关功能行为不符合预期Zed use-api-access 文档
disable_ai关闭全部 AI 功能的设置,写法 "disable_ai": true忘了它开着,会以为模型配置没生效Zed configuration 文档

第三列需要说明白:官方文档记录的是这些字段是什么、怎么填,并没有逐条说明每个字段填错后客户端具体如何表现。表里那一列是按 OpenAI 兼容协议的通用机制推出来的排查方向,用来给你指路,不要当成 Zed 的文档结论。真实报错以你实际看到的为准。

注意示例里的 api_urlhttps://example.com/v1,带 /v1。你的服务商给的地址到底带不带这一段,以对方文档为准——各家客户端对这一段的处理并不一致,比如 Kilo Code 的文档明确写了它接受 https://api.provider.com/v1https://api.provider.com/v1/chat/completions 两种形态,Zed 文档给的示例则是前一种形状。这类差异是各写各的,别拿一家的填法套另一家。

三、密钥不进 settings.json:keychain 与环境变量两条路

这一节是 Zed 配置里态度最明确的一块。文档的原话是:“Do not put API keys in settings.json.”(这是 Zed 官方文档的说法。)另一页写的是:“Provider keys saved through Zed are stored in the system keychain, not in settings.json.”

keychain,指操作系统自带的凭据保管服务,密钥由系统加密保存、按应用授权读取,不以明文躺在你的项目文件里。Zed 文档说通过 Zed 保存的 provider 密钥存在系统 keychain,而不是 settings.json。

按文档,凭据走两条路:一是 provider 设置界面(Zed 相关命令里,agent: open settings 是用来配 LLM provider 的;另有 zed: open settingszed: open settings file。界面长什么样以你实际看到的为准);二是环境变量,命名规则是 <PROVIDER_NAME>_API_KEY。文档给的对应关系是:provider 名为 my-provider 时,环境变量是 MY_PROVIDER_API_KEY

所以第二节里”provider 名是你自己起的”这件事有后果——你起的名字直接决定环境变量叫什么。名字改了,环境变量名要跟着改。

顺带把一个容易混淆的概念说清:环境变量插值,指配置文件里写 $VAR_NAME 这样的占位符,程序加载配置时把它替换成当前环境变量的值,好处是配置文件可以进版本库而密钥不进。Gemini CLI 的 settings.json 就支持 $VAR_NAME${VAR_NAME} 这种写法。Zed 这边,本篇依据的那两页文档记录里出现的是”密钥别写进 settings.json、走界面或 <PROVIDER_NAME>_API_KEY 环境变量”这条路径,没有出现在 settings.json 里做插值的写法——这不等于 Zed 没有相关机制,只是不在本篇核对的这两页里,以官方文档最新版为准。

从结果上看,这个设计对团队协作是友好的:language_models 那段可以放心提交进仓库,密钥各人各配。配套的密钥管理思路可以参考 API Key 的安全管理

四、模型为什么要手写,这对你意味着什么

各家客户端拿到模型列表的路子不一样,这是 Zed 这套配置最需要提前有心理准备的一点:

  • Zed:模型要在 available_models 里手写,每项自己填 namedisplay_namemax_tokens
  • Kilo Code:凭据有效时会从 /v1/models 端点自动拉取模型列表,自动检测失败可手动填模型 ID。
  • Continue:在 config.yamlmodels 块里手写,必填 nameprovidermodel,可选 apiBase 覆盖默认 API 端点。

三家的字段名彼此不通用:Zed 叫 api_url,Continue 叫 apiBase,Kilo Code 界面里叫 Base URL。名字不同、位置不同,不要互相搬。

手写的直接后果有三个,这三条是按”清单由你维护”这个前提推出来的,官方文档并没有逐条写明客户端在这些情形下如何表现,实际以官方文档为准。第一,服务商上新模型,这个数组不会自己多出一项,得你回来改配置。第二,max_tokens 这个数是你填的,文档记录的只是它代表上下文窗口上限,并没有说客户端会去跟服务端核对这个值,所以填多填少都由你负责——不清楚就去查服务商文档,别拍脑袋。第三,模型标识 name 是要和服务端认的模型 ID 对上的那个字符串,一字不差地抄,别自己改大小写或加前缀。

关于 capabilities:文档写它是控制能力开关的对象,含 tools、images、parallel_tool_calls 等键。这些键在客户端内部具体怎么被使用,本篇依据的文档记录里没有逐条说明,所以这里只说它是你要填的能力声明,别把它理解成”打开了模型就会有这个能力”——模型支不支持工具调用取决于服务商那边,声明只是告诉客户端你的判断。

这一点在别家产品上有更硬的例子:Roo Code 的文档原话是 “Roo Code uses native tool calling exclusively. This is the only supported tool protocol — there is no XML-based fallback.”(这是 Roo Code 官方文档的说法。)也就是不支持原生工具调用的模型在那边直接用不了,文档建议先查服务商文档确认该模型是否支持工具调用。Continue 那边则是用 capabilitiestool_use 来声明。三家都在同一件事上设了字段,说明选模型时先确认工具调用支持这条建议是普遍适用的。

五、边界与代价:这套做法不管什么

先说放弃了什么。手写模型清单意味着你把”模型目录的维护”揽到了自己身上:省掉了自动发现可能带来的不确定性,代价是每次服务商变动你都要手动跟。如果你同时挂三五个端点、每个端点又挂好几个模型,这份 settings.json 会越来越长,而且没有人替你校验里面的数字对不对

再说它明确不管的几件事:

  • 不管模型质量。配置正确只意味着请求能发出去,回来的东西好不好用是另一回事。
  • 不管账单。本篇依据的这两页记录里没有出现计费相关的字段,花了多少钱要去服务商那边看。
  • 不管限速与重试策略。你自己填的 max_tokens 与服务端的限流是两套东西,撞上 429 该怎么退避,属于调用侧的工程问题。
  • 不管嵌入与重排嵌入是把文本转成向量用于检索,重排是对检索结果再打一次分调整顺序——这两件事在 Continue 那边有 roles 里的 embedrerank 取值对应。本篇依据的 Zed 那两页记录里没有出现这类角色字段,这不等于 Zed 没有相关能力,只是不在本篇核对范围内。

什么场景不适用?如果你要的是”开箱即用、不想碰配置文件”,那 Zed 文档列出的模型接入路径其实有五类:Zed 托管模型、自带 API key、复用已有订阅、网关(OpenRouter / Vercel AI / Amazon Bedrock)、本地模型(Ollama / LM Studio / 自托管)。本篇讲的只是其中自定义 OpenAI 兼容端点这一条路;其余几条的取舍以官方文档为准。

六、避坑清单

1. 配完看不到模型,先数 available_models 里有几项。 为什么会踩:习惯了别的客户端连上就能拉出一串模型,下意识以为 Zed 也一样。怎么避:Zed 这边模型是手写进数组的,数组里没有的模型就是不存在。先确认这个数组,再去怀疑网络和密钥。

2. api_url 的路径段照抄服务商文档,别按别家习惯改。 为什么会踩:见过 Cline 的示例带 /v1、见过 Kilo Code 接受两种形态,就以为哪家都随便。怎么避:Zed 文档示例是 https://example.com/v1 这种形状,但你实际该填哪一段取决于服务商——按对方文档原样粘贴,不要自己加减 /v1 或补 chat/completions

3. 改了 provider 名,忘了改环境变量名。 为什么会踩:provider 名是自定义的,改名看着无害。怎么避:记住命名规则是 <PROVIDER_NAME>_API_KEY,文档给的对应是 my-providerMY_PROVIDER_API_KEY。改名和改环境变量必须成对做。

4. 顺手把 key 写进 settings.json。 为什么会踩:所有字段都在一个文件里,密钥也塞进去最省事,何况配置文件很少有人翻。怎么避:文档原话是 “Do not put API keys in settings.json.”,走界面(密钥存系统 keychain)或环境变量。这也是这份配置能安全进版本库的前提。

5. max_tokens 拍脑袋填一个大数。 为什么会踩:看别人写 128000 就照抄,觉得填大点不吃亏。怎么避:这是上下文窗口上限,按 OpenAI 兼容协议的通用机制,超过服务端真实上限的请求会被服务端判定并报错,填小了则是你自己把可用上下文压窄。去服务商文档查真实值再填。相关概念看 上下文窗口是什么

6. 模型明明配好了,Agent 功能却像没启用。 为什么会踩:忽略了还有个全局开关。怎么避:Zed 有 disable_ai 设置,写法是 "disable_ai": true,检查一下它在哪一层配置里被打开过。至于配 LLM provider 的入口,文档给的命令是 agent: open settings

7. 拿一家的字段名去填另一家。 为什么会踩:api_urlapiBase、Base URL 语义上都是”接口地址”,看着可以互换。怎么避:它们是三个产品的三个不同字段,写错了就是无效键。每次配新工具,先翻那家自己的文档确认字段名。

数据来源与核对日期

以下 URL 均为本篇事实的来源,核对日期 2026-08-07。文中提到的所有字段名与文档原话,都是截至该日期官方文档页面的情况,请以官方文档最新版为准。

本篇没有写什么,以及为什么: 不写任何产品的价格、免费额度、订阅档位、限速数字、版本号,也不列完整模型清单——这几类信息变动频繁,且本次核对未覆盖,写出来就是给你埋雷,请一律以各产品官方文档和服务商控制台为准。不写各家界面长什么样、菜单在第几级、报错文案怎么写,因为本篇核对的是配置层文档,界面以你实际看到的为准。也不写”哪一家文档更好”这类评价。文中凡涉及”填错会怎样”的表述,都是按 OpenAI 兼容协议的通用机制作出的推理,不是任何一家产品文档的结论。

延伸阅读:同一组里的 aider 模型设置文件放哪一层生效Zed 为什么不让把密钥写进 settings.json;接完之后照 接完自定义模型别急着干活 逐项过一遍,才算真接通。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。