Files
butubb ed9e8bacb1 feat(AI 建任务): 直接创建 + 草稿沉淀 + MCP de_snapshot;修「建任务页收不到 done」
用户报的"探索完无法点击创建任务"真因:一个 run 的事件原先只有**一条** queue.Queue,
聊天页与建任务页同时开着时两个 EventSource 会**瓜分**它——建任务页的回放卡在中间、
`done` 被聊天页取走 → 永远等不到草稿,页面上自然没有可点的"创建"。

一、修(根因 + 表现)
- `web/agent_api.py` 新增 `_Fanout`:**每个订阅者一个专属队列**,多开页面各看各的,
  还带单轮事件缓冲(晚订阅/刷新重连也能补齐回放,终止事件一定送达)。
  实测两路订阅者收到完全一致的 1039 条事件(含 done)。
- `static/admin/agent.js`:断线重连的兜底订阅也按 `mode` 让开(此前漏了这一处)。

二、补齐上一批的三项
- **「直接创建」**:`POST /api/agent/task_draft/create`(草稿体只在服务端、创建前再校验一次、
  成功后清草稿避免重复建)+ 草稿预览里的「✓ 直接创建任务」按钮 + 「探索完直接创建任务」勾选框。
- **草稿沉淀经验/动作**:designer 轮次也走 `_distill_experience/_distill_actions`,
  但**只在草稿通过校验时**(没走通的试错不入库,免得把误点当经验)。
- **MCP `de_snapshot`**(第 20 个工具):截图+元素树一次取齐(省一次来回、不会因界面在动而错位),
  附带 `screen_state`/`unstable`;两套提示词都改为优先用它。
  平台侧 `/api/uiauto/snapshot` 随之多返回 `screen_state`。

三、文档
- AI_TASK_GEN §10:§10.3 记两个 bug 的真因与修法、§10.4 三项标完成、§10.5 剩余项。
- AI_CONSOLE(扇出语义、多页面同时看一轮)、API(task_draft/create、snapshot 字段)、
  MCP/MCP_DESIGN/staffdeck/README/ARCHITECTURE:工具数 19→20 + de_snapshot 条目。
- backlog:记一条新发现的缺陷——`mcp_server/platform_client._login()` 会把"登录页 200"
  当成登录成功(现场进程缺 `MCP_PLATFORM_PASS` 时表现为含糊的 platform_unavailable)。

自测:真机浏览器端到端(勾上"探索完直接创建")→ 探索 12 步 → 草稿 → 自动建任务成功;
`de_snapshot` 直连真机校验;校验器 21 条用例、扇出单元用例、本地工具契约用例全绿。
自测产生的任务/草稿已全部清理(未碰用户既有数据)。
2026-09-14 08:14:11 +08:00

14 KiB
Raw Permalink Blame History

知识库 · 设备自动化平台(auto_control)接入与操作手册

读者:StaffDeck 数字员工(外部 Agent)。 目标:让你达到与平台内置 AI 控制台同等的操作水平——不是"能调工具",而是"会看、会判断、会收尾"。 版本:2026-09-10 | 工具清单权威版:doc/MCP.md|配置权威版:mcp_server/config.py


0. 快速开始(30 秒版)

1) de_list_devices            → 选一台 online 且 worker_status 非 running/connecting 的设备
2) de_screenshot(serial)      → 看当前屏;若画面黑/锁屏 → de_wake 后重截(见 §6、§7)
3) 判断当前页 → 不对就 de_open_app(package) 或 de_press_key(back) 回到起点
4) 循环体:观察 → 操作 → 验证(见 §8)
   - 优先 de_tap_text(文字);有歧义用 de_ui_tree + de_tap_element;纯图形才 de_tap(坐标)
   - 每次关键操作后再 de_screenshot 验证是否生效
5) 连续 6 步无进展 → 停止并如实汇报(不要空转、不要臆测成功)

1. 平台与能力边界

安卓设备自动化中台:管理一批手机(网络 IP:5555 / USB 串号),支持任务调度、步骤编排、看屏与操作。

  • 你能用的入口:MCP Server(推荐,20 个 de_* 工具);备选 REST(§2.2)。
  • 可做:看屏、截图、UI 树、OCR、开/关 App、点击、滑动、按键、输入、剪贴板、亮/熄屏、看前台包名、列应用、只读看平台任务。
  • 不可做:创建/修改/启停平台任务、分组/设备池/备份管理(MCP 未提供)。

2. 接入方式

2.1 首选:MCP(HTTP / streamable)

  • 地址:http://<host>:8033/mcp。
  • 鉴权现状:MCP 层无独立鉴权(服务端内部用平台账号登录),谁能连 8033 谁就能操控设备 → 只走内网/Tailscale,不要公网裸露。
  • 审计:每次调用(含只读)写一行 JSON。

2.2 备选:平台 REST(http://<host>:18050)

认证 = 表单登录 → 会话 Cookie + X-CSRF-Token。无 API Token。端点见 doc/API.md。

2.3 服务端配置(部署方设置,你只需知道含义)

变量 默认 对你的影响
MCP_ALLOW_WRITE 0 0 时写工具全返回 write_disabled(只能看不能动)
MCP_ALLOWED_SERIALS 空 非空=白名单;为空时不自动限设备池(仅校验非空)
MCP_HTTP_HOST / MCP_HTTP_PORT 0.0.0.0 / 8033 监听
MCP_SCREENSHOT_WIDTH / MCP_JPEG_QUALITY 540 / 70 截图尺寸/质量
MCP_PLATFORM_TIMEOUT 30 平台请求超时
MCP_AUDIT_FILE /var/log/mcp/audit.log 审计文件

3. 工具清单(20 个)

只读(不触发占用锁):de_list_devices · de_screenshot · de_snapshot(截图+元素树一次取齐,推荐)· de_ui_tree · de_ocr · de_foreground_app · de_list_apps · de_read_clipboard · de_list_tasks

写(受占用锁约束):de_tap_text · de_tap_element · de_tap · de_swipe · de_press_key · de_type_text · de_set_clipboard · de_open_app · de_stop_app · de_wake · de_sleep

参数与返回详见 doc/MCP.md。


4. 通用约定

4.1 serial

  • 网络 IP:5555(如 100.100.10.13:5555);USB 纯串号(如 ZY322XXXX)。
  • 用 de_list_devices 取,别猜。

4.2 坐标空间(重要)

  • de_screenshot/de_snapshot 返回缩放图(≤540px 宽)+ native_size;de_tap/de_swipe 用截图坐标系,服务端换算原生(两者都会建立坐标空间)。
  • 必须先截图再坐标操作;否则报「请先执行 de_screenshot」。
  • 屏可能旋转/滚动 → 优先文字/元素,坐标仅兜底。

4.3 占用锁(busy)

  • 写工具执行前查设备任务状态:running/connecting → device_busy(不与任务抢设备)。换设备或等待,别硬试。
  • 只读工具不受限(任务运行中也能安全截图)。

4.4 错误码

错误 含义 应对
write_disabled 写门控关闭 上报部署方
device_busy 设备被任务占用 换设备/等待
device_offline 设备不可达 换设备;报运维
device_not_allowed 不在白名单 换设备;加白名单
text_not_found 屏上无该文字 重截图/de_ui_tree/de_ocr 复核
platform_unavailable 平台不可达 稍后重试
invalid_param 参数不合法 修参数

5. 操作纪律(与平台内置 AI 控制台等价,务必遵守)

这是平台内置 Agent 的系统规范,逐条对齐即可达到同等效果。

  1. 先看设备:de_list_devices 确定目标设备(在线才可操作)。
  2. 先看屏:任何决策前 de_screenshot 理解当前界面(图会给你)。
  3. 点击优先级(不要自己推算像素坐标——精度最差): a) 有可见文字(按钮/菜单/标题/标签/输入框提示)→ de_tap_text 一步"找到并点"(原生与 WebView/图片文字都支持); b) 文字有歧义或未命中 → de_ui_tree(limit=80) 看可点元素 → de_tap_element(text/text_contains); c) 只有纯图形(视频/无文字图标且树里没有)→ 才 de_tap 给坐标(大致对准中心即可,服务端自动吸附)。
  4. 验证点击:de_tap 返回 snapped=true 表示已吸附命中(可核对 label);截图有变化=成功,无变化=未命中。
  5. 输入文字:先 de_tap_text/de_tap 点中输入框 → 再 de_type_text。
  6. 每关键步后再截图验证,直到完成目标。
  7. 无变化不重复点:同坐标点完没变化,禁止再点同一位置;换 de_tap_text/de_tap_element,或先 de_ui_tree 核对文案。
  8. 如实汇报:做了什么、当前状态、注意事项;失败就说失败,不臆测成功。
  9. 效率:界面没变就别重复截图/点击;每步都要推进目标。
  10. 收敛:连续 6 步无进展(截图内容未变/操作无效)→ 停止并总结原因。

6. 开跑前状态检查清单(Pre-flight,逐项过)

# 检查 怎么做 通过条件 不通过怎么办
1 设备在线且空闲 de_list_devices online=true 且 worker_status 非 running/connecting 换设备;全忙则上报
2 屏幕是否点亮/解锁 de_screenshot 看 screen_state 与画面 亮屏且非锁屏界面 de_wake(亮屏解锁)→ 重新 de_screenshot
3 是否能看清画面 截图 非纯黑/非"正在加载"白屏 黑屏→de_wake;白屏→等 2~3s 重截
4 前台 App 是否正确 de_foreground_app 是目标 App(或桌面,准备开) de_open_app(package) 或 de_press_key(back) 回退
5 是否在起点页 de_ui_tree/截图 元素文案符合"首页/入口"预期 逐级 de_press_key(back) 或重开 App
6 有无拦截弹窗 截图/de_ui_tree 无权限/更新/广告弹窗 找"取消/关闭/允许(按需)/以后再说"文字点掉,或 back
7 坐标基线 记下最近一次截图 本轮坐标操作前必须有一次新截图 补一次 de_screenshot

判断"屏幕有没有开启"的标准做法:de_screenshot 的 screen_state + 画面是否可辨认。黑屏/息屏一律先 de_wake,再重新截图确认;不要在未确认亮屏的情况下点按/滑动。


7. 执行中的状态判据与规则

7.1 屏幕与锁屏

  • 息屏/黑屏 → de_wake → 重截确认;长任务中途可能再次息屏,每轮循环先确认一次。
  • 锁屏界面(有锁/时间/上滑提示)→ de_wake 解锁后重截;仍锁 → 上报(可能需要人工)。
  • 需要保持常亮时:没有专门工具,可在长流程中周期性 de_wake 兜底。

7.2 页面判据(怎么算"到位了")

目标 判据(以 de_ui_tree/截图文字为准) 未达成的处置
已到 App 首页 出现底部导航/搜索框等首页特征文本 back 一次或重开 App
已到视频页 出现点赞/评论/分享等交互图标或全屏画面 等待/滑一次再看
已到目标详情 目标条目标题文本可见 继续上滑查找(有上限,见 §10)
输入框已聚焦 出现键盘/光标或输入法界面 重新点输入框
弹窗已处理 弹窗文本消失 换"取消/关闭/以后再说"再点

7.3 加载与抖动

  • "正在加载/白屏/骨架屏" → 等 2~3s 重截,不要连续狂点。
  • 连续两次截图完全一致且不符预期 → 视为卡住,走 §8.3。

7.4 幂等重放(注意你的运行时特性)

  • 若你的平台会对"相同参数的工具调用"做幂等重放/去重缓存(如返回 idempotent_replay): 观察类工具(de_screenshot/de_ui_tree/de_ocr/de_foreground_app)必须每次拿到新结果,否则你会基于过期画面决策(表现为"屏幕没变/点不动")。
    • 处置:请让编排方对观察类工具关闭去重;或在参数/调用上确保不被判定为重复。
    • 兜底:用 de_ui_tree(文本随页面变化)作为"状态是否变化"的佐证;de_screenshot 用于确认视觉。

8. SOP(标准作业流程)

8.0 总体:五个阶段 + 一个循环

P0 接收与澄清 → P1 选设备与预检(§6) → P2 到达起点 → P3 主流程(观察-行动-验证循环) → P4 收尾与还原 → P5 汇报
                                        └──────────── 循环体 ────────────┘

P0 接收与澄清

  • 输入:用户指令(自然语言)。
  • 必查:目标 App?要做什么动作?哪台设备(或指定)?时长/次数?成功标准是什么?
  • 闸门:任一缺失且影响执行 → 先问,不猜。
  • 拒绝项:L2/L3 级操作(见 §11)→ 停下要授权。

P1 选设备与预检

  • 动作:跑完 §6 的 7 项。
  • 闸门:设备在线 + 空闲 + 亮屏可达 + 前台/起点已就位。任一不过 → 按 §6 处置;仍不过 → 上报。
  • 产出:记下 serial、起点页特征、最近一次截图基线。

P2 到达起点

  • 动作:de_open_app(冷启动到首页)→ de_screenshot/de_ui_tree 确认;或 back 逐级回退。
  • 闸门:起点特征文本出现(§7.2)。
  • 失败:重开 App 一次;仍不行 → 上报(App 异常/未安装:de_list_apps 核对包名)。

P3 主流程 —— 观察-行动-验证(OAV 三拍循环)

每一拍都按下面的节奏,不许跳步:

  1. 观察:de_screenshot(必要时 de_ui_tree)→ 用一句话说清"现在在哪、看到什么"。
  2. 决策:选定下一步唯一动作(按 §5 的定位优先级)。
  3. 行动:执行单个工具调用。
  4. 验证:再观察一次 → 变化符合预期?→ 是:进入下一拍;否:见 §8.3。
  • 闸门:每拍结束必须"状态有推进"的证据(文字/画面变化)。
  • 边界:只在目标 App 内活动,不跳出到系统设置等无关界面(除非任务要求)。

8.3 卡住判定(重要)

情形 判定 处置
同坐标点击无变化 未命中 禁止重复点;换 de_tap_text/de_tap_element,或先 de_ui_tree 看文案
连续 2 步无变化 策略无效 换定位方式 / 检查是否在正确页面
连续 6 步无进展 卡死 停止,汇报"卡在哪、试过什么、可能原因"
device_busy/device_offline 设备不可用 换设备;无可用则中止汇报

P4 收尾与还原

  • 动作:de_stop_app(结束 App)或 back 回到桌面;确认设备状态(亮/熄屏按需)。
  • 闸门:设备处于明确的已知状态(不留在中间页/输入框)。
  • 注意:不做非任务要求的破坏性/不可逆操作。

P5 汇报(固定口径)

【设备操作员 · 汇报】
设备:<serial>  | 目标:<一句话>
过程:<关键 3~5 步:做了什么 → 是否生效>
结果:✅完成 / ⚠️部分完成 / ❌失败(原因)
证据:<关键步骤截图/元素文本>
遗留:<需人工处理 / 未做的高危步骤 / 设备状态>

9. 常见异常与处置(速查)

现象 可能原因 处置
截图全黑/息屏 屏幕关闭 de_wake → 重截
停在锁屏 未解锁 de_wake;仍锁 → 上报
停在启动页/闪屏 App 未就绪 等 2~3s 重截;不行重开
权限/更新弹窗遮挡 系统弹窗 点"取消/关闭/以后再说";back
点不动、画面不变 未命中/被遮挡/图是旧的 换定位方式;核对截图是否新鲜(§7.4)
text_not_found 文字不在当前屏 重截、de_ocr、滑一屏再找
device_busy 设备跑任务 换设备/等待
一直加载 网络/内容未就绪 等待重截,勿狂点

10. 效率与预算

  • 每步必须推进目标;界面未变不重复截图/点击(但每拍开始时需要一次新鲜观察)。
  • 找不到目标时:滑动查找设上限(建议 ≤ 5 屏),超出即停止汇报。
  • 连续 6 步无进展 → 停止(§8.3)。
  • 不要为"确认"而反复截图同一画面(除非上一拍是写操作,需要验证)。

11. 安全红线(不可违反)

  1. 绝不 adb kill-server / adb disconnect。
  2. 不抢任务设备(device_busy 就避开)。
  3. L2 敏感写(发评论/私信、关注取关、发布、下单支付、改资料)→ 默认不做,先截图请人工确认。
  4. L3 破坏性(卸载/清数据/改系统设置/恢复出厂/删文件)→ 一律不做。
  5. 不泄露设备上的个人信息与凭据;不外传截图。
  6. 不绕过写门控/白名单/审计。

12. 当前边界与相关文档

  • MCP 无任务 CRUD、无独立鉴权(靠网络隔离)。
  • doc/MCP.md(工具手册)|doc/MCP_DESIGN.md(设计与现状对照)|doc/API.md(REST 目录)
  • 平台内部机制:doc/AI_CONSOLE.md(AI 控制台)、doc/ARCHITECTURE.md(架构)、doc/DATA_MODEL.md(数据)
  • 文档总索引:doc/README.md
  • 岗位职责与授权分级:doc/staffdeck/JOB_SPEC.md