在 Claude Code CLI 与第三方 Anthropic 兼容模型(DeepSeek / GLM / 其他网关)之间做进程级、零侵入的切换。
- 不改
~/.claude/settings.json - 不在配置文件里存明文 API Key
- 切回官方模型时自动清理三方环境变量
Claude Code 官方 CLI 通过 ANTHROPIC_BASE_URL + ANTHROPIC_API_KEY 环境变量可以接入任何 Anthropic 兼容的第三方模型网关。但手工切换有三个痛点:
- 全局
export后会污染所有终端会话,回切官方模型容易遗漏unset - 不同厂商的 Key 散落在 shell 历史和零散脚本里,容易误提交
- 没有统一的 model id / base_url 登记处,新机器复刻成本高
ccm 用一个单文件 bash 脚本 + 一份 JSON profile 表解决这三件事,进程级注入,不动全局配置。
┌────────────────────────┐ ┌──────────────────────┐
│ profiles.json │ ◀──────│ ccm init │
│ (~/.config/ │ └──────────────────────┘
│ claude-model- │
│ switcher/) │
└──────────┬─────────────┘
│ 读取
▼
┌─────────────────────────────────────────────────────────┐
│ ccm use <profile> │
│ └─ 写入 ~/.config/claude-model-switcher/current │
└──────────┬──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ ccm run / cc │
│ ┌────────────────────────────────────────────────────┐ │
│ │ type = native │ │
│ │ env -u ANTHROPIC_BASE_URL │ │
│ │ -u ANTHROPIC_API_KEY │ │
│ │ -u ANTHROPIC_AUTH_TOKEN │ │
│ │ exec claude --model <model> │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ type = anthropic-compatible │ │
│ │ ANTHROPIC_BASE_URL = <base_url> │ │
│ │ ANTHROPIC_API_KEY = $<api_key_env> │ │
│ │ exec claude --model <model> │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
关键设计:所有 env 注入只发生在 exec 出去的那一个进程,不写入 shell rc,不修改 Claude Code 全局 settings。
| 依赖 | 版本 | 说明 |
|---|---|---|
bash |
≥ 3.2 | macOS 自带版本即可 |
python3 |
≥ 3.6 | 用于解析 profiles.json |
claude |
任意 | Claude Code CLI 已安装并在 $PATH 中 |
平台支持:macOS / Linux / WSL。原生 Windows(非 WSL)未测试。
# 1. 把脚本放到任意位置,授予可执行权限
chmod +x /path/to/claude-model-switch.sh
# 2. 加 alias(写入 ~/.zshrc 或 ~/.bashrc)
alias ccm="/path/to/claude-model-switch.sh"
# 3. 推荐再加一个 cc 函数,平时直接用 cc 替代 claude
cc() { /path/to/claude-model-switch.sh run -- "$@"; }
⚠️ cc在某些环境会与 C 编译器(/usr/bin/cc)冲突。如有冲突可改用cck/ccx等命名。
或者直接让脚本生成片段:
ccm shell-snippet >> ~/.zshrcccm init # 生成默认 profiles.json
export DEEPSEEK_API_KEY="<your key>" # 注入第三方 Key(仅当前 shell)
ccm use deepseek-v4-flash # 切到 DeepSeek
ccm doctor # 自检(profile / Key / claude bin)
ccm probe # 最小连通性测试(一次 --bare -p)
cc # 启动 Claude Code回切官方:
ccm use claude-opus
cc| 命令 | 作用 |
|---|---|
ccm help |
显示帮助 |
ccm init [--force] |
初始化 profiles.json 默认模板 |
ccm list |
列出所有 profile,标星当前生效项 |
ccm current |
查看当前 profile 详情 |
ccm show <profile> |
查看指定 profile 详情(JSON) |
ccm use <profile> |
切换当前 profile(仅写状态文件) |
ccm doctor [--profile <p>] |
自检:claude CLI、Key 环境变量、base_url |
ccm probe [--profile <p>] [--prompt <text>] |
最小连通性探活 |
ccm run [--profile <p>] [-- <claude args...>] |
按 profile 启动 Claude Code |
ccm shell-snippet |
输出推荐的 shell alias / function |
ccm paths |
输出所有相关路径 |
cc # 等价 ccm run,注入 --model
cc -p "hello" # 透传 -p
cc --continue # 透传 --continue
cc --debug api # 透传 --debug api
ccm run --profile deepseek-v4-pro # 临时用别的 profile,不改当前如果你显式传了 --model,脚本就不再注入 profile 的 model,以你的为准。
默认模板(ccm init 生成):
{
"default_profile": "claude-opus",
"profiles": [
{ "name": "claude-opus", "type": "native", "model": "opus" },
{ "name": "claude-sonnet", "type": "native", "model": "sonnet" },
{ "name": "claude-haiku", "type": "native", "model": "haiku" },
{
"name": "deepseek-v4-flash",
"type": "anthropic-compatible",
"model": "deepseek-v4-flash",
"base_url": "https://api.deepseek.com/anthropic",
"api_key_env": "DEEPSEEK_API_KEY"
},
{
"name": "deepseek-v4-pro",
"type": "anthropic-compatible",
"model": "deepseek-v4-pro",
"base_url": "https://api.deepseek.com/anthropic",
"api_key_env": "DEEPSEEK_API_KEY"
}
]
}| 字段 | 必填 | 说明 |
|---|---|---|
name |
✅ | profile 唯一名称,建议 [A-Za-z0-9_-]+ |
type |
✅ | native(官方)或 anthropic-compatible(第三方网关) |
model |
✅ | 传给 claude --model 的 model id |
base_url |
type=anthropic-compatible 时必填 | 第三方 Anthropic 兼容接口地址 |
api_key_env |
type=anthropic-compatible 时必填 | API Key 所在环境变量名(只存变量名,不存值) |
截至 2026-05,DeepSeek Anthropic 兼容接口下:
- ✅
deepseek-v4-flash、deepseek-v4-pro可用- ❌
deepseek-v4不是合法 model id⚠️ deepseek-chat/deepseek-reasoner可用但官方文档显示将弃用
- 对方提供 Anthropic 兼容接口(不是 OpenAI 兼容)
- 你拿得到合法的
base_url - 你知道对方的合法 model id
# 1. 编辑 profiles.json,追加一项
ccm paths # 看 profiles_file 路径
$EDITOR <path>
# 2. 加完后跑一遍三件套验证
ccm use <new-profile>
ccm doctor
ccm probe模板:
{
"name": "glm-flash",
"type": "anthropic-compatible",
"model": "glm-4.5-flash",
"base_url": "https://your-glm-gateway.example.com/anthropic",
"api_key_env": "GLM_API_KEY"
}不要假设所有 OpenAI 兼容接口都能直接被 Claude Code 吃下。本工具只验证了 Anthropic 兼容路径。
-
不写明文 Key 进任何文件:
profiles.json只存api_key_env变量名,Key 只放进程环境变量。 -
状态文件权限
600:profiles.json与current文件init时强制 chmod。 -
测试结束清 Key:
unset DEEPSEEK_API_KEY -
不要把
export DEEPSEEK_API_KEY=...提交进 dotfiles 仓库。Key 推荐方案:- macOS:
security add-generic-password→ shell 启动时security find-generic-password -w - Linux:
pass/gpg/sops - 团队场景: 1Password CLI / Vault
- macOS:
export DEEPSEEK_API_KEY="..."
ccm doctor通常是 model id 写错。回到 DeepSeek model id 已知边界 校对。
脚本在 native 模式会清理 ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN。如果仍异常,检查你 shell 里是否还残留:
env | grep -i anthropic
env | grep -i claude_code发现残留就 unset 掉。
ccm paths # 看 claude_bin
export CLAUDE_REAL_BIN="/opt/homebrew/bin/claude" # 显式指定export CLAUDE_SWITCHER_HOME="$HOME/.config/my-ccm"rm -rf ~/.config/claude-model-switcher
# 删 alias / cc 函数(编辑 ~/.zshrc 或 ~/.bashrc)
# 删脚本本身
rm /path/to/claude-model-switch.sh- 修复
SCRIPT_PATHheredoc 解析(实际无害但不优雅) - native 模式扩展
env -u清单(ANTHROPIC_MODEL/ANTHROPIC_DEFAULT_*/ANTHROPIC_CUSTOM_HEADERS/CLAUDE_CODE_USE_BEDROCK/CLAUDE_CODE_USE_VERTEX) - profile name 格式校验、重名检测
- bash completion
- CI(shellcheck + bats)
Apache 2.0