自定义模型 · BYOK、Ollama 与 OpenAI 兼容端点
grok 不绑死 xAI 模型——能接自带 key、Ollama、OpenAI 兼容、Anthropic。这一章看模型目录怎么分层合并、凭据怎么逐级解析、协议(api_backend)与鉴权(auth_scheme)为什么在采样器里是正交的两个字段,以及采样器为什么刻意「不认 URL」。
自定义模型 · BYOK、Ollama 与 OpenAI 兼容端点
Part 4 最后一章,回到三种 API 流埋的线:grok 怎么接任意模型——自带 key、本地 Ollama、OpenAI 兼容端点、Anthropic。xai-grok-config 只管配置文件的加载与分层合并;模型目录、凭据这些逻辑在 shell 的 agent/config.rs 里,最后组装成采样器要的 SamplerConfig。
两个正交的字段:协议 vs 鉴权
一个清晰的设计:在采样器里,api_backend(协议)和 auth_scheme(鉴权)是独立的。
ApiBackend:ChatCompletions(OpenAI 兼容,默认)/Responses/Messages(Anthropic)——决定请求长什么样。AuthScheme:Bearer(Authorization: Bearer)/XApiKey(x-api-key)——决定怎么带凭据。
但只有前者是你能配的:[model.<名>] 里有 api_backend,却没有 auth_scheme——生产路径都不设它,落到默认的 Bearer。所以接 Anthropic 的官方写法是 api_backend = "messages",再把 key 放进 extra_headers 的 x-api-key(grok 原样发送);接某个 OpenAI 兼容端点 = ChatCompletions + Bearer。
模型目录:一次分层合并
模型列表不是写死的,而是 resolve_model_list 组装的一个 IndexMap,优先级从低到高:
- 内置默认(
default_models.json)——若你配了自定义端点,这层跳过; /v1/models预取的模型——注意这层是整体替换而不是合并:预取成功后,服务端没返回的内置模型直接丢掉,内置条目只在字段上「捐献」(比如预取条目没报上下文窗口时,从同名内置条目借context_window);- 你
[model.<名>]的覆盖(最高优先级,新模型默认 200k 上下文); - 全局
[models]的extra_headers、temperature等兜底填充(仅当每模型没设时)。
一句话:config [model.*] > 预取 /v1/models > 内置默认。[model.<名>] 能配的很全:base_url、api_key/env_key、api_backend、context_window、extra_headers,还有 query_params、env_http_headers(从环境变量取头的值,不落盘)、mtls_cert_dir(按模型配 mTLS 客户端证书)……多个模型共用一个提供方时,可以写一个 [model_providers.<id>],模型里用 model_provider 引用、继承它的地址与凭据。
凭据:逐级解析
resolve_credentials 按优先级找凭据(注释原话是 model api_key/env_key > cached auth-provider token > session token > XAI_API_KEY):
- 模型自带(
[model.foo]的api_key或env_key指的环境变量)→ApiKey; - 凭据助手:模型声明了
auth_provider(引用一个[auth_provider.<名>]定义的、负责铸 token 的助手)时,用它缓存的 token; - 会话 token(
grok login登的)→SessionToken; XAI_API_KEY环境变量 →ApiKey;- 都没有(若配了
env_key却没设,会警告)。
还有个企业 kill-switch enforce_disable_api_key_auth:把第一方 xAI 的 API key 强制换成会话鉴权,但BYOK / 非 xAI 端点不受影响。
采样器刻意「不认 URL」
一个漂亮的解耦:采样器本身是 URL-agnostic 的——它不知道自己在连 xAI 代理还是 Ollama。所有和具体端点相关的头(代理鉴权头等)由 shell 在边界上用 inject_url_derived_headers 注入,且从不覆盖你已设的头(你的 extra_headers 赢);它还会给所有请求补一个标明交互或 headless 的客户端模式头,BYOK、Ollama 也不例外。让核心组件不认具体端点、把端点差异挤到边界,是这类「要支持多后端」的系统里反复出现的架构原则。
用法侧对应仓库内 user-guide 11-custom-models,别把两种配方混在一起:接 Ollama 只要一个 [model.*],把 base_url 指向 http://localhost:11434/v1;而 GROK_MODELS_BASE_URL(或 [endpoints] models_base_url)是另一种「自定义模型端点」模式——从 {base_url}/models 拉整张模型表、跳过全部内置模型、改走 API key 鉴权(免 grok login)。BYOK 记得设 context_window:自己配的新模型默认给 200k,从端点拉来却没报窗口的默认 256k,都可能和实际不符。
和《从 LLM 到 Coding Agent》对照
对照 raw-llm-api:最小实现里模型端点常是写死的一个。grok 的增量是一整套模型目录 + 凭据解析 + 协议/鉴权正交 + URL-agnostic 采样器,让「换任意模型」成为配置而非改码。这也是 api-streams 那三种后端存在的最终理由。Part 4 扩展机制完——下一部分钻进终端 UI。