☰
炸裂!!!给 codeX 装上本地大脑:cc-switch_Ollama 接入全记录
2026/10/9 4:56:54 网站建设 项目流程

1. 为什么我要把 Codex 的请求从云端拽回本地

先说清楚这篇在解决什么问题。Codex CLI 是 OpenAI 出的终端编码代理,默认所有请求都发往云端 API;cc-switch 是一个桌面端的 AI 工具总控台,能统一管理 Codex、Claude Code、Gemini CLI 这些 CLI 的供应商入口;Ollama 则是本机跑推理的运行时,默认监听127.0.0.1:11434。把这三者串起来,就是给 Codex 装一个「本地大脑」——请求不出本机,模型跑在自己的显卡上,费用只剩电费。

适合谁看:手上有能跑 7B 到 35B 量化模型的机器(Mac 统一内存或带独显的 Windows 工作站都行),平时用 Codex CLI 写代码,又希望把一部分请求切到本地模型省钱的开发者。如果你只是偶尔用一次,云端更省心;但如果你每天要跑几十上百次补全和重构,本地推理的账算下来差别很大。

我自己的场景是两台机器:一台 M1 Pro 的 MacBook 做日常开发,一台 RTX 5090 加 96GB 内存的 Windows 工作站跑重活。Ollama 里躺着 Qwen、DeepSeek、GLM 几个模型,平时用着挺顺。可一打开 Codex,请求还是往云端走,本地模型就在硬盘里吃灰。cc-switch 本身很好用,一个 App 管住所有 CLI 的供应商切换,但它内置的 Provider 全是云端的,没有 Ollama,也没有任何本地推理入口。

于是我去翻了 cc-switch 的源码,原本以为要大动干戈,结果发现距离支持 Ollama 只差最后一公里:类型系统加一个分类、预设里加一个模板、代理层补一个 URL 拼接、再加三层防御兜底。改完提交了 5 个 commit,Codex 的请求就能直接路由到本机 Ollama。下面把整条接入路径拆开讲,包括 cc-switch 侧可复制的配置片段、Ollama 服务地址和模型名的填写方式,以及怎么用一条最小请求验证链路是否打通。

2. 前置准备:Ollama 服务、cc-switch 与模型命名

动手之前先把三样东西准备好,顺序别乱。

第一是 Ollama 本身。装好之后确认服务在跑,默认端口 11434。打开终端执行:

ollama list

能看到模型列表就说明服务正常。如果列表是空的,先拉一个模型下来,比如:

ollama pull qwen2.5:7b

拉完再ollama list确认。这里有个容易忽略的点:Ollama 的 OpenAI 兼容接口路径是/v1,完整地址是http://127.0.0.1:11434/v1,而 Chat Completions 的完整端点是http://127.0.0.1:11434/v1/chat/completions。后面配置里填的 base_url 只到/v1,/chat/completions由代理层拼上去——这个细节是后面 404 报错的根源,先记住。

第二是 cc-switch。用官方版本的话,供应商列表里没有 Ollama 预设,需要手动添加一个自定义供应商;用带 Ollama 支持的 fork 版本(比如feat/ollama-codex-proxy分支)则可以直接选预设。两条路都行,区别只是手动填的字段多一点。我建议先用官方版手动配一遍,理解每个字段的含义,再决定要不要换 fork。

第三是模型命名。Ollama 里模型的完整名字带 tag,比如qwen2.5:7b、qwen2.5:14b、qwen3:8b。填到 cc-switch 的 Model ID 字段时,必须和ollama list里显示的完全一致,包括冒号和后面的 tag。写成qwen2.5而不带:7b,Ollama 会返回 model not found。这一点在云端供应商那里不常见,因为云端模型名通常不带 tag,所以从云端切过来的人特别容易踩。

还有一个前置认知:Codex CLI 说的是 Responses API 协议,Ollama 只认 Chat Completions。两者不是一回事,中间必须有一次协议转换。cc-switch 的代理层负责这件事,所以配置里要明确告诉它「这个供应商走 Chat Completions」,否则请求会原样透传给 Ollama,对方看不懂,直接报错。这个开关就是后面配置片段里的apiFormat字段。

3. 可复制配置:cc-switch 侧 JSON 与 Codex 的 TOML

这一节是全文最该照着抄的部分。cc-switch 的供应商配置本质是一段 JSON,存在它的配置目录里;Codex 自己还有一份~/.codex/config.toml,两者要配合。

先看 cc-switch 侧的供应商配置。在「供应商」页面点添加,选自定义,然后按下面的结构填。如果你能直接编辑配置文件,就照这个 JSON 写:

{ "name": "Ollama (Local)", "category": "local", "base_url": "http://127.0.0.1:11434/v1", "apiFormat": "openai_chat", "models": [ "qwen2.5:7b", "qwen2.5:14b", "qwen3:8b" ], "codexChatReasoning": { "supportsThinking": true, "supportsEffort": false, "thinkingParam": "thinking", "outputFormat": "reasoning" } }

逐个字段说。category填local,这样在供应商列表里会和云端供应商视觉隔离,一眼看出这是本机模型不花钱。base_url只到/v1,不要自己补/chat/completions。apiFormat填openai_chat,这是告诉代理层「走 Chat Completions 转换」的关键开关,填错或漏填,请求就会以 Responses 格式打到 Ollama,必然失败。

models数组里列你本机实际有的模型名,带 tag。codexChatReasoning这一段是给带思考能力的模型用的:supportsThinking打开,supportsEffort必须关掉,因为 Ollama 不认识reasoning.effort这个参数,传过去会 400。outputFormat填reasoning而不是thinking——Ollama 的思考 token 走的是delta.reasoning字段,不是 OpenAI/Claude 那套delta.thinking。这个值配错,Codex CLI 收不到推理过程会直接崩,而且不给任何有意义的报错,非常难查。

再看 Codex 侧的~/.codex/config.toml。cc-switch 开启 Codex 路由接管后,会往这个文件里写配置。核心几行长这样:

model_provider = "ollama-local" model = "qwen2.5:7b" [model_providers.ollama-local] name = "Ollama (Local)" base_url = "http://127.0.0.1:15721/v1" wire_api = "chat" [model_providers.ollama-local.model_reasoning] effort = "none"

注意这里的base_url指向的是 cc-switch 的代理端口15721,不是 Ollama 的 11434。请求先到 cc-switch,由它做协议转换和路由,再转发给 Ollama。wire_api填chat,和前面的apiFormat呼应。effort设成none,避免 Codex 往请求里塞reasoning.effort。

如果你想把 endpoint 改到 TaoToken 来统一 Key 通道,做法是把上面base_url换成 TaoToken 的 API 地址https://taotoken.net/api,Model ID 换成你要用的云端模型名,Key 在 cc-switch 的供应商配置里填 TaoToken 控制台生成的 Key。这样本地模型和云端模型共用一套 cc-switch 入口,切换时只改供应商,不用动 Codex 的配置。TaoToken 的接入文档在 https://taotoken.net/doc ,API Key 在 https://taotoken.net/api-keys 生成,模型对话调试入口在 https://taotoken.net/model-chat 。长期跑编码和 Agent 任务的话,Coding Plan 页面 https://taotoken.net/coding-plan 有更细的额度说明。

配置写完保存,回到 cc-switch 的「Codex 路由」页面,开启接管,选中刚建的 Ollama 供应商。这一步不做,请求还是走云端。

4. 验证链路:一条最小请求打通 Responses 到 Chat 的转换

配置填完不代表通了,必须发一条真实请求验证。分两步,先验 Ollama 本身,再验整条链路。

第一步,绕过 cc-switch,直接打 Ollama 的 OpenAI 兼容接口:

curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "只回复两个字:通了"}], "stream": false }'

返回里能看到choices[0].message.content是「通了」,说明 Ollama 侧没问题。如果这里就报 model not found,回去检查模型名带没带 tag;如果连接被拒,检查 Ollama 服务在不在跑。

第二步,走 cc-switch 代理,验证协议转换。先确认代理端口在监听:

curl -s http://127.0.0.1:15721/v1/models

能返回模型列表,说明代理层活着。然后发一条 Chat Completions 请求到代理端口:

curl http://127.0.0.1:15721/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "用一句话说明你跑在哪"}], "stream": true }'

看到 SSE 流式返回、delta里逐字吐内容,链路就通了。这一步的关键是观察返回里有没有delta.reasoning字段——如果模型带思考能力,这个字段应该出现;如果配成了thinking,这里会空,Codex CLI 那边就会出问题。

第三步,直接跑 Codex CLI:

codex

进去之后输入一句让它写个简单函数,观察输出是不是流式的、首 token 是不是很快。本地推理的 TTFT 通常在 50ms 以内,比云端 500ms 起步快一个数量级,体感差异非常明显。如果 Codex 里能看到本地模型列表、请求也能正常返回,整条链路就算打通了。

验证通过后,你可以在 cc-switch 里保留云端供应商和本地供应商两套配置,需要省钱时切本地,需要更强模型时切云端,Codex 侧不用改任何东西。

5. 常见报错排查:401、404、502 与 OAuth 失败

这一节按真实报错对照,遇到问题直接查表。

401 Unauthorized。本地 Ollama 不需要 Key,出现 401 通常是 cc-switch 把请求路由到了云端供应商,或者你在供应商配置里填了一个无效的 Key。检查「Codex 路由」里选中的是不是 Ollama 供应商,以及base_url有没有误填成云端地址。如果你是把 endpoint 改到 TaoToken 统一 Key 通道,401 就是 Key 本身的问题,去 https://taotoken.net/api-keys 重新生成一个,确认填到了正确字段。

404 Not Found,请求打到了/v1而不是/v1/chat/completions。这是最隐蔽的一个。根因是代理层做 Responses 到 Chat 的转换时,build_url发现 base_url 已经以/v1结尾,就误以为 endpoint 已经被包含,把/chat/completions丢掉了,最终请求变成POST http://127.0.0.1:11434/v1,Ollama 返回 404。修复方式是在build_url之后做二次校验:如果最终 URL 里不包含/chat/completions,就手动补回去。用官方版 cc-switch 遇到这个错,说明它还没带这个修复,需要换到带 Ollama 支持的 fork,或者手动改forwarder.rs。

400 Bad Request,提示 reasoning.effort 参数非法。Ollama 不认识reasoning.effort。根因是 cc-switch 的 UI 表单在编辑供应商时会把supportsEffort覆盖成 true,导致请求里带上了这个参数。解决办法是在代理层对 Ollama 供应商强制supportsEffort = false,不管 UI 怎么写都关掉。手动配置的话,确认codexChatReasoning.supportsEffort是 false,并且~/.codex/config.toml里model_reasoning.effort设成none。

502 Bad Gateway,代理压根没启动。检查 cc-switch 的「Codex 路由」接管有没有开,代理端口 15721 有没有在监听。用curl -s http://127.0.0.1:15721/v1/models测一下,连不上就是代理没起来。

健康检查一直红灯,但请求其实能通。这是isFullUrl的坑。如果配置里写了isFullUrl=true,健康检查会把 base_url 当完整地址直接 GET,但 Ollama 的 base_url 不含/chat/completions,于是 404,指示灯永远红。修复逻辑是:Chat 模式下如果 URL 里没有/chat/completions,就退化回正常拼接模式,别直接请求。

OAuth 相关失败。Codex CLI 首次运行可能引导你走 OAuth 登录云端账号。如果你已经切到本地供应商,这一步应该跳过;如果它仍然弹出来,检查~/.codex/config.toml里的model_provider是不是指向了本地供应商,以及有没有残留的云端凭据在干扰。清理掉旧的 auth 缓存再试。

表单保存后配置被清空。cc-switch 的 UI 在保存供应商时会清掉meta.apiFormat字段,导致代理层不知道要做协议转换。代码层的兜底是:识别到 Ollama 供应商就强制走 Chat 转换。手动配置的话,加完 Ollama 供应商后尽量别再编辑那个表单,避免触发覆盖。

排查顺序建议从下往上:先确认 Ollama 本身能通,再确认代理端口活着,再看协议转换对不对,最后看 Codex 侧配置。大部分问题出在中间两层。

6. 把本地和云端收进同一个入口

链路打通之后,日常用起来是这样:cc-switch 里同时挂着 Ollama 本地供应商和几个云端供应商,Codex 路由接管开着。写常规代码、做重构、跑测试用例这类高频但不需要顶级模型的活,切到本地,零 API 费用,首 token 50ms 以内,代码不出本机。遇到需要强推理的复杂任务,切到云端供应商,几秒钟的事。

如果你希望连云端这一侧也统一 Key 通道,把供应商的base_url指向https://taotoken.net/api,Key 用 TaoToken 控制台生成的,Model ID 填对应模型名。这样本地和云端共用一套 cc-switch 配置结构,切换只改供应商选项。接入细节看 https://taotoken.net/doc ,Key 管理在 https://taotoken.net/api-keys ,想先试模型效果可以用 https://taotoken.net/model-chat ,长期跑编码任务的话 https://taotoken.net/coding-plan 有额度方案。

最后留一个实用技巧:本地模型的上下文窗口和云端不一样,qwen2.5:7b这类小模型上下文通常 32K 到 131K 不等,Codex 默认可能按云端的大窗口发请求,超了会被截断或报错。在 cc-switch 的供应商配置里把模型的上下文窗口标清楚,Codex 侧就不会发超长请求。这个值填错不会立刻报错,但会在长对话里悄悄丢上下文,属于那种「用着用着发现不对劲」的坑,提前标好省事。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询