首页
/ cc-switch 本地代理服务实战指南:监听配置、应用接管与 API 格式转换原理

cc-switch 本地代理服务实战指南:监听配置、应用接管与 API 格式转换原理

2026-09-06 13:54:03作者:柏廷章Berta

cc-switch 的本地代理服务在 127.0.0.1:15721 上启动一个 HTTP 代理,将 Claude、Codex、Gemini 等应用的 API 请求统一经其转发,从而实现请求日志记录、用量统计与供应商故障转移(Failover)。本文以官方用户手册中的代理服务文档为主体,结合 代理服务器实现代理服务业务层代理类型定义,讲清楚服务的启动/停止方式、监听配置、运行状态指标、应用接管的底层机制、API 格式转换与常见问题排查。

cc-switch 主界面顶部的代理服务开关

一、功能定位:为什么需要本地代理

本地代理服务(Proxy Service)是 cc-switch 将"配置管理"升级为"流量治理"的核心组件,主要用途包括:

  • 记录请求日志:为每个 API 请求落一条结构化日志;
  • 统计 API 用量:聚合 Token 消耗与请求耗时,支撑用量面板;
  • 支持故障转移:当前供应商连续失败时自动切换到队列中的下一家;
  • 统一管理多应用请求:Claude、Codex、Gemini 等应用共用一个本地入口,由 ProviderRouter 按应用类型路由到对应供应商。

从源码结构看,代理服务器基于 Axum 构建,并使用手动 hyper HTTP/1.1 accept 循环以 preserve_header_case(true) 保留客户端原始请求头的大小写,保证转发到上游时的线级头部与"不走代理直连"完全一致(见 server.rs 文件头注释)。

二、启动代理的两种方式

方式 1:主界面开关

点击主界面顶部的代理服务开关按钮即可启动。开关颜色表示状态:

  • 白色:代理已停止;
  • 绿色:代理运行中。

对应前端组件为 ProxyToggle,状态轮询由 useProxyStatus 驱动。

方式 2:设置页

  1. 打开"设置 → 高级 → 代理服务";
  2. 点击面板右上角的开关。

设置页中的代理服务配置面板

该面板由 ProxyTabContent 渲染,内部再组合 ProxyPanel 显示运行指标。

三、基本配置项与默认值

官方文档列出的核心配置

配置项 说明 默认值
监听地址 代理绑定的 IP 地址 127.0.0.1
监听端口 代理监听的端口 15721
启用日志 是否记录请求日志 开启

这些默认值在后端 ProxyConfig 的 Default 实现 中可以直接验证:

impl Default for ProxyConfig {
    fn default() -> Self {
        Self {
            listen_address: "127.0.0.1".to_string(),
            listen_port: 15721, // 使用较少占用的高位端口
            max_retries: 3,
            request_timeout: 600,
            enable_logging: true,
            live_takeover_active: false,
            streaming_first_byte_timeout: 60,
            streaming_idle_timeout: 120,
            non_streaming_timeout: 600,
        }
    }
}

数据库层同样将 15721 作为 schema 默认值持久化(见 proxy_config 表定义listen_port INTEGER NOT NULL DEFAULT 15721),配置在应用重启后依然生效。

源码中更多可配置的超时参数

除了文档表格中的三项,ProxyConfig 结构体 还包含一组面向长请求的超时参数,对大模型流式场景很关键:

字段 含义 默认值
max_retries 最大重试次数 3
streaming_first_byte_timeout 流式首字超时(1–120 秒) 60 秒
streaming_idle_timeout 流式静默超时,两个数据块间的最大间隔(60–600 秒,填 0 禁用) 120 秒
non_streaming_timeout 非流式请求总超时(60–1200 秒) 600 秒

这些参数解释了"请求超时"类故障的排查方向:如果模型思考时间较长但网络正常,往往是流式静默超时先于上游触发。

修改配置的步骤

  1. 先停止代理服务(修改地址/端口前必须停止);
  2. 修改监听地址或端口;
  3. 点击"保存";
  4. 重新启动代理。

注意:地址/端口变更需要先停止服务,因为监听器只在启动时绑定一次。从 ProxyServer::start 的实现看,启动流程是解析 listen_address:listen_portSocketAddr,随后调用 tokio::net::TcpListener::bind;绑定失败会返回 ProxyError::BindFailed——这就是 FAQ 中 "Address already in use" 报错的来源。

监听地址说明

地址 说明
127.0.0.1 仅本机可访问(推荐)
0.0.0.0 允许局域网内其他设备访问

由于代理转发的是带真实凭据的 API 流量,源码中的 HTTP 客户端也对"代理是否指向回环地址"做了专门校验(见 http_client.rs 中的 proxy_points_to_loopback 测试),这从实现侧印证了文档"仅本机访问推荐"的建议。

四、运行状态面板

代理运行中,面板显示以下四类信息。

4.1 服务地址

http://127.0.0.1:15721

面板提供"复制"按钮一键复制该地址。这个地址就是后续接管各应用时写入的 base_url

4.2 当前使用供应商

按应用显示当前路由目标:

Claude: PackyCode
Codex: AIGoCode
Gemini: Google 官方

底层对应 ProxyStatus 中的 current_provider 字段与 active_targets 列表(每个 ActiveTarget 记录 app_type / provider_name / provider_id)。

4.3 统计数据

指标 说明
活跃连接数 当前正在处理的请求数
总请求数 启动以来的累计请求数
成功率 成功请求占比(>90% 显示绿色,≤90% 显示黄色)
运行时长 代理持续运行时间

这些指标与 ProxyStatus 结构体 的字段一一对应:active_connectionstotal_requestssuccess_rateuptime_seconds,另有 last_errorfailover_count 等字段供前端展示最近的错误与切换次数。

4.4 故障转移队列

代理面板按应用类型显示 Failover 队列,前端由 FailoverQueueManager 渲染:

Claude
├── 1. PackyCode      [使用中] ●
├── 2. AIGoCode                ●
└── 3. 备用                    ○

Codex
├── 1. AIGoCode       [使用中] ●
└── 2. 备用                    ●

队列元素含义:

  • 数字表示优先级顺序;
  • "使用中"标签标记当前正在服务的供应商;
  • 健康徽标反映供应商状态:
    • 绿色:健康(连续失败 0 次);
    • 黄色:降级(连续失败 1–2 次);
    • 红色:不健康(连续失败 ≥3 次)。

该徽标逻辑对应 ProviderHealthBadge,其数据源是 ProviderHealth 结构中的 consecutive_failures(连续失败计数)与 is_healthy 布尔值;熔断判断本身由 ProviderRouter 持有并在跨请求间保持状态(见 ProxyState 注释:"共享的 ProviderRouter(持有熔断器状态,跨请求保持)")。

五、工作原理

5.1 请求流转

sequenceDiagram
    participant CLI as CLI 工具 (Claude)
    participant Proxy as 本地代理 (CC Switch)
    participant API as API 供应商 (Anthropic)
    participant DB as 数据存储 (Logger)

    CLI->>Proxy: 发送 API 请求
    Proxy->>DB: 记录请求日志/统计用量
    Proxy->>API: 转发请求
    API-->>Proxy: 返回响应
    Proxy-->>CLI: 返回响应

5.2 应用接管:配置改写机制

代理启动并启用应用接管后,cc-switch 会改写各应用的本地配置,把流量指向本地代理:

Claudesettings.json 的 env):

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://127.0.0.1:15721"
  }
}

Codexconfig.toml):

base_url = "http://127.0.0.1:15721/v1"

Gemini(环境变量):

GOOGLE_GEMINI_BASE_URL=http://127.0.0.1:15721

源码层面有几个值得注意的实现细节:

  1. 占位 Token:接管模式下,写回 Live 配置的 API Key 使用占位符 PROXY_MANAGED,避免客户端因"缺少 key"报错,同时不泄露真实 Token(见 PROXY_TOKEN_PLACEHOLDER 常量)。
  2. 接管状态按应用独立跟踪ProxyTakeoverStatusclaudecodexgeminigrokbuildopencodeopenclaw 各维护一个布尔位,说明接管是逐应用粒度的,可以只接管部分应用。
  3. 模型覆盖字段的接管:接管 Claude 时,ANTHROPIC_MODEL 等 12 个模型覆盖字段会被移除并改写成稳定的 Claude 角色别名(haiku/sonnet/opus/fable),再由本地代理映射到当前供应商的真实模型,防止模型菜单残留上一家供应商的名称(见 CLAUDE_MODEL_OVERRIDE_ENV_KEYS 及其注释)。
  4. 接管前的配置快照:写入新配置之前,原始 Live 配置会作为 LiveBackup(含 app_typeoriginal_config,见 LiveBackup 结构)备份到数据库,供停止时精确恢复。

六、API 格式转换

代理对设置了非 Anthropic 格式供应商的场景支持自动 API 格式转换,使仅支持 OpenAI 兼容 API 的供应商也能被 Claude Code 使用:

供应商 API 格式 代理行为
Anthropic Messages 直通(不转换)
OpenAI Chat Completions Anthropic 请求转换为 OpenAI Chat 格式,响应再逆转换
OpenAI Responses API Anthropic 请求转换为 OpenAI Responses 格式,响应再逆转换

API 格式在添加/编辑 Claude 供应商时的"高级选项"中按供应商配置(参见添加供应商文档的 API 格式一节)。转换的入口实现在 forwarder.rsproviders 模块 中,按供应商配置的 api_format 分派不同转换管道。

注意:格式转换依赖代理处于"应用接管启用"的运行状态;转换同时覆盖流式与非流式两类请求。

七、停止代理与恢复行为

停止方式

  • 方式 1:点击主界面开关关闭代理;
  • 方式 2:在代理面板中将开关设为关闭。

停止时的三步处理

代理停止时,cc-switch 依次执行:

  1. 恢复应用配置:把各应用配置写回接管前的原始状态;
  2. 保存请求日志:将本轮运行的请求记录落库;
  3. 关闭所有连接:终止监听并释放端口。

从源码看,停止走的是带恢复语义的 stop_with_restore 路径(services/proxy.rs),内部先停服务、再对每个被接管的应用执行 restore_live_config_for_app 系列函数,用 LiveBackup 中保存的原始配置覆盖回写。该模块还针对 Codex 的 auth.json 实现了带硬链接探针的事务式恢复(CodexAuthFileTransaction),保证"恢复配置"和"用户正在 Codex 内重新登录"两个并发操作不会互相覆盖;仓库中 stop_with_restore*restore_* 相关的测试用例(同一文件内 restore_waits_for_hot_switch_and_restores_latest_backup 等十余个测试)覆盖了这些边界场景。

八、请求日志

启用日志

打开代理面板的"启用日志"开关(对应 ProxyConfig.enable_logging,默认开启)。

日志字段

每条请求记录包含:

字段 说明
时间 请求发生时间
应用 Claude / Codex / Gemini
供应商 实际使用的供应商
模型 请求的模型名
Token 输入/输出 Token 数
延迟 请求耗时
状态 成功/失败

查看日志

在"设置 → 用量"标签页中查看请求日志,前端实现见 RequestLogTable

九、常见问题排查

9.1 端口被占用

错误信息:Address already in use

解决方法:

  1. 更换端口(例如 5001);
  2. 或结束占用该端口的程序。

对应源码中 TcpListener::bind 失败即抛出 BindFailedserver.rs 启动流程),因此该报错只会在启动/重启阶段出现。

9.2 代理启动失败

检查清单:

  • 端口是否被其他程序占用;
  • 是否有足够权限(部分系统对低端口段有限制);
  • 防火墙是否拦截了本地回环连接。

9.3 请求超时

可能原因:

  • 网络问题;
  • 供应商服务端问题;
  • 代理配置错误。

排查手段:

  • 确认网络连通性;
  • 绕过代理直接访问供应商 API 验证账号/Key 是否有效;
  • 核对供应商配置(尤其是 base_url 与 API 格式设置),并留意流式/非流式超时参数是否过短。

十、延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388