CC Switch v3.9.0 深度解析:本地 API 代理、自动故障转移与 Universal Provider 的实现原理
CC Switch v3.9.0 是 v3.9 系列预发布版(3.9.0-1、3.9.0-2、3.9.0-3)之后的正式稳定版,于 2026-01-07 发布。该版本的核心主题是:在本地启动一个 Axum 高性能 HTTP 代理服务,统一接管 Claude Code / Codex / Gemini CLI 的 API 请求,并在此基础上叠加自动故障转移(熔断器 + 应用级故障转移队列)、跨应用共享的 Universal Provider、统一管理的 Skills/MCP 等能力,显著提升了多 CLI 工作流的稳定性与可操作性。读完本文,你既能掌握该版本各项功能的用法,也能结合仓库源码理解代理接管、熔断状态机与配置同步背后的实现机制(本文基于 日文版发布说明,English / 中文版 可对照阅读)。
版本亮点总览
v3.9.0 的主要变化可以归纳为八条主线:
- 本地 API 代理(Local API Proxy):统一代理 Claude Code / Codex / Gemini CLI,支持按应用单独接管;
- 自动故障转移(Auto Failover):熔断器保护 + 每个应用独立的故障转移队列与健康状态;
- Universal Provider:一份供应商配置同步到多个应用,面向 NewAPI 等多协议 API 网关;
- Skills 管理改进:多应用共享 Skills、SSOT + React Query 统一管理、旧目录布局迁移;
- 通用配置片段(Common Config Snippet):从编辑器内容或当前供应商中抽取共享配置并合并回已激活供应商;
- MCP 管理:从已安装应用导入 MCP servers,加固同步稳定性与 Windows 兼容性;
- 用量与价格数据:自动更新、缓存指标、时区修正、内建价格表更新;
- Linux 打包:新增 RPM 与 Flatpak 发布产物。
以下按功能模块逐一展开,并给出对应源码位置作为佐证。
本地 API 代理(Local API Proxy)
功能定位
v3.9.0 在本地启动一个基于 Axum 的高性能 HTTP 代理服务器,将 Claude Code、Codex、Gemini CLI 三个应用的 API 请求统一收口处理。其关键能力包括:
- 应用级接管(Takeover):可以按应用单独决定是否让流量经过代理,互不干扰;
- Live 配置接管:启用时会先备份 CLI 的 live 配置,再把请求重定向到本地代理;
- 可观测性:通过请求日志与用量统计支持调试与成本核算;
- 错误请求日志:失败的代理请求也会被详细记录,方便排查上游问题(PR #401,感谢 @yovinchen)。
源码中的接管机制
从源码结构看,"接管"由 ProxyTakeoverStatus 结构描述,每个受支持的应用都有一个独立的布尔位(见 src-tauri/src/proxy/types.rs#L112-L119):
/// 各应用的接管状态(是否改写该应用的 Live 配置指向本地代理)
pub struct ProxyTakeoverStatus {
pub claude: bool,
pub codex: bool,
pub gemini: bool,
pub grokbuild: bool,
pub opencode: bool,
pub openclaw: bool,
}
这意味着接管粒度是"每个应用一个开关",与发布说明中"アプリ別テイクオーバー"(应用级接管)的描述一致;同时仓库后续已将接管范围扩展到 Grok Build、OpenCode、OpenClaw 等更多应用。
接管前的 live 配置备份由 LiveBackup 记录(src-tauri/src/proxy/types.rs#L136-L143),包含应用类型、原始配置 JSON 与备份时间。代理服务的启动流程在 src-tauri/src/services/proxy.rs 中可见:start_with_takeover 会先调用 backup_live_configs() 备份各应用的 live 配置,再改写配置指向本地代理;若启用过程失败,rollback_failed_takeover_activation 会通过 save_live_backup / delete_live_backup 回滚(src-tauri/src/services/proxy.rs#L863-L866)。这与"注意事项"中"CC Switch 会在重定向前备份 live 配置"的说明相互印证。
代理的监听参数由 GlobalProxyConfig 承载(src-tauri/src/proxy/types.rs#L148-L157):
| 字段 | 说明 |
|---|---|
proxy_enabled |
代理总开关 |
listen_address |
监听地址 |
listen_port |
监听端口 |
enable_logging |
是否启用请求日志 |
前端侧,代理相关的界面集中在 src/components/proxy/ 目录(ProxyPanel.tsx、ProxyToggle.tsx、AutoFailoverConfigPanel.tsx、FailoverQueueManager.tsx 等),与后端的代理命令(src-tauri/src/commands/proxy.rs)对应。
自动故障转移(Auto Failover / 熔断器)
状态机
自动故障转移的核心是熔断器(Circuit Breaker):检测到供应商不健康后自动"跳闸",把请求切到备用供应商,并在一段时间后试探恢复。三态定义在 src-tauri/src/proxy/circuit_breaker.rs#L14-L23:
pub enum CircuitState {
/// 关闭状态 - 正常工作
Closed,
/// 打开状态 - 熔断激活,拒绝请求
Open,
/// 半开状态 - 尝试恢复,允许部分请求通过
HalfOpen,
}
状态流转由 allow_request() 判定(请求是否放行、是否占用 HalfOpen 探测名额),并由 record_success() / record_failure() 更新计数;当请求总数达到 min_requests 后,错误率(failed / total)超过 error_rate_threshold 即打开熔断器(src-tauri/src/proxy/circuit_breaker.rs#L272-L278)。
默认参数
CircuitBreakerConfig 的默认值(src-tauri/src/proxy/circuit_breaker.rs#L63-L73):
| 参数 | 默认值 | 含义 |
|---|---|---|
failure_threshold |
4 | 连续失败多少次后打开熔断器 |
success_threshold |
2 | 半开状态下连续成功多少次后关闭熔断器 |
timeout_seconds |
60 | 熔断打开后多久尝试进入半开(秒) |
error_rate_threshold |
0.6 | 错误率超过该值时打开熔断器(0.0–1.0) |
min_requests |
10 | 计算错误率前要求的最小请求数 |
这些参数并非硬编码,而是从"应用级代理配置" AppProxyConfig 热更新而来(src-tauri/src/proxy/types.rs#L162-L187),每个应用(app)独立持有:
| 字段 | 说明 |
|---|---|
enabled |
该应用的代理启用开关 |
auto_failover_enabled |
该应用的自动故障转移开关 |
max_retries |
最大重试次数 |
streaming_first_byte_timeout |
流式首字超时(秒) |
streaming_idle_timeout |
流式静默超时(秒) |
non_streaming_timeout |
非流式总超时(秒) |
circuit_failure_threshold / circuit_success_threshold / circuit_timeout_seconds / circuit_error_rate_threshold / circuit_min_requests |
熔断器参数(对应上表) |
需要特别注意发布说明中的一条行为约定:当自动故障转移处于关闭状态时,超时/重试相关配置不会影响正常请求流程——即这些参数只在 auto_failover_enabled 开启时生效,这解释了为什么配置面板把重试/超时与故障转移放在一起管理(前端对应 src/components/proxy/AutoFailoverConfigPanel.tsx 与 src/components/proxy/FailoverQueueManager.tsx)。
应用级队列与健康状态
"每个应用维护独立的故障转移队列与健康状态"在源码中体现为 ProviderHealth 结构(src-tauri/src/proxy/types.rs#L123-L132),记录 provider_id、app_type、is_healthy、consecutive_failures、最近成功/失败时间与最近错误信息;故障转移的判定与切换逻辑集中在 src-tauri/src/proxy/failover_switch.rs 与 src-tauri/src/proxy/provider_router.rs 中,熔断器实例则按"应用 × 供应商"维度挂在代理服务端(src-tauri/src/proxy/server.rs)。
Universal Provider:一份配置,多应用同步
使用场景
Universal Provider 面向 NewAPI 这类同时提供多种协议端点的 API 网关(PR #348,感谢 @Calcium-Ion):你在一个供应商条目里配置一次 baseUrl 与 apiKey,即可把同一供应商同步到 Claude / Codex / Gemini 多个应用,并可为每个应用单独指定默认模型,免去在三个应用里重复维护几乎相同的供应商配置。
数据结构
UniversalProvider 的完整定义见 src-tauri/src/provider.rs#L688-L719:
pub struct UniversalProvider {
pub id: String,
pub name: String,
/// 供应商类型(如 "newapi", "custom")
#[serde(rename = "providerType")]
pub provider_type: String,
/// 应用启用状态
pub apps: UniversalProviderApps, // { claude, codex, gemini }
#[serde(rename = "baseUrl")]
pub base_url: String,
#[serde(rename = "apiKey")]
pub api_key: String,
/// 各应用的模型配置
pub models: UniversalProviderModels,
// website_url / notes / icon / icon_color ...
}
其中"按应用分配默认模型"体现在 UniversalProviderModels(src-tauri/src/provider.rs#L677-L684):
| 应用 | 可配置项 |
|---|---|
| Claude | model、haikuModel、sonnetModel、opusModel(四档模型映射) |
| Codex | model、reasoningEffort(推理强度) |
| Gemini | model |
持久化层面,Universal Provider 以 JSON 形式整体存放在 SQLite 的 settings 表、键为 universal_providers,CRUD 实现在 src-tauri/src/database/dao/universal_providers.rs。前端界面位于 src/components/universal/(UniversalProviderPanel.tsx、UniversalProviderFormModal.tsx),预设数据见 src/config/universalProviderPresets.ts。
通用配置片段(Common Config Snippet)
该功能用于沉淀"跨供应商共享"的那部分配置:把一段公共配置片段保存起来,在激活某个供应商时合并/追加到该供应商的配置中,避免把公共项在每个供应商里复制一遍。
抽取流程
v3.9.0 引入了新的抽取流程,对应 Tauri 命令 extract_common_config_snippet(src-tauri/src/commands/config.rs#L419-L437):
- 优先从编辑器当前内容抽取——即你正在编辑的那份配置;
- 编辑器没有内容时,从当前激活的供应商中抽取。
实现入口在 src-tauri/src/services/provider/mod.rs#L5519 的 extract_common_config_snippet 与 extract_common_config_snippet_from_settings。此外,系统还支持自动补抽取:当片段缺失且满足条件(should_auto_extract_config_snippet,见 src-tauri/src/database/dao/settings.rs#L92)时,应用启动阶段会从干净的 live 文件中自动抽取片段(src-tauri/src/lib.rs#L1991-L2034)。
Codex 抽取的安全性处理
对 Codex 的 config.toml 做公共片段抽取时,必须剔除"供应商私有"的部分,否则会污染其他供应商:
- 移除
model_provider、model字段以及整个model_providers表; - 保留
[mcp_servers.*]下的base_url,避免破坏 MCP 配置。
这一"保留/剔除"策略使 Codex 的片段抽取更安全,是 v3.9.0 对该模块的主要加固点。
Skills 管理的统一与提速
v3.9.0 对 Skills(技能库)做了三方面的改进:
- 多应用共享与迁移:Claude Code 与 Codex 的 Skills 支持多应用复用,并改善了从旧目录布局迁移的体验(PR #365、#378,感谢 @yovinchen);
- SSOT + React Query 统一管理:以单一数据源(SSOT)配合 React Query 缓存,保证各面板间状态一致、刷新行为统一。前端统一入口为 src/components/skills/UnifiedSkillsPanel.tsx,状态逻辑在 src/hooks/useSkills.ts;
- Discovery 体验与性能:
- 扫描时跳过隐藏目录;
- 对 discoverable skills 应用长周期缓存,加速发现过程;
- 改进加载指示,整理导入/更新等操作入口;
- 修复 Skills 仓库分支配置问题(PR #505,感谢 @kjasn)。
后端技能仓库管理面板对应 src/components/skills/RepoManagerPanel.tsx,存储位置与同步方式可在设置页配置(src/components/settings/SkillStorageLocationSettings.tsx、src/components/settings/SkillSyncMethodSettings.tsx)。
MCP 管理:导入与加固
- 导入:支持从已安装的应用中导入 MCP servers;
- 稳定性:目标 CLI 未安装时跳过同步,且能正确容错无效的 Codex
config.toml(PR #461,感谢 @majiayu000); - Windows 兼容:MCP 导出时把
npx/npm调用用cmd /c包裹,解决 Windows 下 shell 调用问题。
MCP 的后端服务位于 src-tauri/src/mcp/,前端管理界面为 src/components/mcp/UnifiedMcpPanel.tsx(含表单弹窗 src/components/mcp/McpFormModal.tsx 与向导 src/components/mcp/McpWizardModal.tsx)。
用量与价格数据
- 用量/价格链路整体改善:自动更新、缓存指标、时区修正、内建价格表更新(PR #508,感谢 @yovinchen);
- DeepLink 支持:可从 deeplink 导入用量查询配置(PR #400,感谢 @qyinter);
- 从用量统计中抽取模型信息(PR #455,感谢 @yovinchen);
- 用量查询凭据可在缺失时回落到供应商配置(PR #360,感谢 @Sirhexs)。
前端用量面板集中在 src/components/usage/(UsageDashboard.tsx、RequestLogTable.tsx、PricingConfigPanel.tsx 等),价格数据的自动同步逻辑见 src/lib/modelsDevAutoSync.ts,DeepLink 导入对话框为 src/components/DeepLinkImportDialog.tsx。
其他使用体验改进
- 供应商搜索过滤:按名称快速检索供应商(PR #435,感谢 @TinsFox);
- 图标着色:可为供应商图标设置任意颜色以便区分(PR #385,感谢 @yovinchen);
- 快捷键:
Cmd/Ctrl + ,打开设置(PR #436,感谢 @TinsFox); - Claude Code 首次确认对话框支持跳过(可选);
- Toast 关闭按钮:切换通知与成功通知可手动关闭(PR #350,感谢 @ForteScarlet);
- 更新徽章点击后跳转到 About 标签页;
- 设置页标签样式改进(PR #342,感谢 @wenyuanw);
- 应用/视图切换的淡入动画与面板退出动画;
- 代理接管期间应用翡翠色系主题,让"流量正在被代理接管"的状态一目了然;
- 深色模式可读性改进;
- FullScreenPanel 的窗口拖拽区域改进(PR #525,感谢 @zerob13)。
平台相关说明
Windows
- 版本检查时不再弹出终端窗口;
- 调整了窗口最小尺寸默认值;
- 采用系统标题栏方式,避免启动时的黑屏;
- 为旧版 WebView 增加
crypto.randomUUID()的兜底实现。
macOS
- 自动启动改用
.app捆绑包路径,避免拉起终端(PR #462,感谢 @majiayu000); - 改进托盘与头部区域的交互体验。
Linux 打包
- 新增 RPM 与 Flatpak 打包支持,纳入发布产物生成流程;Flatpak 相关清单见 flatpak/com.ccswitch.desktop.yml 与 flatpak/com.ccswitch.desktop.metainfo.xml。
安全与注意事项
- 安全加固:修复了 JavaScript 执行器与用量脚本执行相关的安全问题(PR #151,感谢 @luojiyin1987);
- SQL 导入限制:出于安全考虑,SQL 导入仅接受 CC Switch 自身导出的备份;
- 代理接管会改写 CLI 的 live 配置:CC Switch 在重定向前会备份 live 配置;如需还原,应关闭接管或停止代理,并在必要时从备份恢复。
下载与安装
请从项目 Releases 页下载对应平台的 v3.9.0 构建。
系统要求
| 系统 | 最低版本 | 架构 |
|---|---|---|
| Windows | Windows 10 及以上 | x64 |
| macOS | macOS 10.15 (Catalina) 及以上 | Intel (x64) / Apple Silicon (arm64) |
| Linux | 见下表 | x64 |
Windows
| 文件 | 说明 |
|---|---|
CC-Switch-v3.9.0-Windows.msi |
推荐 - MSI 安装器,支持自动更新 |
CC-Switch-v3.9.0-Windows-Portable.zip |
便携版,免安装 |
macOS
| 文件 | 说明 |
|---|---|
CC-Switch-v3.9.0-macOS.zip |
推荐 - 解压后拖入 Applications,Universal Binary |
CC-Switch-v3.9.0-macOS.tar.gz |
供 Homebrew 安装与自动更新使用 |
注意:由于作者没有 Apple Developer 账号,首次启动可能出现"无法验证开发者"警告。关闭应用后前往"系统设置"→"隐私与安全性"→点击"仍要打开"即可正常启动。
Homebrew (macOS)
brew tap farion1231/ccswitch
brew install --cask cc-switch
升级:
brew upgrade --cask cc-switch
Linux
| 发行版 | 推荐格式 | 安装方式 |
|---|---|---|
| Ubuntu / Debian / Linux Mint / Pop!_OS | .deb |
sudo dpkg -i CC-Switch-*.deb 或 sudo apt install ./CC-Switch-*.deb |
| Fedora / RHEL / CentOS / Rocky Linux | .rpm |
sudo rpm -i CC-Switch-*.rpm 或 sudo dnf install ./CC-Switch-*.rpm |
| openSUSE | .rpm |
sudo zypper install ./CC-Switch-*.rpm |
| Arch Linux / Manjaro | .AppImage |
赋予执行权限后直接运行,或使用 AUR |
| 其他 / 未知 | .AppImage |
chmod +x CC-Switch-*.AppImage && ./CC-Switch-*.AppImage |
| 希望沙箱运行 | .flatpak |
flatpak install CC-Switch-*.flatpak |
小结
v3.9.0 的关键词是"收口":把多个 CLI 的 API 流量收口到本地 Axum 代理,把多应用的供应商配置收口到 Universal Provider,把 Skills/MCP/公共配置收口到统一数据源。如果你同时使用 Claude Code 与 Codex,建议优先体验"本地代理 + 自动故障转移"组合——先按应用开启接管并确认 live 配置已被备份,再配置熔断阈值(默认连续失败 4 次熔断、半开 60 秒后探测、错误率 60% 触发)与重试/超时参数;若以 NewAPI 等网关为上游,则可用 Universal Provider 一次配置、三端同步。该版本行为以当前仓库源码与发布说明为准,接管类功能请务必留意 live 配置备份与还原流程。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00