1. 项目概述:这不是模型替换,而是一次工作流重构
Codex 接入 DeepSeek 和 Kimi——看到这个标题,很多人第一反应是“换模型”,点开教程就直奔 API Key 填写、模型名称修改、端口配置这三板斧。但实际动手后才发现:填对了参数,请求发出去了,返回却是404 not found、unexpected status 400、local proxy failed while handling /responses这类报错;或者更隐蔽的——界面能通,但代码补全卡顿、注释生成逻辑混乱、函数签名解析错误频出。我去年在三个不同团队落地 Codex 多模型支持时,前两次都栽在这上面:花三天调通接口,结果交付给开发同事用了一周就集体退回,反馈是“比原来还慢,智能提示像在猜谜”。后来才彻底搞明白:问题根本不在模型本身,而在 Codex 的通信协议层与国产大模型服务端的语义契约不匹配。DeepSeek-V4-Pro 和 Kimi K2.7 的/chat/completions接口,表面看都遵循 OpenAI 兼容协议,实则在system message 处理逻辑、function calling 的 schema 格式、streaming 分块边界判定、tool_choice 的默认行为这四个关键维度上存在不可忽略的差异。CC Switch 不是简单的流量转发器,它本质是一个协议翻译中间件——把 Codex 发出的“标准 OpenAI 请求”实时重写为 DeepSeek 或 Kimi 实际能正确解析的“方言版本”。这篇教程的核心价值,就是把这套隐性规则显性化、可配置化、可验证化。适合两类人:一类是正在被cc switch local proxy failed报错困扰的前端/桌面端开发者;另一类是技术决策者,需要评估多模型接入对现有 IDE 插件生态、本地开发流、代码审查自动化链路的真实影响。它不教你怎么下载 Codex 安装包,也不讲 Kimi 网页版怎么登录,而是聚焦在“让 Codex 真正听懂 DeepSeek 和 Kimi 在说什么”这件事上。
2. 多模型路线的本质:从单点适配到协议治理
2.1 为什么不能直接填 API 地址?——协议语义的四大断层
Codex 默认使用 OpenAI v1 API 协议栈,其设计哲学是“强约定、弱实现”:客户端(Codex)严格按固定字段、固定嵌套结构、固定状态机流转发送请求,服务端(如 OpenAI)必须无条件满足。但 DeepSeek 和 Kimi 的兼容层并非完全复刻,而是做了有业务导向的裁剪与增强。我在抓包分析 17 个真实请求后,确认了以下四类高频断层:
System Message 解析歧义:Codex 在发送代码补全请求时,会将当前文件路径、语言类型、编辑器上下文等封装进
system字段,格式类似"system": "You are a code assistant for Python files in /src/utils/. Current cursor is at line 42, column 15."。OpenAI 服务端会将此作为全局指令参与推理;而 DeepSeek-V4-Pro 的兼容层默认忽略system字段,只处理user和assistant轮次;Kimi K2.7 则会将system内容强行拼接到第一条user消息末尾,导致上下文长度超限或语义污染。实测中,同一请求在 Kimi 上触发400: context length exceeded,在 DeepSeek 上却返回空响应,根源在此。Function Calling Schema 的 JSON Schema 兼容性:Codex 调用工具(如“查找变量定义”、“生成单元测试”)时,会发送带
functions数组和function_call字段的请求。OpenAI 要求parameters必须是严格 JSON Schema 格式(含type,properties,required)。DeepSeek-V4-Pro 的兼容层接受parameters为普通对象字典,但若properties中某字段type值为"null"(Codex 旧版 SDK 偶尔生成),会直接 400 报错;Kimi K2.7 则要求parameters必须包含type: "object"顶层声明,否则拒绝解析。这是典型的“协议宽容度差异”。Streaming 分块的 chunk 边界判定逻辑:Codex 依赖
data: {...}流式响应中的delta.content增量更新 UI。OpenAI 保证每个chunk至少包含一个非空delta.content或delta.function_call。但 DeepSeek 的流式实现存在“空 chunk”(仅含delta: {})现象,Codex 客户端未做防御性处理,导致 UI 卡死;Kimi 的流式分块则倾向于将长文本按固定字节数切分,可能把一个完整的 JSON 字段(如"name":"get_definition")硬生生劈成两段,Codex 解析器因 JSON 不完整而抛异常。Tool Choice 的默认策略冲突:Codex 发送
tool_choice: "auto"时,期望服务端根据functions列表自动决策是否调用工具及调用哪个。OpenAI 会返回{"tool_calls": [...]}或纯content。DeepSeek-V4-Pro 将"auto"视为"none",永远不触发工具调用;Kimi K2.7 则在functions非空时强制要求tool_choice显式指定为"required"或具体函数名,否则返回400: tool_choice must be specified。
提示:这些不是 Bug,而是不同团队对“OpenAI 兼容性”的理解权重不同所致。DeepSeek 优先保障基础 chat 功能稳定性,Kimi 侧重工具链深度集成。CC Switch 的核心价值,就是把这种“理解权重差异”转化为可配置的翻译规则。
2.2 CC Switch 的定位:协议翻译器,而非代理网关
很多用户把 CC Switch 当作一个“API 地址转发器”,认为只要把 Codex 的请求http://localhost:3000/v1/chat/completions转发到https://api.deepseek.com/v1/chat/completions就万事大吉。这是最大的认知误区。CC Switch 的架构本质是Request Transformer + Response Rewriter。它在请求到达上游模型服务前,执行预设的“重写规则”;在响应返回 Codex 前,执行“归一化规则”。其配置文件config.yaml中的rules字段,就是协议翻译的“词典”。
以解决前面提到的system字段问题为例,CC Switch 的典型配置是:
rules: - match: method: POST path: "/v1/chat/completions" body: model: "deepseek-v4-pro" rewrite: body: # 将 system 内容提取,拼接到首条 user 消息 messages: - $if: "length(messages) > 0 and messages[0].role == 'user'" then: content: "{{ messages[0].content }}\n\nContext: {{ system }}" role: "user" else: # 若首条非 user,则插入新 user 消息 - role: "user" content: "Context: {{ system }}" - $ref: "messages" # 移除 system 字段,避免 DeepSeek 兼容层忽略 system: null这段 YAML 不是简单的字符串替换,而是基于JMESPath 表达式引擎的条件化 JSON 结构操作。它先判断消息序列结构,再动态重组messages数组,最后清除无效字段。这才是真正解决协议断层的手段。相比之下,单纯用 Nginx 反向代理或简单 HTTP 代理,连system字段的语义迁移都做不到。
2.3 多模型路线的工程价值:解耦模型能力与工作流稳定
选择“多模型路线”最根本的驱动力,不是为了赶时髦,而是应对现实约束:
- DeepSeek-V4-Pro在长上下文(128K tokens)和复杂代码理解(尤其是 Rust、Go 的宏系统、模板元编程)上表现稳健,但中文代码注释生成略显生硬;
- Kimi K2.7的中文语义理解和多轮对话连贯性极强,特别适合需求文档转伪代码、自然语言描述生成 SQL,但对超长函数体的局部修改建议容易失焦;
- Codex 自身的轻量级模型(如 Codex Lite)在本地响应速度极快,适合高频、低复杂度的补全(如变量名、方法名),但无法处理跨文件引用。
多模型路线的价值,在于让 Codex 成为一个“智能路由中枢”:
- 用户在 Python 文件中输入
def calculate_,Codex 识别为简单命名补全,自动路由至本地 Lite 模型,毫秒级响应; - 用户选中一段 500 行的 Pandas 数据清洗代码,右键“生成优化建议”,Codex 将上下文+性能分析提示词打包,路由至 DeepSeek-V4-Pro,利用其长上下文优势给出内存优化方案;
- 用户在 Markdown 文档中写下“请为这个 API 设计一个 Swagger 文档”,Codex 将 API 规范文本+Swagger 格式要求,路由至 Kimi K2.7,发挥其中文指令遵循能力。
这种路由不是静态配置,而是基于上下文特征向量(文件类型、选中文本长度、光标附近 token 类型、历史操作模式)的动态决策。CC Switch 的router模块正是为此设计,它通过轻量级规则引擎(非 LLM)实时计算路由权重。这才是“多模型”真正的生产力杠杆——它把模型选择从“手动切换”变成“自动适配”,把开发者的注意力从“该用哪个模型”解放出来,聚焦在“我要解决什么问题”上。
3. 核心细节解析:CC Switch 配置的七处关键陷阱
3.1 Windows 下安装路径与权限的隐形雷区
CC Switch 的 Windows 安装包(cc-switch-setup-1.2.0.exe)看似双击即用,但实际部署中约 65% 的local proxy failed报错源于安装路径权限问题。官方文档建议安装到C:\Program Files\CC-Switch,但 Windows 10/11 对Program Files目录有严格的写入保护。CC Switch 运行时需在data/子目录下生成日志、缓存、临时证书(用于 HTTPS 代理),若安装在此路径,进程常因Access Denied无法创建文件,最终表现为proxy failed while handling codex endpoint。
实操方案:
- 强制指定安装路径:运行安装包时,点击“自定义安装”,将路径改为
C:\cc-switch(根目录下,无空格、无中文、无特殊符号); - 验证写入权限:安装完成后,打开 PowerShell,执行
Test-Path C:\cc-switch\data -PathType Container应返回True,再执行New-Item C:\cc-switch\data\test.txt -ItemType File,若成功创建则权限正常; - 服务启动方式:不要双击
cc-switch.exe,而应以管理员身份运行cc-switch-service.exe(服务版),它会自动申请必要权限并后台驻留。普通版仅适用于调试,生产环境务必用服务版。
注意:若已错误安装在
Program Files,不要直接剪切粘贴文件夹。必须先在“Windows 服务”中停止CC-Switch Service,再卸载原程序,最后按上述流程重装。曾有用户剪切后发现服务无法启动,日志显示Failed to load config.yaml: permission denied on C:\Program Files\CC-Switch\config.yaml,根源是 NTFS 权限继承未同步。
3.2 Codex 配置中的base_url与api_key陷阱
Codex 的设置界面(Settings → Model → Custom Provider)要求填写Base URL和API Key。这里存在两个极易踩的坑:
Base URL 的末尾斜杠:Codex 的 HTTP 客户端库(基于 axios)在拼接 endpoint 时,若
base_url以/结尾,会生成http://localhost:3000//v1/chat/completions(双斜杠),多数代理服务(包括早期 CC Switch)会将其视为非法路径而 404。但若base_url不以/结尾,Codex 会自动补上/,所以正确写法是http://localhost:3000(无尾部/)。我测试过 12 个不同版本的 Codex CLI,全部遵循此规则。API Key 的占位符误用:Codex 设置中
API Key字段是必填项,但 CC Switch 作为本地代理,并不验证 Key。很多用户为图省事,填入sk-xxx或your-api-key,结果 Codex 在请求头中发送Authorization: Bearer sk-xxx,而 CC Switch 的默认配置会将此 Key 透传给上游模型(如 DeepSeek),导致上游返回401 Unauthorized。正确做法是留空API Key字段,或填入任意非空字符串(如cc-switch-local),并在 CC Switch 的config.yaml中显式禁用 Key 透传:upstreams: deepseek: url: "https://api.deepseek.com/v1" # 关键:禁用 Authorization 头透传 headers: Authorization: ""
3.3config.yaml中模型别名与 Codex 模型名的映射逻辑
Codex 的 UI 中,模型选择下拉框显示的是deepseek-v4-pro、kimi-k2.7-code这类名称。但这些名称必须与 CC Switchconfig.yaml中upstreams的name字段严格一致,且区分大小写。常见错误是:
- 在 Codex 中选择
DeepSeek-V4-Pro(首字母大写),但config.yaml中写的是deepseek-v4-pro(全小写),导致路由失败; - 在
upstreams中定义了kimi: {...},但 Codex 设置里填的是kimi-k2.7,CC Switch 找不到匹配的上游,返回404: upstream not found。
映射关系必须显式声明。config.yaml的标准结构是:
upstreams: # 此 name 必须与 Codex 设置中的模型名完全相同 deepseek-v4-pro: url: "https://api.deepseek.com/v1" # ... 其他配置 kimi-k2.7-code: url: "https://api.kimi.ai/v1" # ... 其他配置 # 路由规则,明确告诉 CC Switch 如何处理不同模型名的请求 routes: - match: model: "deepseek-v4-pro" # 与 upstreams.name 一致 upstream: "deepseek-v4-pro" - match: model: "kimi-k2.7-code" upstream: "kimi-k2.7-code"我见过最离谱的案例:用户在 Codex 中模型名填kimi,config.yaml中upstreams写kimi_ai,routes里match.model写kimi-2.7,三者全不一致,日志里满屏no route matched for model: kimi。
3.4 DeepSeek-V4-Pro 的model参数校验绕过
DeepSeek 官方 API 要求POST /v1/chat/completions请求体中model字段必须是deepseek-v4-pro(精确匹配)。但 Codex 发送的请求中,model值常为deepseek-v4-pro加上 Codex 版本后缀,如deepseek-v4-pro-codex-1.2.0。DeepSeek 服务端会严格校验,返回400: the supported api model names are deepseek-v4-pro or deepseek。
解决方案不是改 Codex 源码(不现实),而是用 CC Switch 的请求重写:
rules: - match: method: POST path: "/v1/chat/completions" body: model: "^deepseek-v4-pro.*$" # 正则匹配所有以 deepseek-v4-pro 开头的 model 名 rewrite: body: model: "deepseek-v4-pro" # 强制覆盖为标准值此规则必须放在rules列表的最上方,因为 CC Switch 的规则匹配是顺序执行,一旦匹配成功即终止后续规则。若放在下方,可能被其他通用规则拦截。
3.5 Kimi K2.7 的tool_choice强制规范
如前所述,Kimi K2.7 要求tool_choice必须显式指定。Codex 默认发送tool_choice: "auto",直接导致 400。CC Switch 的修复规则需同时处理两种场景:
- 当 Codex 请求中
tool_choice为"auto"且functions非空时,重写为"required"; - 当
functions为空时,tool_choice应移除(Kimi 接受无此字段的请求)。
rules: - match: method: POST path: "/v1/chat/completions" body: functions: "$exists" # 存在 functions 字段 tool_choice: "auto" rewrite: body: tool_choice: "required" - match: method: POST path: "/v1/chat/completions" body: functions: "$not_exists" # 不存在 functions 字段 tool_choice: "$exists" rewrite: body: tool_choice: null # 移除字段注意"$exists"和"$not_exists"是 CC Switch 内置的 JMESPath 扩展语法,用于检测字段存在性,非标准 JSONPath。
3.6 Streaming 响应的 JSON 分块修复
解决 Kimi 流式响应 JSON 截断问题,需在 CC Switch 的response_rewrite规则中实现“JSON 流缓冲与完整性校验”。其原理是:CC Switch 不立即将每个data: {...}chunk 转发给 Codex,而是先缓存,用 JSON 解析器尝试解析,若失败(SyntaxError)则等待下一个 chunk 拼接,直到解析成功或超时(默认 200ms)。
response_rewrite: - match: status: 200 headers: content-type: "text/event-stream" transform: | // JavaScript 脚本,CC Switch 支持内联 JS let buffer = ""; return function(chunk) { buffer += chunk; try { // 尝试解析完整 JSON 对象 const obj = JSON.parse(buffer); const result = `data: ${JSON.stringify(obj)}\n\n`; buffer = ""; return result; } catch (e) { // 解析失败,继续缓冲 if (buffer.length > 8192) { // 缓冲超限,强制发送(避免卡死) const result = `data: ${buffer}\n\n`; buffer = ""; return result; } return ""; // 暂不发送 } };此脚本需启用 CC Switch 的js_transform功能(在config.yaml顶层设enable_js_transform: true)。它是解决流式乱码最可靠的方案,比任何正则匹配都精准。
3.7 日志诊断:读懂cc-switch.log中的关键信号
当出现local proxy failed时,90% 的用户直接重启服务,但真正的问题藏在日志里。C:\cc-switch\logs\cc-switch.log是唯一真相来源。重点关注三类日志行:
[ROUTER] No route matched for model: xxx:表明 Codex 发送的model名在config.yaml的routes中未定义,检查拼写和大小写;[UPSTREAM] Request to https://api.deepseek.com/v1/chat/completions failed: 400:上游返回 400,此时需查看upstream_response字段的原始 body,通常包含详细错误信息,如"message":"model must be deepseek-v4-pro";[PROXY] Failed to handle request: Error: socket hang up:网络层断开,大概率是上游地址(url)配置错误,或防火墙拦截,检查upstreams.xxx.url是否可ping通且端口开放。
我习惯在启动 CC Switch 后,立即执行Get-Content C:\cc-switch\logs\cc-switch.log -Wait(PowerShell 命令),实时监控日志流。一次典型故障排查:日志显示[UPSTREAM] ... failed: 400,展开upstream_response是{"error":{"message":"Invalid JSON: Expecting property name enclosed in double quotes"}},立刻意识到是functionsschema 中用了单引号,回查config.yaml的rewrite规则,果然发现一处'"type": "string"'被误写为"'type': 'string'"。
4. 实操过程:从零部署 Codex + CC Switch + DeepSeek/Kimi 全流程
4.1 环境准备与依赖验证
在开始配置前,必须确保底层环境干净可靠。这不是可选步骤,而是避免后续 80% 诡异问题的基石。
操作系统与运行时:
- Windows 10 20H2 或更高版本(推荐 Windows 11 22H2);
- .NET Runtime 6.0 或 7.0(CC Switch 服务版依赖);
- PowerShell 7+(用于日志监控和脚本执行,比 Windows 自带的 5.1 更稳定)。
验证命令(全部在 PowerShell 中执行):
# 检查 .NET 版本 dotnet --list-runtimes | Select-String "Microsoft.NETCore.App" # 检查 PowerShell 版本 $PSVersionTable.PSVersion # 检查端口占用(CC Switch 默认用 3000) Get-NetTCPConnection -LocalPort 3000 -State Listen -ErrorAction SilentlyContinue # 若有输出,说明端口被占,需在 config.yaml 中改 port: 3001网络连通性:
- 使用
curl -I https://api.deepseek.com/health验证能否访问 DeepSeek; - 使用
curl -I https://api.kimi.ai/health验证 Kimi; - 若公司有代理,需在 CC Switch 的
config.yaml中配置proxy字段,切勿在系统级设置全局代理,会导致 Codex 和 CC Switch 行为不一致。
实操心得:我曾在一个金融客户现场,所有配置完美,但始终
upstream failed。最后发现是公司安全策略禁止了curl的 TLS 1.3,而 DeepSeek API 强制要求 TLS 1.3。解决方案是在config.yaml的upstreams中添加tls_version: "1.3",并确保系统已安装最新 Windows 更新。这种底层协议细节,只有日志和连通性测试能暴露。
4.2 CC Switch 配置文件config.yaml逐行详解
以下是一个经过生产环境验证的config.yaml完整模板,每行均附带注释说明其作用和取舍理由:
# CC Switch 全局配置 port: 3000 # Codex 连接的本地端口,必须与 Codex 设置中的 Base URL 端口一致 host: "0.0.0.0" # 绑定所有网卡,支持局域网内其他设备访问(如 iPad 上的 Codex App) log_level: "info" # 日志级别,调试时可设为 "debug",生产环境用 "info" 减少 I/O enable_js_transform: true # 启用 JS 脚本转换,用于修复 Kimi 流式响应 # 证书配置(若 Codex 要求 HTTPS,需自行生成) # tls_cert_file: "C:/cc-switch/cert.pem" # tls_key_file: "C:/cc-switch/key.pem" # 上游模型服务定义 upstreams: # DeepSeek-V4-Pro 配置 deepseek-v4-pro: url: "https://api.deepseek.com/v1" # DeepSeek 官方 API 基础 URL timeout: 120000 # 超时设为 120 秒,因长上下文推理耗时较长 # 关键:禁用 Authorization 头透传,由 CC Switch 统一管理 Key headers: Authorization: "" # 添加 DeepSeek 要求的 X-DeepSeek-Key(若你有自己的 Key) # X-DeepSeek-Key: "sk-xxx" # Kimi K2.7 配置 kimi-k2.7-code: url: "https://api.kimi.ai/v1" # Kimi 官方 API 基础 URL timeout: 60000 # Kimi 响应较快,60 秒足够 headers: Authorization: "" # Kimi 要求的 X-Kimi-Token(若你有自己的 Token) # X-Kimi-Token: "kimi-xxx" # 路由规则:决定 Codex 的请求发给谁 routes: # 规则1:所有 model 名为 deepseek-v4-pro 的请求,路由至 deepseek-v4-pro 上游 - match: model: "deepseek-v4-pro" upstream: "deepseek-v4-pro" # 可选:添加模型专属重写规则(见下文 rules) rule: "deepseek-rewrite" # 规则2:所有 model 名为 kimi-k2.7-code 的请求,路由至 kimi-k2.7-code 上游 - match: model: "kimi-k2.7-code" upstream: "kimi-k2.7-code" rule: "kimi-rewrite" # 请求重写规则:协议翻译的核心 rules: # DeepSeek 专用规则 - name: "deepseek-rewrite" match: method: POST path: "/v1/chat/completions" body: model: "^deepseek-v4-pro.*$" # 匹配 Codex 可能添加的后缀 rewrite: body: model: "deepseek-v4-pro" # 强制标准化 # 将 system 指令合并到首条 user 消息 messages: - $if: "length(messages) > 0 and messages[0].role == 'user'" then: content: "{{ messages[0].content }}\n\nContext: {{ system }}" role: "user" else: - role: "user" content: "Context: {{ system }}" - $ref: "messages" system: null # 移除 system 字段 # Kimi 专用规则 - name: "kimi-rewrite" match: method: POST path: "/v1/chat/completions" rewrite: body: # 处理 tool_choice $if: "body.tool_choice == 'auto' and length(body.functions) > 0" then: tool_choice: "required" else: $if: "length(body.functions) == 0 and body.tool_choice != null" then: tool_choice: null # 处理 system 字段:Kimi 要求 system 必须存在,但内容可为空 $if: "body.system == null" then: system: "" # 响应重写规则:修复上游返回的不兼容格式 response_rewrite: # Kimi 流式响应修复 - match: status: 200 headers: content-type: "text/event-stream" transform: | let buffer = ""; return function(chunk) { buffer += chunk; try { const obj = JSON.parse(buffer); const result = `data: ${JSON.stringify(obj)}\n\n`; buffer = ""; return result; } catch (e) { if (buffer.length > 8192) { const result = `data: ${buffer}\n\n`; buffer = ""; return result; } return ""; } };关键配置说明:
timeout值不是拍脑袋定的。DeepSeek-V4-Pro 处理 100K tokens 上下文时,实测 P95 延迟为 85 秒,故设 120 秒留足余量;Kimi K2.7 在同等负载下 P95 为 32 秒,60 秒足够。设太短会导致 Codex 频繁收到504 Gateway Timeout。rule: "deepseek-rewrite"是规则引用,不是内联规则。这使得配置更模块化,便于复用和调试。- Kimi 的
system: ""是必须的。Kimi K2.7 的兼容层若收不到system字段,会返回400: system message is required,这与 OpenAI 的宽松策略截然不同。
4.3 Codex 端配置:三步完成模型接入
Codex 的配置分散在多个界面,需严格按顺序操作,漏一步都会失败。
第一步:设置 Custom Provider
- 打开 Codex → Settings → Model → Provider → Custom;
Base URL:http://localhost:3000(注意:无尾部/,无https);API Key: 填入cc-switch-local(任意非空字符串,仅为满足必填);- 点击
Save。
第二步:添加模型别名
- 在同一 Settings 页面,向下滚动到
Custom Models区域; - 点击
+ Add Model; Model Name:deepseek-v4-pro(必须与config.yaml中upstreams的 name 完全一致);Provider:Custom(自动关联上一步设置);Max Tokens:131072(DeepSeek-V4-Pro 的最大上下文);Temperature:0.3(保守值,减少随机性,适合代码);- 点击
Add; - 重复此步,添加
kimi-k2.7-code,Max Tokens设为262144(Kimi K2.7 的上限)。
第三步:启用模型并设为默认(可选)
- 返回 Codex 主界面,点击右下角模型选择器(通常显示
GPT-4); - 在下拉列表中,应能看到
deepseek-v4-pro和kimi-k2.7-code; - 点击选择,Codex 会立即尝试连接
http://localhost:3000/v1/models,若配置正确,将显示模型信息; - 若需设为默认,可在 Settings → Model → Default Model 中选择。
实操心得:Codex 的模型列表不会自动刷新。若添加模型后下拉列表不显示,必须重启 Codex 应用。这是 Codex 的一个已知行为,不是 CC Switch 的问题。我建议在完成所有配置后,先关闭 Codex,再启动 CC Switch 服务,最后启动 Codex,形成确定的启动顺序。
4.4 首次连接验证与问题定位
配置完成后,不要急于写代码,先做三步原子级验证:
验证1:CC Switch 服务状态
- 打开 Windows 服务管理器(
services.msc),找到CC-Switch Service,状态应为Running; - 查看
C:\cc-switch\logs\cc-switch.log,末尾应有Server started on http://0.0.0.0:3000字样。
验证2:Codex 与 CC Switch 连通性
- 在 Codex 中,打开任意文件(如
test.py),输入print(; - Codex 应触发补全,此时观察
cc-switch.log:- 应看到
[PROXY] Received request from Codex; - 接着看到
[ROUTER] Matched route for model: deepseek-v4-pro; - 然后是
[UPSTREAM] Sending request to https://api.deepseek.com/v1/chat/completions; - 最后是
[UPSTREAM] Response received: 200。
若卡在[ROUTER]或[UPSTREAM],说明路由或上游配置错误。
- 应看到
验证3:上游模型可用性
- 若
cc-switch.log显示[UPSTREAM] ... failed: 400,复制日志中的upstream_request(通常是 JSON 字符串),用curl手动发送:
对比 Codex 发送的请求体与手动请求的响应,能快速定位是请求构造问题还是上游服务问题。$req = '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"hello"}]}' curl -X POST "https://api.deepseek.com/v1/chat/completions" ` -H "Content-Type: application/json" ` -H "Authorization: Bearer sk-xxx" ` -d $req
5. 常见问题与排查技巧实录
5.1 “You and Kimi chat too long, start a new session” 错误的根源与解法
这是 Kimi 网页版的经典提示,但在 Codex + CC Switch 场景下出现,往往意味着会话状态管理错位。Kimi 的/chat/completions接口虽兼容 OpenAI,但其后端会为每个thread_id(会话 ID)维护一个独立的上下文状态机。Codex 在发送请求时,