明明全局安装了 agent-browser,为什么 AI 代理还是说“找不到”?
Frank Zhang
- 2 minutes read - 300 wordsTL;DR
文章从一次 Codex 找不到 agent-browser 的问题出发,拆解交互 shell、非交互 shell 与多套 Node 环境并存时最容易出现的错位,并给出一套更稳的规避方法。
你有没有遇到过这种极其别扭的瞬间?
明明前几天才执行过:
npm install -g agent-browser
还亲手跑过:
agent-browser --version
agent-browser open https://www.google.com
可当 AI 代理真正开始干活时,它却一本正经地告诉你:
agent-browser: command not found
你如果遇到这种情况,第一反应通常有两种:
- “是不是这个 AI 太蠢了?”
- “是不是 tmux 窗口不一样,所以环境没继承过来?”
我这次的排查结果证明:这两种猜测都不是真正的根因。
问题的本质,其实是更隐蔽、更常见的一类故障:
你以为自己只有一套 Node 环境,但实际上系统里跑着两套。
一、为什么“我明明装过”这句话,依然可能是错的
“全局安装”这个词,听起来像是装进了整台机器。
但对 Node 生态来说,所谓“全局”,很多时候并不是“系统全局”,而是:
当前这一套 Node 运行时自己的全局目录。
如果你的电脑里同时存在:
- 一套 Homebrew 安装的 Node
- 一套
nvm管理的 Node
那么“全局安装”至少就有两种可能:
- 装进Homebrew管理的环境中
- 装进nvm管理的环境中
表面上你都在运行 npm install -g ...,但背后落盘的位置,取决于此刻命中的到底是哪一个 npm。
所以,“我装过”这句话本身没错;
真正有问题的是,你脑子里的“全局”只有一个,而系统里的“全局”其实有两个。
二、这次排查里,真正发生了什么
这次问题出现在 agent-browser 上。
现象非常矛盾:
- Shell历史记录中确实能找到之前成功安装和运行过
agent-browser的记录 - 但 AI 代理第一次检查时,
command -v agent-browser却显示它不存在
如果只看其中一边,你会觉得必有一方记错了。
可一旦把证据串起来,真相反而很清晰:
1. 我之前确实装过,而且真的跑通过
从~/.zsh_history中看到,之前运行过下面的命令:
npm install -g agent-browser
agent-browser install
agent-browser --version
agent-browser open https://www.google.com
agent-browser snapshot
agent-browser close
这说明“之前确实装过”不是错觉。
2. 旧安装其实落在 nvm 的 Node 20 下面
进一步排查后,找到了旧的安装路径:
~/.nvm/versions/node/v20.19.5/bin/agent-browser
~/.nvm/versions/node/v20.19.5/lib/node_modules/agent-browser
也就是说,之前那次安装,发生在 nvm 环境里。
3. AI 代理实际命中的却是 Homebrew Node
AI 代理执行环境里看到的是:
which node
# /opt/homebrew/bin/node
which npm
# /opt/homebrew/bin/npm
而不是 ~/.nvm/.../bin/node。
于是问题立刻成立了:
- 你装工具时,命中的是 A 环境
- 代理找工具时,命中的是 B 环境
从 A 的视角看,“我明明装过”;
从 B 的视角看,“这个命令根本不存在”。
两边都没错,只是根本不在同一个世界里说话。
三、tmux 不是主因,目录也不是主因
很多人会把这种问题怪到 tmux、标签页或者当前目录上。
这些因素当然可能影响环境,但它们不是这次问题的核心。
因为只要是:
- 同一个用户
- 同一套 PATH
- 同一套 Node 前缀
那么不管你在第几个 tmux pane、哪个工作目录里,command -v agent-browser 的结果都应该是一致的。
这次真正的差异,不是“窗口不同”,而是:
交互式 shell 和非交互式 shell 命中了不同的 Node 体系。
四、最坑的一层:你可能自己把环境分裂了
这次还有一个更隐蔽的坑。
检查 ~/.zshrc 时发现里面其实有一套懒加载 nvm 的包装逻辑:
- 平时不主动初始化
nvm - 但一旦你在交互终端里输入
node、npm、npx - 就临时切到
nvm版本
这类写法初衷通常是好的:减少 shell 启动开销,延迟加载。
问题在于,它会制造一种错觉:
你在交互式终端里输入 npm,看到的是 nvm 版本;
可 AI 代理、脚本、zsh -lc 这类非交互执行环境,却未必会吃到这些包装函数,最后实际走的还是 Homebrew。
于是系统就被硬生生劈成了两半:
- 你手里敲命令的世界,看到的是 Node A
- 代理和自动化执行的世界,看到的是 Node B
最要命的是,这两边平时都能正常工作,所以问题会潜伏很久,直到某个 CLI 工具恰好只装在其中一边,矛盾才突然爆炸。
五、真正有效的规避方式,不是“多记几个命令”
很多文章讲到这里,会开始给你列一堆排查命令。
这些命令当然有用,但它们只能救火,不能防火。
我这次最后采取的做法,其实只有一句话:
给默认工作流只保留一套 Node 环境。
具体来说:
- 把默认的
node/npm/npx统一到 Homebrew 版本 - 保留
nvm,但只在你手动切版本时显式调用 - 不再用
.zshrc去重写node/npm/npx这些基础命令
这样之后:
- 交互式 shell
- tmux 新开 pane
- AI 代理
- 非交互脚本
看到的都是同一套可执行文件和同一个全局包目录。
这才是真正意义上的“装一次,到处能认”。
六、以后每次装全局 CLI,我都会做这 4 步确认
如果你经常和 AI 代理、脚本、自动化工具一起工作,我非常建议把下面这组检查动作固定下来:
which node
which npm
npm prefix -g
command -v agent-browser
如果这是一个要给自动化环境用的工具,再多做一步:
zsh -lc 'which node; which npm; npm prefix -g; command -v agent-browser'
这一步非常重要。
因为很多“我明明装过”的故障,本质上都不是安装失败,而是:
你装工具时所在的 shell,和代理执行命令时所在的 shell,根本不是同一个环境。
七、一个比“修好问题”更重要的结论
这次排查给我最大的提醒,不是某个 which 命令有多有用,而是:
自动化时代里,环境一致性本身就是生产力。
如果一个人的电脑里同时存在多套运行时、多层 PATH 覆盖、以及只在交互 shell 生效的包装逻辑,那么他平时看起来可能一切正常,但只要开始接入 AI 代理、CLI 自动化、MCP、定时任务,环境分裂迟早会变成显性故障。
很多时候,真正拖慢效率的,不是工具本身,而是:
你以为你在维护工具,实际上你在维护多套彼此不一致的现实。
最后:别只追求“我装上了”,要追求“系统怎么看都装上了”
“我能在这个窗口里跑起来”,不等于“系统已经稳定可用”。
真正可靠的标准应该是:
- 我知道当前默认 Node 来自哪里
- 我知道全局包装到了哪个前缀
- 我知道交互 shell 和非交互 shell 的结果是否一致
- 我知道 AI 代理看到的环境,和我手动执行时看到的是不是同一个
只有这样,“全局安装”这四个字,才真正有意义。
否则,它就只是另一种形式的自我安慰。