【免费下载链接】opencodex
Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code
本文深入讲解 opencodex(Universal provider proxy)如何决定 Codex 模型选择器(picker)中的模型顺序:从 Codex 的priority升序排序规则、确定性字母序 tie-break,到subagentModels/modelPickerOrder/selectedModels/disabledModels的各自职责,以及 Dashboard「Sub-agents」与「Models」页面的排序控件。读完本文,你将掌握 featured 模型置顶、路由模型字母序排列、显示级排序与完整 picker 排序的配置方法,并能区分"可见性过滤"与"排序"两个容易混淆的概念。
背景:排序解释为何值得单独成文
opencodex 通过 src/codex/catalog.ts 维护一份 Codex 可见的模型目录(catalog),并暴露给 Codex picker 与spawn_agent。此前,三个用户触达面(docs-site 文档站、GUI 的 Sub-agents 页面、GUI 的 Models 标签页)都缺少对"模型顺序到底由什么决定"的说明,导致用户误以为调整配置文件里providers对象的声明顺序或models数组的先后就能改变 picker 顺序。相关工作记录见 010_report.md:最终在文档站新增了多语言文章model-ordering.md,并在 GUI 两个页面加入了orderHint提示行,把这一规则透明化。
需要先记住的根本结论:Codex 模型选择器不保留 provider 声明顺序,也不保留模型数组顺序。最终顺序完全由目录条目的priority决定,同优先级的路由模型则按确定性字母序排列。
Codex 应用的排序规则
Codex 的 models-manager 对 picker 可见的目录条目按priority升序排序,并且丢弃目录数组本身的顺序。也就是说,把某个条目在生成的 JSON 数组里往前提,并不会让它出现在 picker 的更前面。该约束直接记录在src/codex/catalog/sync.ts的注释与实现中。
因此 opencodex 控制 featured(精选)位置的方式是赋予更小的 priority 数值,而不是依赖数组位置。除非特别说明,下面给出的固定优先级与示例描述的都是"没有任何合格 Codex 账户选择器(account selector)"的目录。
无选择器场景的优先级表
| 目录条目 | 优先级 | 来源 |
|---|---|---|
subagentModels[i] | i(0到4) | src/codex/catalog/sync.ts中的 featured 排名映射 |
| 其他路由模型 | 5 | src/codex/catalog/sync.ts中的路由条目创建 |
列在modelPickerOrder中的非 featured 路由模型 | 1000 + i | src/codex/catalog/sync.ts中仅显示用的 picker 排名 |
| 默认的原生 GPT slug | 9 | src/codex/catalog/sync.ts中的原生条目创建 |
| 存在 featured 列表时未被选中的原生模型 | 至少featured.length + 100 | src/codex/catalog/sync.ts中的原生目录合并 |
有账户选择器时的 stride 规则
当存在N个合格选择器时,featured 优先级以N为步长(stride)展开:配置排名为i的裸原生选择会展开为选择器行,优先级为i * N + j(j是该选择器从 0 开始的位置);路由选择使用i * N;精确指定选择器的选择使用i * N + j。未被选中的路由行会被移出这些选择器分组。Codex 仍然只对外通告前五个 picker 可见行。
5 选上限
管理 API 用slice(0, 5)把subagentModels限制为五个条目,见 src/server/management/agent-settings-routes.ts。这与 Codexspawn_agent表面一致——它只通告前五个模型覆盖项。这五个之外的其他模型仍可在主 picker 中保持可见,并可通过其精确 id 调用。
同优先级 tie 的顺序:确定性字母序
所有普通路由模型优先级都是5,所以必须有一个 tie-breaker。在目录条目构建之前,gatherRoutedModels()会先把路由模型列表按provider 名、再按model id分别做字母序排序(src/codex/catalog/provider-fetch.ts)。
这意味着以下两个配置细节都不会改变最终顺序:
providers对象中键的声明顺序;- 某个 provider 的
models数组中 id 的先后顺序。
随后orderForSubagents()使用稳定排序,把配置好的 featured 选择按subagentModels中的顺序移到最前;非 featured 模型保持先前确立的 provider/id 字母序相对顺序(src/codex/catalog/sync.ts,实现位于 src/codex/catalog/build-entries.ts)。featured 排名在构建条目时也会被转换为0到4的优先级,因此 Codex 的优先级排序会保留这段领先序列。
从源码看,orderForSubagents用rank映射featured.map((id, i) => [id, i]),并兼容三种 id 形式(别名、provider/id、编码 slug),未命中 featured 的条目返回Number.MAX_SAFE_INTEGER,从而稳定排在末尾——这正是"featured 置顶、其余保持原相对顺序"的实现基础。
可见性与排序是两回事
selectedModels与disabledModels决定哪些路由模型被暴露,它们不是排序控件。filterCatalogVisibleModels()把两者都转换为Set查询,然后过滤已收集的列表,绝不把数组当排名用(src/codex/catalog/provider-fetch.ts,实现位于 src/codex/catalog/model-visibility.ts)。
因此,重排selectedModels或disabledModels中的元素对 picker 位置没有任何影响,只会改变模型是否被包含。disabledModels与各 provider 的selectedModels始终是可见性字段;项目里不存在独立的modelOrder、providerOrder或优先级映射配置项——这是一个诚实的局限。
有效的 picker 排列模式
在无账户选择器且 featured 列表非空时,最终顺序为:
- 按
subagentModels精确配置顺序排列的模型,优先级0到4; - 其余全部路由模型,按 provider 再按 model id 字母序,优先级
5; - 未选中的原生模型,在目录合并时被压到 featured 块之下。
若没有subagentModels,路由模型保持在优先级5,原生 GPT 条目使用其正常优先级(通常为 opencodex 构建条目的9),路由组仍保持 provider/id 字母序。
示例
假设subagentModels按此精确顺序包含五个 id:
subagentModels = [ "gpt-5.5", "opencode-go/glm-5.2", "anthropic/claude-opus-4-6", "gpt-5.6-sol", "gpt-5.6-terra", ]picker 起始排列如下:
| Picker 位置 | 模型 | 优先级 | 出现原因 |
|---|---|---|---|
| 1 | gpt-5.5 | 0 | 第一个subagentModels选择 |
| 2 | opencode-go/glm-5.2 | 1 | 第二个选择,即使其 provider 在anthropic之后排序 |
| 3 | anthropic/claude-opus-4-6 | 2 | 第三个选择 |
| 4 | gpt-5.6-sol | 3 | 第四个选择 |
| 5 | gpt-5.6-terra | 4 | 第五个选择 |
| 6 | anthropic/claude-fable-5 | 5 | provider/id 字母序中第一个剩余路由 id |
| 7 起 | 其余路由模型 | 5 | 先 provider 字母序,再 model id 字母序 |
| 路由模型之后 | 其余原生模型 | featured.length + 100或更高 | 未选中的原生模型被移到 featured 块之下 |
前五个条目即通告给spawn_agent的覆盖项;其余按正常 picker 顺序继续。有账户选择器时,五条上限在裸原生选择展开为选择器限定组之后应用。
修改顺序的两种手段
用subagentModels控制头部
使用subagentModels选择并排列 Codex 同时通告给spawn_agent的头部模型。Dashboard 的Sub-agents页面可以重排裸原生与路由 id;也可以用ocx agent subagents set或直接编辑 opencodex 配置来精确指定<selector>/<native-openai-model>选择(Dashboard 保存后会保留这些 id,包括当前不可用的选择)。最多配置五个 id。注意:有账户选择器时,一个裸原生选择可能展开为多行选择器限定的目录条目,因此"配置的选择"与"通告的行"未必一一对应。
如果某个账户门控的原生模型没有合格账户支持,请求会以"无效模型选择"失败;如果存在支持账户但暂时耗尽或不可用,则以"可重试的速率限制"失败。这两种状态永远不会被报告为无效 API key——请改选其他可用模型,或等待有能力的账户配额窗口重新开放。
用modelPickerOrder控制显示级排序
modelPickerOrder用于对 featured 块之外的路由<provider>/<model>行做仅显示排序:
{ "modelPickerOrder": [ "tyler/deepseek-v4-flash", "jd-chat/kimi-k3", "jd-chat/glm-5.2" ] }列出的路由行按配置顺序出现。被省略的路由行保持其正常优先级,因此会排在modelPickerOrder显示带之前——想控制相对位置,就必须把每个路由行都列出来。同时出现在subagentModels中的行保持其 featured 优先级。若列表只含路由行,原生行保持正常位置。
要排序完整 picker,请加入一个裸原生 id:
{ "modelPickerOrder": ["gpt-5.6-sol", "opencode-go/glm-5.3"] }列出的行按数组顺序排在最前,未列出的行按自然优先级随后排列。匹配使用精确目录 id:gpt-5.6-sol与openai/gpt-5.6-sol是两行。同一路由 id 的原始拼写与编码拼写都可接受,精确匹配优先。空条目被忽略。账户限定的行需要在列表中使用其选择器限定 id。
从源码看,orderForModelPicker(src/codex/catalog/build-entries.ts)通过检查列表中是否存在不含/的 slug 来判定这是否为"完整排序"(complete)模式;完整模式下未列出的行按pickerOrder.length + natural排名,而仅路由模式下未列出的行保持在 featured 带内。sync.ts中构建条目时还会把非 featured 行的原始priority备份到SPAWN_PRIORITY_FIELD,再覆盖为1000 + i的显示优先级——这是"显示排序不影响 spawn_agent 通告优先级"的关键机制。
迁移注意:现有排序中的原生 id
此前modelPickerOrder中的原生 id 会被忽略。现在,包含裸原生 id 的既有列表会激活完整 picker 排序(含 featured 行)。要恢复旧的路由专用行为,请移除裸原生 id。未设置、空列表与纯路由列表均保持原行为;OpenCodex 的自然优先级引导候选计算不变。
modelPickerOrder保留 OpenCodex 对最多五个首选候选的自然优先级计算。每一被移动的行保留其独立于原生priority的自然优先级;仅改变 picker 顺序不得改变该项 OpenCodex 计算。它也不限制精确名称模型覆盖的资格:原生通告列表不是 allowlist,既有的认证、模型/effort 与后端约束依然生效。
原生 Codex 使用原生priority在 V1 及 V2(当模型覆盖暴露时)选出spawn_agent通告的前五个合格 picker 可见模型。因此这通告的五个可能随 picker 顺序变化,即使 OpenCodex 的首选候选不变。V1 不接收 OpenCodex 首选名册注入;V2 在客户端目录状态允许时可能额外接收 OpenCodex 的自然优先级引导,但该引导不会重排原生工具的通告列表。
Dashboard 的 picker 预设
在Models页面,选择Default、A–Z by model、Group by provider或Most used snapshot,然后Apply order。这会保存当前可见的路由 id 与modelPickerOrderMode(alphabetical、provider或most-used)。Most used 在应用时读取一次全部保留用量;重新加载时恢复快照,不再抓取用量。新增或移除的模型不会自动重算它。手动保存的顺序(包括完整/原生顺序)在你显式应用替换前保持不变。Default 会清空两个 picker 字段,即使没有路由模型可用。
这些控件使用GET/PUT /api/subagent-models:chosen与available保留已保存的名册选择(包括被禁用或缺失的模型);pickerAvailable仅含合格的路由目录 id。Models 页面发送pickerOrder与pickerOrderMode,从不发送models。仅名册的保存会保留 picker 设置。无效的联合更新与持久化失败会保持之前的 picker/名册状态不变。
从 src/server/management/agent-settings-routes.ts 的实现看,PUT /api/subagent-models对pickerOrder校验了非空字符串、去重与 trim,pickerOrderMode只接受alphabetical、provider、most-used或null,且pickerOrderMode必须与pickerOrder同时更新,否则返回 400——这正是"模式必须配对顺序"的契约来源。
仅路由的预设保留既有的 featured/原生优先级带。它们影响 Codex 目录与 Claude discovery 的路由组;Claude 的原生前缀与显式 Desktop profile/alias 归属不变。OpenCodex 引导排名与配置的 fallback 设置保留,但原生 Codex 的通告五个与推荐默认可能随显示优先级变化。保存不会重启客户端;目录刷新可能仍在挂起,持有旧目录的客户端可能需要重新打开。
自定义路由顺序
在 Models 页面选择Custom order加载全新的路由快照。将可拖动的行拖到另一行之前,或使用其 Up/Down 按钮,然后Save draft。featured 路由行保持在配置排名的前端且不可移动。原生行不显示;这不是完整原生 picker 的预览。存活的已保存行保持相对顺序,新候选跟随当前候选列表。每次保存都发送完整路由列表,不改变 featured 名册。
包含裸原生 id 的顺序会保持受保护,直到你显式应用路由预设或 Default。仅选择不同选项不会替换它。未知的 featured 状态会阻止编辑。保存前,编辑器会检查全新快照;若发现变化会保留你的草稿并阻止保存,直到Reload and discard draft加载当前设置。请求失败保留草稿。已接受的保存仍可能有挂起的目录刷新;再次编辑前请重新加载。
编辑器还要求每个路由候选都有无歧义的模型身份。若模型目录不完整,请在编辑前刷新 Models 页面;仅重载 picker 设置无法恢复缺失的目录身份。featured 选择精确匹配且不修剪;重复选择使用其最后配置的位置,规范 id 优先于原始 id。
顺序解释的三个用户触达面
本次工作把以上规则同时落地到三个界面(详见 010_report.md):
- docs-site 文档站:新增文章 model-ordering.md(英文),并同步了韩文 ko 版、中文 zh-cn 版 以及 fr/ja/ru/tr/zh-tw 等语言版本,侧边栏入口位于
docs-site/astro.config.mjs。 - GUI Sub-agents 页面(
gui/src/pages/Subagents.tsx):在 Featured 列表上方新增orderHint提示行,说明当前顺序即 picker 1-5 顺序加spawn_agent候选。 - GUI Models 标签页(gui/src/pages/Models.tsx):在模型列表上方新增
orderHint说明——subagent 选择优先、随后是路由 provider/id 字母序、再到原生;可见性开关仅做过滤。i18n key 在 en/ko/zh/de 中均有提供。
小结与实操清单
- 想控制 picker 头部顺序:配置
subagentModels(最多 5 个),或使用 Dashboard Sub-agents 页面重排。 - 想控制 featured 块之外路由行的显示顺序:配置
modelPickerOrder;需要完整排序时加入裸原生 id。 - 想理解"为什么我的配置顺序没生效":因为 Codex 按
priority升序排序,数组顺序被丢弃;路由模型按 provider/id 字母序 tie-break。 - 想隐藏/暴露模型:用
selectedModels/disabledModels——它们是过滤,不是排序。 - 别忘了诚实局限:目前不存在
modelOrder/providerOrder/ 优先级映射配置;modelPickerOrder是显示级手段,不改变spawn_agent通告的自然优先级计算。
【免费下载链接】opencodex
Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code
相关推荐
Hetty scope优先级:规则执行顺序完全指南
Hetty scope优先级:规则执行顺序完全指南 你是否曾在使用Hetty进行安全测试时,遇到过scope规则不按预期匹配的情况?明明配置了拦截规则却无法捕获
网络安全应用安全AdGuardHome规则执行顺序:优先级调整完全指南
AdGuardHome规则执行顺序:优先级调整完全指南 你是否遇到过这样的困扰:明明添加了广告过滤规则,却依然看到弹窗?或者自定义规则与预设规则冲突导致某些网站
网络后端网络安全Sinatra配置优先级规则:理解设置加载顺序
Sinatra配置优先级规则:理解设置加载顺序 在使用Sinatra开发Web应用时,正确理解配置的加载顺序至关重要。配置冲突是导致应用行为异常的常见原因,本文
后端Web框架
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考