最近我一直在折腾 AI 编码 Agent 的落地,说实话,Codex、Claude Code、Cline 这些工具写代码、改 bug 都很能打,但只要一碰上"需要登录态"的场景就直接歇菜。你让 Agent 去修一个线上工单、查一个私有仓库的 issue、调用一个企业内部门户的接口,它的沙箱环境里什么都没有——没有 Cookie、没有登录态、没有企业 SSO 授权,它只能盯着 401 发呆。Tencent BrowserSkill 解决的就是这个问题:在已登录的真实浏览器和编码 Agent 之间架一座本地桥,让 Agent 可以借用浏览器里现成的登录身份去完成需要认证的交互。我把这个项目的设计思路、搭建过程和踩过的坑完整过一遍,给正在做 AI Agent、多智能体协助开发的朋友一个可直接参考的落地样本。
1. 项目定位拆解:它到底解决了什么问题
1.1 核心需求:让 Agent 拥有"真实身份"
先说清楚这个项目不是什么。BrowserSkill 不是浏览器自动化工具,虽然它底层会借用浏览器的能力,但它不追求"模拟用户点击"这种 UI 自动化路线。它要解决的是身份问题,也就是让 AI Agent 在执行任务时,能够带上你已登录的浏览器会话身份。
我见过太多 Agent 项目卡在认证这一关。你要 Agent 去读取一个需要登录的 Web 页面,常见做法有几种:把账号密码交给 Agent 让它自己登录;或者给 Agent 配一个专用服务账号;再或者让 Agent 通过无头浏览器登录。这三种方案各有各的坑。账号密码交出去,安全风险很大,而且很多企业系统有二次验证,Agent 根本搞不定。专用服务账号需要额外申请、维护权限,重活全压在你运维身上。无头浏览器登录更是噩梦,验证码、单点登录跳转、设备风控,任何一个环节都能把流程卡死。
BrowserSkill 的思路很直白:你本地的浏览器已经登录好了,身份就摆在那里,为什么还要让 Agent 重新走一遍认证流程?它直接在浏览器和 Agent 之间开一条安全通路,把浏览器里的会话状态按需暴露给 Agent,Agent 拿着这个身份去访问目标系统,就像你在浏览器里操作一样。
1.2 这个项目适合谁用
从我的实际使用看,BrowserSkill 最适配的人群有三类。第一类是重度使用编码 Agent 的开发者,尤其是需要让 Agent 访问 GitLab、GitHub 私有仓库、云厂商控制台、内部工单系统的场景。第二类是做 AI Agent 产品化的团队,他们需要给 Agent 补上"登录后才能操作"的能力,又不愿意自己维护一套账号体系。第三类是负责企业级 AI Agent 应用的工程师,他们更关心权限隔离和审计,BrowserSkill 这种"借用本地已登录会话"的设计,正好可以把账号管理成本打包丢给现有的身份体系。
但这项目不适合一种人:希望 Agent 完全无人值守、在服务器上独立运行的人。BrowserSkill 的设计前提是"旁边有一个真人浏览器",它解决的是人机协同场景下的身份借用,而不是云端全自动场景的身份供给。想清楚这一点,后面搭起来就不会走偏。
2. 编码 Agent 的认证困境:为什么必须要一座本地桥
2.1 沙箱环境的死结:没有 Cookie,就没有"你是谁"
编码 Agent 跑在什么环境里?要么是 Docker 容器,要么是虚拟机,要么是一个独立的进程。这些环境的共同特征是:干净。干净意味着没有历史 Cookie、没有缓存、没有 Extension 里的登录态,连操作系统级的凭据管理器都是空的。好的一面是隔离到位,坏的一面是它根本不认识你是谁。
很多团队会让 Agent 通过环境变量注入 API Token 来解决认证,比如 GITHUB_TOKEN、GITLAB_TOKEN。这在纯 API 场景下是有效的,但当目标系统只有 Web 界面、没有公开 API 时,这条路就走不通了。更麻烦的是,现在不少企业内部系统用的是 Web 端单点登录,Token 拿不到,Cookie 被 HttpOnly 保护,脚本里 document.cookie 都读不到,Agent 再怎么折腾都是白搭。
2.2 为什么"借用真实浏览器"是最务实的解法
有人会问,为什么不做一个代理服务器,统一帮 Agent 处理登录?理论上可行,但实际上企业场景里 SSO 流程五花八门,有的要短信验证,有的要企业微信扫码,有的要做设备指纹校验,靠一个统一的代理去模拟这些流程,工作量非常大,而且任何一个流程变化都要同步更新。而真实浏览器已经把所有这些复杂度消化掉了。用户在浏览器里完成登录,浏览器里就有当前最完整的会话状态。
BrowserSkill 的聪明之处在于:它不跟认证流程较劲,只跟结果打交道。它只要拿到浏览器里现成的会话结果,然后以受控的方式把它交给 Agent。这有点像你去银行办事,大厅经理(BrowserSkill)不需要知道你当初是怎么开户的,只需要验证你本人到了场,然后带你去柜台办业务。认证过程完全绕开,不重复造轮子。
这个方案还有一个隐藏优势:它天然照顾到了风控。很多系统对异地登录、新设备登录有风控策略,如果 Agent 用一套全新的无头环境去登录,大概率会触发验证要求。但借用本地浏览器身份,设备指纹、IP 这些维度都和日常工作环境一致,风控系统根本不会觉得异常,Agent 做事就顺畅多了。
3. 本地桥架构拆解:会话怎么安全地流转
3.1 三个核心组件:扩展、守护进程、Agent 客户端
BrowserSkill 的整体架构可以拆成三块,理解这三块就掌握了整个项目。
第一块是浏览器端的采集组件,通常以浏览器扩展的形式存在。它的职责是读取当前浏览器里指定域名的会话标识,包括 Cookie、localStorage 这类能代表身份的持久化数据。采集范围不是无差别的,而是按域名白名单来,只收集你配置的那些域名下的信息,其他域名一概不碰。
第二块是本地守护进程,一个跑在 localhost 上的轻量服务。它负责接收扩展传来的会话数据,把它们封装成 Agent 可以请求的接口,同时做权限校验。Agent 发过来的每个请求,都要先经过它的检查,确认目标域名在白名单里,确认这次访问在有效期限内,才把对应的会话信息拿出来。
第三块是 Agent 侧的客户端,连接方式很现代,直接走 MCP(Model Context Protocol)。对用过 Claude Code、Cline 的朋友来说,MCP 已经是老朋友了。Agent 通过 MCP 暴露的工具列表里看到"访问某已登录页面""抓取某私有接口数据"这些能力,调用后由守护进程实际执行。
3.2 会话传递链路:从浏览器到 Agent 之间的每一步
我画一条完整的链路给你看。用户先在 Chrome 里登录目标系统,登录成功后扩展组件感知到相关域名的 Cookie 发生变化,会把会话数据加上时间戳,通过本地 WebSocket 或 HTTP 推送到守护进程。守护进程收到后做归一化处理:去掉无关字段、标记来源浏览器、设置过期时间,然后缓存在内存里。注意是内存,不是落盘。
Agent 需要访问目标页面时,通过 MCP 调用 BrowserSkill 的工具,守护进程收到请求后先做一次"三查":查域名是否在白名单、查会话是否在有效期内、查请求来源是否为本机 Agent。三层都通过,它把会话凭据附加到 HTTP 请求里,以服务器端请求的方式去访问目标页面,然后把页面内容转成 Markdown 或结构化数据返回给 Agent。
整个过程里,Agent 其实并没有直接拿到你浏览器的 Cookie 原文,它拿到的是守护进程"代为请求"之后的业务数据。这个设计非常重要,它意味着即使 Agent 被提示注入攻击,攻击者也拿不到原始凭据,只能拿到特定页面上的可见内容。这就是标题里 SSP 的核心含义——Session Scoped Permission,会话作用域权限,让每个会话的暴露面被严格限制在 Agent 当前任务的范围内。
3.3 为什么不直接走 CDP 取 Cookie
看到这里可能有朋友问,Chrome DevTools Protocol(CDP)也能拿到 Cookie,为什么还要专门做扩展和守护进程两层?我试过直接走 CDP,就是启动 Chrome 时加上 --remote-debugging-port,然后通过调试接口拿 Network.getAllCookies。这条路有两个硬伤。
第一,开启远程调试端口意味着浏览器所有调试能力都暴露了,不只是 Cookie,连页面 DOM、网络请求、JavaScript 执行环境都开放了,安全边界非常模糊。第二,很多企业环境会检测到调试端口,甚至浏览器会直接提示"正在使用自动化测试工具",这会改变页面的渲染行为,反而拿不到正常的页面数据。BrowserSkill 用扩展组件的方式,权限边界就清晰很多:扩展只读取配置允许的域名,只暴露必要字段,而且扩展的权限本身是用户可见、可撤销的。
4. 实操落地:从 0 到 1 把本地桥跑起来
4.1 最小环境准备:哪些前置条件别偷懒
先把环境说清楚。我实际跑通 BrowserSkill 用的是一台 macOS 笔记本,Chrome 稳定版,Node.js 版本 18 以上,Agent 端用的是 Claude Code。Windows 和 Linux 我也在同事机器上验证过,链路基本一致,差别主要在扩展安装和防火墙放行上。
前置条件有几个容易忽略的地方。第一,Chrome 必须要允许本地扩展安装,如果是企业统一管理的 Chrome 浏览器,可能需要 IT 部门开白名单。第二,localhost 端口要预留好,默认守护进程会监听一个不常用端口,比如 8765,但如果你本机有服务占用,启动时它会报错,这时候要手动改端口。第三,Node.js 的 npm 全局路径要注意,Windows 下 npx 执行时偶尔会遇到 PATH 不正确的问题,建议直接用 npm install 到项目目录的方式安装。
我给一个最小可跑通的配置参考,MCP 配置文件一般放在 Agent 的工作目录下:
{ "mcpServers": { "browserskill": { "command": "npx", "args": ["-y", "@tencent/browserskill"], "env": { "BSK_PORT": "8765", "BSK_SCOPE": "github.com,gitlab.example.com" } } } }这里的 BSK_SCOPE 就是关键配置,它决定了 Agent 能借用哪些域名的登录会话。我建议第一次配置时只填一个域名,比如 github.com,先把链路打通,再加其他域名,不然排查问题时会很痛苦。
4.2 连接已登录浏览器:扩展安装与配对的细节
守护进程启动之后,下一步是连接浏览器。BrowserSkill 的扩展安装好之后,扩展弹窗里会显示一个配对码,这个配对码是本地守护进程下发的,作用是建立"这台机器上这个浏览器和这个守护进程"的对应关系。你需要在扩展里输入配对码或者点击确认,两者才算绑定。
这里我踩过一个大坑:一开始我没注意配对码的有效期,过了几分钟才去输入,结果扩展显示配对失败。后来翻了源码才知道,配对码默认有效期只有五分钟,而且安全性上设计成一次性使用——即使别人拿到了过期或已用的码也作废。所以在实操时要先启动守护进程,再打开扩展页面,趁热打铁完成配对。
配对成功后,扩展应该会显示当前已前置登录的站点列表。比如你已经登录了 GitHub,列表里就会出现 github.com 的会话条目。如果列表是空的,不要急着怀疑项目坏了,先去检查一下白名单配置,再看扩展有没有获得读取该站点 Cookie 的权限。Chrome 扩展的站点权限是运行时申请的,很多浏览器默认第一次访问时会静默拒绝,需要在扩展设置里手动授权。
4.3 Agent 端接入:让编码 Agent 认识 BrowserSkill
守护进程和浏览器都就绪之后,最后一步是让 Agent 用起来。如果你用的是支持 MCP 的 Agent,配置文件里加好 mcpServers 之后,重启 Agent 就能看到新的工具列表。我在 Claude Code 里执行 /mcp 命令,能够看到 browserskill 下面的工具,比如 fetch_authed_page 和 list_available_sessions。
第一次调用时我建议先执行 list_available_sessions,确认 Agent 能够看到"哪些登录会话可用"。这一步输出很清楚,每个会话会显示域名、过期时间、账号标识(脱敏)。看到 github.com 出现在列表里,说明链路已经通了。
然后就可以让 Agent 做一些实际任务了。比如我让它"帮我看看私有仓库里最新的 PR 描述写了什么"。Agent 通过 BrowserSkill 访问页面,拿到的是渲染后的文本内容,然后它自己阅读、总结、回答。整个过程 Agent 没有真正看到浏览器界面,但拿到的信息和你在浏览器里看到的基本一致。需要注意的是,BrowserSkill 拿到的页面内容可能不含图片和复杂 JavaScript 渲染结果,如果目标页面是重度前端框架,可能需要额外配置等待渲染时间。
5. 安全模型与权限隔离:SSP 是怎么保护你的身份的
5.1 会话作用域权限:把暴露面控制到最小
我之前讲 SSP 是 Session Scoped Permission,这是整个项目安全设计的灵魂。具体怎么做?我观察到三层控制。
第一层是域名白名单。你会在配置里明确写出允许访问哪些域名,Agent 只能向这些域名的会话发起借用。这一层过滤了绝大多数恶意场景——即使 Agent 被提示注入攻击诱导,它也无法去访问白名单外的站点。第二层是时效控制。每次从扩展取出的会话数据都带超时时间,一般跟浏览器 Cookie 的过期时间对齐,同时守护进程还会设置一个较短的"借用有效期",过了这个有效期必须重新请求。第三层是请求代转。Agent 不直接拿 Cookie,而是让守护进程代发请求,隐藏在数据层之下。
这三层合在一起的效果是:Agent 的会话能力是一个个"窄通道",每个通道只通向特定域名,只存活特定时间,只返回特定页面的文本数据。就算某个环节失守,攻击者拿到的也只是某个页面的一次性快照,而不是能够持续使用的身份凭证。
5.2 使用中的安全边界:有哪些事千万别做
安全模型再完善,使用姿势不对也会破功。这里说几个我自己遇到过的边界问题。
第一个问题是不要为了省事把所有域名都加入白名单。你就用 * 通配符,看起来方便了,实际上是把整个浏览器的登录身份敞开了。万一 Agent 被恶意提示词引导,去你银行网站、云控制台、企业办公系统里逛一圈,数据泄露风险非常高。我的建议是白名单永远列具体域名,一个任务加一个。
第二个问题,不要在共享机器上部署 BrowserSkill。它的设计前提是"本机当前用户本人",如果机器有多人使用,或者有远程桌面、共享账号场景,会话借用容易张冠李戴。我团队里就发生过一次,两个开发者共用一台测试机,A 的 BrowserSkill 守护进程没关,B 启动后直接占用了端口,导致 A 的 Agent 请求被 B 的实例响应,虽然最后没有实际数据泄露,但足够让人出一身冷汗。
第三个问题是审计日志。BrowserSkill 的守护进程默认会在日志里记录每一次会话借用行为,我强烈建议把日志输出到文件而不是只打到控制台,并且定期检查。这不仅仅是排查问题用,更是安全事件回溯的依据。你永远不知道哪次 Agent 调用会触发什么问题,有日志在手心里不慌。
6. 踩坑实录与排查经验
6.1 高频问题速查表
我把这段时间实操中遇到的典型问题整理成了一个速查表,方便大家直接对照排查。
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 扩展列表为空,没有显示已登录会话 | 域名未加入白名单 | 检查 BSK_SCOPE 配置,确认域名精确匹配 |
| 守护进程启动即报端口冲突 | 8765 被其他进程占用 | 换端口,并同步修改 MCP 配置里的 BSK_PORT |
| Agent 调用工具时报 401 | 会话过期,或浏览器 Cookie 已失效 | 在浏览器里重新登录目标站点,等待扩展同步 |
| 页面内容空白或缺少关键数据 | 单页应用渲染未完成 | 增大页面等待时间,或让 Agent 换个 URL 片段 |
| 配对码输入后提示无效 | 配对码超过 5 分钟有效期 | 重启守护进程,重新获取新的配对码,尽快输入 |
| 无痕窗口扩展不生效 | 无痕模式默认禁用扩展 | 在扩展详情里开启"允许在无痕模式下运行" |
这个表只是一个起点,每个环境的差异都可能有新的幺蛾子。我把两个最典型的排错思路展开讲一下。
6.2 会话同步问题的定位方法
我遇到最多的一个坑是"浏览器已经登录了,但 Agent 就是拿不到数据"。这种问题的根源通常是扩展没有及时把最新的 Cookie 状态同步给守护进程。Cookie 的更新受 HttpOnly 限制,一部分会话数据是 JS 读不到的,扩展只能依托浏览器事件去感知变化。
排查这种问题时,我先看守护进程的日志,确认最近有没有收到来自扩展的心跳或会话更新事件。如果没有收到,我再回到浏览器扩展的弹窗页面,看它的"已连接"状态是不是变成了"断开"。经常出现的情况是扩展在浏览器升级后自动停用了,或者企业安全软件把扩展给禁了。这类问题和项目本身无关,但会让你误以为项目坏了,提前知道可以少浪费时间。
另一个容易忽略的细节是系统休眠唤醒后的重新配对。笔记本合盖休眠,唤醒后守护进程还活着,但扩展的连接已经断了。这时候 Agent 侧表现出来的症状很诡异:上次还能用,这次全部 401。解决办法很简单,刷新浏览器页面让扩展重连,或者直接重启守护进程。
6.3 Agent 多会话冲突的处理
做多智能体协助开发时,我让两个 Agent 同时跑任务,一个访问 GitHub 私有仓库,一个访问公司内部 TAPD 系统。结果第二个 Agent 频繁报错,拿到的数据明显不对。排查下来发现,两个 Agent 是通过同一个 MCP 配置启动的,它们共用同一个 BrowserSkill 守护进程的会话池,而守护进程对同一域名默认只维护一个最新会话。
这就暴露了一个设计细节:BrowserSkill 的会话池是"域名维度单例"的,同一个域名下同时只保留最新登录的一个会话。如果你开了两个不同账号登录同一个网站,后登录的会覆盖先登录的。解决方式有两种:一是让两个 Agent 分开跑在不同的用户目录下,各自独立配置 MCP;二是在目标系统里明确用同一个账号,避免覆盖。第一种更干净,我实际测试下来,用两个独立的用户目录分别启动 Agent,会话互不干扰,效果很好。
7. 个人经验与扩展思考
项目跑到现在,我的体会是 BrowserSkill 这种"借用真实浏览器"的思路,不只是解决了一个认证问题,它打开了一类新的交互模式。以往 AI Agent 和 Web 应用之间有堵墙,Agent 只能用 API 或者靠爬虫抓数据,现在这堵墙被本地桥砸开了一个门。但门开了,管理的复杂度也上来了。
如果要在这个项目基础上继续扩展,我建议团队可以试试两个方向。第一个方向是给它加一层"操作审批"能力,Agent 每次借用会话时,在浏览器端弹一个确认框,由人确认后再放行。虽然多一步操作,但当 Agent 访问敏感系统时,这个确认框能挡住非常多意外。第二个方向是做一个缓存层,把 Agent 访问过的页面结果按 URL+时间维度缓存下来,相同任务重复执行时直接读缓存,减少面向目标系统的访问频率,既不打扰线上系统,也能降低被风控盯上的概率。
最后分享一个小技巧:给 BrowserSkill 配一个独立的 Chrome 用户配置文件,别用你日常的主力浏览器。这样即使测试过程中出现什么意外,也不会影响你正在用的浏览器环境,而且独立的配置目录可以让 Agent 的访问模型更干净,排查问题也更省心。我就是在踩过一次"主力浏览器卡死、所有登录态一起失效"的坑之后,才老老实实换成了独立用户目录。这个改造前后只花了几分钟,但之后再也没有因为浏览器问题影响过 Agent 任务的执行。