浏览器中继:AI 智能体的本地 Chromium 控制 - Openclaw Skills

作者:互联网

2026-03-30

AI教程

什么是 浏览器中继?

浏览器中继技能(Browser Relay Skill)是一个专门的技术框架,旨在让 AI 智能体能够直接、经身份验证地控制用户的本地 Chromium 浏览器。通过利用与 Chrome 开发者工具协议 (CDP) 通信的 HTTP 中继,该技能确保所有 Web 交互均源自用户的本地住宅 IP 地址。这是 Openclaw Skills 生态系统中的一项关键能力,用于访问小红书等经常拦截数据中心 IP 范围流量的平台。

该技能在构建时注重安全性和效率,使用仅 localhost 的本地化中继服务,并且每次请求都需要随机生成的身份验证令牌。这种设置允许开发人员构建需要真实浏览器环境的高保真度 AI 工作流,同时维护宿主机的隐私和安全。

下载入口:https://github.com/openclaw/skills/tree/main/skills/esojourn/browser-relay-xiaohongshu

安装与下载

1. ClawHub CLI

从源直接安装技能的最快方式。

npx clawhub@latest install browser-relay-xiaohongshu

2. 手动安装

将技能文件夹复制到以下位置之一

全局模式 ~/.openclaw/skills/ 工作区 /skills/

优先级:工作区 > 本地 > 内置

3. 提示词安装

将此提示词复制到 OpenClaw 即可自动安装。

请帮我使用 Clawhub 安装 browser-relay-xiaohongshu。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。

浏览器中继 应用场景

  • 绕过针对住宅受限网站的反爬虫和基于 IP 的封锁。
  • 自动化需要现有用户 Cookie 或本地会话状态的复杂 Web 交互。
  • 通过捕获屏幕截图并将其发送到 T@elegrimm 进行用户确认,实现远程视觉审计。
  • 在多个浏览器标签页中执行多步 Web 研究和数据提取。
浏览器中继 工作原理
  1. AI 智能体验证 Chromium 是否在远程调试端口 9222 上处于活动状态。
  2. 如果未激活,智能体将使用必要的标志(如 --remote-allow-origins)启动 Chromium 以进行 CDP 访问。
  3. 智能体启动 Python 中继服务,该服务充当 AI 与浏览器之间的中间人。
  4. 在临时系统中生成唯一的、受限访问的令牌,用于授权 API 调用。
  5. 智能体读取此令牌并将其存储在会话状态中,以验证后续的 HTTP 请求。
  6. AI 向中继发出导航、点击或 JS 执行等命令,中继在本地浏览器中执行这些命令。

浏览器中继 配置指南

要在 Openclaw Skills 框架内初始化浏览器中继,请按照以下步骤操作:

# 1. 启动启用远程调试的 Chromium
DISPLAY=:0 nohup chromium --remote-debugging-port=9222 --remote-allow-origins=* > /dev/null 2>&1 &

# 2. 检查中继服务的健康状况
curl -s http://127.0.0.1:18792/health

# 3. 如果未运行,启动中继
bash start.sh

# 4. 获取用于 API 身份验证的自动生成令牌
cat /tmp/browser-relay-token

浏览器中继 数据架构与分类体系

该技能通过特定的文件路径和会话密钥管理其运行数据和元数据:

数据组件 位置 / 密钥 描述
中继令牌 /tmp/browser-relay-token 具有 0600 文件权限的身份验证令牌
进程 ID /tmp/browser-relay.pid 跟踪活动中继服务的 PID
屏幕截图 ./screenshots/ 带有时间戳的浏览器状态 JPG 文件
缓存 session_state 存储会话的令牌和 T@elegrimm Bot 元数据
日志 /tmp/relay.log 记录中继活动和错误消息
name: browser-relay
description: 通过 HTTP relay 控制用户本地 Chromium 浏览器(绕过数据中心 IP 封锁),支持截图发送到 T@elegrimm
allowed_tools:
  - exec
  - session_state
  - memory_search

Browser Relay Skill

通过 HTTP relay 控制用户本地 Chromium,用于操作会封锁数据中心 IP 的网站(如小红书)。

架构

AI → HTTP (port 18792) → relay.py → CDP (port 9222) → 用户本地 Chromium

所有请求从用户本地 IP 发出,绕过反爬。

安全说明

  • relay 仅 127.0.0.1(localhost),不会暴露到外部网络
  • 每次启动自动生成随机 auth token,所有 API 请求必须携带
  • token 文件 (/tmp/browser-relay-token) 以 0600 权限写入,仅文件所有者可读
  • /evaluate 端点允许在浏览器上下文中执行 JS,可访问 DOM、cookies、localStorage 等。仅限本地可信调用方使用,不应暴露给不受信任的客户端
  • 建议在隔离环境(虚拟机、容器)中运行,使用专用浏览器 profile(不含敏感站点的登录态)
  • start.sh 仅通过 PID 文件精确停止 relay 进程,不会影响其他进程

Agent 行为约束

使用此 skill 的 agent 必须遵守以下规则:

exec 使用范围

exec 仅允许用于以下操作:

  • 127.0.0.1:18792(relay)和 127.0.0.1:9222(CDP)发送 HTTP 请求
  • 运行 start.sh 启动/停止 relay
  • 读取 /tmp/browser-relay-token
  • 保存截图到 ./screenshots/
  • 通过 T@elegrimm Bot API 发送截图(仅限用户明确要求时)

禁止使用 exec 执行上述范围之外的命令。

/evaluate 使用范围

/evaluate 仅允许用于 UI 自动化目的:

  • 查询 DOM 元素位置、文本内容、页面标题
  • 等待元素加载、检查页面状态
  • 模拟用户交互(滚动、表单填写)

禁止通过 /evaluate 提取以下敏感数据:

  • document.cookie
  • localStorage / sessionStorage 中的 token 或凭据
  • 页面中的密码字段值
  • 任何认证相关的 header 或 token

数据外发限制

  • 仅允许向 T@elegrimm Bot API 发送截图图片,且仅在用户明确要求时
  • 禁止向任何外部端点发送从浏览器提取的文本数据、cookies、token 或凭据
  • 禁止将浏览器敏感数据写入 session_state 或 memory(auth token 除外,指 relay 自身的 token)

文件位置

以下路径均相对于项目安装目录,请根据实际位置调整。

  • Relay 代码: ./relay.py
  • 启动脚本: ./start.sh
  • Token 文件: /tmp/browser-relay-token
  • PID 文件: /tmp/browser-relay.pid
  • 日志: /tmp/relay.log
  • 截图目录: ./screenshots/

启动流程

每次会话开始使用 relay 前,按以下步骤操作:

1. 检查 Chromium 是否运行

curl -s http://127.0.0.1:9222/json/version

如果连接失败,说明 Chromium 未启动,需要启动它(见下方"启动 Chromium")。

2. 启动 Chromium(如果未运行)

DISPLAY=:0 nohup chromium --remote-debugging-port=9222 --remote-allow-origins=* > /dev/null 2>&1 &

注意事项:

  • 必须加 --remote-allow-origins=* 否则 WebSocket 连接会被拒绝
  • 必须加 DISPLAY=:0(或对应的显示环境变量)以在用户桌面上显示
  • Puppy Linux 环境,chromium 命令名可能是 chromiumchromium-browser,按实际情况调整
  • 启动后等待几秒再继续操作

3. 检查 relay 状态

curl -s http://127.0.0.1:18792/health

如果返回 {"status":"ok"},跳到步骤 5。否则继续。

4. 启动 relay

bash start.sh

5. 获取并缓存 token

cat /tmp/browser-relay-token

读取后用 session_state 缓存到当前会话:

session_state set namespace=browser-relay key=token value=

后续所有请求从 session_state 读取 token,不重复读文件。

API 调用模板

所有请求都需要 Authorization: Bearer 头。

获取标签页列表

curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:18792/tabs

导航

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"url":"https://www.xiaohongshu.com"}' r
  http://127.0.0.1:18792/navigate

截图(带自动保存)

TOKEN=$(cat /tmp/browser-relay-token)
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"quality":70}' http://127.0.0.1:18792/screenshot r
  | python3 -c "
import sys, json, base64, os
from datetime import datetime
data = json.load(sys.stdin)
if data.get('ok'):
    os.makedirs('./screenshots', exist_ok=True)
    fname = datetime.now().strftime('%Y%m%d_%H%M%S') + '.jpg'
    path = f'./screenshots/{fname}'
    with open(path, 'wb') as f:
        f.write(base64.b64decode(data['data']))
    print(f'saved:{path} size:{os.path.getsize(path)}')
else:
    print(f'error:{data}')
"

截图并发送到 T@elegrimm

当用户在 T@elegrimm 上交互时,截图需要发送到 TG 才能看到。流程:

# 1. 截图并保存
TOKEN=$(cat /tmp/browser-relay-token)
SCREENSHOT_PATH="/tmp/relay_screenshot.png"
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"quality":80}' http://127.0.0.1:18792/screenshot r
  | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
if data.get('ok'):
    with open('$SCREENSHOT_PATH', 'wb') as f:
        f.write(base64.b64decode(data['data']))
    print('ok')
else:
    print(f'error:{data}')
"

# 2. 通过 T@elegrimm Bot API 发送图片
TG_BOT_TOKEN="<从 session_state 或 memory 获取>"
TG_CHAT_ID="<从 session_state 或 memory 获取>"
curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendPhoto" r
  -F "ch@t_id=${TG_CHAT_ID}" r
  -F "photo=@${SCREENSHOT_PATH}"

T@elegrimm 配置:

  • Bot Token 和 Chat ID 从 memory 或 session_state 获取
  • Chat ID 可从 session 信息中提取(telegram:alzmoltis_bot:
  • 发送前确保截图文件存在且非空
  • 安全提示:建议使用专用 Bot(权限最小化),不要复用管理其他敏感频道的 Bot Token

点击(坐标)

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"x":100,"y":200}' http://127.0.0.1:18792/click

点击(CSS 选择器)

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"selector":"button.submit"}' http://127.0.0.1:18792/click

输入文字

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"text":"要输入的内容"}' http://127.0.0.1:18792/type

按键

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"key":"Enter"}' http://127.0.0.1:18792/keypress

滚动

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"y":300}' http://127.0.0.1:18792/scroll

执行 JS

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"expression":"document.title"}' http://127.0.0.1:18792/evaluate

等待元素出现

curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"selector":".target-element","timeout":5000}' http://127.0.0.1:18792/wait

标签页管理

# 新建标签页
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"url":"https://example.com"}' http://127.0.0.1:18792/tab/new

# 切换标签页
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"tab_id":"xxx"}' http://127.0.0.1:18792/tab/activate

# 关闭标签页
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" r
  -d '{"tab_id":"xxx"}' http://127.0.0.1:18792/tab/close

标准操作规范

  1. 截图确认制:任何发布/提交操作前,必须先截图让用户确认
  2. 截图自动保存:所有截图保存到 ./screenshots/ 并带时间戳
  3. T@elegrimm 截图发送:当用户在 TG 上交互时,截图通过 T@elegrimm Bot API 发送,而不是仅保存到本地
  4. Token 会话缓存:token 只读一次,缓存在 session_state 中
  5. 错误重连:如果请求失败(连接拒绝),自动尝试重启 relay
  6. 操作间隔:点击/输入操作之间加 sleep 0.5~1 模拟人类节奏

停止 relay

bash start.sh stop