Flexgate
本地 Anthropic API 网关,根据请求中的 model 名称自动路由到不同的 provider。同时提供 Claude Code settings.json 的自动管理功能。
用途
Claude Code 只能配置一个 ANTHROPIC_BASE_URL,所有 tier(opus/sonnet/haiku)都指向同一个 provider。Flexgate 在本地启动一个 Anthropic 兼容端点,按 model 名称路由到不同 provider。
Claude Code → localhost:8765 → opus → z.ai (glm-5.1)
→ sonnet → minimax (MiniMax-M3)
→ haiku → minimax (MiniMax-M3)
运行原则:持久化只走 service。 Linux 上的持久化 serve 只由 systemd 用户服务
flexgate.service管理。flexgate run仅用于前台调试,不再创建第二套 PID/guardian 后台进程,因此不会再与 service 抢占同一端口。
安装
cd flexible-gateway
uv sync
源码开发时可以前台运行:
uv run flexgate config init
uv run flexgate run
日常使用推荐从 PyPI 全局安装,并交给 systemd 用户服务管理:
pipx install flexgate # 或: uv tool install flexgate / pip install flexgate
flexgate config init
flexgate service install
从源码安装则用:uv tool install -e .
快速开始
# 1. 初始化配置文件(~/.flexgate/config.yaml)
flexgate config init
# 编辑 ~/.flexgate/config.yaml 填入你的 API key
# 2. 从已有 Claude Code 配置自动导入(可选)
flexgate settings import # 读取 ~/.claude/settings.json* 中的凭证
# 3. 安装并启动唯一的持久化服务
# install 会询问是否将 Claude Code settings.json 指向本地网关
flexgate service install
# 4. 如果安装时跳过了 settings 修改,可稍后手动应用
flexgate settings apply
命令参考
服务管理(默认持久化模式)
systemd 用户服务是 Linux 上唯一推荐的持久化运行方式,负责开机/登录自启、崩溃重启、日志和进程生命周期。
flexgate service install # 安装、启用并立即启动
flexgate service install --no-start # 仅安装并启用,不立即启动
flexgate service start # 启动;自动修复旧格式或失效的 unit
flexgate service stop # 停止
flexgate service restart # 重启
flexgate service reload # 热重载;host/port 变化时自动安全重启
flexgate service status # 查看 systemd 状态和当前路由表
flexgate service uninstall # 停止、禁用并删除 unit
说明:
- unit 写入
~/.config/systemd/user/flexgate.service,直接运行前台 server,由 systemd 监督(Type=simple、Restart=on-failure)。 install会执行loginctl enable-linger,使服务在未登录时仍保持运行并随开机启动。install --no-start不会修改 Claude Code settings,避免把客户端指向尚未运行的 endpoint。- unit 只能引用持久化配置路径;为避免重启后失效,
/tmp下的配置会被拒绝。 start/restart会清理旧 PID/guardian 残留、修复旧 unit 或已失效的配置路径,并在端口被其他进程占用时拒绝启动。- 若升级时检测到旧版后台 gateway 仍在运行,会先准备好 systemd unit,但不会强杀正在服务的进程;按提示手动
kill <PID>停掉旧进程,再执行flexgate service start完成切换。 - unit 设置了启动速率限制,永久配置错误不会再无限快速重启。
service reload和config set/edit会在仅路由变化时发送 SIGUSR1;如果 endpoint 变化,则先检查再 restart。若只改 host、仍复用当前 port,为避免误停服务会要求先执行service stop,再执行service start。- 查看日志:
journalctl --user -u flexgate -e。
版本与升级
flexgate --version # 打印版本号(service status / 裸 flexgate 也会显示)
flexgate doctor # 只读体检:Python、PyPI 新版、配置 schema、端口、systemd、Claude settings
flexgate doctor --offline # 跳过 PyPI 检查
flexgate update # 一键升级:pip/pipx/uv 升级包 + 迁移配置 schema + 热重载服务
flexgate update --check # 只报告将要做什么,不改动
flexgate update --config-only # 只迁移配置,不升级包
升级策略:
- 包升级:版本号唯一来源是
flexgate/__init__.py;发布到 PyPI 后,flexgate update自动检测安装方式(pipx / uv tool / pip)并升级到最新 release。 - 新版本自动提示:裸
flexgate和flexgate service status会自动比对 PyPI 上的 最新版本,有新版时打印一行升级提示。检查结果缓存在~/.flexgate/update-check.json,每 24 小时最多访问一次 PyPI,离线时静默跳过。 - 配置迁移:
config.yaml带config_version标记。每次 schema 变化在flexgate/migrate.py的MIGRATIONS中登记一条 N → N+1 规则,升级时逐级走完整个迁移链。 迁移前自动备份为config.yaml.bak-<时间戳>;配置比当前 flexgate 更新时会被拒绝并提示先升级。 - 自检:发版或排障时跑
flexgate doctor,有 FAIL 项时退出码为 1,可直接用于 CI 门禁。
发布流程(维护者)
仓库托管在 https://github.com/Agony5757/flexible-gateway,通过 GitHub Actions 自动发布到 PyPI(trusted publishing,无需 API token):
# 1. 修改 flexgate/__init__.py 中的 __version__(唯一版本来源)
# 2. 提交后打 tag,tag 必须与 __version__ 一致(CI 会校验)
git tag v0.2.0
git push origin main --tags
推送 v* tag 触发 .github/workflows/release.yml:校验 tag 与 __version__ 一致 →
构建 sdist/wheel → 发布到 PyPI。首次发布前需在 PyPI 项目设置中配置
Trusted Publisher(repo: Agony5757/flexible-gateway,workflow: release.yml)。
上游连通性预检
运行 flexgate check 会向每个 被路由引用的 (provider, model) 组合
发送一次 POST /v1/messages(max_tokens=1,消耗约 1~2 token),用于主动检查:
- DNS / TCP / TLS 不可达(
base_url写错、网络不通) - API key 无效或过期(HTTP 401 / 403)
- 仍是默认占位符(如
your-zai-api-key) - Provider 侧 5xx 故障
可通过 --verify-timeout N 调整每个 provider 的超时时间(默认 15 秒)。
前台调试与连通性检查
run / check 是独立的顶层调试命令,不属于持久化服务模式:
flexgate run # 单个前台进程,仅用于开发/调试
flexgate check # 上游 provider 连通性检测
非 systemd 环境只能使用 flexgate run 前台运行。--port PORT 也只对
run 生效;持久化服务的端口必须写入 server.port。
配置管理
flexgate config init # 创建默认配置(~/.flexgate/config.yaml)
flexgate config show # 查看当前配置(providers、路由、定时规则)
flexgate config edit # 交互式选择每个 tier(opus/sonnet/haiku)的 provider/model
flexgate config path # 打印配置文件路径
flexgate config set <tier> <target> [model] # 快速设置路由(tier 可为 all/opus/sonnet/haiku)
config set 支持按 provider 名或 model 名设置路由:
# 批量切换所有 tier(opus/sonnet/haiku)到同一个 provider
flexgate config set all xiaomi
# 用逗号组合多个 tier
flexgate config set opus,sonnet xiaomi
# 按 provider 名 + model 名
flexgate config set sonnet minimax MiniMax-M3
# 按 provider 名(不改写 model)
flexgate config set opus zai
# 按 model 名自动查找 provider
flexgate config set haiku MiniMax-M3
# → 自动解析为 minimax / MiniMax-M3
# 如果 model 名在多个 provider 中存在,会提示歧义:
# Ambiguous: 'xxx' found in multiple providers:
# flexgate config set haiku providerA xxx
# flexgate config set haiku providerB xxx
注意:
config set不会修改 API key。如需添加新 provider 或修改密钥,请手动编辑配置文件。
交互式编辑(config edit)
运行 flexgate config edit 进入全屏交互界面,用 ↑/↓ 方向键移动、回车选择,无需记忆 provider/model 名称:
Flexgate config — ~/.flexgate/config.yaml
↑/↓ move · Enter edit tier · s save · q quit
▶ opus ustc / deepseek-v4-pro
sonnet ustc / deepseek-v4-pro
haiku ustc / deepseek-v4-pro
○ no unsaved changes
- 方向键选中某个 tier(opus/sonnet/haiku),回车进入:先从候选 provider 列表选择,再从该 provider 的候选 model 列表选择。
- model 列表包含:
available_models中的各个模型、「使用 provider 默认(首个可用模型,不写死 model)」、以及「自定义模型…」(手动输入)。 - 按
s保存(并向运行中的网关发送 SIGUSR1 热重载),按q退出(有未保存改动时会提示保存或放弃);子菜单中按Esc/←返回上一级。 - 需要交互式终端(TTY);非交互场景请改用
flexgate config set。
Settings 管理
flexgate settings import # 从 ~/.claude/settings.json* 导入凭证到 config.yaml
flexgate settings apply # 将 config.yaml 配置写入 ~/.claude/settings.json
全局参数
--config PATH指定配置文件(默认~/.flexgate/config.yaml)--port PORT覆盖配置文件中的端口(仅flexgate run)
配置文件
主要运行时资源:
| 文件 | 说明 |
|---|---|
~/.flexgate/config.yaml |
主配置文件 |
~/.flexgate/service-state.json |
最近一次成功启动所应用的 config 路径与 endpoint |
~/.flexgate/update-check.json |
PyPI 新版本检查的缓存(24h 有效期) |
~/.config/systemd/user/flexgate.service |
唯一的持久化服务 unit |
| systemd journal | 服务日志(journalctl --user -u flexgate) |
旧版本的 ~/.flexgate/flexgate.pid、flexgate.guardian.pid 和
flexgate.log 不再属于当前运行架构;service 启动时会安全清理 PID 残留,
历史日志文件可按需手动删除。
运行 flexgate config init 创建默认配置,或手动编辑:
server:
host: "127.0.0.1"
port: 8765
providers:
zai:
base_url: "https://api.z.ai/api/anthropic"
api_key: "your-zai-api-key"
minimax:
base_url: "https://api.minimaxi.com/anthropic"
api_key: "your-minimax-api-key"
claude_settings:
default_opus_model: "claude-opus-4-7"
default_sonnet_model: "claude-sonnet-4-6"
default_haiku_model: "claude-haiku-4-5"
api_timeout_ms: 3000000
# 定时路由(可选):按时间自动切换,首个时间窗口命中生效
# schedule:
# - name: "night-shift"
# start: "22:00"
# end: "06:00"
# routes:
# - pattern: "^claude-sonnet"
# provider: zai
# model: "glm-5.1"
routes: # 从上到下匹配,首个命中生效
- pattern: "^claude-opus"
provider: zai
model: "glm-5.1" # 可选,发给 provider 的实际模型名
- pattern: "^claude-sonnet"
provider: minimax
model: "MiniMax-M3"
- pattern: "^claude-haiku"
provider: minimax
model: "MiniMax-M3"
- pattern: ".*" # 兜底
provider: minimax
model: "MiniMax-M3"
配置字段说明
| 字段 | 说明 |
|---|---|
server.host/port |
网关监听地址 |
providers.<name>.base_url |
Provider 的 API 地址 |
providers.<name>.api_key |
Provider 的 API 密钥 |
claude_settings.* |
写入 settings.json 的模型和超时配置 |
routes[].pattern |
正则匹配请求中的 model 字段 |
routes[].provider |
路由到的 provider 名称 |
routes[].model |
可选,替换发给 provider 的模型名 |
schedule[].name |
定时规则名称 |
schedule[].start/end |
时间窗口(HH:MM 格式,支持跨夜如 22:00-06:00) |
schedule[].routes |
该时间窗口内生效的路由(格式同 routes) |
Settings Import
flexgate settings import 会扫描 ~/.claude/settings.json*,从每个文件中提取 ANTHROPIC_BASE_URL 和 ANTHROPIC_AUTH_TOKEN,自动写入 config.yaml 的 providers 部分。
文件名与 provider 名称的映射规则:
settings.json→ 根据域名自动推断(如含z.ai→zai)settings.json.zai→ provider 名zaisettings.json.minimax→ provider 名minimaxsettings.json.bak.*→ 跳过(备份文件)
适合场景:你有多套 Claude Code 配置文件,想要快速将凭证合并到网关中统一管理。
Settings Apply
flexgate settings apply 会:
- 读取 config.yaml 中的
server和claude_settings - 备份当前
~/.claude/settings.json为settings.json.bak.{timestamp} - 生成新的 settings.json,将
ANTHROPIC_BASE_URL指向本地网关 - 保留原有的
permissions等非 env 字段
生成的 settings.json 示例:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:8765",
"ANTHROPIC_AUTH_TOKEN": "gateway",
"API_TIMEOUT_MS": "3000000",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-7",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5"
},
"permissions": {
"defaultMode": "bypassPermissions"
}
}
ANTHROPIC_AUTH_TOKEN 值任意但不能为空,网关会替换为对应 provider 的 key。
环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
FLEXGATE_CONFIG |
~/.flexgate/config.yaml |
覆盖配置文件路径 |
注意事项
- 配置默认存放在
~/.flexgate/,全局安装后可在任意目录管理 systemd 用户服务 - Linux 持久化运行统一使用
flexgate service;不要额外启动独立后台进程 config.yaml已加入.gitignore,不会被提交到 Git- 请使用
config.yaml.template作为参考模板 - 如果 API 密钥曾经被推送到远程仓库,请立即轮换(rotate)该密钥
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flexgate-0.1.0.tar.gz.
File metadata
- Download URL: flexgate-0.1.0.tar.gz
- Upload date:
- Size: 71.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1cfb47cdb958f20bc02f5d48afaa6009e9234ceebeb32a85262b1659f685f426
|
|
| MD5 |
08d412894d38d0cb94ad1ca294173621
|
|
| BLAKE2b-256 |
dc4321eefb4348985769d90a5e8cfd5d3415ecff5ad0d77acd4b7076f7761a33
|
Provenance
The following attestation bundles were made for flexgate-0.1.0.tar.gz:
Publisher:
release.yml on Agony5757/flexible-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flexgate-0.1.0.tar.gz -
Subject digest:
1cfb47cdb958f20bc02f5d48afaa6009e9234ceebeb32a85262b1659f685f426 - Sigstore transparency entry: 2482994755
- Sigstore integration time:
-
Permalink:
Agony5757/flexible-gateway@c69787cc6374a5d11b26a166a07e3aea59f9b419 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agony5757
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c69787cc6374a5d11b26a166a07e3aea59f9b419 -
Trigger Event:
push
-
Statement type:
File details
Details for the file flexgate-0.1.0-py3-none-any.whl.
File metadata
- Download URL: flexgate-0.1.0-py3-none-any.whl
- Upload date:
- Size: 51.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a5542adabc9c6b999315f612d3112de4341467d0ef1af641a39805ea0b0d3db
|
|
| MD5 |
e3825e3ff7b3464ae99b51d0524ea1bb
|
|
| BLAKE2b-256 |
a73349a0a253d7dc61d6526b8016a51191bc0306621563c18c2db2f0591b0ec9
|
Provenance
The following attestation bundles were made for flexgate-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Agony5757/flexible-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
flexgate-0.1.0-py3-none-any.whl -
Subject digest:
0a5542adabc9c6b999315f612d3112de4341467d0ef1af641a39805ea0b0d3db - Sigstore transparency entry: 2482994959
- Sigstore integration time:
-
Permalink:
Agony5757/flexible-gateway@c69787cc6374a5d11b26a166a07e3aea59f9b419 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agony5757
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c69787cc6374a5d11b26a166a07e3aea59f9b419 -
Trigger Event:
push
-
Statement type: