WebDroid Agent 是一个以浏览器为核心的 Android 手机 Agent 实验项目。静态部署时它完全在前端运行;Docker 部署时会额外启用一个本地 Node API 代理,让模型请求通过容器转发而不是从浏览器直接跨域请求。它在浏览器中通过 WebUSB/WebADB 连接 Android 设备,截取手机屏幕并发送给 OpenAI 兼容的视觉模型,再把模型返回的受控动作解析、校验并通过 ADB 执行。
项目目标不是替代人工长期托管手机,而是提供一个可以在本地浏览器中快速验证「视觉模型 + 手机控制」链路的实验环境。
历史在线地址(Pages 旧域名) · 英文版 · Tango / WebADB
Chromium WebUSB -> Tango/WebADB -> Android ADB
静态部署: 浏览器 fetch -> OpenAI 兼容 /v1/chat/completions -> 视觉模型
Docker: 浏览器 fetch -> 同源本地代理 -> OpenAI 兼容 /v1/chat/completions -> 视觉模型
- 核心能力
- 适合谁使用
- 项目状态
- 工作流程
- 环境要求
- 快速开始
- 配置说明
- Docker 部署
- 模型动作协议
- mobilerun 兼容
- Open-AutoGLM 兼容
- 设备控制细节
- 安全边界
- 项目结构
- 验证
- 路线图
- 贡献说明
- 部署到 Cloudflare Pages
- License
- 相关项目和社区
- 静态部署纯前端运行,适合本地实验、Cloudflare Pages 等静态站点部署。
- Docker 部署内置同源本地 API 代理,可避免模型服务浏览器 CORS 限制。
- 通过 WebADB 在浏览器中连接已开启 USB 调试的 Android 设备。
- 截取手机屏幕,并把截图、当前 App、设备状态、完整已安装应用列表和历史步骤发送给视觉模型。
- 可显式选择
webdroid_json、open_autoglm_function或mobilerun_xml动作协议。 - 使用 canonical JSON 提示词和动作格式,并保留 Open-AutoGLM、mobilerun 风格动作输出的解析兼容。
- 自动解析、规范化并校验模型返回的下一步动作。
- 通过 ADB 执行启动应用、点击、滑动、输入文本、返回、Home、长按、双击、等待等操作,支持模型显式配置等待时间。
- 支持输入前清空文本、动作后固定等待、瞬时模型 API 错误/模型空回复重试和非敏感执行失败的有限自动恢复。
- 支持可编辑 App Cards、本地 Custom Tools,以及只向模型暴露 ID/标签的安全 Secret 输入。
- 发送聊天消息后默认自动执行,也保留单步计划等高级调试能力。
- 支持敏感动作确认、完全无限制模式、最大步数限制、停止运行,以及高级区中的上下文重置和运行日志导出。
- 页面配置持久化到本机浏览器
localStorage,Agent thread/turn 历史持久化到 IndexedDB。
适合用于:
- 验证 OpenAI 兼容视觉模型是否能理解真实手机界面。
- 调试手机 Agent 的动作协议、坐标映射和自动执行流程。
- 研究 Open-AutoGLM、mobilerun 风格动作和更通用 JSON 动作之间的兼容层。
- 在本地安全环境中做 Android UI 自动化原型实验。
- 想快速体验 WebUSB + ADB + 多模态模型闭环的开发者。
不建议用于:
- 支付、下单、删除、授权、账号设置等高风险流程。
- 登录、验证码、密码输入等需要人工明确介入的流程。
- 需要后台服务、长期稳定托管或多设备调度的生产场景。
当前项目处于实验可用阶段,核心链路已经打通:
- 浏览器端连接 Android 设备并获取截图。
- 调用 OpenAI 兼容视觉模型生成下一步动作。
- 解析 canonical JSON、Open-AutoGLM 和 mobilerun 风格动作。
- 执行常见 ADB 控制指令并记录运行日志。
- 支持聊天驱动的自动执行、人工确认、停止、上下文恢复和基础失败恢复。
仍建议把它当作本地实验工具使用。真实设备、模型能力、浏览器权限、CORS 配置和 Android ROM 差异都会影响效果。
- 在 Chromium 系浏览器中打开应用。
- 连接开启 USB 调试的 Android 设备,并在手机上授权 ADB 调试。
- 填写 OpenAI 兼容接口的
Base URL、API Key和Model。 - 在右侧聊天区输入自然语言指令,例如「打开设置并进入 Wi-Fi 页面」。
- 发送后应用截屏并请求模型返回一个动作。
- 前端解析、校验动作,并自动执行安全动作;敏感动作默认仍会请求确认。
- 如果非敏感动作执行失败,失败反馈会进入下一轮上下文,模型最多获得少量自动恢复机会。
- 重复执行,直到模型返回
done、请求take_over、达到最大步数或用户停止;开启完全无限制模式时不会因take_over停止。
- 支持 WebUSB 的 Chromium 系浏览器,例如 Chrome 或 Edge。
- 已开启 USB 调试的 Android 设备。
- 可传输数据的 USB 数据线。
- OpenAI 兼容的
/v1/chat/completionsAPI。 - 支持
image_url输入的视觉模型。 - 静态部署时,API 服务需要允许浏览器跨域请求,也就是正确配置 CORS;Docker 部署可通过同源本地代理规避这项要求。
- 页面需要运行在
localhost或 HTTPS 环境下,WebUSB 才能正常工作。
npm install
npm run dev然后用 Chrome 或 Edge 打开 Vite 输出的本地地址。
常用命令:
npm test
npm run lint
npm run build
npm run preview应用会把以下配置保存在当前浏览器的 localStorage 中:
Base URL:OpenAI 兼容接口地址,默认https://api.openai.com/v1。API Key:模型接口密钥。Model:模型名称,默认gpt-5.5。Thinking depth:GPT-5.5 等推理模型的reasoning_effort,可使用服务默认值,或选择none、minimal、low、medium、high、xhigh。Action protocol:模型动作协议,可选webdroid_json、open_autoglm_function、mobilerun_xml。Max steps:自动执行的最大步数,默认50。Confirm sensitive actions:敏感点击是否需要人工确认,默认开启。完全无限制模式:绕过本地安全策略和敏感确认,模型也会被提示不要请求人工接管。Stream responses:是否启用流式响应,默认关闭。Use ADB Keyboard for text:是否优先使用 ADB Keyboard 输入文本,默认关闭。Action settle、Double tap interval、Keyboard step:动作执行后的等待和输入节奏参数。App Cards:按包名编辑的应用上下文卡片,默认内置 Chrome、Gmail、Settings。Secrets:本地 Secret 列表,模型只看到id和label,执行时通过type_secret在本机解析真实值。Custom Tools:本地工具定义,模型只看到工具名和描述,执行结果在本地返回给下一轮上下文。
API Key 只保存在浏览器本地。请只在可信设备和本地实验环境中使用。Docker 部署时,浏览器会把模型请求发送到同源的本地代理接口,再由容器内 Node 服务请求模型 API,以绕过浏览器 CORS 限制。
Docker 镜像会构建同一个前端应用,并额外启用一个本地 Node 服务:
- 浏览器访问容器页面,WebUSB/WebADB 仍然在浏览器中工作。
- 前端请求同源
/api/openai/chat/completions。 - 容器内 Node 服务读取请求里的
Base URL、API Key和 OpenAI-compatible payload,再转发到模型 API。 - Cloudflare Pages 不使用这个 Node 服务,也不会设置代理构建变量,仍然是静态前端和浏览器直连模型 API。
构建并运行:
npm run docker:build
docker run --rm -p 8080:8080 webdroid-agent然后用 Chrome 或 Edge 打开:
http://localhost:8080/
如果使用仓库内的 Docker Compose 配置:
docker compose up -d --build则打开:
http://localhost:8083/
Docker 运行时不需要把 API Key 写进环境变量;继续在页面里的模型配置中填写。请不要把这个容器代理直接暴露到不可信公网,因为它会转发浏览器提交的任意 OpenAI-compatible Base URL。
推荐让模型只返回一个 JSON 对象,不要包含 Markdown 或解释性文本:
{ "action": "tap", "x": 540, "y": 1280, "reason": "点击搜索框" }canonical JSON 推荐使用的标准动作:
| 动作 | 说明 |
|---|---|
launch |
启动应用,可传常见应用名或包名 |
tap |
点击屏幕坐标 |
swipe |
从一个坐标滑动到另一个坐标 |
input_text |
输入文本;clear:true 会先清空当前焦点文本框 |
type_secret |
输入本地 Secret;模型只传 secretId,不会看到真实值 |
open_url |
使用 Android ACTION_VIEW 打开网页 URL 或 App deep link |
set_clipboard |
设置 WebDroid 剪贴板文本,并尽力同步到设备剪贴板 |
paste |
将 WebDroid 剪贴板文本粘贴/输入到当前焦点 |
custom_tool |
调用本地配置的 Custom Tool |
key |
发送 Android 按键,如 BACK、HOME、ENTER |
back |
返回 |
home |
回到桌面 |
long_press |
长按坐标 |
double_tap |
双击坐标 |
wait |
等待一段时间,推荐使用 duration 秒数 |
take_over |
请求人工接管 |
note |
记录观察,不执行设备动作 |
done |
任务完成 |
示例:
{ "action": "launch", "app": "Settings", "reason": "打开系统设置" }{ "action": "swipe", "fromX": 540, "fromY": 1700, "toX": 540, "toY": 500, "durationMs": 400, "reason": "向下滚动列表" }{ "action": "take_over", "message": "需要用户输入验证码" }{ "action": "type_secret", "secretId": "gmail_password", "clear": true, "reason": "输入已配置的本地密码" }{ "action": "open_url", "url": "https://example.com/search?q=webdroid", "reason": "直接打开目标网页" }遗留兼容层仍能接收 interact 和 call_api,但它们不是推荐给模型使用的真实执行动作:interact 会转成 take_over,call_api 会转成带有“不支持二次 API 调用”说明的 take_over。
解析器也接受常见 mobilerun 风格动作,并映射到 WebDroid 的真实执行动作:
| mobilerun 风格 | WebDroid 执行动作 |
|---|---|
click_at / tap_at |
tap |
click_area / tap_area |
点击区域中心点 |
long_press_at |
long_press |
type_text / type_text_direct |
input_text |
type_secret |
type_secret |
custom_tool |
custom_tool |
system_button / press_button |
key |
open_app / open_bundle_id |
launch |
remember |
note |
complete |
done |
swipe 也兼容 coordinate、coordinate2 和 duration 秒数。mobilerun 风格的 coordinate、point、position、click_area 坐标都按截图像素处理;只有 Open-AutoGLM 的 element 继续按 0-1000 相对坐标处理。
解析器也兼容 Open-AutoGLM 风格的动作名称和载荷,包括:
LaunchTap,支持element: [x, y]相对坐标TypeSwipeBackHomeLong PressDouble TapWaitTake_overInteract,会转成take_overNoteCall_API,会转成带“不支持二次 API 调用”说明的take_overtype_secret(secret_id="...")custom_tool(tool="...")
也支持类似下面的函数式输出:
do(action="Launch", app="京东")
Open-AutoGLM 风格坐标使用 0-1000 的相对坐标空间;canonical JSON 默认使用截图像素坐标。应用会在执行前把坐标映射回设备原生坐标。
- 启动应用:优先匹配设备已安装应用列表,也支持内置常见 App 名称映射或直接传 Android 包名。
- 点击/滑动:执行前会校验坐标是否在屏幕范围内。
- 界面结构:每步会尽力通过
uiautomator dump --compressed读取当前控件树,把可见文本、描述、资源 ID、可点击状态和 bounds 注入模型上下文。 - 打开 URL:使用 Android
am start -a android.intent.action.VIEW -d <url>,支持网页和设备上已注册的 deep link。 - 长按:使用 Android
input swipe x y x y duration命令模拟。 - 双击:连续发送两次
tap,中间带可配置延迟。 - 文本输入:简单 ASCII 文本使用 Android
input text。 - 清空后输入、中文和复杂字符:使用 ADB Keyboard 或 AutoGLM Keyboard 广播模式输入。
- 剪贴板:
set_clipboard会保存一份本地 WebDroid 剪贴板并尝试调用cmd clipboard set;paste优先用本地剪贴板通过当前输入通道写入焦点框。 - ADB Keyboard 模式要求设备上已安装并启用
com.android.adbkeyboard/.AdbIME;设备面板提供安装和启用入口。 - 每个设备动作执行后会按
Action settle配置等待,避免动画或页面加载期间过早进入下一步。
项目会尽量在前端执行前做约束和确认:
- 模型输出必须能解析为受支持动作。
- 坐标会进行屏幕范围校验。
- 文本输入会限制长度并拒绝控制字符。
type_secret只从模型接收本地 Secret ID,真实 Secret 值不会进入模型请求或日志摘要。- 自动执行有最大步数限制。
- 用户可以随时停止运行。
- 敏感点击可要求人工确认;开启完全无限制模式时会跳过这些确认。
take_over、note、done不会直接操作设备;遗留interact和call_api会转成人工接管。
仍然建议避免让 Agent 操作账号登录、支付、下单、删除、授权、验证码、隐私页面等高风险流程。默认情况下模型返回 take_over 时,自动执行会停止并等待人工接管;开启完全无限制模式后不会因接管请求停止。
src/
adapters/
adbKeyboard.ts # ADB Keyboard 安装、检测和编码工具
appPackages.ts # 常见 App 名称和包名映射
deviceCommands.ts # 设备命令兼容导出口
deviceParsers.ts # dumpsys 和截图二进制解析
deviceRetry.ts # 设备读取重试和延迟工具
deviceTiming.ts # 设备执行时序默认值
deviceTypes.ts # 设备后端共享类型和错误
inputCommands.ts # ADB 输入命令构建
installedApps.ts # 已安装应用解析、搜索和显示名
sensitiveActions.ts # 敏感动作确认
screenshotPreprocess.ts # 截图预处理
stayAwakeCommands.ts # ADB 连接期间保持唤醒命令
webAdbBackend.ts # WebADB/WebUSB 实现
components/
AgentStepCard.tsx # Agent 步骤卡片
AppTopbar.tsx # 顶栏品牌和状态
ChatHistorySidebar.tsx # 历史会话侧栏
ChatPanel.tsx # 聊天记录和输入区外壳
ConfigRail.tsx # 收起状态下的配置快捷栏
ConfigSidebar.tsx # 设备和模型配置侧栏编排
ConversationPanel.tsx # 聊天、历史会话和待执行动作
DeviceOptionsSection.tsx # 设备输入、确认和时序选项
DevicePanel.tsx # 设备连接和执行设置面板
DirectCommandsSection.tsx # 直接 ADB 动作面板
InstalledAppsSection.tsx # 已安装应用搜索和启动
LazyDetails.tsx # 延迟渲染的折叠区域
MarkdownContent.tsx # 聊天消息 Markdown 渲染
ModelPanel.tsx # 模型配置面板
PendingActionCard.tsx # 待执行动作确认卡片
PhoneStage.tsx # 手机截图和动作覆盖层
RunLog.tsx # 运行日志
ScreenshotLightbox.tsx # 截图预览弹窗
SettingsDialog.tsx # 应用设置、仓库信息和可编辑资源
TutorialPanel.tsx # 顶部栏展开的快速上手教程
hooks/
useAgentRunController.ts # Agent 自动运行和待执行动作控制
useAgentSessionHistory.ts # 会话恢复、保存和历史列表状态
useBusyTask.ts # 运行中任务和错误状态管理
useConfigTargetScroll.ts # 配置侧栏目标定位
useDeviceBackendPreferences.ts # 设备后端偏好同步
useDeviceController.ts # 设备连接、截图和直接动作控制
useDocumentPreferences.ts # 文档主题和语言属性同步
useLatestValue.ts # 异步回调读取最新值的 ref
usePersistedSettings.ts # 设置变更持久化
useRepositoryStats.ts # 设置弹窗中的 GitHub 仓库统计加载
useRunLog.ts # 运行日志状态管理
useStorageEstimate.ts # 本地存储容量估算
lib/
actionDefaults.ts # 常用截图动作默认值
actionParser.ts # 动作解析、规范化和校验
actionPreview.ts # 动作预览文案格式化
actionProtocol.ts # 显式动作协议枚举
actionSafetyPolicy.ts # 本地动作安全策略
actionTypes.ts # 动作类型和校验错误定义
actions.ts # 动作模块兼容导出口
agentResources.ts # App 外的本地 Secret 和 Custom Tool 资源
agent.ts # Agent 循环调度
agentThread.ts # 持久化 Agent thread/turn/event 模型
appCards.ts # 可编辑应用上下文卡片
appCopy.ts # 界面文案聚合和语言解析
appCopy.en-US.ts # 英文界面文案
appCopy.zh-CN.ts # 中文界面文案
busyTask.ts # 页面运行中任务标识
contextBuilder.ts # 本轮模型上下文构建和压缩
deviceDoctor.ts # 设备和模型配置诊断
deviceState.ts # 设备状态展示格式化
interactionStream.ts # 聊天消息和 Agent 步骤合并展示
openAiClient.ts # OpenAI 兼容网络客户端
openAiErrors.ts # OpenAI 客户端错误类型
openAiPayload.ts # OpenAI 兼容请求体构造
openAiResponse.ts # OpenAI 兼容响应读取和错误格式化
openAiRuntimeConfig.ts # OpenAI 请求运行时配置
openAiTypes.ts # OpenAI 客户端和消息类型
promptContextFormatting.ts # 模型上下文格式化工具
prompts.ts # 提示词和动作规则
repository.ts # 仓库链接和 GitHub 统计解析
runLogEntries.ts # 运行日志条目和截图视图格式化
screenshot/ # 截图坐标、上下文和内存保留策略
coordinates.ts
index.ts
retention.ts
settings.ts # 本地设置读写
threadStore.ts # Agent thread 持久化存储
toolRegistry.ts # Agent 动作工具注册和执行入口
styles/ # 按页面区域拆分的样式
agent-step-card.css # Agent 步骤卡片样式
chat-composer.css # 聊天输入区样式
chat-history.css # 历史会话侧栏样式
chat-panel.css # 聊天面板样式
compact-section.css # 折叠工具区样式
config-panel.css # 设备和模型配置面板样式
config-rail.css # 收起配置栏样式
controls.css # 表单、按钮和通用控件样式
conversation-panel.css # 会话面板外壳和待执行动作样式
device-doctor.css # 设备诊断结果样式
device-options.css # 设备执行选项样式
device-panel.css # 设备连接区样式
direct-commands.css # 直接命令面板样式
index.css # 全局样式入口
installed-apps.css # 已安装应用列表样式
layout.css # 页面布局和面板外框
markdown-content.css # Markdown 内容样式
model-panel.css # 模型配置区样式
phone-stage.css # 手机预览和动作覆盖层样式
responsive.css # 响应式布局调整
run-log.css # 运行日志样式
screenshot-lightbox.css # 截图预览弹窗样式
settings-dialog.css # 设置弹窗样式
theme.css # 主题变量和基础 reset
tutorial-panel.css # 教程面板样式
App.tsx # 页面状态、业务流程和组件编排
main.tsx # React 入口和全局样式加载
server/
index.js # Docker 中的静态文件和 API 代理服务
openAiProxy.js # OpenAI 兼容接口本地代理
npm test
npm run lint
npm run build当前测试主要覆盖:
- 动作解析和动作安全校验。
- OpenAI 兼容请求体构造、响应解析和网络客户端错误处理。
- Agent 单步和连续执行流程。
- 失败反馈、瞬时模型 API 错误/模型空回复重试和有限自动恢复。
- 设置持久化和兼容迁移。
- Agent thread/turn 持久化。
- 已安装应用解析、匹配和完整上下文注入。
- 截图坐标映射。
- 运行日志、截图预览和主界面布局组件。
真实设备控制仍需要连接 Android 设备进行手动验证。
- 浏览器中通过 WebADB 连接 Android 设备。
- 截图并发送给 OpenAI 兼容视觉模型。
- 支持 canonical JSON 动作协议。
- 显式支持
webdroid_json、open_autoglm_function、mobilerun_xml三种动作协议。 - 支持可编辑 App Cards、本地 Custom Tools 和安全 Secret 输入。
- 支持自动执行、单步执行和敏感动作确认。
- 支持运行日志和截图查看。
- 支持已安装应用列表、文本清空输入、可配置等待和基础失败恢复。
- 补充更完整的真实设备验证矩阵。
- 增加更多模型提供商配置示例。
- 增强更系统的失败分类、动作重试和任务暂停恢复体验。
- 提供更系统的安全策略和风险分级。
欢迎围绕以下方向提交 issue 或 pull request:
- 新设备、新浏览器或新模型的兼容性反馈。
- 动作解析、坐标映射、ADB 执行稳定性改进。
- Open-AutoGLM 或其他手机 Agent 协议兼容。
- 文档、示例任务、故障排查和安全建议补充。
- UI 可用性、日志可读性和本地实验体验优化。
提交改动前建议先运行:
npm test
npm run lint
npm run build项目已创建在 Cloudflare Pages:
- 历史在线地址(Pages 旧域名):https://webadb-autoglm.pages.dev/
- 部署方式:GitHub 绑定自动部署
重新部署:
git push origin main也可以本地先验证构建:
npm run buildCloudflare Pages 使用普通 npm run build,不要设置 VITE_OPENAI_PROXY_URL。这样线上静态站点会继续由浏览器直接请求你填写的 OpenAI 兼容 API,不依赖 Docker 的本地 Node 代理。
本项目基于 MIT License 开源。你可以自由使用、复制、修改、分发和二次开发本项目代码,但需要保留原始版权声明和许可证文本。
项目依赖的第三方库仍遵循各自的开源许可证,请在分发或商用前自行确认依赖合规性。
- Tango / WebADB:浏览器中的 ADB/WebUSB 能力基础。
- Open-AutoGLM:手机 GUI Agent 动作协议的重要参考。
- Linux.do:活跃的中文技术社区,围绕 AI、软件开发、资源分享与前沿资讯展开讨论。
