第 01 模块 · 2 节

API Key 与环境变量

《Pi 生产级工程》01 多模型与提供方 · 本节时长 28 分钟

用 API Key 而不是订阅

上一节讲了订阅。这一节讲另一半:API Key。用订阅靠 OAuth 令牌,用 API Key 靠「一把显式的钥匙」。脚本、CI、分发出去的包,几乎都走 API Key。

配 API Key 有两条路,效果等价:

  1. 在交互模式敲 /login,选提供方,把 Key 存进 auth.json
  2. 直接设环境变量
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 的环境变量其实分三类,别混为一谈:

  1. 提供方 Key:如 ANTHROPIC_API_KEY(Providers 文档)
  2. 进程标记AI_AGENT=piPI_CODING_AGENT=true,让子进程能识别「我在 pi 里」
  3. 进程配置:如 PI_OFFLINE 关闭启动联网、PI_TELEMETRY 控制遥测、HTTP_PROXY 走代理
export PI_OFFLINE=1          # 关闭启动联网(更新检查、遥测等)
export PI_TELEMETRY=0        # 关闭遥测
pi

对生产环境,PI_OFFLINEPI_TELEMETRY 在 CI 里很实用——不想每次启动都去联网。


落地练习:配一个环境变量并验证

配一个 API Key,确认 pi 真正读到了它:

  1. .bashrc(或 .zshrc)里 export DEEPSEEK_API_KEY=sk-...(或你手头的任一家)
  2. 新开一个终端,用 echo $DEEPSEEK_API_KEY 确认变量在
  3. pi,敲 /model,确认该提供方的模型可选

怎么判断做对了?——环境变量能 echo 出来,且 pi 的 /model 里能看到对应模型,不再提示缺凭据。

卡住了怎么办? 变量设了但 pi 不认?先确认你设的是正确的那一个变量名(对照上面的表,别把 ANTHROPICOPENAI 搞混)。也可能是被 auth.json 里的旧凭据盖过了——检查解析顺序。


常见坑:把 Key 写进代码或提交进 git

生产级第一忌讳:把 API Key 明文写进仓库。很多泄露事故就是这么来的——Key 一旦进了 git 历史,就算删掉也救不回来。

正确姿势:Key 只放环境变量或 auth.json,用 !command 从系统钥匙串取,绝不硬编码进脚本。分发 md-tools 时更要提醒用户:你的包不该要求任何人把 Key 写死在配置里,只应指引他们设环境变量。


小结

  1. API Key 可放环境变量或 auth.json,优先级 auth.json 更高
  2. 每个提供方有专属环境变量名
  3. 解析顺序:CLI → auth.json → 环境变量 → models.json
  4. key 字段支持命令执行、环境插值、转义、字面量
  5. 环境变量还用于进程标记和进程配置(如 PI_OFFLINE

下一节,我们讲怎么给 pi 配一个自定义 provider——也就是 models.json