修了一个隐藏的代理问题 — pi daemon 启动排查记
昨晚家里断电,NAS 和 Mac 都关了。今天回来发现 pi(飞书机器人 daemon)没自动启动。本来以为简单重启一下就行,结果花了半小时才找到真正的问题——一个已经关闭的 WiFi 代理留下的幽灵。
症状
pi 启动后飞书连接显示「已连接」,但几秒后进程就退出了。重新启动,同样的情况反复出现。
第一层:以为是 stdin 问题
pi 用的是 RPC 模式,需要 stdin 保持打开。进程退出最先想到的就是 stdin EOF。加上 tail -f /dev/null 喂 stdin——这是之前验证过的方案:
tail -f /dev/null | pi --mode rpc \
--no-extensions --no-skills --no-prompt-templates \
-e /path/to/feishu/index.ts
但这次没用,进程还是退。
第二层:日志里的 ECONNREFUSED
翻 daemon.log,看到一行关键报错:
Error: connect ECONNREFUSED 192.168.1.2:20172
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1637:16)
[feishu] daemon autoStart failed:
Cannot destructure property 'tenant_access_token'
of '(intermediate value)' as it is undefined.
192.168.1.2:20172 是 NAS 上的 HTTP 代理。 pi 的飞书插件请求飞书 API 获取 tenant_access_token,但请求被代理拦截——而代理已经死了。
问题是:我之前已经在 Mac 的 WiFi 设置里把代理关了啊?
第三层:系统代理关了,环境变量还在
这是最坑的地方。macOS 的 WiFi 代理设置关掉后,当前 shell 会话里的 http_proxy / https_proxy 环境变量并不会自动清除。这些变量是在代理开启时被注入到进程环境中的,只要终端/session 不重启,它们就一直存在。
pi 作为子进程继承了这些环境变量,所有 HTTP 请求都先走 192.168.1.2:20172——一个已经不存在的代理。
修复
启动前手动 unset 所有代理变量:
export PATH="/Users/hai/.nvm/versions/node/v22.22.2/bin:$PATH"
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY all_proxy
tail -f /dev/null | pi --mode rpc \
--no-extensions --no-skills --no-prompt-templates \
--no-themes --no-context-files --no-builtin-tools \
-e /Users/hai/.pi/agent/git/github.com/AX1202/pi-feishu-lark/.pi/extensions/feishu/index.ts
这次飞书连接成功,进程稳定运行不再退出。
两个坑,一个比一个隐蔽
| 问题 | 原因 | 表现 |
|---|---|---|
| 代理幽灵 | WiFi 代理关闭后 http_proxy 环境变量未清除 | ECONNREFUSED,飞书 token 获取失败 |
| stdin EOF | RPC 模式读 stdin,EOF 触发退出 | 飞书已连接但进程秒退 |
两个问题叠加在一起,第一个导致飞书连不上,第二个导致即使连上了也保不住。单独排查任何一个都找不到完整答案。
教训
- 关闭代理 ≠ 清除环境变量。macOS 系统代理设置变更不会同步到已运行的 shell session。以后关代理后,要么重开终端,要么手动
unset。 - 看日志比猜原因快。第一反应是 stdin 问题(因为是已知的老问题),差点忽略了日志里的
ECONNREFUSED。如果一开始就tail daemon.log,5 分钟就能定位。 - 把排查过程写成 Skill。这次的问题(代理残留 + stdin EOF)以后断电重启还会遇到。直接写成了一个 Hermes Skill(
pi-feishu-daemon),下次同样的情况,Agent 加载技能就能自动按正确步骤启动,不用再重新排查。
每一次断电都是一次灾难恢复演练。问题是,你不想每次都从头排查。
附:pi feishu daemon 排查速查
# 1. 检查 pi 是否在运行
ps aux | grep "[e]arendil"
# 2. 看飞书连接状态
tail -5 ~/.pi/agent/feishu/daemon.log
# 3. 看有没有代理残留
env | grep -i proxy
# 4. 启动(unset 代理 + tail stdin)
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
tail -f /dev/null | pi --mode rpc ...
← 返回首页