bb-browser 卡顿优化实战:从根源解决 404 和操作超时

背景

在上一篇 bb-browser 卡顿与 404 问题排查指南 中,我分析了使用 Pi 编码代理 + bb-browser 时频繁卡顿的 5 个根因。本篇是实战篇——把分析结果落地为具体的优化措施

问题回顾

经过排查,核心问题有 5 个:

#问题影响
1Tab 坏请求堆积渲染进程被阻塞,CDP 命令排队
2CDP 命令超时 30 秒失败前要干等半分钟
3Daemon 日志被丢弃到 /dev/null黑盒排障,无从下手
4Chrome 长期不重启内存 1.7GB,响应越来越慢
5缺乏自动恢复机制卡死后只能手动重启

优化方案

方案一:Pi 扩展增强——自动恢复 + 新增工具

Pi 通过 TypeScript 扩展暴露 bb-browser 工具。原来的扩展只有被动检查 daemon 是否运行,没有任何恢复逻辑。

改动点/home/w/.pi/agent/extensions/bb-browser.ts

1.1 自动重启恢复机制

原来的 ensureDaemon() 只有简单的状态检查:

// 优化前:失败就直接返回
async function ensureDaemon(): Promise<boolean> {
    if (daemonRunning) return true;
    const status = await bb(["daemon", "status"], 10_000);
    if (status.code === 0 && status.stdout.includes("running")) {
      daemonRunning = true;
      return true;
    }
    const start = await bb(["daemon", "start"], 15_000);
    return start.code === 0;
}

优化后增加了自动重启和防递归锁:

// 优化后:失败时自动尝试完全重启
async function ensureDaemon(): Promise<boolean> {
    if (daemonRunning) return true;
    // ...检查状态...
    // 如果 CDP 未连接,先停再启
    await bb(["daemon", "stop"], 8_000);
    await pi.sleep(1000);
    const start = await bb(["daemon", "start"], 20_000);
    // ...
}

关键改进:

  • 状态检查不仅看 daemon 是否运行,还检查 CDP connected 标志
  • 增加 daemonRestarting 防递归锁,避免无限重试
  • 所有工具在 daemon 连接失败时自动调用 ensureDaemon 恢复

1.2 新增 bb_browser_cleanup 工具

这是最重要的新增工具——一键清理所有状态:

pi.registerTool({
    name: "bb_browser_cleanup",
    description: "Close all open tabs and restart the daemon...",
    parameters: {
        force: optional boolean // 强制重启
    },
    async execute() {
        // 1. 停止 daemon
        // 2. 杀死 Chrome CDP 进程(清除所有 tab)
        // 3. 等待 2 秒
        // 4. 启动全新 daemon(自动生成新的 Chrome)
        // 返回清理结果
    }
});

这个工具会:

  1. 停止 daemon → 2. 杀 Chrome → 3. 等待 → 4. 启动新 daemon + 新 Chrome

Chrome 的 user-data-dir 是持久化的,所以 cookies 和登录状态不会丢失

1.3 新增 restart action

在原有的 bb_browser_daemon 工具中增加了 restart action:

action: StringEnum(["start", "stop", "restart", "status"])

1.4 提示词优化(promptGuidelines)

在每个工具的 promptGuidelines 中加入了最佳实践指引:

工具新增指引
navigate强调用完必须 close;优先用 eval 而非 snap;复杂 SPA 预期会慢
eval明确标注 PREFER eval over snapshot
snapshot标注提取文本用 eval 替代
tabs提醒超过 2-3 个 tab 时要关闭
site强调 site adapter 优于打开完整页面
daemon介绍 restart action

这些提示词会直接注入到 AI 模型的 system prompt 中,从源头引导正确的使用习惯。

方案二:Daemon 日志捕获——告别黑盒

bb-browser 的 daemon start 命令在源码中这样启动 daemon:

const child = spawn(process.execPath, daemonArgs, {
    detached: true,
    stdio: "ignore"  // ← stdout/stderr 全部丢弃
});

所有 daemon 的输出都去了 /dev/null。任何错误信息、异常堆栈、连接断开警告都不可见。

解决方案:创建一个包装脚本,直接启动 daemon.js 并捕获输出。

#!/usr/bin/env bash
# bb-browser-daemon.sh — 日志包装脚本

# 找到 daemon.js 路径
DAEMON_JS="/path/to/bb-browser/dist/daemon.js"

# 直接启动 daemon.js,输出重定向到日志文件
nohup node "${DAEMON_JS}" --cdp-host 127.0.0.1 --cdp-port 9222 \
    >> ~/.bb-browser/logs/daemon.log 2>&1 &

优化前 vs 优化后的日志对比:

# 优化前:/dev/null,什么都看不到
/proc/231/fd/1 → /dev/null

# 优化后:清晰的内部日志
[Daemon] Chrome already running on port 9222
[Daemon] HTTP server listening on http://127.0.0.1:19824
[Daemon] Auth token: d4578366e580275e9123809c3cac1492
[Daemon] Connecting to Chrome CDP at 127.0.0.1:9222...
[Daemon] CDP connected, monitoring 1 tab(s)

包装脚本还提供了:

  • 日志轮转:超过 10MB 自动压缩归档
  • 自动清理:7 天前的日志自动删除
  • PID 跟踪:记录 daemon 进程 ID 便于管理

方案三:健康监控 + 自动恢复

每隔 2 小时自动检查 daemon 健康状况:

#!/usr/bin/env bash
# bb-browser-health.sh — 健康监控脚本

# 检查项目:
# 1. Daemon 进程是否存在?→ 不存在则启动
# 2. CDP 是否已连接?→ 未连接则重启
# 3. Chrome 运行是否超过 4 小时?→ 超过则重启
# 4. Tab 数量是否超过 3 个?→ 超过则重启

通过 cron 定时执行:

# 每 2 小时检查一次
0 */2 * * * /home/w/.local/bin/bb-browser-health.sh check
# 每天凌晨 3 点清理旧日志
0 3 * * * /home/w/.local/bin/bb-browser-daemon.sh clean

同时在 Pi 扩展中增加了主动防御——所有工具在调用前都会检查 daemon 健康状态,不依赖定时任务。

方案四:快捷别名

alias bb-status='bb-browser daemon status'
alias bb-restart='bb-browser daemon stop; sleep 1; bb-browser daemon start'
alias bb-tabs='bb-browser tab list'
alias bb-close='bb-browser close'
alias bb-logs='bb-browser-daemon.sh logs'
alias bb-cleanup='bb-browser-daemon.sh restart'
alias bb-health='bb-browser-health.sh --status'

验证结果

优化前状态

指标数值
daemon 运行时间1h13min
Chrome 内存占用1.7 GB
累计操作命令数1504 条
打开标签页数3 个
坏请求数(tab 5c04)67 个
日志不可见(→ /dev/null)

优化后状态

指标数值
daemon 运行时间刚重启
Chrome 内存占用~200 MB
累计操作命令数0(全新)
打开标签页数1 个或 0 个
坏请求数0
日志实时捕获到文件

功能验证

测试项结果
Daemon 日志捕获✅ 正常工作
完全重启(杀 Chrome)✅ tab 全部清除
Site adapter✅ 正常返回数据
打开/关闭 tab✅ 正常
健康检查脚本✅ 报告正确
定时 Cron 任务✅ 已安装

文件清单

优化涉及 5 个文件:

文件说明行数
/home/w/.pi/agent/extensions/bb-browser.tsPi 扩展(11 个工具,含新增 cleanup)844
/home/w/.local/bin/bb-browser-daemon.shDaemon 日志包装脚本160
/home/w/.local/bin/bb-browser-health.sh健康监控脚本(cron 调用)142
/home/w/.pi/agent/skills/bb-browser/SKILL.mdSkill 文档(加入使用规范)更新
~/.bashrcBash 别名追加

总结

这次优化不只是解决”卡顿”这个表面问题,而是做了整套工程化改进

层面措施效果
恢复自动重启 + cleanup 工具卡顿时一键恢复
可见性日志捕获到文件从黑盒变透明
预防每 2h 健康检查 + 自动重启问题在发生前被消灭
习惯prompt 指引 + 别名从源头引导最佳实践

最有价值的一点是:日志从 /dev/null 变成了可读文件。以前 daemon 内部发生了什么完全是黑盒,现在任何异常都能第一时间看到:

# 查看 daemon 日志
bb-logs
# 或
cat ~/.bb-browser/logs/daemon.log

如果你也用 pi + bb-browser,建议把这三样东西配齐:自动恢复机制、日志捕获、健康监控。它们不仅解决卡顿问题,更让你在遇到新问题时能快速定位根因。