☰
Claude Code 环境管理器(开源):用 Go + Wails 打造多环境切换面板
2026/9/26 22:57:48 网站建设 项目流程

1. 为什么我又写了一个 Claude Code 环境切换工具

如果你同时维护两三个项目,每个项目用的 Claude Code 后端配置都不一样,那你大概率经历过这种场景:早上到公司先改一遍ANTHROPIC_BASE_URL,中午切到另一个仓库再改回来,晚上回家跑个人项目又得重新设一遍 token。改环境变量本身不复杂,烦的是它散落在 shell 配置、.env、系统环境变量三四个地方,改完还得重启终端才生效。

Claude Code 环境管理器就是冲着这个痛点来的。它是一个用 Go + Wails 写的开源桌面应用,核心能力只有一件事:把多套 Anthropic API 配置存成 JSON,点一下就把对应的一组环境变量写进系统,再点一下切到另一套。适合需要在多套 API 配置间频繁切换的开发者,尤其是同时用官方通道和统一网关通道的人。

我试过纯手写 shell 函数来切换,能用,但配置一多就乱,而且团队里其他人拿到你的脚本还得改路径。桌面面板的好处是配置可视化、状态实时可见、切换动作有明确反馈。下面我把项目骨架、配置文件结构、以及通过 TaoToken 统一 Key 接入的完整配置和验证步骤都拆开讲,你可以直接照着搭一套自己的。

2. TaoToken 前置:先把统一通道和 Key 准备好

这个工具管理的是环境变量,而环境变量最终指向哪个 API 通道,取决于你填什么。我建议把 TaoToken 作为统一入口来配,原因是它一个 Key 就能覆盖 Claude 系列模型,切换模型时不用换 Key,只需要改ANTHROPIC_MODEL,这对环境管理器来说正好——配置项少一个变量,切换逻辑就简单一分。

先到官网注册并进入控制台,在 API Keys 页面创建一个 Key。创建时注意两点:一是给它起个能区分用途的名字,比如claude-code-dev,二是创建后立刻复制,页面刷新后就看不到完整值了。

拿到 Key 之后,你需要记住两个地址:

  • 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • API 基址:https://taotoken.net/api

注意 API 基址后面不要手动加/v1,Claude Code 客户端会自己拼接路径。这一点我在排障章节还会再强调,因为它是最高频的 404 来源。

如果你后面要跑长期编码任务或者 Agent 流程,可以顺带看一下 Coding Plan 页面,它和按量调用是两套计费逻辑,选错了会多花钱:

  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
  • 模型对话体验:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

Key 和地址都齐了,接下来进入代码部分。

3. Go + Wails 项目骨架与配置文件结构

3.1 环境准备与初始化

Wails 的前置要求是 Go 1.21+ 和 Wails CLI v2。Windows 上还需要 WebView2 运行时,Win11 一般自带,Win10 可能需要手动装。

go install github.com/wailsapp/wails/v2/cmd/wails@latest wails doctor

wails doctor会告诉你缺什么依赖,按提示补就行。然后初始化项目:

wails init -n claude-env-switcher -t vanilla cd claude-env-switcher go mod tidy

模板选 vanilla 就够了,这个工具不需要前端框架,原生 HTML + CSS 反而更轻。

3.2 目录结构

我习惯把环境变量读写逻辑单独抽一层,方便以后加测试:

claude-env-switcher/ ├── app.go # Wails 绑定层,暴露给前端的方法 ├── main.go # 入口,注册窗口和资源 ├── envstore/ │ ├── store.go # config.json 读写 │ └── apply.go # 环境变量写入系统 ├── frontend/ │ ├── index.html │ ├── style.css │ └── main.js └── config.json # 运行时生成

3.3 配置文件结构

配置文件是整个工具的核心,结构设计得越清晰,后面切换越省事。我用的是「当前激活环境 + 环境数组」的结构:

{ "current_env": "taotoken-dev", "environments": [ { "name": "taotoken-dev", "description": "TaoToken 统一通道 - 开发用", "variables": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的Key", "ANTHROPIC_MODEL": "claude-sonnet-4-5-20250929" } }, { "name": "taotoken-prod", "description": "TaoToken 统一通道 - 生产用", "variables": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-另一个Key", "ANTHROPIC_MODEL": "claude-opus-4-1-20250805" } } ] }

这里有个设计取舍值得说:我把ANTHROPIC_API_KEY留空了。原因是 Claude Code 在同时存在ANTHROPIC_AUTH_TOKEN和ANTHROPIC_API_KEY时,行为可能不符合预期,容易互相覆盖。统一用ANTHROPIC_AUTH_TOKEN一个字段,排障时变量更少。

3.4 读写逻辑

envstore/store.go里最关键的是加载和保存两个函数,注意用os.UserConfigDir()而不是当前目录,否则打包后配置文件会散落在奇怪的地方:

package envstore import ( "encoding/json" "os" "path/filepath" ) type Environment struct { Name string `json:"name"` Description string `json:"description"` Variables map[string]string `json:"variables"` } type Config struct { CurrentEnv string `json:"current_env"` Environments []Environment `json:"environments"` } func configPath() (string, error) { dir, err := os.UserConfigDir() if err != nil { return "", err } full := filepath.Join(dir, "claude-env-switcher") os.MkdirAll(full, 0o755) return filepath.Join(full, "config.json"), nil } func Load() (*Config, error) { p, err := configPath() if err != nil { return nil, err } data, err := os.ReadFile(p) if os.IsNotExist(err) { return &Config{Environments: []Environment{}}, nil } if err != nil { return nil, err } var c Config if err := json.Unmarshal(data, &c); err != nil { return nil, err } return &c, nil } func Save(c *Config) error { p, err := configPath() if err != nil { return err } data, err := json.MarshalIndent(c, "", " ") if err != nil { return err } return os.WriteFile(p, data, 0o600) }

0o600这个权限别省,配置文件里有 Key,同机器其他用户不该读到。

3.5 写入系统环境变量

apply.go负责把选中的配置写进系统。跨平台写法不同,Windows 走setx,类 Unix 走 shell profile 追加:

package envstore import ( "os" "os/exec" "runtime" ) func Apply(env Environment) error { for k, v := range env.Variables { if v == "" { continue } if err := setVar(k, v); err != nil { return err } } return nil } func setVar(key, value string) error { if runtime.GOOS == "windows" { return exec.Command("setx", key, value).Run() } os.Setenv(key, value) return nil }

Windows 的setx是持久化的,写注册表;类 Unix 这里只设了当前进程,要持久化得往~/.zshrc或~/.bashrc追加,你可以按需扩展。

3.6 Wails 绑定

app.go里把方法暴露给前端,前端按钮直接调:

package main import ( "context" "claude-env-switcher/envstore" ) type App struct { ctx context.Context } func NewApp() *App { return &App{} } func (a *App) Startup(ctx context.Context) { a.ctx = ctx } func (a *App) ListEnvs() ([]envstore.Environment, error) { c, err := envstore.Load() if err != nil { return nil, err } return c.Environments, nil } func (a *App) ApplyEnv(name string) error { c, err := envstore.Load() if err != nil { return err } for _, e := range c.Environments { if e.Name == name { if err := envstore.Apply(e); err != nil { return err } c.CurrentEnv = name return envstore.Save(c) } } return nil }

跑wails dev就能看到窗口,改前端代码热重载,改 Go 代码自动重编译。

4. 可复制配置:settings.json 与切换验证

4.1 Claude Code 侧的 settings.json

环境管理器写的是系统环境变量,但 Claude Code 自己还有一份settings.json。两者关系是:系统环境变量提供默认值,settings.json可以覆盖。我建议把通道信息统一放在环境变量里,settings.json只留权限和工具相关配置,避免两处都写 Key 导致排查困难。

如果你确实想在settings.json里固定通道,可以这样写:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的Key", "ANTHROPIC_MODEL": "claude-sonnet-4-5-20250929" }, "permissions": { "allow": ["Read", "Edit", "Bash(git:*)"], "deny": [] } }

这个文件放在项目根目录的.claude/settings.json,或者用户级的~/.claude/settings.json。项目级优先级更高,适合团队统一配置。

4.2 切换后的验证步骤

切完配置别急着写代码,先验证通道通不通。最直接的方式是用 curl 打一次模型列表或对话接口:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_AUTH_TOKEN" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-5-20250929", "max_tokens": 64, "messages": [{"role": "user", "content": "ping"}] }'

返回里带content字段就说明通道正常。如果返回 401,检查 Key;返回 404,检查 base URL 是不是多写了/v1。

然后在 Claude Code 里跑一次真实请求:

claude -p "用一句话说明当前工作目录的作用"

能正常返回,说明环境变量已经被 Claude Code 读到。注意:已经打开的终端不会自动刷新环境变量,切换后要新开一个终端窗口。

4.3 环境变量状态检查

在终端里直接打印,确认值写进去了:

echo $ANTHROPIC_BASE_URL echo $ANTHROPIC_MODEL

Windows PowerShell 用:

$env:ANTHROPIC_BASE_URL $env:ANTHROPIC_MODEL

如果打印为空,说明setx写的是用户级变量但当前会话没继承,重开终端即可。

5. 本篇常见错排查

5.1 切换后 Claude Code 仍走旧配置

最常见的原因是终端会话缓存。环境变量在进程启动时读取,已经开着的终端不会感知新值。解决办法就是关掉重开。另一个可能是settings.json里的env字段覆盖了系统变量,检查项目级和用户级两个文件。

5.2 404 Not Found

九成是 base URL 写错。正确写法是https://taotoken.net/api,不要写成https://taotoken.net/api/v1,也不要漏掉/api。Claude Code 会在 base URL 后面自己拼/v1/messages,你多写一层就变成/api/v1/v1/messages。

5.3 401 Unauthorized

Key 无效或没被读到。先确认ANTHROPIC_AUTH_TOKEN的值没有多余空格,再确认 Key 没有过期或被删除。如果同时设了ANTHROPIC_API_KEY,把它清掉,只留ANTHROPIC_AUTH_TOKEN。

5.4 Windows 上 wails build 报 WebView2 缺失

去微软官网下载 WebView2 Runtime 安装即可,这是 Wails 在 Windows 上的硬依赖,不是项目问题。

5.5 配置文件丢失

如果你把config.json放在项目目录,wails build后运行的是build/bin下的可执行文件,工作目录变了,配置就找不到了。用os.UserConfigDir()就是为了避免这个问题,配置固定在用户目录下,跟可执行文件位置无关。

5.6 模型名写错导致 400

ANTHROPIC_MODEL必须是完整模型 ID,比如claude-sonnet-4-5-20250929,不能简写成sonnet。不同通道支持的模型 ID 可能略有差异,拿不准时先用模型对话页面确认一下可用模型:

  • 模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

6. 把切换这件事收进一个面板

搭完这套东西,你手里就有了一个能存多套配置、一键切换、状态可见的桌面面板。它的价值不在于技术多复杂,而在于把「改环境变量」这个动作从三四个文件里收拢到一个按钮上。团队协作时,把config.json的模板发出去,每个人填自己的 Key,配置结构统一,排障时沟通成本直接降一半。

如果你还没建 Key,先去控制台创建一个:

  • API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

接入过程中遇到报错,对照接入文档查参数:

  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

长期跑编码任务的话,Coding Plan 比按量调用更划算:

  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

最后提醒一句:config.json里有明文 Key,别提交到 Git,.gitignore里加一行,或者干脆用os.UserConfigDir()把它放到仓库外面。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询