用 API Key 而不是订阅
上一节讲了订阅。这一节讲另一半:API Key。用订阅靠 OAuth 令牌,用 API Key 靠「一把显式的钥匙」。脚本、CI、分发出去的包,几乎都走 API Key。
配 API Key 有两条路,效果等价:
- 在交互模式敲
/login,选提供方,把 Key 存进auth.json - 直接设环境变量
export ANTHROPIC_API_KEY=sk-ant-...
pi
pi 支持一大堆提供方,每个有自己的环境变量名,比如:
| 提供方 | 环境变量 | auth.json 键 |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY |
anthropic |
| OpenAI | OPENAI_API_KEY |
openai |
| DeepSeek | DEEPSEEK_API_KEY |
deepseek |
| Google Gemini | GEMINI_API_KEY |
google |
| xAI | XAI_API_KEY |
xai |
| OpenRouter | OPENROUTER_API_KEY |
openrouter |
完整对照表在官方 Providers 文档里,具体环境变量名以你所用版本文档为准。
md-tools 分发来说,这一节最关键:你的包文档必须写清楚**用户该设哪个环境变量**。因为分发出去后,你控制不了别人的认证方式——你只能把「设 ANTHROPIC_API_KEY」这类说明写进 README,让用户自己配好。本节学会「环境变量 → 提供方」的映射,你写文档就不会写错变量名。**这就是 md-tools 分发体验好不好的第一步。**用 auth.json 存 Key
环境变量适合临时或单机;想持久化、且只属于某个用户,用 auth.json:
{
"anthropic": { "type": "api_key", "key": "sk-ant-..." },
"deepseek": { "type": "api_key", "key": "sk-..." },
"google": { "type": "api_key", "key": "..." }
}
几个关键点:
- 这个文件以
0600权限创建(只有当前用户可读写) - auth.json 里的凭据优先级高于环境变量
- 想清掉某个 Key,删掉对应条目即可
凭据解析顺序(别再猜了)
pi 解析一个提供方的凭据,按这个顺序:
CLI --api-key 参数
→ auth.json 条目(API key 或 OAuth 令牌)
→ 环境变量
→ models.json 里的自定义提供方 key
高优先级命中就不往下走了。上一节「以为登录成功其实是老 Key」的坑,就来自这里。
Key 的高级写法:命令、插值、转义
auth.json 和 models.json 里的 key 字段,支持四种写法:
| 写法 | 含义 | 示例 |
|---|---|---|
!command |
执行命令,用 stdout 作为 Key | "!security find-generic-password -ws 'anthropic'" |
$ENV_VAR / ${ENV_VAR} |
环境变量插值 | "key": "$MY_ANTHROPIC_KEY" |
$$ / $! |
转义,输出字面 $ 或 ! |
"$$literal-dollar-prefix" |
| 普通字符串 | 直接用字面值 | "key": "sk-ant-..." |
{ "type": "api_key", "key": "!op read 'op://vault/item/credential'" }
{ "type": "api_key", "key": "${KEY_PREFIX}_${KEY_SUFFIX}" }
把 Key 交给系统钥匙串(macOS security)或密码管理器(op),比明文放文件里安全得多——这对生产环境是加分项。
环境变量的三种用途(不只是 Key)
pi 的环境变量其实分三类,别混为一谈:
- 提供方 Key:如
ANTHROPIC_API_KEY(Providers 文档) - 进程标记:
AI_AGENT=pi和PI_CODING_AGENT=true,让子进程能识别「我在 pi 里」 - 进程配置:如
PI_OFFLINE关闭启动联网、PI_TELEMETRY控制遥测、HTTP_PROXY走代理
export PI_OFFLINE=1 # 关闭启动联网(更新检查、遥测等)
export PI_TELEMETRY=0 # 关闭遥测
pi
对生产环境,PI_OFFLINE 和 PI_TELEMETRY 在 CI 里很实用——不想每次启动都去联网。
落地练习:配一个环境变量并验证
配一个 API Key,确认 pi 真正读到了它:
- 在
.bashrc(或.zshrc)里export DEEPSEEK_API_KEY=sk-...(或你手头的任一家) - 新开一个终端,用
echo $DEEPSEEK_API_KEY确认变量在 - 跑
pi,敲/model,确认该提供方的模型可选
怎么判断做对了?——环境变量能
echo出来,且 pi 的/model里能看到对应模型,不再提示缺凭据。
卡住了怎么办? 变量设了但 pi 不认?先确认你设的是正确的那一个变量名(对照上面的表,别把 ANTHROPIC 和 OPENAI 搞混)。也可能是被 auth.json 里的旧凭据盖过了——检查解析顺序。
常见坑:把 Key 写进代码或提交进 git
生产级第一忌讳:把 API Key 明文写进仓库。很多泄露事故就是这么来的——Key 一旦进了 git 历史,就算删掉也救不回来。
正确姿势:Key 只放环境变量或 auth.json,用 !command 从系统钥匙串取,绝不硬编码进脚本。分发 md-tools 时更要提醒用户:你的包不该要求任何人把 Key 写死在配置里,只应指引他们设环境变量。
小结
- API Key 可放环境变量或 auth.json,优先级 auth.json 更高
- 每个提供方有专属环境变量名
- 解析顺序:CLI → auth.json → 环境变量 → models.json
key字段支持命令执行、环境插值、转义、字面量- 环境变量还用于进程标记和进程配置(如
PI_OFFLINE)
下一节,我们讲怎么给 pi 配一个自定义 provider——也就是 models.json。