用浏览器历史追查部分智能体操作
Chromium 历史记录中的 FROM_API 标志可识别部分经调试协议或扩展触发的导航。直接创建标签页、模拟点击等操作不会留下该标志,因此不能据此完整还原智能体活动。
AI 深度解读
AI agent 能操作浏览器之后,一个很实际的问题出现了:人离开电脑,回来怎么知道它打开过哪些页面?ccdeck 作者给出的办法,是读取 Chromium 历史记录中的导航标记,再结合前后有没有其他浏览记录,把部分自动访问单独列出来。
这个功能叫 Browser Watch。它适合回看 agent 的活动,但不能证明电脑前没人,也不能发现所有自动化操作。理解它怎么判定,比看到一张告警卡片更有用。
Chromium 留下的标记,能认出哪些自动访问
Chromium 的每条访问记录都有一个 transition 值,用来描述页面是通过点击链接、输入地址等哪种方式打开的。其中的 FROM_API 标志位,数值是 0x08000000,位于 bit 27,标记部分来自外部应用的导航。
这里最容易误解的是:用了 API,不一定就有这个标记。原文列出的区别如下:
| 操作方式 | 是否带 FROM_API |
|---|---|
DevTools 协议的 Page.navigate |
有 |
扩展通过 chrome.tabs.update 设置 URL |
有 |
通过 Target.createTarget 直接在指定 URL 新建标签页 |
没有 |
通过 chrome.tabs.create 新建标签页 |
没有 |
| 程序点击页面链接 | 没有 |
通过 open 或 xdg-open 传入地址 |
没有 |
同样是 agent 打开网页,仅仅换一条调用路径,检测结果就可能不同。
Browser Watch 检查的是这个位,不是根据 URL 猜测访问者是谁。作者称分类代码附有 Chromium 源码依据,但原文没有提供覆盖率测试,也没有证明各种浏览器、扩展组合下都能稳定识别。
它识别的是符合特定条件的导航记录,无法直接识别「AI 正在操作浏览器」。
入口在 ccdeck 工具栏的眼睛图标,也可以按 B。徽标显示上次关闭面板后新开始的事件数量。面板左侧展示受监测的浏览器配置,以及 deck 启动后程序打开的页面数;右侧 Findings 展示符合条件的事件。
每张卡片对应一个浏览器中的一个主机名,展开后能查看完整地址和时间,包含 ? 后面的查询参数、# 后面的片段。核对完成后,点击 × 可以永久移除该卡片。

「人不在」是根据历史推算的,默认还要等一阵
Browser Watch 没有空闲计时器,也不监听键盘。它用浏览历史判断是否处于无人浏览的时段。
一条访问要进入 Findings,必须携带 FROM_API,并且同一浏览器配置中,它之前和之后的静默窗口内都没有未标记访问。这个窗口由 Nobody browsing for 控制,默认是 15 分钟,可选 1、5、15、30、60 分钟。
后面的窗口还没走完时,卡片会显示 provisional,即暂定状态。一条新出现的未标记访问,就可能让它撤回。问题在于,未标记访问也可能来自自动化,所以程序活动不仅可能漏报,还可能取消附近的候选事件。
同一个主机名、同一个浏览器的访问,只要相邻两次间隔都小于 15 分钟,就会归为同一事件。这个归组间隔需要和可配置的静默窗口区分开。deck 自己的标签页不会被报告。
发现事件后的动作有三种:默认通知、关闭标签页,以及退出浏览器。关闭标签页仅支持 macOS;Linux 退出时只针对持有该配置的浏览器进程,无法确定进程就不执行,例如 Flatpak Brave。

这些动作都有延迟。每个新事件只触发一次,要等首个页面脱离暂定状态;默认窗口下,约在首个页面出现 16 分钟后,于下一次检查执行。
页面在此之前已经加载了。关闭标签页只是清理,退出浏览器也挡不住程序再次启动它。
每次反应还会发出标题为 Browser watch 的系统通知,除非启动时设置了 AGENTS_DECK_NO_NOTIFY=1。Settings 中的 Notifications while closed 开关不影响它。多个 deck 同时运行时,只有端口最低的实例负责记录和反应。
它不上传历史,但会在本地保存完整事件地址
Browser Watch 默认开启,会读取找到的 Google Chrome、Chromium、Brave、Microsoft Edge、Vivaldi 配置,以及 macOS 上的 Arc。它只处理 deck 启动后的访问,不扫描展示既有历史;Firefox、Safari,以及自动化工具自行创建的临时配置目录不在覆盖范围内。
查询时,它会在 History 文件变化后,将文件复制到 browser-watch/staging/ 下的私有目录,执行一次查询后删除副本,避免直接查询正在使用的数据库。它不读取 cookies、保存的密码或页面内容。
确认后的事件则会持久保存:
~/.claude/agent-dag/browser-watch/watch.log记录每个标记事件及完整地址,达到2 MiB后轮转为watch.log.1,macOS、Linux 可用tail -f查看。- 同目录的
state.json最多保存500个事件,以及关闭卡片的记录和设置。 - 设置
CLAUDE_CONFIG_DIR会迁移这两处存储位置,CCDECK_HOME不会。
普通浏览只计数,不保存逐条地址。不过,这里的「普通」仍依赖分类结果,不能理解成工具已经知道哪些页面由人操作。
用于显示 Claude in Chrome 是否在线的 Remote control 状态,还会读取 hosts 文件及相关配置设置。面板打开且安装了 dig 时,约每 30 秒查询一次中继域名。作者明确表示,这是监测功能产生的出站请求,不携带浏览历史。
检查也不是持续运行:deck 页面打开时每五分钟读一次历史,Browser Watch 面板打开时每 10 秒一次,手动刷新最多每分钟一次。没有 deck 标签页或桌面窗口打开,就不会检查。
关闭 Watch browser activity 后,后台不再读取浏览器,也不新增保存记录;但主动打开面板仍会读取实时活动,展示本次 deck 启动后看到的内容。
我的判断
我认可它把判断依据讲清楚:检查哪个标志、哪些调用会漏掉、为什么撤回、记录保存在哪里,都比一个笼统的「检测到 AI 操作」更有参考价值。
和翻浏览器完整历史相比,它减少了筛选工作,还能保留完整 URL 和时间。和查看 agent 自己的执行日志相比,它从浏览器这一侧补充了证据。但它没有 agent 身份信息,不能把某次访问准确归因到某个任务。
最大的局限是用「没有未标记访问」推测人已离开。你可能正在读文档,只是没打开新页面;也可能已经离开,但 agent 的未标记访问让候选事件被取消。窗口缩短能增加发现机会,也会混入更多自己工作时的活动。
原文没有误报率、漏报率或不同窗口的对照数据。这是一套有明确实现依据的经验规则,效果还需要结合自己的操作路径判断。
有 Findings,说明标记访问满足了静默规则;没有 Findings,不能证明程序没用过浏览器。
另外,历史不出机器,不代表没有新增敏感记录。完整查询参数可能包含业务标识或临时凭据,本地日志应当按实际内容管理。原文没有说明对这些字段进行脱敏。
能拿来做什么
- 如果你让 AI 编程助手操作自己的 Chromium 浏览器,可以先用默认通知模式,离开后回来核对它访问的域名、完整路径和时间,检查是否与任务一致。
- 如果你在写浏览器自动化,先确认实际使用的是
Page.navigate、chrome.tabs.update,还是不带标记的创建标签页、点击路径,再决定能否用它辅助回看。 - 如果你经常边浏览边运行 agent,可以试用 1 或 5 分钟窗口,但要结合执行日志核对结果,不能把增加的卡片都当成异常。
- 本地试用可运行下面的命令,再保持 deck 页面打开并按
B。运行前要有 Node.js22.13或更新版本,或者 PATH 中存在sqlite3;macOS 自带sqlite3,Windows 不自带。
npx ccdeck
这条命令启动后,默认开启的监测才会开始观察后续访问,启动前的历史不会被补扫。