- 首页
- Documentation
- 提供者
- 模型与提供商配置(`models.yml`)
模型与提供商配置(`models.yml`)
本文档描述了编码代理当前如何加载模型、应用覆盖配置、解析凭据以及在运行时选择模型。
控制模型行为的要素
Section titled “控制模型行为的要素”主要实现文件:
src/config/model-registry.ts— 加载内置和自定义模型、提供商覆盖、运行时发现、认证集成src/config/model-resolver.ts— 解析模型模式并选择 initial/smol/slow 模型src/config/settings-schema.ts— 模型相关设置(modelRoles、提供商传输偏好)src/session/auth-storage.ts— API 密钥 + OAuth 解析顺序packages/ai/src/models.ts和packages/ai/src/types.ts— 内置提供商/模型以及Model/compat类型
配置文件位置和旧版行为
Section titled “配置文件位置和旧版行为”默认配置路径:
~/.xcsh/agent/models.yml
仍然存在的旧版行为:
- 如果
models.yml不存在但同一位置存在models.json,则会自动迁移为models.yml。 - 当通过编程方式传递给
ModelRegistry时,仍支持显式的.json/.jsonc配置路径。
models.yml 结构
Section titled “models.yml 结构”configVersion: 1 # optional — written by auto-config, used for migration detectionproviders: <provider-id>: # provider-level configequivalence: overrides: <provider-id>/<model-id>: <canonical-model-id> exclude: - <provider-id>/<model-id>configVersion 是一个可选整数,由自动配置系统写入。存在时,xcsh 使用它来检测过时的配置并自动升级。
provider-id 是在选择和认证查找中使用的规范提供商键。
equivalence 是可选的,用于在具体提供商模型之上配置规范模型分组:
overrides将精确的具体选择器(provider/modelId)映射到官方上游规范 idexclude将具体选择器从规范分组中排除
提供商级别字段
Section titled “提供商级别字段”providers: my-provider: baseUrl: https://api.example.com/v1 apiKey: MY_PROVIDER_API_KEY api: openai-completions headers: X-Team: platform authHeader: true auth: apiKey discovery: type: ollama modelOverrides: some-model-id: name: Renamed model models: - id: some-model-id name: Some Model api: openai-completions reasoning: false input: [text] cost: input: 0 output: 0 cacheRead: 0 cacheWrite: 0 contextWindow: 128000 maxTokens: 16384 headers: X-Model: value compat: supportsStore: true supportsDeveloperRole: true supportsReasoningEffort: true maxTokensField: max_completion_tokens openRouterRouting: only: [anthropic] vercelGatewayRouting: order: [anthropic, openai] extraBody: gateway: m1-01 controller: mlx允许的提供商/模型 api 值
Section titled “允许的提供商/模型 api 值”openai-completionsopenai-responsesopenai-codex-responsesazure-openai-responsesanthropic-messagesgoogle-generative-aigoogle-vertex
允许的 auth/discovery 值
Section titled “允许的 auth/discovery 值”auth:apiKey(默认)或nonediscovery.type:ollama
验证规则(当前)
Section titled “验证规则(当前)”完整自定义提供商(models 非空)
Section titled “完整自定义提供商(models 非空)”必需:
baseUrlapiKey(除非设置了auth: none)api在提供商级别或每个模型上
仅覆盖提供商(models 缺失或为空)
Section titled “仅覆盖提供商(models 缺失或为空)”必须至少定义以下之一:
baseUrlmodelOverridesdiscovery
discovery需要提供商级别的api。
id必需contextWindow和maxTokens如果提供则必须为正数
合并和覆盖顺序
Section titled “合并和覆盖顺序”ModelRegistry 管道(刷新时):
- 从
@f5-sales-demo/pi-ai加载内置提供商/模型。 - 加载
models.yml自定义配置。 - 将提供商覆盖(
baseUrl、headers)应用到内置模型。 - 应用
modelOverrides(按提供商 + 模型 id)。 - 合并自定义
models:- 相同
provider + id替换现有的 - 否则追加
- 相同
- 应用运行时发现的模型(目前是 Ollama 和 LM Studio),然后重新应用模型覆盖。
规范模型等价和合并
Section titled “规范模型等价和合并”注册表保留每个具体的提供商模型,然后在它们之上构建规范层。
规范 id 仅为官方上游 id,例如:
claude-opus-4-6claude-haiku-4-5gpt-5.3-codex
models.yml 等价配置
Section titled “models.yml 等价配置”示例:
providers: zenmux: baseUrl: https://api.zenmux.example/v1 apiKey: ZENMUX_API_KEY api: openai-codex-responses models: - id: codex name: Zenmux Codex reasoning: true input: [text] cost: input: 0 output: 0 cacheRead: 0 cacheWrite: 0 contextWindow: 200000 maxTokens: 32768
equivalence: overrides: zenmux/codex: gpt-5.3-codex p-codex/codex: gpt-5.3-codex exclude: - demo/codex-preview规范分组的构建顺序:
- 来自
equivalence.overrides的精确用户覆盖 - 来自内置模型元数据的捆绑官方 id 匹配
- 针对网关/提供商变体的保守启发式规范化
- 回退到具体模型自身的 id
当前启发式方法故意设计得较为保守:
- 嵌入的上游前缀可以在存在时被剥离,例如
anthropic/...或openai/... - 点号和连字号版本变体仅在映射到现有官方 id 时才进行规范化,例如
4.6 -> 4-6 - 模糊的系列或版本在没有捆绑匹配或显式覆盖的情况下不会被合并
规范解析行为
Section titled “规范解析行为”当多个具体变体共享同一个规范 id 时,解析使用:
- 可用性和认证
config.yml中的modelProviderOrder- 如果未设置
modelProviderOrder,则使用现有的注册表/提供商顺序
被禁用或未认证的提供商会被跳过。
会话状态和转录继续记录实际执行该轮次的具体提供商/模型。
提供商默认值与按模型覆盖:
- 提供商
headers是基线。 - 模型
headers覆盖提供商的头部键。 modelOverrides可以覆盖模型元数据(name、reasoning、input、cost、contextWindow、maxTokens、headers、compat、contextPromotionTarget)。compat对嵌套路由块(openRouterRouting、vercelGatewayRouting、extraBody)进行深度合并。
运行时发现集成
Section titled “运行时发现集成”隐式 Ollama 发现
Section titled “隐式 Ollama 发现”如果 ollama 未被显式配置,注册表会添加一个隐式可发现提供商:
- 提供商:
ollama - api:
openai-completions - 基础 URL:
OLLAMA_BASE_URL或http://127.0.0.1:11434 - 认证模式:无密钥(
auth: none行为)
运行时发现调用 Ollama 的 GET /api/tags 并使用本地默认值合成模型条目。
隐式 llama.cpp 发现
Section titled “隐式 llama.cpp 发现”如果 llama.cpp 未被显式配置,注册表会添加一个隐式可发现提供商:
注意:它使用的是较新的 anthropic messages api 而不是 openai-completions。
- 提供商:
llama.cpp - api:
openai-responses - 基础 URL:
LLAMA_CPP_BASE_URL或http://127.0.0.1:8080 - 认证模式:无密钥(
auth: none行为)
运行时发现调用 llama.cpp 的 GET models 并使用本地默认值合成模型条目。
隐式 LM Studio 发现
Section titled “隐式 LM Studio 发现”如果 lm-studio 未被显式配置,注册表会添加一个隐式可发现提供商:
- 提供商:
lm-studio - api:
openai-completions - 基础 URL:
LM_STUDIO_BASE_URL或http://127.0.0.1:1234/v1 - 认证模式:无密钥(
auth: none行为)
运行时发现获取模型(GET /models)并使用本地默认值合成模型条目。
显式提供商发现
Section titled “显式提供商发现”您可以自行配置发现:
providers: ollama: baseUrl: http://127.0.0.1:11434 api: openai-completions auth: none discovery: type: ollama
llama.cpp: baseUrl: http://127.0.0.1:8080 api: openai-responses auth: none discovery: type: llama.cpp扩展提供商注册
Section titled “扩展提供商注册”扩展可以在运行时注册提供商(pi.registerProvider(...)),包括:
- 为提供商替换/追加模型
- 为新 API ID 注册自定义流处理器
- 自定义 OAuth 提供商注册
认证和 API 密钥解析顺序
Section titled “认证和 API 密钥解析顺序”请求提供商密钥时,有效顺序为:
- 运行时覆盖(CLI
--api-key) - 存储在
agent.db中的 API 密钥凭据 - 存储在
agent.db中的 OAuth 凭据(带刷新) - 环境变量映射(
OPENAI_API_KEY、ANTHROPIC_API_KEY等) - ModelRegistry 回退解析器(来自
models.yml的提供商apiKey,环境变量名或字面量语义)
models.yml 中 apiKey 的行为:
- 值首先被视为环境变量名。
- 如果不存在对应的环境变量,则将字面字符串用作令牌。
如果 authHeader: true 且提供商设置了 apiKey,模型会获得:
- 注入的
Authorization: Bearer <resolved-key>头部。
无密钥提供商:
- 标记为
auth: none的提供商被视为无需凭据即可使用。 getApiKey*对它们返回kNoAuth。
模型可用性与全部模型
Section titled “模型可用性与全部模型”getAll()返回已加载的模型注册表(内置 + 合并的自定义 + 发现的)。getAvailable()过滤为无密钥或可解析认证的模型。
因此,模型可以存在于注册表中,但在认证可用之前无法被选择。
运行时模型解析
Section titled “运行时模型解析”CLI 和模式解析
Section titled “CLI 和模式解析”model-resolver.ts 支持:
- 精确的
provider/modelId - 精确的规范模型 id
- 精确的模型 id(推断提供商)
- 模糊/子字符串匹配
--models中的通配符范围模式(例如openai/*、*sonnet*)- 可选的
:thinkingLevel后缀(off|minimal|low|medium|high|xhigh)
--provider 是旧版选项;推荐使用 --model。
精确选择器的解析优先级:
- 精确的
provider/modelId绕过合并 - 精确的规范 id 通过规范索引解析
- 精确的裸具体 id 仍然有效
- 模糊和通配符匹配在精确路径之后运行
初始模型选择优先级
Section titled “初始模型选择优先级”findInitialModel(...) 使用以下顺序:
- 显式的 CLI provider+model
- 第一个作用域模型(如果不是恢复会话)
- 已保存的默认 provider/model
- 可用模型中的已知提供商默认值(例如 OpenAI/Anthropic 等)
- 第一个可用模型
角色别名和设置
Section titled “角色别名和设置”支持的模型角色:
default、smol、slow、plan、commit
类似 pi/smol 的角色别名通过 settings.modelRoles 展开。每个角色值还可以附加思考选择器,如 :minimal、:low、:medium 或 :high。
如果一个角色指向另一个角色,目标模型仍然正常继承,引用角色上的任何显式后缀在该角色特定使用中优先。
相关设置:
modelRoles(记录)enabledModels(作用域模式列表)modelProviderOrder(全局规范提供商优先级)providers.kimiApiFormat(openai或anthropic请求格式)providers.openaiWebsockets(auto|off|onOpenAI Codex 传输的 websocket 偏好)
modelRoles 可以存储以下任一值:
provider/modelId用于固定具体的提供商变体- 规范 id(如
gpt-5.3-codex)以允许提供商合并
对于 enabledModels 和 CLI --models:
- 精确的规范 id 展开为该规范组中的所有具体变体
- 显式的
provider/modelId条目保持精确 - 通配符和模糊匹配仍然在具体模型上操作
/model 和 --list-models
Section titled “/model 和 --list-models”两个界面都保持提供商前缀模型的可见和可选性。
它们现在还暴露了规范/合并的模型:
/model在提供商标签旁包含规范视图--list-models打印规范部分加上具体的提供商行
选择规范条目会存储规范选择器。选择提供商行会存储显式的 provider/modelId。
上下文提升(模型级别回退链)
Section titled “上下文提升(模型级别回退链)”上下文提升是一种溢出恢复机制,适用于小上下文变体(例如 *-spark),当 API 因上下文长度错误拒绝请求时,自动提升到更大上下文的同级模型。
当一轮因上下文溢出错误(例如 context_length_exceeded)失败时,AgentSession 在回退到压缩之前尝试提升:
- 如果
contextPromotion.enabled为 true,解析提升目标(见下文)。 - 如果找到目标,切换到该目标并重试请求——无需压缩。
- 如果没有可用目标,则在当前模型上回退到自动压缩。
选择是模型驱动的,而不是角色驱动的:
currentModel.contextPromotionTarget(如果已配置)- 同一提供商 + API 上最小的更大上下文模型
除非凭据可解析(ModelRegistry.getApiKey(...)),否则候选项会被忽略。
OpenAI Codex websocket 交接
Section titled “OpenAI Codex websocket 交接”如果从/切换到 openai-codex-responses,会话提供商状态键 openai-codex-responses 在模型切换前关闭。这会丢弃 websocket 传输状态,使下一轮在提升后的模型上全新启动。
提升使用临时切换(setModelTemporary):
- 在会话历史中记录为临时
model_change - 不会重写已保存的角色映射
配置显式回退链
Section titled “配置显式回退链”通过模型元数据中的 contextPromotionTarget 直接配置回退。
contextPromotionTarget 接受以下任一格式:
provider/model-id(显式)model-id(在当前提供商内解析)
示例(models.yml)用于同一提供商上的 Spark -> 非 Spark:
providers: openai-codex: modelOverrides: gpt-5.3-codex-spark: contextPromotionTarget: openai-codex/gpt-5.3-codex内置模型生成器在同一提供商存在基础模型时,也会自动为 *-spark 模型分配此项。
兼容性和路由字段
Section titled “兼容性和路由字段”models.yml 支持以下 compat 子集:
supportsStoresupportsDeveloperRolesupportsReasoningEffortmaxTokensField(max_completion_tokens或max_tokens)openRouterRouting.only/openRouterRouting.ordervercelGatewayRouting.only/vercelGatewayRouting.order
这些由 OpenAI-completions 传输逻辑消费,并与基于 URL 的自动检测相结合。
本地 OpenAI 兼容端点(无认证)
Section titled “本地 OpenAI 兼容端点(无认证)”providers: local-openai: baseUrl: http://127.0.0.1:8000/v1 auth: none api: openai-completions models: - id: Qwen/Qwen2.5-Coder-32B-Instruct name: Qwen 2.5 Coder 32B (local)使用基于环境变量密钥的托管代理
Section titled “使用基于环境变量密钥的托管代理”providers: anthropic-proxy: baseUrl: https://proxy.example.com/anthropic apiKey: ANTHROPIC_PROXY_API_KEY api: anthropic-messages authHeader: true models: - id: claude-sonnet-4-20250514 name: Claude Sonnet 4 (Proxy) reasoning: true input: [text, image]覆盖内置提供商路由 + 模型元数据
Section titled “覆盖内置提供商路由 + 模型元数据”providers: openrouter: baseUrl: https://my-proxy.example.com/v1 headers: X-Team: platform modelOverrides: anthropic/claude-sonnet-4: name: Sonnet 4 (Corp) compat: openRouterRouting: only: [anthropic]LiteLLM 代理自动配置
Section titled “LiteLLM 代理自动配置”当 LITELLM_BASE_URL 和 LITELLM_API_KEY 环境变量都已设置时,xcsh 会自动管理 LiteLLM 代理的 models.yml 配置。
首次运行自动生成
Section titled “首次运行自动生成”如果 models.yml 不存在且检测到 LiteLLM 环境变量,xcsh 会自动生成:
# Auto-generated by xcsh for LiteLLM proxy# API key resolved from LITELLM_API_KEY env var at runtimeconfigVersion: 1providers: anthropic: baseUrl: "https://your-litellm-proxy.example.com/anthropic" apiKey: LITELLM_API_KEY同时还会生成一个带有合理图像提供商设置的默认 config.yml。
每次启动时,模型注册表中的 startupHealthCheck() 会运行以下检查:
| 条件 | 操作 |
|---|---|
models.yml 缺失 | 从环境变量自动生成 |
models.yml 损坏或无法解析 | 备份为 .bak,重新生成 |
baseUrl 与 LITELLM_BASE_URL 不匹配 | 备份为 .bak,使用新 URL 重新生成 |
configVersion 缺失或过时 | 备份为 .bak,使用当前版本重新生成 |
| 配置健康 | 无操作 |
所有修复在覆盖前都会创建 .bak 备份。所有操作都是幂等的。
CLI 命令
Section titled “CLI 命令”xcsh setup litellm # Generate or fix LiteLLM configxcsh setup litellm --check # Validate without writingxcsh setup litellm --check --json # Machine-readable validation output必需的环境变量
Section titled “必需的环境变量”| 变量 | 用途 |
|---|---|
LITELLM_BASE_URL | LiteLLM 代理 URL(例如 https://your-proxy.example.com)。必须以 http:// 或 https:// 开头。 |
LITELLM_API_KEY | 代理的 API 密钥。在生成的配置中按名称引用,在运行时解析。 |
如果任一变量未设置,自动配置将被静默跳过。
配置版本控制
Section titled “配置版本控制”生成的配置包含 configVersion 字段。当生成格式在未来版本中发生变化时,xcsh 会检测过时的配置并自动升级(带备份)。
旧版消费者注意事项
Section titled “旧版消费者注意事项”大多数模型配置现在通过 ModelRegistry 经由 models.yml 流转。
一个值得注意的旧版路径仍然存在:Web 搜索 Anthropic 认证解析仍然直接在 src/web/search/auth.ts 中读取 ~/.xcsh/agent/models.json。
如果您依赖该特定路径,请在该模块迁移之前注意保持 JSON 兼容性。
如果 models.yml 未通过模式或验证检查:
- 如果设置了
LITELLM_BASE_URL和LITELLM_API_KEY,启动健康检查会尝试自动修复(备份损坏文件,从环境变量重新生成)。如果修复成功,注册表会重新加载修复后的配置。 - 如果无法自动修复(环境变量未设置、写入失败),注册表将继续使用内置模型运行。
- 错误通过
ModelRegistry.getError()暴露,并在 UI/通知中显示。