一个轻量级的 Go CLI 工具,通过按需加载配置文件(Profile)向 AI 命令行程序(如 claude、codex 等)注入环境变量,实现多账号、多模型、多密钥的快速切换。
~/.codeai/setting.json 按当前环境变量自动选择 Profile,无需手动指定"log_level": "debug" 后输出详细调试信息,便于排查问题git clone https://cnb.cool/hepeichun/codeai.git
cd codeai go build -o codeai .
交叉编译多平台[OR]
goreleaser release --clean --skip=publish --snapshot
sudo mv codeai /usr/local/bin/
codeai init <程序名> <profile名>
示例:
codeai init claude default
# 创建 ~/.codeai/claude/default.json
打开生成的 JSON 文件,填入你的配置:
{
"env": {
"ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx"
},
"args": ["--verbose"],
"log_level": "",
"proxy": {
"enabled": false,
"upstream": "http://user:pass@proxy.host:port",
"mode": "whitelist",
"rules": ["api.anthropic.com", "*.anthropic.com"]
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
env | map[string]string | 注入的环境变量,覆盖当前 Shell 中的同名变量 |
args | []string | 启动程序时自动附加的参数 |
log_level | string | 日志级别,留空或省略时静默运行,设为 "debug" 时输出调试日志至 stderr |
proxy | object | 内置代理配置,省略或 enabled: false 时不启用 |
| 字段 | 类型 | 说明 |
|---|---|---|
enabled | bool | 是否启用内置代理 |
upstream | string | 上游代理地址,格式 http://[user:pass@]host:port |
mode | string | "whitelist" 或 "blacklist",见下文 |
rules | []string | 匹配规则列表,支持精确 IP、CIDR、域名、通配符域名(*.example.com) |
mode 语义:
| mode | rules 内的主机 | rules 外的主机 |
|---|---|---|
whitelist | 走上游代理 | 直连 |
blacklist | 直连(绕过代理) | 走上游代理 |
工作原理:
启用后,codeai 在本地随机端口(20000–30000)启动一个轻量 HTTP 代理,将子进程的 HTTP_PROXY / HTTPS_PROXY 指向它,同时清空 NO_PROXY。代理根据规则决定每个连接是转发至上游还是直连。子进程退出后代理随即关闭。
# 使用 default profile 启动
codeai claude
# 指定 profile(跳过自动匹配)
codeai claude work
等效于:
ANTHROPIC_API_KEY=sk-ant-xxxxxxxx claude --verbose
无需每次手动输入 profile 名称。在 ~/.codeai/setting.json 中配置规则,codeai 启动时会依次评估规则,命中第一条匹配的规则即使用对应的 profile;若无匹配则回退到 default。
~/.codeai/setting.json 示例:
{
"env_profiles": [
{
"program": "claude",
"profile": "work",
"when": { "ANTHROPIC_BASE_URL": "https://work.example.com" }
},
{
"program": "claude",
"profile": "corp",
"when": {
"$and": [
{ "ANTHROPIC_BASE_URL": "https://corp.example.com" },
{ "ANTHROPIC_AUTH_TOKEN": "sk-corp-token" }
]
}
},
{
"program": "claude",
"profile": "personal",
"when": {
"$or": [
{ "ANTHROPIC_BASE_URL": "https://personal.example.com" },
{ "ANTHROPIC_AUTH_TOKEN": "sk-personal-token" }
]
}
}
]
}
规则字段说明:
| 字段 | 说明 |
|---|---|
program | 规则作用的程序名,与 codeai <program> 中的程序名对应,不匹配则跳过 |
profile | 命中时使用的 profile 名称 |
when | 匹配条件(见下文) |
when 条件语法:
| 写法 | 含义 |
|---|---|
{ "KEY": "VALUE" } | 环境变量 KEY 的值等于 VALUE |
| 多个顶层 key | 隐式 AND,所有条件均需满足 |
{ "$or": [...] } | 任意一个子条件满足即可 |
{ "$and": [...] } | 所有子条件均需满足 |
$or / $and 可任意嵌套。
codeai list claude
# 输出:
# default
# work
# personal
所有配置文件存放在 ~/.codeai/ 目录下,按程序名分组:
~/.codeai/ ├── setting.json # 全局设置:env_profiles 自动匹配规则 ├── claude/ │ ├── default.json │ └── work.json └── codex/ └── default.json
07000600| 场景 | 退出码 |
|---|---|
| 未传入参数 | 1 |
| Profile 文件不存在 | 1 |
| JSON 格式错误 | 1 |
| 程序不在 PATH 中 | 127 |
| 子进程退出 | 子进程的退出码 |
init 目标文件已存在 | 1 |
所有错误信息输出至 stderr,以 codeai: 为前缀。
场景一:个人账号与工作账号分离
codeai init claude personal
codeai init claude work
# 分别填入不同的 API Key
codeai claude personal # 使用个人账号
codeai claude work # 使用工作账号
场景二:切换不同模型
{
"env": {
"ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx",
"ANTHROPIC_MODEL": "claude-opus-4-6"
},
"args": []
}
场景三:通过代理访问(黑名单模式)
内网域名直连,其他流量走上游代理:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"proxy": {
"enabled": true,
"upstream": "http://user:pass@corp-proxy.example.com:8080",
"mode": "blacklist",
"rules": [
"localhost",
"127.0.0.1",
"192.168.0.0/16",
"*.internal.example.com"
]
}
}
场景四:白名单模式——仅代理 Anthropic API
只让 Anthropic 相关域名走代理,其余全部直连:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"proxy": {
"enabled": true,
"upstream": "http://127.0.0.1:7890",
"mode": "whitelist",
"rules": [
"api.anthropic.com",
"*.anthropic.com"
]
}
}
场景五:按环境变量自动切换 Profile
在不同终端会话或 CI 环境中设置不同的环境变量,codeai 自动使用对应的 Profile,无需手动指定:
// ~/.codeai/setting.json
{
"env_profiles": [
{
"program": "claude",
"profile": "work",
"when": { "ANTHROPIC_BASE_URL": "https://work.example.com" }
},
{
"program": "claude",
"profile": "personal",
"when": { "ANTHROPIC_BASE_URL": "https://personal.example.com" }
}
]
}
export ANTHROPIC_BASE_URL=https://work.example.com
codeai claude # 自动使用 work profile
export ANTHROPIC_BASE_URL=https://personal.example.com
codeai claude # 自动使用 personal profile
codeai claude default # 显式指定时跳过自动匹配
场景七:管理多个 AI 工具
codeai init codex default codeai init gemini default codeai codex codeai gemini
场景八:开启调试日志排查问题
当程序运行无输出或行为异常时,在 Profile 中设置 "log_level": "debug" 即可在 stderr 看到完整的执行过程:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"log_level": "debug"
}
示例输出(运行 codeai curl default -s https://ipinfo.io):
codeai[debug] loaded profile: program=curl, profile=default codeai[debug] profile args: [] codeai[debug] resolved path: /usr/bin/curl codeai[debug] final args: [-s https://ipinfo.io] codeai[debug] injected env keys: [ANTHROPIC_API_KEY] codeai[debug] proxy disabled codeai[debug] exec: /usr/bin/curl [-s https://ipinfo.io] codeai[debug] exit code: 0
调试完毕后将 log_level 删除或置为 "" 即可恢复静默模式。
codeai/ ├── main.go # 入口 ├── cmd/ │ ├── root.go # 命令分发 │ ├── run.go # codeai <程序> [profile] │ ├── list.go # codeai list <程序> │ ├── init.go # codeai init <程序> <profile> │ └── open.go # codeai open <程序> ├── config/ │ ├── config.go # 配置路径解析、JSON 解析、Profile / ProxyConfig 结构体 │ └── setting.go # 全局设置解析、env_profiles 规则匹配引擎 ├── logger/ │ └── logger.go # 全局调试日志(由 log_level 控制) ├── proxy/ │ ├── proxy.go # 本地 HTTP 代理服务器(CONNECT + 普通 HTTP) │ └── rules.go # 规则匹配引擎(IP / CIDR / 域名 / 通配符) └── executor/ └── executor.go # 环境变量合并、代理生命周期、进程启动、stdio 透传
MIT