☰
深入理解 OpenClaw 环境变量加载机制:优先级、配置注入与路径覆盖完整指南
2026/10/5 2:21:13 网站建设 项目流程
  • 人工智能
  • AI Agent
  • 即时通讯
  • 后端
  • 本地部署
  • 语音

【免费下载链接】openclaw-cn

中文社区版OpenClaw,同原版保持定期更新,已内置钉钉、企业微信、飞书、QQ、微信以及国内网络环境优化。你的专属个人AI助手。支持所有操作系统和平台。🦞

项目地址:https://gitcode.com/gh_mirrors/op/openclaw-cn
点击查看免费下载

环境变量是 OpenClaw 的"神经中枢",理解它的加载顺序是排查网关 API Key 缺失、配置部署异常的关键。本文基于docs/environment.md并结合 src/config/paths.ts、src/config/io.ts、src/infra/dotenv.ts、src/infra/shell-env.ts 等源码,系统梳理 OpenClaw(Clawdbot)加载环境变量的全部来源、优先级顺序、配置env块的两种写法、登录 shell 导入机制、配置内${VAR}替换语法,以及OPENCLAW_HOME、OPENCLAW_STATE_DIR、OPENCLAW_CONFIG_PATH三个路径类变量的覆盖规则。

环境变量从哪里来:五大来源与"绝不覆盖"原则

OpenClaw(Clawdbot)的配置加载器会从多个来源收集环境变量,核心规则只有一条:never override existing values(绝不覆盖已存在的值)。也就是说,环境变量一旦在更高级别的来源中被设定(非空),低优先级来源的同名变量将被忽略,这与传统的.env覆盖行为截然不同,可以避免部署环境中意外的"环境变量劫持"。

按优先级从高到低,环境变量来源如下:

优先级来源说明
1(最高)进程环境Gateway 进程从父 shell / 守护进程(daemon)继承的变量,任何情况下都不会被后续来源覆盖
2当前工作目录的.env使用 dotenv 默认行为加载(dotenv.config({ quiet })),不覆盖已有值
3全局.env位于~/.openclaw/.env(即$OPENCLAW_STATE_DIR/.env),不覆盖已有值
4配置文件env块位于~/.openclaw/openclaw.json中的env配置,仅在变量缺失时应用
5(最低)登录 shell 导入由env.shellEnv.enabled或OPENCLAW_LOAD_SHELL_ENV=1触发,仅对缺失的"预期 Key"生效

从源码实现看,第 2、3 步由 src/infra/dotenv.ts 中的loadDotEnv()完成:先以dotenv.config({ quiet })加载当前工作目录(CWD)的.env,再尝试读取path.join(resolveConfigDir(process.env), ".env")作为全局回退文件,并使用override: false保证绝不覆盖已存在的值。

需要特别注意的是:如果配置文件完全不存在,第 4 步(configenv块)会被跳过,但第 5 步(shell 导入)只要启用就仍然执行。这一行为在 src/config/io.ts 的loadConfig()中可见——当configPath不存在且 shell 回退已启用且未延迟时,会直接调用loadShellEnvFallback()并返回空配置{}。

配置文件中的env块:两种等价的非覆盖式写法

在~/.openclaw/openclaw.json(JSON5 格式)中,你可以通过env块直接内联设置环境变量。它提供两种等效的写法,均为非覆盖式(即仅当变量缺失时才生效):

{ env: { OPENROUTER_API_KEY: "sk-or-...", vars: { GROQ_API_KEY: "gsk-..." } } }
  • 顶层直接书写KEY: "value",如OPENROUTER_API_KEY;
  • 或将多个变量收纳进vars子对象,如GROQ_API_KEY;
  • 两种方式完全等价,可以混用。

从源码层面看,src/config/env-vars.ts 中的collectConfigEnvVars()会先遍历envConfig.vars,再遍历envConfig顶层除shellEnv和vars之外的所有字符串键,最后统一交给 src/config/io.ts 的applyConfigEnv()应用——应用逻辑非常简单:if (env[key]?.trim()) continue;,即环境里已有非空值就跳过,否则才写入。

env块的 Schema 在 src/config/zod-schema.ts 中定义:shellEnv对象可选,包含enabled: boolean与timeoutMs: number(整数、非负);vars为Record<string, string>;顶层允许任意字符串键(.catchall(z.string())),这正是两种写法都能被接受的原因。

Shell 环境导入:把登录 shell 的密钥带进 Gateway

env.shellEnv机制会执行你的登录 shell,并只导入缺失的预期 Key——这是解决"明明在终端里 export 了 API Key,但 Gateway 作为守护进程/服务运行时却拿不到"这一经典问题的方案。

{ env: { shellEnv: { enabled: true, timeoutMs: 15000 } } }

对应的环境变量等价写法:

  • OPENCLAW_LOAD_SHELL_ENV=1—— 等价于enabled: true
  • OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000—— 等价于timeoutMs: 15000(默认 15000ms)

源码实现位于 src/infra/shell-env.ts 的loadShellEnvFallback()。其执行逻辑依次为:

  1. 若未启用,直接跳过;
  2. 若expectedKeys中已有任意一个键存在于环境中(非空),则整个导入被跳过(skippedReason: "already-has-keys")——这是一个重要的短路优化:只要检测到任意一个预期 Key 已存在,就认为环境已就绪,不再执行登录 shell;
  3. 否则通过execFileSync(shell, ["-l", "-c", "env -0"], { timeout })执行$SHELL(缺省回退/bin/sh)的登录 shell,以 NUL 分隔输出环境变量(env -0),解析后用\0分割(parseShellEnv(),见 src/infra/shell-env.ts);
  4. 仅对缺失的预期键逐一代入值,最终返回实际应用的 Key 列表。

所谓"预期 Key"(SHELL_ENV_EXPECTED_KEYS)在 src/config/io.ts 中定义,包含常见模型与渠道凭据:OPENAI_API_KEY、ANTHROPIC_API_KEY、ANTHROPIC_OAUTH_TOKEN、GEMINI_API_KEY、ZAI_API_KEY、OPENROUTER_API_KEY、AI_GATEWAY_API_KEY、MINIMAX_API_KEY、SYNTHETIC_API_KEY、ELEVENLABS_API_KEY、TELEGRAM_BOT_TOKEN、DISCORD_BOT_TOKEN、SLACK_BOT_TOKEN、SLACK_APP_TOKEN、OPENCLAW_GATEWAY_TOKEN、OPENCLAW_GATEWAY_PASSWORD。

加载时机上(src/config/io.ts),当shouldEnableShellEnvFallback(env)为真或配置中cfg.env?.shellEnv?.enabled === true,且未设置OPENCLAW_DEFER_SHELL_ENV_FALLBACK时,会在配置加载完成、applyConfigEnv之后触发 shell 导入;超时值优先取cfg.env?.shellEnv?.timeoutMs,否则回退到OPENCLAW_SHELL_ENV_TIMEOUT_MS或默认 15 秒。

配置内的${VAR}替换:把密钥写进配置但不落盘

你可以在配置文件的任意字符串值中使用${VAR_NAME}语法直接引用环境变量,加载时会被替换为实际值:

{ models: { providers: { "vercel-gateway": { apiKey: "${VERCEL_GATEWAY_API_KEY}" } } } }

这一语法在 src/config/env-substitution.ts 的substituteString()中实现,规则要点:

  • 仅匹配大写环境变量名,模式为[A-Z_][A-Z0-9_]*;
  • 使用$${}转义可输出字面量${};
  • 若引用的变量缺失或为空,会抛出MissingEnvVarError(携带变量名与配置路径上下文),加载因此失败——这保证了配置不会在静默中拿到空密钥;
  • 关键时序:在 src/config/io.ts 中,applyConfigEnv先于resolveConfigEnvVars执行,因此${VAR}可以引用同配置env块中定义的变量;
  • 配置写入(writeConfigFile)时,未变更路径上的${VAR}引用会被restoreEnvVarRefs/restoreEnvRefsFromMap还原,避免把解析后的明文密钥写回磁盘(见 src/config/io.ts)。

更完整的说明可参见 网关配置文档。

路径相关的环境变量:三个覆盖入口

OpenClaw 提供三个路径类环境变量,用于调整内部路径解析:

变量用途
OPENCLAW_HOME覆盖所有内部路径解析所依赖的主目录(默认~/.openclaw/、agent 目录、会话、凭据),适合以专用服务用户运行 OpenClaw
OPENCLAW_STATE_DIR覆盖状态目录(默认~/.openclaw)
OPENCLAW_CONFIG_PATH覆盖配置文件路径(默认~/.openclaw/openclaw.json)

OPENCLAW_HOME:为无头服务账户实现完整文件系统隔离

设置OPENCLAW_HOME后,它将替换系统主目录($HOME/os.homedir())用于全部内部路径解析,从而让无头(headless)服务账户获得完整的文件系统隔离。

其解析优先级为:

OPENCLAW_HOME > $HOME > USERPROFILE > os.homedir()

源码实现在 src/infra/home-dir.ts 的resolveEffectiveHomeDir()中:若OPENCLAW_HOME非空则直接采用;否则依次回退$HOME、USERPROFILE、os.homedir()。OPENCLAW_HOME也支持波浪号路径(如~/svc),会在使用前基于$HOME展开——这正是expandHomePrefix()(src/infra/home-dir.ts)的职责,resolveRequiredHomeDir()则在所有来源都不可用时回退到process.cwd()。

macOS LaunchDaemon 示例:

<key>EnvironmentVariables</key> <dict> <key>OPENCLAW_HOME</key> <string>/Users/kira</string> </dict>

由于 LaunchDaemon 以 root 运行且没有常规登录环境,显式注入OPENCLAW_HOME是让服务使用指定用户配置目录的标准做法。

路径解析的完整链路

从 src/config/paths.ts 可以看到三个变量的协同:

  • resolveStateDir()(src/config/paths.ts):优先读取OPENCLAW_STATE_DIR(兼容旧名CLAWDBOT_STATE_DIR)的覆盖;否则在~/.openclaw(新目录)与.clawdbot、.moltbot、.moldbot(历史遗留目录,见第 20 行的LEGACY_STATE_DIRNAMES)之间按存在性选择;
  • resolveCanonicalConfigPath()(src/config/paths.ts):优先读取OPENCLAW_CONFIG_PATH(兼容CLAWDBOT_CONFIG_PATH),否则默认$OPENCLAW_STATE_DIR/openclaw.json;
  • resolveConfigPath()/resolveConfigPathCandidate()还会在状态目录中按openclaw.json→clawdbot.json→moltbot.json→moldbot.json的顺序探测已存在的配置文件(src/config/paths.ts),保证老用户升级后配置仍能无缝找到。

此外,paths.ts还暴露了若干相关覆盖项可供部署参考:OPENCLAW_OAUTH_DIR(OAuth 凭据目录,默认$STATE_DIR/credentials,见 src/config/paths.ts)、OPENCLAW_GATEWAY_PORT(默认 18789,见 src/config/paths.ts)、OPENCLAW_NIX_MODE=1(Nix 部署模式,禁止自动安装流程,见 src/config/paths.ts)。

调试排查清单

当你在 Gateway 中遇到"API Key 缺失"类问题时,可按以下顺序自检:

  1. 进程环境:确认启动 Gateway 的父进程/shell 中变量确实存在且非空(echo $OPENAI_API_KEY);
  2. .env文件:检查当前工作目录与~/.openclaw/.env(或$OPENCLAW_STATE_DIR/.env)中是否有同名变量——注意低优先级.env里的值不会覆盖进程环境中的值;
  3. 配置文件env块:确认openclaw.json的env块没有拼写错误,且 JSON5 语法合法;
  4. shell 导入:确认env.shellEnv.enabled或OPENCLAW_LOAD_SHELL_ENV=1已设置,且预期 Key(见上文SHELL_ENV_EXPECTED_KEYS列表)确实存在于你的登录 shell 中——可临时执行$SHELL -l -c 'env -0'验证;
  5. ${VAR}引用:检查配置中apiKey等字段是否为${SOME_KEY}形式且对应变量非空,否则会触发MissingEnvVarError并导致配置加载失败;
  6. 路径类变量:若使用服务账户或容器部署,核对OPENCLAW_HOME/OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH是否指向了正确的目录,避免读取到"另一份"配置。

相关文档

  • 网关配置完整说明
  • FAQ:环境变量与 .env 加载
  • 模型提供商概览
  • 人工智能
  • AI Agent
  • 即时通讯
  • 后端
  • 本地部署
  • 语音

【免费下载链接】openclaw-cn

中文社区版OpenClaw,同原版保持定期更新,已内置钉钉、企业微信、飞书、QQ、微信以及国内网络环境优化。你的专属个人AI助手。支持所有操作系统和平台。🦞

项目地址:https://gitcode.com/gh_mirrors/op/openclaw-cn
点击查看免费下载

相关推荐

上一篇:3 步让笔记自动"认识"彼此:Obsidian Smart Connections 语义关联实战指南
下一篇:BetterJoy 零基础全解:三步让 Switch 手柄在 PC 上跑起来

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询