ToApp
15.35M · 2026-03-23
这次踩了一个很典型、也很容易误判的坑:
明明 ~/.bashrc 里已经配置了 TAVILY_API_KEY,但在 OpenClaw 里使用 Tavily skill 时,依然报 Missing TAVILY_API_KEY。与此同时,内置 web_search 还因为 Brave Search API 没配 key 直接报错。
看起来像是“配置丢了”,但真正的问题并不在 ~/.bashrc 本身,而在 Gateway 进程的启动方式。
这篇文章把完整的排查链路、根因分析和修复步骤整理出来,给遇到类似问题的同学一个可复用的参考。
最开始暴露出来的是两个现象:
调用内置搜索时,直接拿到类似下面的错误:
missing_brave_api_key
这说明当前 OpenClaw 的内置 web_search 走的是 Brave Search,而不是 Tavily。
Tavily skill 的 SKILL.md 里已经写得很清楚:
Needs TAVILY_API_KEY from
我进一步检查运行环境,结果是:
TAVILY_API_KEY_SET=no
这就奇怪了:终端里明明能看到 ~/.bashrc 中存在 export TAVILY_API_KEY=...,为什么 OpenClaw 运行时却拿不到?
先看 Tavily skill 本身。
它的搜索脚本逻辑非常直接:
const apiKey = (process.env.TAVILY_API_KEY ?? '').trim();
if (!apiKey) {
console.error('Missing TAVILY_API_KEY');
process.exit(1);
}
这意味着只要当前进程环境里没有 TAVILY_API_KEY,它就一定失败。
所以问题就从“有没有写配置”转变成了:
继续检查 OpenClaw Gateway 状态:
bash -i -lc 'openclaw gateway status'
输出里有一个关键点:
Service: systemd (enabled)
Service file: ~/.config/systemd/user/openclaw-gateway.service
这一下就基本破案了。
OpenClaw Gateway 不是我当前 terminal session 里手工启动的长期进程,而是 systemd user service 托管的服务。
这意味着:
source ~/.bashrcecho $TAVILY_API_KEY 能看到值因为它们根本不是同一个环境来源。
~/.bashrc 给了 interactive shell,但没给 systemd user service这是这次问题的核心。
~/.bashrc 什么时候会生效?通常是:
但 systemd user service 启动的进程,并不会自动读取你的 ~/.bashrc。
所以会出现一种非常迷惑的状态:
echo $TAVILY_API_KEY
# 有值
TAVILY_API_KEY = 空
这也是为什么很多人会说:
因为 你 export 给的是当前 shell,不是 systemd service。
既然目前主要想用的是 Tavily 和 LangSearch,而 Brave Search API 不是免费方案,那一个实际的处理方式就是:
先把内置 web_search 关掉,避免以后继续因为 BRAVE_API_KEY 报错。
配置修正后,搜索路径就会更清晰:
这个动作不是必须,但在多搜索源共存时很有价值:
既然 Gateway 是由 systemd user service 启动,那么最短修法就是:
bash -i -lc 'echo $TAVILY_API_KEY'
如果这里为空,说明你的 ~/.bashrc 本身就没配对,或者没被当前 shell 加载。
systemctl --user import-environment TAVILY_API_KEY FIRECRAWL_API_KEY
这一步非常关键。它会把当前 shell 中的环境变量同步给 systemd user manager。
systemctl --user restart openclaw-gateway.service
这样新的 Gateway 进程就有机会拿到刚刚导入的变量。
systemctl --user show-environment | grep -E '^(TAVILY_API_KEY|FIRECRAWL_API_KEY)='
如果能看到输出,说明 systemd user manager 已经持有这些变量。
可以直接检查进程环境,或者更简单,直接实测 Tavily:
bash -i -lc 'node skills/tavily-search/scripts/search.mjs "OpenClaw latest release" -n 3'
如果能正常返回答案和来源,说明修复已经生效。
修复完成后,验证结果如下:
SHELL_TAVILY=yes
SHELL_FIRECRAWL=yes
TAVILY_API_KEY=<redacted>
FIRECRAWL_API_KEY=<redacted>
PROC_TAVILY=yes
PROC_FIRECRAWL=yes
已经成功返回 OpenClaw 最新 release 的答案和来源。
这说明修复不是“看起来像好了”,而是 从 shell → systemd → Gateway → skill 调用链路全部打通了。
~/.bashrc 里重复定义了两次 TAVILY_API_KEY排查过程中还发现一个隐患:
~/.bashrc 里曾经同时存在两个 export TAVILY_API_KEY=...。
这类问题的风险不在于 bash 不能运行,而在于:
因此后面又做了一步清理:
这一步不直接决定功能是否可用,但会显著降低后续维护成本。
因为这类系统经常同时存在多种“环境来源”:
如果你只在某一个地方 export KEY=...,很容易出现“这个地方能用,另一个地方不能用”的现象。
对 AI Agent 场景来说,这类问题尤其常见,因为工具调用往往发生在:
所以经验上更稳妥的原则是:
如果你也遇到类似问题,可以直接按下面这份清单来:
# 1) 确认当前 interactive shell 里有变量
bash -i -lc 'echo $TAVILY_API_KEY'
# 2) 导入到 systemd user manager
systemctl --user import-environment TAVILY_API_KEY FIRECRAWL_API_KEY
# 3) 重启 Gateway
systemctl --user restart openclaw-gateway.service
# 4) 检查 systemd 环境
systemctl --user show-environment | grep -E '^(TAVILY_API_KEY|FIRECRAWL_API_KEY)='
# 5) 检查 Gateway 状态
bash -i -lc 'openclaw gateway status'
# 6) 实测 Tavily
bash -i -lc 'node skills/tavily-search/scripts/search.mjs "OpenClaw latest release" -n 3'
如果第 6 步成功返回结果,基本就说明整条链路已经修好了。
这次问题最值得记录的,不是某一条命令,而是排查思路:
很多“明明写了环境变量却不生效”的问题,本质上都不是 key 配错,而是:
一旦把这层想清楚,定位和修复就会快很多。
如果你也在折腾 OpenClaw、Tavily、LangSearch 或其他 AI Agent 工具链,希望这篇记录能帮你少踩一个坑。