# chrome-use:让任何 AI Agent 直接驱动你已登录的真实 Chrome,CreepJS 给它打 0% bot

![chrome-use:开你已经登录的那个浏览器](https://img.leeguoo.com/media/3f74a992-9b69-4d78-a3ef-6e827099d3f8/cover.png)

做 AI Agent 的人迟早会撞到同一堵墙:**让 agent 在浏览器里替你干活**。订机票、发帖、抓后台数据、跑一遍回归,只要涉及网页,几乎都绕不开浏览器自动化。

然后你就掉进了熟悉的坑里。

## 为什么传统浏览器自动化这么难用

Playwright、Puppeteer、browser-use,以及任何 `--launch` 出来的新浏览器,做的都是同一件事:**开一个全新的、空白配置的浏览器**。这意味着:

- **每次都要重新登录。** 你在 Chrome 里常年保持登录的 ChatGPT、X、GitHub、公司后台,在那个空浏览器里统统不存在。默认起的就是空配置:Cookie、session 全是空的(你当然可以手动喂 profile,但那又得自己维护登录态)。
- **验证码把 agent 卡死。** 空浏览器、陌生指纹、数据中心 IP,网站一看就知道是脚本,直接弹验证码或 Cloudflare 拦截页,agent 当场卡住,没人帮它点。
- **指纹一看就是假的。** `navigator.webdriver`、headless 痕迹、CDP 泄漏……这些都是一眼可辨的自动化破绽。而 Akamai、DataDome、PerimeterX 这些 Bot 检测厂商还会在几十个维度上打分,默认配置的 Playwright/Puppeteer 很容易露馅。
- **你看不见它在干嘛。** 它在另一个进程的另一个窗口里跑,你既插不上手,出了问题也只能对着日志干猜。

问题的根源是一个:**它开的是一个「别的」浏览器,不是你的。**

## chrome-use 换了个思路:开你那个真浏览器

[chrome-use](https://github.com/leeguooooo/chrome-use) 把**任何** agent(Claude Code、Cursor、Codex、你自己的脚本)指向你那台**各种网站早就登录好了的 Chrome**。

项目主页：https://chrome-use.leeguoo.com/

它在**你的窗口**里点击,所以你能看着它干活,撞到 2FA 或验证码的瞬间你随手就能接管;而且因为它**就是你的真实浏览器**(走一个一键安装的商店扩展 + 原生消息通道,用 `chrome.debugger` 驱动标签页,**不暴露 TCP 远程调试端口**),网站在指纹层面看到的就是一个真实的人类浏览器,没有自动化痕迹可抓(CreepJS 隐身分 0%,见下文「反检测」一节)。当然,IP 信誉、账号风险、行为节奏是另外几条轴,仍然需要你自己把握。

一句话:**不开新 Chrome,不重新登录,不再撞「你是机器人吗?」那道墙。**

| | 传统自动化(Playwright / `--launch`) | chrome-use(连接你的 Chrome) |
|---|---|---|
| 浏览器 | 启动一个新的空浏览器 | 连上你正在用的 Chrome |
| 登录态 | 空的,得重新登 | 你现成的全部 session |
| 指纹 | 带自动化痕迹 | 你真实的指纹 |
| 协作 | 另开一个窗口 | 同一个窗口,随时接管 |
| 验证码 | agent 卡死 | 你点一下,agent 继续 |

### 那 Claude 自带的 Chrome 插件、web-access、CDP 端口呢?

- **Playwright / Puppeteer / browser-use?** 它们启动一个**空**浏览器,你得把每个登录重做一遍、每个验证码硬刚一遍,而且照样被标记成自动化。chrome-use 用的是你**已经有**的那个 session。
- **Claude 自带的 Chrome 插件?** 很好,但它只驱动 Claude 自己。chrome-use 驱动**任何** agent 或 CLI。
- **裸的 `--remote-debugging-port`(web-access 那类)?** Chrome 136+ 在连接时会弹一个拦截弹窗「**是否允许远程调试?**」(该 Chrome 会话内持续生效)。chrome-use 永远不会,因为它走的是一键商店扩展 + 原生消息。

## 工作原理:全程在你本机,不走网络

![chrome-use 架构:CLI ↔ 扩展 ↔ 你的 Chrome](https://img.leeguoo.com/media/b2f9d8cd-3c5e-4f6d-b572-ee7fe95eb6ae/arch.png)

你的 **chrome-use CLI** 通过 Chrome 的**原生消息(native messaging)**和一个很小的**浏览器扩展**对话,这是一条本机进程间通道,**没有网络 socket、没有 token、没有远程服务器**。扩展用 `chrome.debugger` 去驱动你指定的标签页(就在你那个**已经登录好的 Chrome** 里),再把结果交回 CLI。**一切都留在你的机器上。**

### 为什么是扩展,而不是裸 debug 端口

别的本机工具走裸 `--remote-debugging-port`(CDP)。从 **Chrome 136** 开始,这样的连接首次会弹一个拦截式的「**是否允许远程调试?**」授权框(该 Chrome 会话内持续生效),而且端口还得提前开。chrome-use 的扩展走原生消息:**装一次,之后每次用零确认。**

| | chrome-use(扩展) | web-access(裸 CDP 端口) | Claude 自带插件 |
|---|---|---|---|
| 连接方式 | 原生消息,无端口、无 token | `--remote-debugging-port` | `chrome.debugger` |
| 「是否允许远程调试?」弹窗 | **永不** ✅ | **会弹(每会话)** 🔴 | 无 |
| 用你的真实登录 | 是 | 是 | 是 |
| `Runtime.enable` CDP 泄漏 | **默认关 → 干净** ✅ | 域已启用 | 不适用 |
| CreepJS 隐身分 | **0% stealth · 0% headless** ✅ | 真 Chrome | 真 Chrome |
| 每会话独立标签组 / 并发 agent | **支持** ✅ | 否 | 否 |

这个授权弹窗不是危言耸听:裸端口工具首次**连接(attach)**会弹一个拦截式授权框(该 Chrome 会话内持续生效);扩展这条路装一次之后不再弹这个阻塞框。

> **一个要说清楚的点:别误以为「全程无感知」。** 扩展底层驱动标签页用的还是 `chrome.debugger`,它本质就是 CDP,只是走原生消息、不开 TCP 端口。所以它避开的是那个**阻塞式**的「是否允许远程调试?」对话框,以及对外暴露的调试端口。但只要 chrome-use 正在驱动你的真 Chrome,Chrome 顶部就会挂一条**非阻塞**的「chrome-use started debugging this browser」提示条(带一个 Cancel 按钮);这是 `chrome.debugger` API 的固有行为,**避不掉**,随手点 Cancel 就能断开。准确的说法是:**没有阻塞弹窗、没有对外开放的调试端口,但有一条可以随手关掉的提示条**,而不是「完全无感知」。

## 给 Agent 用的接口:看一眼页面只花 200–400 token

到这里都在讲「连谁的浏览器」。但对 AI agent 来说,还有一件同样要命的事:**每看一眼页面,要烧掉多少 token。**

很多浏览器 agent 是**截图驱动**的:把整张网页截图喂给视觉模型,让它在像素里找按钮。一张截图动辄几千 token,点一次、翻一页就得再来一张;跑一个稍微长点的流程,token 就这么哗哗地烧。另一些则把整段原始 HTML/DOM 塞进上下文,同样又长又脏。

chrome-use 走的是**结构化优先**:`snapshot -i` 给 agent 一棵**可访问性树(accessibility tree)快照**,只保留可交互元素,每个元素配一个紧凑的 `@eN` 引用。一整页通常只要 **~200–400 token**,而不是去解析原始 HTML、更不是塞一张截图进去。agent 直接按引用操作:

```bash
chrome-use open <url>
chrome-use snapshot -i      # 只看可交互元素,每个带一个 @eN 引用
chrome-use click @e3        # 按引用操作,不靠坐标,也不靠截图
```

截图在 chrome-use 里是**产出**,不是**输入**:你要留证、给人看时才截图,agent 自己定位 / 读取 / 点击的全程都不需要它。而 site adapters(见下文)更进一步:直接拿回干净的 JSON,连快照都省了,是「读结构化数据」最省的一条路。

省下来的是实打实的成本:同一个流程,结构化接口往往比截图驱动便宜一个数量级,任务越长越明显。这也是为什么 chrome-use 把自己定位成**给 agent 用的 CLI**,而不是给人看的浏览器面板。

## 反检测:不打补丁,就没有可被测谎的痕迹

![真实但不可检测的指纹](https://img.leeguoo.com/media/ab527c98-5ac6-41c6-9322-404a2ec258a0/stealth.png)

连接到你的真实 Chrome 时,chrome-use 一条 JavaScript 补丁都不注入。你浏览器的指纹**完全是真的**。指导原则是**用原生的 CDP/Chrome 层覆盖,而不是靠 JS 伪造**,被重定义的 getter 本身就能被检测出来,而原生层的覆盖不会留下这种痕迹。

- `navigator.webdriver = false` 走 `Emulation.setAutomationOverride`(原生覆盖,不像被重定义的 getter 那样会被 CreepJS 那类「测谎」检测当场抓到)。
- **`Runtime.enable` 默认是关的。** 一个活着的 `Runtime` 域本身就是一个可检测的 CDP 信号(patchright/rebrowser 说的「runtime leak」),哪怕你连的是真 Chrome 也一样。我们只在你主动开启 console/error 抓取时才启用它。`click`、`fill`、`eval` 这些不开它也照常工作。

**实测结果(连接真实 Chrome):**

| 检测站 | 结果 |
|---|---|
| [CreepJS](https://abrahamjuliot.github.io/creepjs/) | **0% stealth · 0% headless**(没有自动化覆盖痕迹) |
| [bot.incolumitas.com](https://bot.incolumitas.com/) | 全部 OK:`overflowTest`、`overrideTest`、`puppeteerExtraStealthUsed`、worker 一致性 |
| [bot.sannysoft.com](https://bot.sannysoft.com) | 全绿 |
| [BrowserScan](https://www.browserscan.net/bot-detection) | Webdriver · User-Agent · CDP 全干净 |
| Cloudflare Turnstile([nowsecure.nl](https://nowsecure.nl) 被动挑战) | 通过 |

CreepJS 上的 `0% stealth` 是关键数字:因为连接路径**什么都不打补丁**,根本不存在能被「测谎器」抓到的覆盖。我们也**故意不做自己的 bot 检测器**,最经得起检验的基准,就是拿公开检测站里最严的那几个(CreepJS、incolumitas)去打你的真浏览器,注意它们测的是指纹/痕迹,而商业的行为 + IP 信誉栈是另一层更难的关。不必信我们的话,[自己去验一遍](https://abrahamjuliot.github.io/creepjs/)。

### 行为级隐身:让点击像真人出手

指纹只是故事的一半。这些 Bot 检测厂商(Akamai、DataDome、PerimeterX)还会给**行为**打分。一个把光标瞬移到元素正中心、没有任何接近路径、零按下延迟的点击,本身就是个破绽,**哪怕我们的 CDP 事件是 `isTrusted` 的**。

![Humanize:机器直线 vs 类人曲线轨迹](https://img.leeguoo.com/media/548c21e0-7a97-4eec-8e55-b839d8f8f2d1/humanize.png)

开启 humanize 后,光标的移动就像真人在操作:点击走一条**曲线、减速的贝塞尔路径**,落在元素内部一个**带随机抖动的位置**上(绝不是正中心);打字用**变化的击键间隔**;滚动分段缓动;拖拽走曲线。而且它是**自适应**的,每次导航都会探测已知的反爬厂商(cookie / 脚本 / 全局变量),被盯防的页面自动升级到类人轨迹,消除「瞬移点击」这类最低级的破绽,这能去掉明显的机器痕迹,但行为级风控还会看停留、节奏、整段会话的熵,humanize 不是万能解;普通网站则保持原来的瞬时点击(零额外开销)。

用 `--humanize off|fast|human` 或环境变量控制,默认 `off`,自适应探测器会按页面自动升级。

### 静默运行:绝不抢你的前台

既然是驱动你自己的真实 Chrome,就**绝不该打断你手上的活**。agent **完全在后台**运作:新标签页**不抢焦点**地打开(在它自己那一组带颜色的标签里),agent **从不强行把标签页提到前台**,而 `Emulation.setFocusEmulationEnabled` 让每个 agent 标签页持续渲染、并且 `document.hasFocus()` 返回 `true`、`visibilityState` 报告 `visible`。所以截图照常能用、页面不会被渲染节流,「整段会话标签页都不可见」这种可能被当成异常的信号,也不会被触发。你在你的活动标签页里继续干活,agent 在旁边静静地干它的。

## 多 Agent 共享一个 Chrome,互不打架

每个 `--session` 拿到**自己一组带颜色的 Chrome 标签**,所以多个 agent 能**并发**共用同一个真浏览器,既不互相干扰,也不会动到你自己的标签页。一个会话只拥有它自己创建的标签,它**绝不**接管你的标签页,也不接管其它 agent 的标签页;命令的下发也按会话相互隔离。这意味着你可以在一个真实 Chrome 上同时跑好几个 agent,各干各的。

## Site Adapters:把一个网站变成结构化数据 CLI

很多「读 GitHub issues」「搜 Reddit」「取我的 B 站动态」这类任务,根本不需要点击和截图,网站背后早就有一个 JSON API(只是要在登录态下才能调)。一个 **site adapter** 就是一小段 JS,**在你登录好的标签页里**调那个 API(你的 cookie、同源 `fetch`、网站自己的模块),返回干净的 JSON。在网站看来,这个请求和你本人手动操作发出的几乎无从区分。

chrome-use **不内置任何** adapter,`site update` 在运行时去拉社区的 [bb-sites](https://github.com/epiral/bb-sites) 包(像包管理器拉依赖那样),再用 chrome-use 的隐身传输跑它们:

```bash
chrome-use site update                      # 拉取 adapter 包(约 145 个命令)
chrome-use site list                        # github/issues、reddit/search、bilibili/feed…
chrome-use site github/issues epiral/bb-browser --json
chrome-use site bilibili/feed --json        # 能跑,因为用的是你登录好的 session
```

而且它**自动同步、自动提示**:你 `open`/`snapshot` 一个有 adapter 的域名时,chrome-use 会直接在输出里给你一行 `💡 site adapters for <domain>`,让 agent 优先去用结构化数据 adapter,而不是去 DOM 里刮。

## 把「点点点」变成可重跑的测试套件(`chrome-use test`)

那种「打开它、点一圈、检查对不对」的重复劳动,可以变成一套**可重跑的测试**,相当于给前端加一层冒烟/回归测试。用 YAML 写用例,步骤复用 chrome-use 自己的命令,断言编译成单个检查:

```yaml
# smoke.yaml
suite: chatgpt smoke
cases:
  - name: home loads logged in
    steps:
      - open: https://chatgpt.com/
      - wait: { load: networkidle }
    assert:
      - url: { contains: chatgpt.com }
      - visible: "#prompt-textarea"
```

```bash
chrome-use test smoke.yaml                  # 起一个隔离浏览器跑用例
chrome-use test smoke.yaml --session default # …或对着你连接的 Chrome 跑
```

任一用例失败,退出码非零(直接塞进 CI),失败用例还会存一张截图。断言支持 `url`/`visible`/`hidden`/`text`/`count`/`eval`,步骤支持 `open`/`click`/`fill`/`type`/`press`/`wait`/`scroll`/`eval`。发现了回归问题?补一个用例就行,用得越多,这套测试越有价值。

## 上手:一行装好,接到任何 agent

```bash
curl -fsSL https://raw.githubusercontent.com/leeguooooo/chrome-use/main/install.sh | sh
```

从最新的 [GitHub Release](https://github.com/leeguooooo/chrome-use/releases) 下载对应平台的预编译二进制,装好 `chrome-use`(外加 `abs` 短别名)。**不走 npm,也不需要任何 token。**

连上你的 Chrome(推荐扩展这条路,一键、零弹窗):装上 [Chrome 应用商店里的 chrome-use 扩展](https://chromewebstore.google.com/detail/chrome-use/knfcmbamhjmaonkfnjhldjedeobeafmk),然后注册一次本地桥:

```bash
chrome-use extension install      # 注册原生消息宿主(一次性)
chrome-use open https://x.com/home
```

之后就能全程通过原生消息,驱动你那台真实、已登录的 Chrome,**无 debug 端口、无 token、永远不弹「是否允许远程调试?」**。

给 AI agent 装上配套技能(Claude Code、Cursor 等):

```bash
npx skills add leeguooooo/chrome-use
```

这会把 `skills/chrome-use` 连同专项技能一起放进你的项目,你的 agent 就有了正确的用法范例,以及预先授权好的 bash 权限。

日常用起来就是这样,任何 agent 都能调:

```bash
chrome-use open https://example.com
chrome-use click "Post"
chrome-use fill "Title" "Hello World"
chrome-use screenshot ./page.png
```

agent 在你的 Chrome 里操作,你能实时看到标签页打开、页面加载、点击发生。任何时候你都能接管(比如解个验证码),再让 agent 继续。

不想碰你的真 Chrome?用 `chrome-use --launch open <url>` 起一个全新的隔离隐身浏览器(完整反检测补丁全上),CI 里会自动走这条路。

## 它凭什么不一样

- **默认就连你现有的 Chrome**,`chrome-use open <url>` 驱动你正在用的浏览器,而不是另起一个。
- **Token 高效的结构化接口**,给 agent 的是可访问性树快照 + `@eN` 引用,一页 ~200–400 token,不靠截图、也不塞原始 HTML;截图只是产出,不是输入。
- **扩展中继传输**,一键商店扩展 + 原生消息,没有 debug 端口,没有「是否允许远程调试?」弹窗。
- **CDP 原生隐身**,反检测靠 Chrome/CDP 覆盖而非 JS 补丁;连真 Chrome 时零补丁,只有 `--launch` 才上完整补丁。
- **Humanize**,类人光标轨迹 + 自适应反爬处理。
- **多 agent 隔离**,并发 agent 通过每会话标签组共享一个真 Chrome,互不串扰。
- **静默运行**,后台运作,绝不抢你的前台标签页。

chrome-use 属于 `*-use` 家族,[iphone-use](https://github.com/leeguooooo/iphone-use) 驱动你的真实 iPhone,chrome-use 驱动你的真实 Chrome。项目 Apache-2.0 开源。

做 agent 自动化的人值得拥有这个,顺手去 GitHub 点个 star,让更多做 Agent 的同行看到它:**[github.com/leeguooooo/chrome-use](https://github.com/leeguooooo/chrome-use)**。

---

> 由 **leeguooooo** 打造,AI agent、逆向工程、Cloudflare Workers 的一线笔记都在 [blog.leeguoo.com](https://blog.leeguoo.com),X 上关注 [@leeguooooo](https://x.com/leeguooooo)。

相关文档：[chrome-use · 驱动真实 Chrome](https://chrome-use.leeguoo.com/real-chrome.html)、[安装](https://chrome-use.leeguoo.com/install.html)。
