☰
让AI接管已登录浏览器:腾讯开源方案实战解析
2026/9/30 9:40:36 网站建设 项目流程

1. 为什么"让 AI 用你已经登录的浏览器"会变成一个独立项目

这两年做 AI Agent 的开发者,应该都撞上过同一堵墙:模型理解网页没问题,规划任务也没问题,可一旦任务里出现"需要登录后才能操作"这一步,成功率就会断崖式下跌。填账密、扫码、滑块验证、短信验证,每一项都能把自动化流程卡在原地。更别提很多企业系统还做了设备指纹,换个浏览器环境登录,风控直接报警。

腾讯这次开源的项目,核心就是解决这个问题——让 AI 直接接管你已经登录好的浏览器,而不是让 AI 再去开一个全新的浏览器实例重复登录。它的思路说起来很朴素:你本机已经有一个登录状态良好的 Chrome/Edge,那就让 AI 连上去操作这个真实存在的浏览器。已有的 cookie、会话、用户数据目录、设备指纹,全部原样复用,AI 从"陌生人"变成了"坐在你电脑前的远程操作员"。

很多人第一次听到这个概念时,会觉得这跟传统 RPA(机器人流程自动化)没什么区别。实际上差别非常大。传统 RPA 靠的是坐标点击和像素识别,网页布局一变就要重新录流程,维护成本高到你怀疑人生。而这套方案靠的是多模态模型在"看"页面,它理解的是页面语义和任务目标,页面改版了也能自己重新找按钮、重新规划路径。相当于你同时拿到了 RPA 的确定性执行能力和大模型的灵活决策能力。

这个项目适合谁?三类人最值得关注:第一类是写办公自动化工具的个人开发者,想把"每天从后台导报表、填系统、发消息"这类重复劳动交给脚本;第二类是在做 AI Agent 平台的工程师,需要给智能体接一个能落地操作的浏览器工具箱;第三类是企业内部做数据中台的人,经常要把多个系统的数据来回搬运,又不想为每个系统单独维护一套登录逻辑。

我自己实际跑过的体会是:与其纠结"模型该用什么 Prompt 才能不瞎点",不如先把门槛最低也最容易出成果的事做了——把登录态这个问题解决掉。登录问题一旦绕开,后面所有自动化流程的开发效率能提升一个量级。这也是为什么看到这类开源方案时,我第一时间就搭了个最小环境验证,结果比我预期的还要顺。

2. 拆开看技术链路:CDP、用户数据与会话复用

2.1 让 AI 操作浏览器的三种常见姿势

目前让 AI "碰到"真实浏览器,主流有三条技术路线,理解它们的差异,你才知道为什么腾讯开源的方案要选择 CDP。

接入方式代表性实现优势天然短板
浏览器扩展 APIChrome Extension + chrome.scripting授权机制清晰,用户可感知AI 能力受扩展权限边界限制,不能任意跨域操作
直接驱动新浏览器Playwright / Puppeteer 独立启动环境干净,可重复,好做 CI 测试没有已登录会话,要自己处理各种验证
远程调试协议 CDPChrome DevTools Protocol能连已有浏览器实例,复用用户数据和登录态需要自己管理工作目录和权限边界

腾讯开源的项目走的是 CDP 这条链路,并且把上层做得更"AI 友好":它不只是给你一个发命令的接口,而是把页面截图、DOM 结构提取、多模态模型决策、元素定位和操作执行串成了一个完整循环。你拿到手的是一个能"自己看、自己想、自己点"的浏览器代理,而不是一堆裸 API。

2.2 "已登录"为什么比"登录一次也行"值钱得多

很多做爬虫或者自动化的人有个误区:只要找地方把 cookie 存下来,下次请求时带上不就行了?现实没这么简单。现在主流网站判断一个会话是否可信,看的不是单一 cookie,而是浏览器指纹、行为轨迹、IP 历史、设备信任等级的综合结果。你单独存下来的 cookie,换个浏览器环境、换套浏览器指纹,后端完全可能判定异常,轻则重新登录,重则直接触发风控。

用已登录的真实浏览器,本质上是把"这个账号已经是一个受信任设备上的合法会话"这个事实直接借给了 AI。因为登录是真人完成的,设备指纹是真实浏览器长久沉淀下来的,行为习惯也有历史数据支撑,AI 在这个环境里操作,被风控盯上的概率比新建一个清环境登录低得多。

这背后还有一层容易被忽略的东西:很多系统登录之后,界面状态本身也构成了"上下文"。比如你开着一个企业后台,里面已经筛选好了时间范围、选好了项目维度,AI 直接在这个页面上接管操作,就不需要从零理解这套系统的完整使用逻辑。这让任务复杂度和出错率都降了很多。

2.3 登录态具体是怎么被"借"给 AI 的

要理解这套方案,必须知道浏览器把登录状态存在哪里。以 Chrome/Edge 为例,所有 session、localStorage、cookie 都绑定在一个用户数据目录(user data directory)下。你日常使用的浏览器,配置里其实绑定了一个默认用户目录;专用调试模式启动时,你可以手动指定另一个目录,里面保存着所有登录状态。

CDP 的工作方式是:用--remote-debugging-port启动一个带调试端口的浏览器实例,这个实例可以是全新打开的,也可以是加载某个已有用户目录的。然后外部程序通过 WebSocket 连接到 9222 端口,就能看到这个浏览器里所有的标签页、DOM 节点、布局位置、网络请求记录,并且能模拟鼠标点击、键盘输入、滚动、导航。

腾讯开源项目做的一个重要封装,就是把"定位一个可点击元素"从"必须写完整 XPath 选择器"变成了"让多模态模型看截图、说出目标位置,框架自动反查真实 DOM 坐标"。这个转变让自动化流程的维护成本急剧下降,也让它能处理的页面类型大大增加。页面是用 Vue 写的、React 写的、甚至是大规模 Canvas 渲染的,模型都能通过截图理解,而不需要你为每种前端框架单独适配。

3. 最小可运行复现:用 Playwright 接管本机 Chrome

3.1 启动一个带调试端口的浏览器

我并不建议直接用你日常办公的主浏览器来做实验,那样容易把工作环境搞乱,profile 锁冲突也会带来一堆莫名其妙的问题。最稳妥的做法,是单独准备一个"工作浏览器"用户目录。

完整启动命令如下,macOS 上路径稍有不同,但参数一致:

# 先完全退出当前正在运行的 Chrome # 然后专开一个用户目录,并开调试端口 /path/to/chrome \ --remote-debugging-port=9222 \ --user-data-dir=/Users/me/work-browser-profile \ --no-first-run \ --no-default-browser-check

这条命令里有两个参数决定了整套方案能不能跑通。--remote-debugging-port=9222是打开远程调试服务,默认只监听127.0.0.1,也就是只有本机程序能连,这个是安全底线,千万别加--remote-debugging-address=0.0.0.0暴露到局域网或者公网;--user-data-dir指定独立用户目录,这样你可以在这个浏览器里登录自己的测试账号,然后把整个目录当作"登录态仓库"。

启动之后,先在浏览器里手动登录你要自动化操作的目标系统。这个动作非常重要,它代替了以往脚本里最痛苦的那段验证逻辑。

3.2 通过 Python 连接已有浏览器

连接已有浏览器的核心 API 是connect_over_cdp。它跟普通的launch最大的区别是:不创建新浏览器,而是作为客户端去连已经在跑的浏览器进程。

from playwright.sync_api import sync_playwright with sync_playwright() as p: # 连接已启动的浏览器,而不是重新启动一个 browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222") # 拿到浏览器里所有已打开的上下文和标签页 contexts = browser.contexts page = contexts[0].pages[0] if contexts and contexts[0].pages else None if page is None: page = browser.new_page() # 截一张当前页面的图,让 AI 看清楚现在的状态 page.screenshot(path="current_state.png") print("当前页面标题:", page.title()) print("当前页面URL:", page.url)

这段代码跑通后,你就已经有了一条 AI 操作真实浏览器的"管道":浏览器的真实环境、真实登录态、真实 DOM,全部通过 CDP 暴露给了你写的程序。后面只需要把"截图给模型看、模型返回动作、程序执行动作"这个循环接上,就变成了一个完整的 AI 浏览器代理。

3.3 一个极简的"观察-决策-执行"循环

最小可用的 Agent 循环,不需要引入复杂的 Agent 框架。核心就是把多模态模型的输出约束成结构化 JSON,然后映射到 Playwright 的页面操作上。

我这里用一个伪接口来说明整体结构,实际使用时你可以换成任意支持视觉输入的模型服务:

import json from playwright.sync_api import sync_playwright # 允许模型输出的动作集合 ACTION_SCHEMA = { "type": "object", "properties": { "action": { "type": "string", "enum": ["click", "input", "scroll", "wait", "finish"] }, "target": {"type": "string", "description": "要操作的元素描述"}, "value": {"type": "string", "description": "输入的文字"} }, "required": ["action"] } PROMPT = """ 你现在是一个浏览器操作员。 根据用户任务和当前网页截图,决定下一步操作。 优先选择完成目标所必需的、风险最低的动作。 只输出 JSON,不要输出解释。 """ def ask_model(screenshot_path: str, task: str) -> dict: # 这里替换成你自己的多模态模型调用逻辑 # 把截图和 task 一起发过去,要求返回符合 ACTION_SCHEMA 的 JSON return json.loads(mock_model_response(screenshot_path, task)) def execute_action(page, action: dict): action_type = action["action"] if action_type == "click": # 先用文本定位元素,定位不到再回退到坐标 try: page.click(action["target"]) except Exception: page.mouse.click(action["x"], action["y"]) elif action_type == "input": page.fill(action["target"], action["value"]) elif action_type == "scroll": page.mouse.wheel(0, int(action["value"])) elif action_type == "wait": page.wait_for_timeout(int(action["value"])) elif action_type == "finish": return False return True def run_agent(task: str, max_steps=10): with sync_playwright() as p: browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222") page = browser.contexts[0].pages[0] for _ in range(max_steps): page.screenshot(path="step_state.png") decision = ask_model("step_state.png", task) should_continue = execute_action(page, decision) if not should_continue: break

实际跑这个循环时,建议把每一轮截图落盘存档。有个最容易犯的错:只保存最新一张截图,不保留历史状态。保留每一轮截图,你在排查"模型为什么突然乱点"时会有极大的便利,也能拿来做行为审计。

3.4 第一步验证选什么站点

我建议第一步先选一个"已登录、无风险影响、但有一定交互复杂度"的站点来验证,比如你自己的云服务器控制台、项目管理后台这类系统。这类后台通常有左侧边栏、筛选器、分页表格,点击路径比较长,足够暴露框架的稳定性问题,又不会因为你点错导致不可逆损失。

先在页面上手动登录并把页面状态调整到你想要的样子,然后让 AI 完成一个只读性质的任务,比如"把当前表格第 3 页的名称列提取出来"或"按创建时间倒序重新排序"。跑通这个阶段,你再逐步上提任务难度:填写表单、跨标签页操作、需要弹窗确认的流程。

这里有个重要原则:一开始就让 AI 操作带付款、删除、群发性质的按钮,纯属给自己找事故。后面我会专门说权限边界怎么设计,但早期验证阶段,宁可选无聊一点的站点。

4. 跑起来之后真正值得注意的坑

4.1 Chrome 正在运行时连不上 9222

这是我见过最多人踩的第一个坑。很多人下载代码后先启动调试浏览器,然后发现connect_over_cdp一直报连接拒绝,或者连上了却发现页面列表是空的。

原因多半出在:你日常使用的主 Chrome 还在运行,而新启动的调试进程用了同一个默认用户目录。Chrome 检测到该目录已被另一个进程占用,就会把命令转发给对方,然后自己退出。你启动参数里的--remote-debugging-port=9222并没有真正生效。

解决办法有两个。一是完全退出当前所有 Chrome 进程再启动调试实例;二是像我之前那样,用独立的--user-data-dir开一个专属工作浏览器,从根上规避 profile 锁冲突。第二个办法明显更省心,因为你可以保底一个专门用于 AI 自动化的浏览器环境,日常浏览器随便开,两者互不干扰。

验证是否连上的最快方式,是在浏览器跑起来后访问http://127.0.0.1:9222/json/version。能正常返回 JSON,说明调试服务是活的,然后再去动 Python 代码。

4.2 风控不是不触发,而是从"瞬间触发"变成了"延迟触发"

很多人以为连上真实浏览器就等于完全绕过了风控,这是另一个极端。真实浏览器的登录态和指纹确实降低了风控拦截的概率,但 AI 的操作行为本身如果太像机器,依旧会被后端模型捕捉到。

比如一个需要人工连续点击 10 次才能填完的表单,AI 在两三秒内全部点完,中间没有滚动、没有停顿、没有鼠标轨迹变化,这本身就是明显的异常行为特征。就算登录态完全正常,后端行为风控也可能要求重新验证或把账号标记为可疑。

实操中我会给动作之间加入合理的随机延迟,避免固定间隔,也避免一律零延迟。有些项目甚至会对鼠标移动轨迹做贝塞尔曲线插值,这个取决于你所在场景的敏感程度。我的经验是:对于企业内部后台这类低风险系统,固定加 0.5 到 1.5 秒的随机等待已经足够;对于面向 C 端用户、风控严苛的平台,则不要轻易让 AI 高频操作。

4.3 多业务尽量分开不同的用户目录

如果只在一个用户目录里登录所有系统的账号,表面上看很省事,实际上隐患不小。第一个问题是账号互相污染,A 系统的操作逻辑出了问题,AI 误点了浏览器里的另一个标签页,可能无意间在 B 系统里留下操作记录;第二个问题是退出登录时难管理,一个目录的 cookie 是整体落盘的,你没法精确控制"只清理某个站点的会话"。

我自己的习惯是给每个业务域单独建一个 profile 目录,例如work-profile-data-platform、work-profile-crm、work-profile-finance。目录建好后写一个小脚本去启动对应 profile 的浏览器,用环境变量或配置项区分。这样每个 AI 任务都只在它该接触的登录态范围内活动,出问题后的清理和隔离成本都低很多。

4.4 必须给 AI 的权限划边界

让 AI 操作一个已登录的账号,意味着它拥有了这个账号在那个站点上的完整权限。你登录了企业微信,它就可能发消息;你登录了财务系统,它就可能点审批或付款按钮;你登录了云控制台,它甚至可能创建按量计费的资源。模型本身不理解"这个动作的实际代价",它只是遵循指令输出操作。

所以权限边界不能指望模型自觉,必须用代码强制约束。比较有效的做法是维护一个敏感操作清单:

禁止 AI 触发的动作类型包括:提交支付、删除资源、发送外部消息、修改账号权限、导出客户隐私数据;需要人工确认后才能执行的动作包括:提交工单、变更配置、批量操作。

SENSITIVE_KEYWORDS = ["删除", "付款", "转账", "移除", "终止服务", "销毁"] def check_action_safety(action_text: str, page_url: str) -> bool: # URL 白名单之外的不允许操作 allowed_domains = ["console.example-corp.com"] if not any(domain in page_url for domain in allowed_domains): return False # 文案命中敏感词则拦截 if any(word in action_text for word in SENSITIVE_KEYWORDS): return False return True

这套安全拦截可以非常简单,但必须具备。让没有边界的 AI 连上有完整权限的浏览器,就像把办公室钥匙交给一个方向感模糊的外包人员,不是每次都会出事,但你不会想赌概率。

5. 除了做 Agent,这套思路还能往哪个方向延伸

5.1 给 AI 套一个 MCP 工具层

单跑一个 Agent 循环只是起点。现在智能体开发流行 MCP(Model Context Protocol)协议,目的就是把各种能力封装成标准工具供模型调用。你可以把"当前浏览器里的页面"封装成一个 MCP server 工具箱,里面提供浏览器观察、元素截图、文本抽取、表单填写、导航跳转这几个工具。

这样做的好处是,以后不管是接腾讯的模型也好,接其他家的模型也好,Agent 只需要知道"我有一组浏览器工具可用",就能在对话中动态决定使用哪些工具。浏览器能力与模型解耦,项目后期替换模型或升级模型都不需要重写操作底层。

5.2 典型高频场景拆解

以我实际接触到的项目来说,这套浏览器接管方案在几类场景里收益最明显。第一类是数据报表的跨系统搬运:每天从 A 系统导出数据、在 B 系统填表提交,过去要人肉操作半小时,现在 AI 连浏览器后一杯咖啡的功夫跑完;第二类是后台运维的巡检:登录控制台查看服务状态、磁盘用量,异常时再调用截图留档;第三类是客服后台的重复操作:批量更新工单状态、按模板回复常见问题,AI 能快速完成,只是在发送前加了人工确认点。

这几类场景有个共同特征:重复性高、规则相对明确、出错的代价可控。反过来说,如果任务本身需要大量主观判断,或者一次误操作的代价特别大,就不太适合现阶段全自动跑,更适合做成"AI 给建议,人来确认"的半自动模式。

5.3 向可视化行为记录演进

因为整个操作过程都在真实浏览器里完成,CDP 能拿到的不只是最终结果,还包括中间每一步的请求记录、页面状态变化、甚至控制台日志。这意味着你可以把 AI 的一次完整行为轨迹录制下来,回放、回溯、审计。

这个能力在内部系统落地时非常有用。法规审计问"这个操作是谁做的",可以说"这是 AI 自动化任务在某个用户会话下执行的",同时给出完整的截图序列和操作日志。相比传统脚本只留一个日志文件,视觉化的操作记录在可信度上强太多。

6. 我实际跑下来的几点体会

说实话,我第一次只用了两三个小时就把整套流程跑通了,但真正把它用到业务里,前后花了两周去处理边界情况。这个过程中最大的观念转变是:不要想着让 AI 一次性完成很长的任务,而是把任务切成小段,每段都给明确的完成信号和失败回退路径。稳定永远优先于炫技。

另外一个很朴素的建议:即使技术方案再好,也一定要给自动化任务设置最大步数和时间上限。模型有时会陷入"反复点击同一个位置"的循环,如果没有上限,它会一直消耗 API 额度并制造无效操作记录。我在框架里默认只让 Agent 跑 10 步到 20 步,超过就停止并报告当前页面截图,宁可让任务失败,也不让模型无限空转。

最后说个小技巧:建议把每次运行结束后的页面最终状态截图,自动移动到以日期命名的目录里。时间久了之后,你会非常感激当初多写了这么三行归档代码——排查"哪一轮开始出错"时,这些截图就是最好的陪侦材料。

这种让 AI 直接接管已登录浏览器的方案,门槛比很多人想象的低,但价值天花板很高。从人肉操作到半自动确认,再到高度可审计的全自动流程,每一步的推进都不需要推翻之前的架构,这也是我推荐这套思路的原因。希望这篇分享能帮你少踩几个我已踩过的坑,早点把重复劳动交出去。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询