diff --git a/.env.example b/.env.example index 6f11229..f05d14d 100644 --- a/.env.example +++ b/.env.example @@ -13,8 +13,8 @@ DEFAULT_ACCOUNT_ID= # 留空=自动;只填纯数字;手 # 是否显示浏览器窗口:网页自动化时是否弹出可见浏览器 OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(必须,便于介入与排查);1=后台静默(勿作日常用法) -# 浏览器防检测:降低被网站识别为自动化工具的概率 -OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启(推荐),0=关闭;一般保持默认 +# 浏览器兼容配置:仅在项目授权与平台规则允许时使用共享兼容能力 +OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=使用共享兼容配置,0=关闭;不得用于伪造身份或绕过平台限制 # 是否录制操作过程:用于留证、复现问题或向他人演示 OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并生成带说明的视频文件;需要留证时再改为 1 @@ -22,11 +22,11 @@ OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并 # 失败时是否截图:任务出错时自动保存现场截图,便于排查 OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败时截图(推荐),0=不截图 -# 步骤最短等待:两步操作之间随机停顿的下限,模拟真人节奏 +# 步骤最短等待:两个正常业务动作之间随机停顿的下限 STEP_DELAY_MIN=1.0 # 单位:秒;一般保持默认,页面不稳定时可略调大 # 步骤最长等待:两步操作之间随机停顿的上限 -STEP_DELAY_MAX=5.0 # 单位:秒;须大于等于最短等待;一般保持默认 +STEP_DELAY_MAX=3.0 # 单位:秒;默认与最短等待组成 1~3 秒节奏;状态等待须另行判断 # 人工处理超时:遇到滑块、验证码、二次验证时,等待人工处理的最长时间 HUMAN_WAIT_TIMEOUT=180 # 单位:秒;来不及处理时可调大,如 300 diff --git a/CHANGELOG.md b/CHANGELOG.md index e792cf6..523d5f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,14 @@ - 小节正文写用户能看懂的变化(新能力、修复、注意事项),避免堆砌内部实现细节 - 打 tag 前**必须**为即将发布的版本新增一节;找不到匹配小节时,本次发布不会更新 changelog 字段 +## 1.0.57 + +- 新增 AI + RPA 技能开发总纲,明确 Agent 负责理解与编排、RPA 负责浏览器 / 桌面 / 手机的确定性执行 +- 增加第三方软件自动化合规红线:禁止破解、逆向、私有协议、安全验证绕过、Hook / 注入、自动换号和无限重试 +- 补齐工业级 RPA 风控、人工介入、状态等待、串行互斥、有限重试、结果核验与前后缓冲标准 +- 真实业务默认步骤节奏统一为 1~3 秒,并增加自动测试守护 +- 需求模板和交活 Checklist 增加授权、风险确认、不可逆操作、风控信号与结构化结果验收 + ## 1.0.56 - 新增第三方交活验收清单 `development/CHECKLIST.md`(观察结果、不重复开发规范) diff --git a/SKILL.md b/SKILL.md index c4e052c..742a220 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,7 +1,7 @@ --- name: 技能开发模板(通用业务版) description: "OpenClaw 通用业务技能开发模板,供复制后定制新业务 skill。定制步骤见 development/DEVELOPMENT.md。" -version: 1.0.56 +version: 1.0.57 author: 深圳匠厂科技有限公司 metadata: openclaw: @@ -22,6 +22,13 @@ allowed-tools: ## Agent / 宿主编排(复制为业务技能后必改) +### AI + RPA 定位 + +- **Agent 是入口与编排者**:理解用户意图、补齐参数、判断风险、选择 Action,并用业务语言解释结果。 +- **RPA 是确定性执行器**:只按已验证步骤操作授权范围内的浏览器、桌面软件或手机;不得破解、逆向、调用未授权私有协议或绕过验证码、安全验证和平台限制。 +- 遇到验证码、人脸、U盾、频控、账号风险或权限不足时,转人工或安全停止,禁止自动硬闯、换号或无限重试。 +- 开发者与 AI 编程工具先读 `development/AI_RPA.md`,三端执行细则再读 `development/RPA.md`。 + ### 架构铁律(先读) - **单业务内核、多入口**:数据管理 / 定时任务 / Agent / 技能详情 / 直接 CLI 必须复用同一 domain service;禁止按入口复制业务逻辑,禁止按 `source` 分叉业务行为。 diff --git a/development/ADAPTER.md b/development/ADAPTER.md index 90163b8..7b7152b 100644 --- a/development/ADAPTER.md +++ b/development/ADAPTER.md @@ -2,6 +2,8 @@ > 凡是"连接三方系统"(ERP、CRM、SaaS、银行等)的 skill,都应采用本文的 **adapter 四档模式**。同一套业务逻辑可在不同档位间切换;**四档都保留**。 +先遵守 [`AI_RPA.md`](AI_RPA.md) 的授权与技术红线:`real_api` 只连接公开或明确授权的官方接口;不得通过抓包、逆向或猜测私有协议构造“API”。没有授权 API 时使用正常界面 RPA;正常界面无法闭环且只能绕过安全机制时,停止并上报。 + ## 为什么要分档 对接一个外部系统,工程上无非四种方式的组合: diff --git a/development/AI_RPA.md b/development/AI_RPA.md new file mode 100644 index 0000000..08e5c6d --- /dev/null +++ b/development/AI_RPA.md @@ -0,0 +1,227 @@ +# AI + RPA 技能开发总纲 + +本文是技术人员与 AI 编程工具进入本模板后的**第一份架构说明**。先理解本文,再按业务类型阅读 [`RPA.md`](RPA.md)、[`ADAPTER.md`](ADAPTER.md)、[`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) 与对应 `examples/`。 + +## 目录 + +1. [一句话定义](#1-一句话定义) +2. [职责边界](#2-职责边界) +3. [标准执行闭环](#3-标准执行闭环) +4. [合规与技术红线](#4-合规与技术红线) +5. [工业级 RPA 风控](#5-工业级-rpa-风控) +6. [等待与操作节奏](#6-等待与操作节奏) +7. [三端统一与选型](#7-三端统一与选型) +8. [结果契约](#8-结果契约) +9. [开发与交付顺序](#9-开发与交付顺序) + +## 1. 一句话定义 + +**AI Agent 是用户入口与业务编排者,RPA 是确定性执行器。** + +- Agent 负责理解用户意图、补齐参数、判断风险、选择 Action、发起任务和解释结果。 +- RPA 负责按已验证的步骤操作浏览器、桌面软件或手机,不临时理解模糊业务。 +- 业务规则放在唯一 domain service 中;Agent、CLI、Action、定时任务与数据管理入口复用同一内核。 +- RPA 必须返回结构化结果、进度与存证,由 Agent 用业务语言反馈给用户。 + +本模板追求的是**稳定、合规、可控制、可追溯、可交付的工业级界面自动化**,不是与第三方安全机制对抗。 + +## 2. 职责边界 + +| 层级 | 负责 | 不负责 | +|------|------|--------| +| Agent | 意图理解、缺参追问、风险确认、Action 选择、结果解释 | 不猜界面步骤,不临时改业务规则,不直接绕过安全验证 | +| Action / 编排层 | 参数校验、鉴权、任务状态、进度、暂停停止、日志、人工介入 | 不按入口复制业务逻辑 | +| Domain Service | 业务规则、幂等、防重复、状态流转、结果汇总 | 不关心来自 Agent、定时任务还是工具栏 | +| Adapter / RPA | 调官方 API 或按确定流程操作界面 | 不理解模糊意图,不自行扩大权限或操作范围 | +| 宿主 | Action 展示、任务中心、数据管理、共享 runtime | 不替技能实现业务规则 | + +Agent 与 RPA 的边界必须保持清晰: + +- 把不确定的理解与沟通交给 Agent。 +- 把可验证、可重复的执行步骤交给代码和 RPA。 +- 不让 Agent 在运行时自由生成高风险界面操作。 +- 不让 RPA 根据模糊文本自行决定付款、删除、审批、发布或发送范围。 + +## 3. 标准执行闭环 + +```text +用户自然语言 + → Agent 识别意图与参数 + → 缺参追问 / 风险确认 + → 选择已声明的 Skill Action + → 编排层做校验、鉴权、预检、幂等检查 + → Domain Service 执行业务规则 + → Adapter 选择 API / 浏览器 / 桌面 / 手机 + → RPA 分步骤执行并持续上报进度 + → 验证码、人脸、U盾等转人工处理 + → 返回结构化结果、日志、截图与可选视频 + → Agent 向用户解释结果与下一步 +``` + +### 执行前 + +Agent 与编排层必须确认: + +- 用户意图、操作对象、范围与必填参数明确。 +- 当前账号、数据、设备和目标软件属于用户或企业授权范围。 +- 查询、准备数据与外部副作用已经分开。 +- 付款、删除、审批、发布、发送等不可逆动作已取得明确确认。 +- 浏览器 Profile、桌面窗口或手机设备已通过预检。 +- 同一业务键不会被重复提交。 + +### 执行中 + +- 每个用户可感知的动作都要有中文进度 step。 +- 使用可暂停、可停止的等待;禁止 RPA 主路径裸 `asyncio.sleep`。 +- 同一账号、Profile 或设备默认串行执行。 +- 遇到安全验证、权限不足、频控或风险提示时,转人工或安全停止。 +- 批量任务记录处理位置,支持失败定位和必要的断点续跑。 + +### 执行后 + +- 先验证业务成功标志,再记录成功;不得把“点击完成”当成“业务成功”。 +- 返回成功、部分成功、失败、停止或等待人工等明确状态。 +- 保存必要的任务日志、错误码、失败截图和可选录屏。 +- Agent 根据结构化结果解释完成数量、失败原因和下一步,不直接粘贴技术日志。 + +## 4. 合规与技术红线 + +### 允许 + +- 使用用户或企业合法拥有、明确授权的账号与业务权限。 +- 通过正常界面入口完成用户本来有权完成的操作。 +- 使用浏览器 DOM、Windows UI Automation、Android/iOS 控件树等公开自动化能力。 +- 采用真实点击、逐字输入、自然鼠标轨迹、分段滚动和合理业务节奏。 +- 遇到验证码、人脸、指纹、短信、U盾或动态口令时暂停并请求人工处理。 +- 在授权范围内保存必要的日志、截图、视频和业务结果。 + +### 禁止 + +- 破解、反编译、逆向第三方软件或分析其私有协议。 +- 调用未经公开授权的隐藏接口,或通过抓包拼装私有请求代替正常界面。 +- 绕过登录、验证码、人脸、指纹、短信、U盾、设备绑定、签名或权限校验。 +- 注入、Hook、篡改第三方进程、客户端、APK、IPA、安全模块或通信内容。 +- 窃取、共享或复用未授权的 Cookie、Token、Session、密码或设备凭据。 +- 撞库、暴力尝试、自动破解验证码、批量养号或伪造身份。 +- 通过换账号、换代理、伪造设备指纹、提高并发等方式规避平台限制。 +- 识别到风险提示或封禁后继续自动重试、试探或隐藏自动化行为。 + +“采用 RPA”不代表任何任务都可以自动执行。技能仍须遵守账号授权、数据权限、目标平台规则、合同约定和适用法律;边界不清时停止并请求负责人确认。 + +## 5. 工业级 RPA 风控 + +### 风控信号与处理 + +| 信号 | 标准处理 | +|------|----------| +| 页面或软件加载缓慢 | 等待真实状态,必要时有限重试 | +| 普通网络错误 | 递增退避后有限重试 | +| 登录失效 | 请求用户重新登录 | +| 验证码、短信、人脸、指纹、U盾 | 进入人工处理,禁止自动绕过 | +| 频率限制 | 停止当前批次或长时间退避 | +| 账号风险、封禁或安全警告 | 立即停止,禁止自动换号或继续试探 | +| 权限不足 | 返回明确失败,不尝试扩大或绕过权限 | +| 页面或控件结构变化 | 截图并停止,交由开发人员重新验证 | +| 提交结果不明确 | 查询业务状态;确认前禁止再次提交 | + +### 运行限制 + +- 同一账号、Profile、桌面会话或手机设备默认只运行一个任务。 +- 设置单批数量、单位时间操作量和总运行时长上限。 +- 只对明确可重试错误做有限重试;禁止无限循环。 +- 采用递增退避,不以快速重复点击或刷新解决延迟。 +- 关键副作用采用“准备数据 → 用户确认 → 执行 → 结果核验”两阶段流程。 +- 风控策略用于减少误操作、系统压力和误判,不得用于规避第三方安全控制。 + +## 6. 等待与操作节奏 + +区分三类等待,禁止只靠固定睡眠碰运气。 + +### 状态等待 + +页面加载、控件可用、弹窗消失、保存成功、下载完成等必须等待**真实条件**并设置超时。固定等待不能代替状态判断。 + +### 操作节奏 + +真实业务环境中,两个正常业务动作之间默认随机等待 **1~3 秒**: + +```env +STEP_DELAY_MIN=1.0 +STEP_DELAY_MAX=3.0 +``` + +- 输入采用逐字符随机延迟。 +- 鼠标采用自然移动轨迹与小幅随机偏移。 +- 滚动采用分段操作。 +- 提交后等待业务结果,禁止重复点击。 +- 测试 / sandbox 可使用更短节奏,但不得把测试节奏用于真实第三方系统。 + +### 前后缓冲 + +- 浏览器或软件启动:先等待会话与目标页面/窗口真实就绪,再额外缓冲约 `1.5~2.5` 秒。 +- 页面导航:关键控件就绪后,再缓冲约 `1~2` 秒。 +- 普通流程结束:确认业务结果、写日志与存证后,再缓冲约 `2~3` 秒关闭。 +- 付款、审批、发布等重要动作:确认结果并截图后,可缓冲约 `3~5` 秒。 + +缓冲时间只用于稳定界面和改善用户观感,不能作为成功判定。RPA 等待必须使用 `interruptible_sleep` 或共享可控制原语。 + +## 7. 三端统一与选型 + +优先选择最稳定、最受支持的执行方式: + +1. 本地确定性逻辑可以完成时,不启动 RPA。 +2. 有稳定且获得授权的官方 API 时,优先 API。 +3. 只能通过网页操作时,使用浏览器 RPA。 +4. 目标为 Windows 原生软件时,优先 UI Automation。 +5. 目标为手机 App 时,使用系统控件树与正常设备自动化。 +6. 只有破解、逆向或绕过安全机制才能完成时,停止开发并上报,不改走违规路线。 + +三端详细标准见 [`RPA.md`](RPA.md)。当前浏览器 RPA 已有可复制案例;桌面与手机仍须基于真实项目继续沉淀,未验证内容不得包装为成熟方案。 + +## 8. 结果契约 + +RPA 至少返回: + +```json +{ + "success": true, + "status": "success", + "message": "任务已完成", + "summary": { + "total": 10, + "success_count": 9, + "failed_count": 1 + }, + "items": [], + "errors": [], + "artifacts": { + "screenshots": [], + "video_path": null + }, + "next_actions": [] +} +``` + +状态至少能区分: + +- `success`:全部完成。 +- `partial`:部分成功,列出失败项。 +- `failed`:未完成,给出稳定错误码与阶段。 +- `waiting_human`:等待人工验证或接管,不是假失败。 +- `confirmation_required`:等待用户批准副作用。 +- `stopped`:用户或宿主主动停止。 + +具体字段可按业务扩展,但不得只返回控制台文本或把技术 traceback 直接交给用户。 + +## 9. 开发与交付顺序 + +1. 填写 [`REQUIREMENTS.md`](REQUIREMENTS.md) 中的 Agent、授权、风险、人工介入与结果设计。 +2. 判断采用 API、浏览器、桌面或手机,并选择真实 / 仿真 adapter。 +3. 定义用户意图、Action、输入 schema 与确认策略。 +4. 先实现 domain service、结构化结果和 mock 测试。 +5. 再实现 RPA 会话、真实操作、状态等待、进度、截图与人工介入。 +6. 在真实界面上确认 selector / 控件,禁止凭经验猜测。 +7. 完成仿真测试、真实业务闭环和宿主多入口验收。 +8. 使用 [`CHECKLIST.md`](CHECKLIST.md) 做第三方交活验收。 + +AI 编程工具不得为了“跑通”擅自采用破解、逆向、私有协议、验证码绕过、进程注入、无限重试或未授权凭据。正常界面无法完成闭环时,应停止并向负责人报告边界。 diff --git a/development/CHECKLIST.md b/development/CHECKLIST.md index 62915a9..1e1e9fb 100644 --- a/development/CHECKLIST.md +++ b/development/CHECKLIST.md @@ -55,6 +55,8 @@ checklist_version: 1.0 - [ ] S0-4 持久化:无 / 仅任务日志 / 另有业务表 - [ ] S0-5 Skill Action:无 / 仅同步短任务 / 含异步长任务 - [ ] S0-6 是否需要在任务中心查看进度或结果:是 / 否 +- [ ] S0-7 外部系统账号、数据、设备与操作权限的授权来源: +- [ ] S0-8 是否包含提交、付款、删除、审批、发布、发送等不可逆副作用:是 / 否 --- @@ -127,17 +129,32 @@ checklist_version: 1.0 --- -## 8. 质量门禁与交活底线(所有技能) +## 8. AI + RPA 合规与工业级风控(外部系统技能适用) -- [ ] A8-1 **P0** 仓库默认测试套件通过(执行技能约定的一键测试命令,如 `python tests/run_tests.py -v`) -- [ ] A8-2 **P0** 不以「仅模拟档通过」作为交活依据(有真实档要求时必须真实跑通或书面阶段性豁免) -- [ ] A8-3 **P0** **NEED_MANUAL** 已声明的宿主入口(详情/Agent/工具栏/定时等)按声明抽测可通过 -- [ ] A8-4 **P1** 对外版本一致:详情、version、更新日志、发布标签能对上 -- [ ] A8-5 **P1** 开发者按平台规则能安装并测到该技能(若平台有开发者可见性要求) +- [ ] A8-1 **P0** 已确认账号、数据、设备和业务操作均在用户或企业授权范围内;边界不明不能以“默认允许”通过 +- [ ] A8-2 **P0** 代码与运行路径不包含破解、反编译、逆向、未授权私有协议、抓包拼隐藏接口、Hook / 注入、验证码破解、设备指纹伪造、撞库、养号、自动换号或代理池规避限制 +- [ ] A8-3 **P0** 验证码、人脸、指纹、短信、U盾、频控、账号风险和权限不足能转人工或安全停止,不自动硬闯 +- [ ] A8-4 **P0** 付款、删除、审批、发布、发送等不可逆动作执行前有明确对象、范围和用户确认 +- [ ] A8-5 **P1** 页面 / 控件加载、保存和业务成功由真实状态判断,不以固定等待代替成功判定 +- [ ] A8-6 **P1** 真实 RPA 两个正常业务动作之间采用约 `1~3` 秒随机节奏;输入、鼠标和滚动符合正常人工操作方式 +- [ ] A8-7 **P1** 同一账号、Profile 或设备默认串行;批量、频率和运行时长有上限 +- [ ] A8-8 **P1** 只对明确可重试错误做有限重试与递增退避;风险、封禁、权限和结果不明确时不盲目重试 +- [ ] A8-9 **P1** 流程结束先核验业务结果并完成日志 / 截图 / 可选视频,再保留合理结束缓冲后关闭会话 +- [ ] A8-10 **P1** Agent 能区分成功、部分成功、失败、等待人工、等待确认和主动停止,并用业务语言解释结果 --- -## 9. 报告结尾必填 +## 9. 质量门禁与交活底线(所有技能) + +- [ ] A9-1 **P0** 仓库默认测试套件通过(执行技能约定的一键测试命令,如 `python tests/run_tests.py -v`) +- [ ] A9-2 **P0** 不以「仅模拟档通过」作为交活依据(有真实档要求时必须真实跑通或书面阶段性豁免) +- [ ] A9-3 **P0** **NEED_MANUAL** 已声明的宿主入口(详情/Agent/工具栏/定时等)按声明抽测可通过 +- [ ] A9-4 **P1** 对外版本一致:详情、version、更新日志、发布标签能对上 +- [ ] A9-5 **P1** 开发者按平台规则能安装并测到该技能(若平台有开发者可见性要求) + +--- + +## 10. 报告结尾必填 报告末尾固定三块: diff --git a/development/CONFIG.md b/development/CONFIG.md index 3df3dce..abd7d91 100644 --- a/development/CONFIG.md +++ b/development/CONFIG.md @@ -87,8 +87,8 @@ DEFAULT_ACCOUNT_ID= # 留空=自动;只填纯数字;手 # 是否显示浏览器窗口:网页自动化时是否弹出可见浏览器 OPENCLAW_BROWSER_HEADLESS=0 # 0=显示窗口(必须,便于介入与排查);1=后台静默(勿作日常用法) -# 浏览器防检测:降低被网站识别为自动化工具的概率 -OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=开启(推荐),0=关闭;一般保持默认 +# 浏览器兼容配置:仅在项目授权与平台规则允许时使用共享兼容能力 +OPENCLAW_PLAYWRIGHT_STEALTH=1 # 1=使用共享兼容配置,0=关闭;不得用于伪造身份或绕过平台限制 # 是否录制操作过程:用于留证、复现问题或向他人演示 OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并生成带说明的视频文件;需要留证时再改为 1 @@ -96,11 +96,11 @@ OPENCLAW_RECORD_VIDEO=0 # 0=不录屏(默认),1=录屏并 # 失败时是否截图:任务出错时自动保存现场截图,便于排查 OPENCLAW_ARTIFACTS_ON_FAILURE=1 # 1=失败时截图(推荐),0=不截图 -# 步骤最短等待:两步操作之间随机停顿的下限,模拟真人节奏 +# 步骤最短等待:两个正常业务动作之间随机停顿的下限 STEP_DELAY_MIN=1.0 # 单位:秒;一般保持默认,页面不稳定时可略调大 # 步骤最长等待:两步操作之间随机停顿的上限 -STEP_DELAY_MAX=5.0 # 单位:秒;须大于等于最短等待;一般保持默认 +STEP_DELAY_MAX=3.0 # 单位:秒;默认与最短等待组成 1~3 秒节奏;状态等待须另行判断 # 人工处理超时:遇到滑块、验证码、二次验证时,等待人工处理的最长时间 HUMAN_WAIT_TIMEOUT=180 # 单位:秒;来不及处理时可调大,如 300 diff --git a/development/DEVELOPMENT.md b/development/DEVELOPMENT.md index 9ce341c..30d9707 100644 --- a/development/DEVELOPMENT.md +++ b/development/DEVELOPMENT.md @@ -30,6 +30,8 @@ `skill-template` 不是业务 skill,它只是一个**新 skill 仓库模板**。 +开发任何外部系统技能前,**先读 [`AI_RPA.md`](AI_RPA.md)**。本模板的统一定位是:Agent 负责理解、确认与编排,RPA 负责通过正常界面确定性执行;只做授权范围内的正规业务自动化,禁止破解、逆向、私有协议、验证码绕过或其他对抗第三方安全机制的实现。 + 你不应该直接在这个仓库里开发业务。新技能仓库有**两种合法来源**(详见 §4「第一步」): | 来源 | 适用情况 | 怎么做 | @@ -131,7 +133,7 @@ scripts/ 若 skill 需要浏览器/桌面/手机自动化,按以下顺序落地: -1. **先读三份标准**:`RPA.md`(含 §0.2:Profile 强制 / 有头 / 登录分平台)、`CONFIG.md`(`.env` 落盘与读取)、`ADAPTER.md`(四档 adapter)。 +1. **先读总纲与三份标准**:`AI_RPA.md`(职责、合规、风控与完整闭环)、`RPA.md`(含 §0.2:Profile 强制 / 有头 / 登录分平台)、`CONFIG.md`(`.env` 落盘与读取)、`ADAPTER.md`(四档 adapter)。 2. **从 examples 选择性复制**(不要整包照搬 `examples//`,见各 example README 的 copy map): - 若是 **真实浏览器 RPA**(真实网站、登录态、验证码、滚动采集),**必须先读** `examples/real_browser_rpa/README.md`,再按需复制到 `scripts/service/`: - `examples/real_browser_rpa/scripts/service/browser_session.py` @@ -156,6 +158,8 @@ scripts/ 4. **单测/CI 须 mock 离线可过**;业务 `.env` 默认 `real_rpa`,须真实跑通。**不得只 mock 通就交活**;须 release 到匠厂宿主验收(见 §15,含用户体验)。 5. **桌面/手机**:本期标准见 RPA.md 第 2/3 节,复用 `jiangchang_desktop_sdk` / `screencast`,**不要在新 skill 里重复造包**(尚待实战验证)。 +**技术路线红线:**正常界面或获得授权的官方 API 无法完成闭环时,停止并向负责人说明;禁止 AI 或开发者擅自改用破解、反编译、逆向、私有协议、Hook / 注入、验证码破解、设备指纹伪造、自动换号或无限重试。 + --- ### 3.1 `requirements.txt` 依赖规范 diff --git a/development/POLICY_MATRIX.md b/development/POLICY_MATRIX.md index 30bd7ec..657b8cb 100644 --- a/development/POLICY_MATRIX.md +++ b/development/POLICY_MATRIX.md @@ -20,6 +20,7 @@ | POLICY-RPA-002 | RPA 交付代码不得直接执行 ffmpeg 拼 MP4;应使用 `RpaVideoSession`(允许 `ffmpeg_path` 等诊断字段) | development/RPA.md §5.3 录屏成片标准 | hard | 扫描 `scripts/**/*.py` 禁止 `subprocess` / `os.system` / `os.popen` 直接调用 ffmpeg(`task_run_support.py` 保留豁免) | `tests/test_development_policy_guard.py::TestPolicyRpa002` | | POLICY-RPA-003 | 即使默认 `OPENCLAW_RECORD_VIDEO=0`,RPA / 长任务模板也必须保留录屏能力:`RpaVideoSession`、`video.add_step`、video artifact merge 到 `result_summary` | development/RPA.md §5.3;development/LOGGING.md;development/CONFIG.md | hard | 扫描 `scripts/service/*.py`(service 层整体须含上述接入) | `tests/test_development_policy_guard.py::TestPolicyRpa003` | | POLICY-RPA-004 | 网页 RPA:`.env.example` 若声明 `OPENCLAW_BROWSER_HEADLESS` 则默认必须为 `0`;`scripts/` 若使用 `launch_persistent_*` 则必须同时存在 `pick_web_account`(先 Profile 再开浏览器;实现上应走 ensure-web);登录不全局强制,但不得跳过 account-manager | development/RPA.md §0.2;development/ADAPTER.md §兄弟依赖 | hard | 解析 `.env.example` + 扫描 `scripts/**/*.py` | `tests/test_development_policy_guard.py::TestPolicyRpa004` | +| POLICY-RPA-005 | 必须保留 AI + RPA 总纲,明确 Agent / RPA 职责、授权范围、禁止破解/逆向/私有协议/安全验证绕过、人工介入、状态等待;真实业务默认动作节奏为 1~3 秒 | development/AI_RPA.md §4–§6;development/RPA.md §0.0/§0.3 | hard(文档与默认配置) / soft(真实行为) | 检查总纲关键边界;解析 `.env.example` 的 `STEP_DELAY_MIN=1.0` / `STEP_DELAY_MAX=3.0` | `tests/test_development_policy_guard.py::TestPolicyRpa005` | | POLICY-PACKAGING-001 | `scripts/**/*.py` 单文件 < 1000 行 | development/DEVELOPMENT.md §3.4 发布打包约束;development/RUNTIME.md §发布打包约束 | hard | 行数统计 | **已有测试覆盖**:`tests/test_release_packaging_constraints.py::test_scripts_py_files_under_pyarmor_line_limit` | | POLICY-PACKAGING-002 | 文本文件 UTF-8 without BOM,无 `U+FEFF` | development/DEVELOPMENT.md §3.4;development/RUNTIME.md §编码与输出 | hard | BOM / 解码检查 | **已有测试覆盖**:`tests/test_release_packaging_constraints.py::test_text_files_are_utf8_without_bom` | | POLICY-DOCS-001 | 本矩阵存在且包含上述全部 `policy_id` | 本次规范化约定 | hard | 解析 `development/POLICY_MATRIX.md` | `tests/test_development_policy_guard.py::TestPolicyDocs001` | @@ -56,7 +57,7 @@ | slug 命名语义(verb-noun-platform) | development/NAMING.md | 部分覆盖于 `tests/test_slug_naming.py`,非本矩阵 hard policy | | 复制模板不得保留 `.git` / template marker | development/DEVELOPMENT.md §4 | 由 `tests/test_scaffold_guard.py` 守护,属脚手架场景 | | 共享 runtime 导入来源非技能目录 | development/RUNTIME.md | 运行时依赖已安装包,见 `tests/test_platform_import.py` | -| RPA 拟人操作、选择器纪律、HITL 超时 | development/RPA.md §0–§1 | 行为与 DOM 质量,无法静态扫描 | +| RPA 真实轨迹、选择器纪律、状态等待、HITL 超时与有限重试是否正确实现 | development/AI_RPA.md;development/RPA.md §0–§1 | 文档和默认节奏已守护,真实行为与 DOM 质量仍需人工验收 | | adapter 四档契约测试覆盖 timeout/unauthorized 等 | development/ADAPTER.md §contract tests | 需业务实现后人工补测 | | `SKILL.md` / `constants.SKILL_SLUG` 一致性 | development/DEVELOPMENT.md §16 | 已有 `tests/test_skill_metadata.py` | | platform_kit_min_version >= 1.2.2 | development/RUNTIME.md | 已有 `tests/test_platform_import.py` | diff --git a/development/README.md b/development/README.md index ce6dcd7..a46f956 100644 --- a/development/README.md +++ b/development/README.md @@ -9,12 +9,13 @@ | 步骤 | 做什么 | 详见 | |------|--------|------| | 1 | **拿到仓库**:① 项目经理在 [自建 Gitea](https://git.jc2009.com/)(`git.jc2009.com`,非 Gitea 官网)开仓并授权后 `git clone`;或 ② 本地已有 `skill-template` 时用 scaffold / 复制出新目录(遵守 Git 红线) | [`DEVELOPMENT.md`](DEVELOPMENT.md) §1、§4 | -| 2 | 按 [`NAMING.md`](NAMING.md) 确认 slug;**先填** [`REQUIREMENTS.md`](REQUIREMENTS.md),再写业务代码 | [`REQUIREMENTS.md`](REQUIREMENTS.md)、[`NAMING.md`](NAMING.md) | -| 3 | 替换标识与占位,按四象限 / examples 实现 `scripts/service/` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §4~§14 | -| 4 | **配置 `developer_ids`(开发自测必做)**:开发期技能在匠厂默认不公开;不加则开发者自己也装测不了。从宿主设置复制用户 ID 写入 `SKILL.md` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §6「关于 developer_ids」 | -| 5 | 本地单测(mock)通过后,按业务默认 **`real_rpa`** 真实跑通;再 `release.ps1`;看 Gitea CI。**mock 通 ≠ 完成** | [`ADAPTER.md`](ADAPTER.md);[`DEVELOPMENT.md`](DEVELOPMENT.md) §15 | -| 6 | 匠厂安装后,按已声明入口自测,并看**用户体验**(进度、失败提示、有头 RPA 等) | [`DEVELOPMENT.md`](DEVELOPMENT.md) §15;[`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) | -| 7 | **交活验收(第三方)**:对照 [`CHECKLIST.md`](CHECKLIST.md) 验收;报告写入仓库根目录 [`acceptance-reports/`](../acceptance-reports/) | [`CHECKLIST.md`](CHECKLIST.md) | +| 2 | **先读 AI + RPA 总纲**,理解 Agent / RPA 职责、授权边界、禁止路线、风控和操作节奏 | [`AI_RPA.md`](AI_RPA.md) | +| 3 | 按 [`NAMING.md`](NAMING.md) 确认 slug;**先填** [`REQUIREMENTS.md`](REQUIREMENTS.md),再写业务代码 | [`REQUIREMENTS.md`](REQUIREMENTS.md)、[`NAMING.md`](NAMING.md) | +| 4 | 替换标识与占位,按四象限 / examples 实现 `scripts/service/` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §4~§14 | +| 5 | **配置 `developer_ids`(开发自测必做)**:开发期技能在匠厂默认不公开;不加则开发者自己也装测不了。从宿主设置复制用户 ID 写入 `SKILL.md` | [`DEVELOPMENT.md`](DEVELOPMENT.md) §6「关于 developer_ids」 | +| 6 | 本地单测(mock)通过后,按业务默认 **`real_rpa`** 真实跑通;再 `release.ps1`;看 Gitea CI。**mock 通 ≠ 完成** | [`ADAPTER.md`](ADAPTER.md);[`DEVELOPMENT.md`](DEVELOPMENT.md) §15 | +| 7 | 匠厂安装后,按已声明入口自测,并看**用户体验**(进度、失败提示、有头 RPA 等) | [`DEVELOPMENT.md`](DEVELOPMENT.md) §15;[`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) | +| 8 | **交活验收(第三方)**:对照 [`CHECKLIST.md`](CHECKLIST.md) 验收;报告写入仓库根目录 [`acceptance-reports/`](../acceptance-reports/) | [`CHECKLIST.md`](CHECKLIST.md) | 脚手架与 Git 防串库:[`../tools/README.md`](../tools/README.md)(`scaffold_skill.ps1`)。业务仓也可直接从自建 Gitea clone,见 [`DEVELOPMENT.md`](DEVELOPMENT.md) §4 来源 A。 @@ -24,19 +25,20 @@ 开始定制 skill 前,建议按以下顺序阅读: -1. [`SHARED_REPOS.md`](SHARED_REPOS.md) — **公共仓库目录**(模板 / 账号管理 / platform-kit 等,可扩展) -2. [`REQUIREMENTS.md`](REQUIREMENTS.md) — 需求文档模板与验收标准 -3. [`NAMING.md`](NAMING.md) — slug / 仓库名命名规范(复制模板前必读) -4. [`DEVELOPMENT.md`](DEVELOPMENT.md) — 完整开发步骤与目录规范 -5. [`TESTING.md`](TESTING.md) — 测试分层、隔离数据根与档位开关 -6. [`LOGGING.md`](LOGGING.md) — 日志分层、必打节点、敏感信息红线(**涉及长任务、RPA、外部系统时必读**) -7. [`ADAPTER.md`](ADAPTER.md) — 涉及外部系统对接时 -8. [`RPA.md`](RPA.md) — 涉及浏览器 / 桌面 / 手机自动化时 -9. [`CONFIG.md`](CONFIG.md) — `.env` 规范与 bootstrap 机制 -10. [`DATA_PATHS.md`](DATA_PATHS.md) — 下载/导入/导出等本地文件路径标准(涉及文件读写时必读) -11. [`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) — Skill Action sync/async、任务中心、Agent 禁令、队列 pick(涉及 RPA / 长任务 / 数据管理按钮 / Cron / Agent 时必读) -12. [`RUNTIME.md`](RUNTIME.md) — 共享 runtime、数据路径、发布打包与编码约定 -13. [`CHECKLIST.md`](CHECKLIST.md) — **交活验收清单(第三方视角)**;报告输出到 [`../acceptance-reports/`](../acceptance-reports/) +1. [`AI_RPA.md`](AI_RPA.md) — **AI Agent + RPA 总纲**:职责边界、合规红线、风控、操作节奏与完整闭环 +2. [`SHARED_REPOS.md`](SHARED_REPOS.md) — **公共仓库目录**(模板 / 账号管理 / platform-kit 等,可扩展) +3. [`REQUIREMENTS.md`](REQUIREMENTS.md) — 需求文档模板与验收标准 +4. [`NAMING.md`](NAMING.md) — slug / 仓库名命名规范(复制模板前必读) +5. [`DEVELOPMENT.md`](DEVELOPMENT.md) — 完整开发步骤与目录规范 +6. [`TESTING.md`](TESTING.md) — 测试分层、隔离数据根与档位开关 +7. [`LOGGING.md`](LOGGING.md) — 日志分层、必打节点、敏感信息红线(**涉及长任务、RPA、外部系统时必读**) +8. [`ADAPTER.md`](ADAPTER.md) — 涉及外部系统对接时 +9. [`RPA.md`](RPA.md) — 涉及浏览器 / 桌面 / 手机自动化时 +10. [`CONFIG.md`](CONFIG.md) — `.env` 规范与 bootstrap 机制 +11. [`DATA_PATHS.md`](DATA_PATHS.md) — 下载/导入/导出等本地文件路径标准(涉及文件读写时必读) +12. [`SKILL_ACTION_RUNTIME.md`](SKILL_ACTION_RUNTIME.md) — Skill Action sync/async、任务中心、Agent 禁令、队列 pick(涉及 RPA / 长任务 / 数据管理按钮 / Cron / Agent 时必读) +13. [`RUNTIME.md`](RUNTIME.md) — 共享 runtime、数据路径、发布打包与编码约定 +14. [`CHECKLIST.md`](CHECKLIST.md) — **交活验收清单(第三方视角)**;报告输出到 [`../acceptance-reports/`](../acceptance-reports/) Agent 调用契约见 [`../references/CLI.md`](../references/CLI.md)、[`../references/SCHEMA.md`](../references/SCHEMA.md)、[`../references/ACTIONS.md`](../references/ACTIONS.md)。 用户市场四 Tab 见根目录 [`README.md`](../README.md) / [`TUTORIAL.md`](../TUTORIAL.md) / [`DEMO.md`](../DEMO.md) / [`CHANGELOG.md`](../CHANGELOG.md),不要写进本目录。 diff --git a/development/REQUIREMENTS.md b/development/REQUIREMENTS.md index 5fcbf60..360fbfb 100644 --- a/development/REQUIREMENTS.md +++ b/development/REQUIREMENTS.md @@ -6,6 +6,7 @@ - 一个 skill 对应一份主需求文档 - 需求先写清楚,再进入开发 +- 涉及外部系统时先读 `AI_RPA.md`,明确 Agent / RPA 边界、授权、风险与人工介入 - 文档描述“要做什么”和“做到什么程度”,不要在这里堆实现细节 - 实现方式、代码结构、发布流程,分别放到 `DEVELOPMENT.md`、`references/`、`development/` 下的技术规范 @@ -30,6 +31,39 @@ - **登记 ≠ 登录**:ensure/add-web 只建账号与 Profile;站点登录由本技能在有头浏览器中完成 - **反模式**:把「需要登录态才能采到数据」的需求写成 `optional`,再省略 `ensure_logged_in` +## 0.1 AI + RPA 协作与授权边界(涉及外部系统时必填) + +### Agent 设计 + +- 用户会怎样描述本任务: +- 支持哪些用户意图;分别映射到哪个 Action: +- 每种意图必须提取哪些参数: +- 缺少哪些参数时必须追问: +- 哪些动作必须先展示对象、数量和影响,再取得明确确认: +- Agent 最终如何解释成功、部分成功、失败、等待人工和停止: + +### 授权与平台边界 + +- 目标浏览器 / 桌面软件 / 手机 App: +- 账号、设备、数据和业务权限由谁授权: +- 是否有获得授权的官方 API;若不用,原因是什么: +- 目标平台规则、合同或客户约定中的自动化边界: +- 明确禁止的实现路线:破解 / 反编译 / 逆向 / 私有协议 / 抓包拼隐藏接口 / Hook 或注入 / 验证码破解 / 设备指纹伪造 / 自动换号: +- 正常界面无法闭环时的上报与停止条件: + +### RPA 风控设计 + +- 执行端:浏览器 / 桌面 / Android / iOS: +- 会话、Profile、窗口或设备如何准备与互斥: +- 单批上限、单位时间操作量和最长运行时间: +- 普通动作节奏(真实环境默认 `1~3` 秒): +- 页面 / 控件真实状态如何判断;禁止用固定睡眠代替的节点: +- 哪些错误允许有限重试;退避策略: +- 哪些信号必须立即停止(频控、封禁、权限不足、结构变化等): +- 哪些步骤进入人工处理(验证码、人脸、指纹、短信、U盾等): +- 如何防止重复提交并支持必要的断点续跑: +- 需要保存哪些日志、截图、视频和业务结果: + ## 1. 文档目标 说明这份需求文档的作用,以及它解决什么问题。 @@ -109,6 +143,8 @@ - 输出格式应尽量机读友好;错误前缀统一为 `ERROR:` - Windows 环境下需保证 UTF-8 输出兼容 - 必须具备基本日志能力;敏感字段脱敏 +- 只做授权范围内的正常界面自动化;禁止破解、逆向、未授权私有协议、安全验证绕过、进程注入、凭据窃取、自动换号和无限重试 +- RPA 的页面加载与成功判断必须由真实状态驱动;正常业务动作之间默认随机等待 `1~3` 秒 - RPA 类 skill:Playwright 由宿主共享 runtime 提供;技能侧不要 `playwright install`;URL 不要放进 `launch_persistent_context` 的 `args` - 网页 RPA:启动前必须经 ensure-web 拿到 `profile_dir`;生产有头;站点登录策略见 §0(required / optional / not_needed);`required` 时每轮须登录门禁 @@ -174,10 +210,13 @@ - `SKILL.md` 的 `developer_ids` 已配置为开发者本人匠厂用户 ID(开发期不公开时,否则本人无法在市场安装自测;取 ID 步骤见 `development/DEVELOPMENT.md` §6) - 发布后 Gitea 工作流成功;匠厂技能市场对开发者账号可见最新版本并可安装 - 安装后按本技能 `actions.json` 声明完成宿主多入口验收(见 `development/DEVELOPMENT.md` §15);**须看用户体验**(进度可见、失败可读、RPA 有头、文案与真实行为一致等),后台通了不算完 +- 已人工核验授权与技术路线:无破解、逆向、私有协议、验证码绕过、Hook / 注入、自动换号或其他规避平台限制的实现 +- RPA 真实主路径已验证状态等待、`1~3` 秒正常操作节奏、有限重试、账号 / 设备串行、人工介入、结果核验和结束存证 ## 10. 开发注意事项 - 只修改当前 skill 仓库,不要改动无关兄弟项目 +- 正常界面或获得授权的官方 API 无法完成闭环时,停止并上报;不得擅自改走破解、逆向或绕过安全机制的路线 - 先判断四象限类型(`real_browser_rpa` / `real_api` / `simulator_browser_rpa` / `simulator_api`),再读对应 `examples/*/README.md` - `cli` 只做参数解析;核心逻辑在 `service`;兄弟 skill 调用集中封装(见 `ADAPTER.md`) - 发布前完成本地验证、工作流验证和正式环境安装验证(含 `developer_ids` 与宿主多入口) diff --git a/development/RPA.md b/development/RPA.md index 395c999..a60d994 100644 --- a/development/RPA.md +++ b/development/RPA.md @@ -2,6 +2,8 @@ > 本文是团队 RPA 开发的**统一标准**。任何需要"自动操作软件界面"的 skill,都应先读这份文档,按这里的选型和范式落地,不要每个项目重新踩坑。 +先读 [`AI_RPA.md`](AI_RPA.md):Agent 负责理解、确认与编排,RPA 只负责授权范围内的确定性界面执行。RPA 是代替人完成正常业务操作的工具,**不是**破解、逆向、私有协议调用或对抗第三方安全机制的手段。 + 网页账号 / Profile 依赖公开兄弟技能 **account-manager**;浏览器 RPA 原语来自 **jiangchang-platform-kit**。二者 Gitea 地址、clone 方式与红线见 [`SHARED_REPOS.md`](SHARED_REPOS.md)。 我们开发的各类 skill,本质上都是在替人操作三类界面:**浏览器、桌面软件、手机软件**。三类的底层技术不同,但**工程范式相同**:可控会话(Profile)、有头运行、拟人操作、失败存证、人工兜底。 @@ -16,8 +18,8 @@ |------|------| | **可控会话 / Profile** | 网页版见下方 **§0.2**(必须走 account-manager 的 `profile_dir`);桌面/手机用对应持久会话,不硬编码密码 | | **有头运行** | 生产 RPA **必须有头**(见 §0.2);禁止把无头当交付/联调常态 | -| **拟人操作** | 真实事件(isTrusted=true),逐字输入、随机延迟、贝塞尔鼠标轨迹;严禁 JS 直接设值/JS 点击/JS 跳转 | -| **步骤间随机等待** | 每两步操作之间 `random_delay(min,max)`,区间由 `.env` 配置(默认 1~5s) | +| **正常人工节奏** | 真实点击、逐字输入、自然鼠标轨迹、分段滚动;严禁 JS 直接设值/JS 点击/JS 跳转绕过页面流程 | +| **步骤间随机等待** | 每两个正常业务动作之间 `random_delay(min,max)`,真实环境默认 **1~3 秒**;状态等待另算,不得用固定睡眠代替 | | **人工兜底(HITL)** | 滑块 / 短信验证码 / 人脸 / U盾 / 动态口令 → **停下来轮询等人工**,超时报 `ERROR:XXX_NEED_HUMAN`,绝不自动硬闯 | | **失败存证** | 失败必截图,合规场景全程录屏,统一存 `{数据目录}/rpa-artifacts/{batch_id}/{tag}_{ts}.png` | | **选择器纪律** | 语义选择器优先(id/name/text/aria);**F12 确认后再写,严禁凭记忆猜 DOM** | @@ -27,6 +29,14 @@ > 三端各自实现一个会话抽象 `RpaSession`(launch / login / act / screenshot / close),上层 skill 不感知是浏览器还是手机。 +### 0.0 合规红线 + +- 只使用用户或企业合法拥有、明确授权的账号、数据、设备和业务权限。 +- 优先正常界面或获得授权的官方 API;只有破解、逆向或绕过安全机制才能实现时,停止并上报。 +- 禁止反编译、私有协议、抓包拼装隐藏接口、Hook / 注入、客户端篡改、验证码破解、设备指纹伪造、撞库、养号、自动换号或代理池规避限制。 +- 验证码、人脸、指纹、短信、U盾、动态口令必须交给人工;权限不足、账号风险、频控或封禁必须安全停止。 +- 合规与完整职责边界以 [`AI_RPA.md`](AI_RPA.md) 为准。 + ### 0.1 步骤控制与进度(SRCP,platform-kit >= 1.2.0) - **禁止** `scripts/util/progress.py` 或 `print({"type":"progress",...})`;进度只走 `emit` / Run Journal。 @@ -74,6 +84,40 @@ async def open_login(page): --- +### 0.3 工业级风控、等待与收尾 + +**状态等待优先:**页面加载、控件可用、弹窗消失、保存成功、下载完成和业务结果出现,必须等待真实条件并设置超时;禁止用固定 `sleep(3)` 假设成功。 + +**操作节奏:** + +- 两个正常业务动作之间默认随机等待 `1~3` 秒。 +- 输入采用逐字符随机延迟;鼠标使用自然轨迹;滚动采用分段操作。 +- 同一账号、Profile、桌面会话或手机设备默认串行。 +- 单批数量、单位时间操作量和运行时长必须有上限。 +- 只对明确可重试错误做有限重试;普通网络错误可递增退避,风险提示和权限错误不得自动重试。 + +**前后缓冲:** + +- 启动浏览器、桌面软件或手机会话后,先等待目标页面 / 窗口 / 控件真实就绪,再额外缓冲约 `1.5~2.5` 秒。 +- 页面导航后,关键控件就绪再缓冲约 `1~2` 秒。 +- 流程结束时,先确认业务结果、写日志并完成存证,再缓冲约 `2~3` 秒关闭会话。 +- 付款、审批、发布等重要动作确认结果并截图后,可缓冲约 `3~5` 秒。 + +缓冲用于稳定界面和改善用户体验,**不能作为成功判断**。RPA 主路径使用 `interruptible_sleep` 等可控制等待,确保暂停与停止能够生效。 + +**风险信号:** + +| 信号 | 标准处理 | +|------|----------| +| 验证码 / 人脸 / 指纹 / U盾 | 进入人工处理 | +| 频率限制 | 停止当前批次或长时间退避 | +| 账号风险 / 封禁 / 安全警告 | 立即停止,禁止换号继续 | +| 权限不足 | 明确失败,不尝试绕过 | +| 页面 / 控件结构变化 | 截图并停止,重新人工验证定位 | +| 提交结果不明确 | 查询业务状态,确认前禁止再次提交 | + +--- + ## 1. 浏览器(标准已成熟) **选型:Playwright + 系统 Chrome/Edge。** 这是团队验证最充分的一条线(标杆技能 `1688-scrape-contacts`、`receive-order` 已落地)。 @@ -87,12 +131,12 @@ async def open_login(page): | CDP | **仅作诊断 / 桌面宿主类场景**;**不要**作为强风控站点的默认生产路径 | | 行为 | 模拟真实用户:真实点击、键盘、鼠标、地址栏输入;**不要**拼接搜索结果 URL、DOM 注入、`el.value=`、JS 跳转 | | 模式 | **有头** `OPENCLAW_BROWSER_HEADLESS=0`(生产强制,见 §0.2) | -| 反检测 | stealth 默认开 `OPENCLAW_PLAYWRIGHT_STEALTH=1`(见 1.1) | +| 浏览器兼容配置 | `OPENCLAW_PLAYWRIGHT_STEALTH` 仅用于经评估的兼容配置;不得用于伪造身份或绕过平台限制 | ### 1.1 Playwright 启动标准 1. **有头**:`OPENCLAW_BROWSER_HEADLESS=0`(`.env.example` 默认;网页 RPA 生产路径禁止改成无头常态,见 §0.2)。 -2. **stealth 默认开**:`OPENCLAW_PLAYWRIGHT_STEALTH=1`;通过 `add_init_script` 注入指纹淡化脚本。 +2. **stealth 须受控**:`OPENCLAW_PLAYWRIGHT_STEALTH` 仅在目标平台授权、规则与项目评估允许时启用;不得把它理解为规避风控或伪造设备身份。 3. **不要在技能里自行安装 playwright**;由宿主共享 runtime 提供。 4. **不要默认传 `--no-sandbox`**(除非特定容器环境且已评估风险)。 5. **不要默认传 `--disable-blink-features=AutomationControlled`**;platform-kit stealth 已覆盖,额外 flag 可能适得其反。 @@ -100,7 +144,7 @@ async def open_login(page): 7. **强风控平台**:优先真实点击、键盘、鼠标、地址栏、account-manager 持久 profile;**不要**直接拼接搜索结果 URL 或 DOM 注入。 8. **先 Profile 再开浏览器**:`user_data_dir` 必须来自 ensure/pick 到的 `profile_dir`;未拿到则不得进入本节后续步骤。 -指纹淡化(stealth)典型项:`navigator.webdriver=undefined`、`chrome.runtime`、`permissions.query`、`plugins`、`languages` 等。共享实现见 `jiangchang_skill_core.rpa`(platform-kit **>= 1.2.0**)。 +浏览器兼容配置由共享 `jiangchang_skill_core.rpa` 提供(platform-kit **>= 1.2.0**)。业务技能不得自行扩展指纹伪造、代理轮换或规避安全检测的代码;遇到明确风控信号时转人工或停止。 **拟人操作**(必做): @@ -108,7 +152,7 @@ async def open_login(page): - 鼠标:贝塞尔曲线轨迹 + 微抖动;进场随机晃动。 - 导航:用真实点击触发,**不要 `window.location.href=` / JS 点击跳转**。 - 翻页:真实点击翻页控件,注意排除禁用态。 -- 延迟:每步之间 `random_delay`(`.env` 中 `STEP_DELAY_MIN/MAX`)。 +- 延迟:两个正常业务动作之间 `random_delay`(`.env` 中 `STEP_DELAY_MIN/MAX`,默认 1~3 秒);页面状态仍须显式等待。 ### 1.2 页面启动标准 @@ -243,6 +287,7 @@ from jiangchang_skill_core.rpa.stealth import stealth_enabled, STEALTH_INIT_SCRI - **DPI/缩放**:图像识别方案必须固定显示缩放比例;UIA 方案不受影响(优先用 UIA 即是为此)。 - **存证**:同样要失败截图(截目标窗口/全屏),存到 `rpa-artifacts`。 - **人工兜底**:U盾插拔、动态口令、人脸 → 停下等人工,超时 `ERROR:XXX_NEED_HUMAN`。 +- **禁止侵入**:不注入或 Hook 第三方进程,不修改客户端文件,不反编译或调用未授权私有协议。 ```bash pip install pywinauto # UIA 自动化 @@ -271,6 +316,7 @@ pip install pywinauto # UIA 自动化 - **登录态**:靠 App 自身保持登录,必要时引导人工首登一次。 - **人工兜底**:短信验证码、人脸、指纹 → scrcpy 投屏让人工完成,程序轮询等待。 - **存证**:失败时 `adb screencap` / Appium 截图存 `rpa-artifacts`。 +- **设备边界**:使用正常授权设备与官方 App;不 Root / 越狱,不 Hook,不修改 APK / IPA,不伪造设备身份或绕过签名、绑定与安全校验。 ```bash # Android(首选) diff --git a/examples/README.md b/examples/README.md index f7e2bfb..2923b41 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,6 +4,8 @@ **`examples/` 不是完整 skill 仓库。** 不要整包照搬 `examples//` 到新技能根目录。应按各 example README 的 **copy map**,**选择性复制**到新技能的 `scripts/`(及按需的 `tests/`)。 +复制任何案例前先读 [`../development/AI_RPA.md`](../development/AI_RPA.md):案例只示范授权范围内的正常界面自动化,禁止把它扩展为破解、逆向、私有协议、验证码绕过、Hook / 注入、自动换号或规避平台限制的实现。 + 根 `README.md`、`SKILL.md`、`references/`、`development/` 仍按模板主目录规则编写,**不要**从 `examples/` 复制。 ## 四类外部交互方式 diff --git a/examples/real_browser_rpa/README.md b/examples/real_browser_rpa/README.md index 5bc1228..2c6a7b3 100644 --- a/examples/real_browser_rpa/README.md +++ b/examples/real_browser_rpa/README.md @@ -7,6 +7,7 @@ - 本示例是通用模板,不绑定具体平台。 - 示例抽象自已跑通的真实浏览器 RPA skill(抖音视频链接采集),但代码已改成中性示例命名。 - 新 skill 开发时可以复制本目录,再替换目标站点、选择器、解析逻辑和业务字段。 +- 只用于授权范围内的正常界面操作;禁止破解、逆向、私有协议、验证码绕过、自动换号或其他规避平台限制的扩展。 ## 适用场景 @@ -142,6 +143,7 @@ real_browser_rpa/ - **不 import account-manager 内部模块** — 只通过 CLI/subprocess 调用 - **不自动破解验证码** — 滑块/短信只检测 + 等待人工完成 +- **不对抗平台风控** — 频控、账号风险、封禁或权限不足时停止并交由人工处理 - **日志脱敏** — 不输出完整手机号/账号 - **租约释放** — `ensure-web` / `pick-web --lease` 后必须在 `finally` 释放 - **失败留痕** — 真实 skill 应在关键失败点截图(示例中已留注释位) diff --git a/examples/real_browser_rpa/scripts/service/task_rpa.py b/examples/real_browser_rpa/scripts/service/task_rpa.py index 0bd580e..6e80c4c 100644 --- a/examples/real_browser_rpa/scripts/service/task_rpa.py +++ b/examples/real_browser_rpa/scripts/service/task_rpa.py @@ -10,6 +10,7 @@ import time from dataclasses import dataclass, field from typing import Any, Callable, Dict, List, Optional, Tuple +from jiangchang_skill_core import config from jiangchang_skill_core.activity import interruptible_sleep from service.browser_session import close_browser_context, get_start_url, start_browser_session @@ -101,9 +102,9 @@ def _step_cb(cb: Optional[StepCallback], text: str) -> None: async def _random_delay() -> None: - lo = int(os.getenv("RPA_STEP_DELAY_MIN_MS") or "900") - hi = int(os.getenv("RPA_STEP_DELAY_MAX_MS") or "2600") - await interruptible_sleep(random.uniform(lo / 1000.0, hi / 1000.0)) + lo = max(0.0, config.get_float("STEP_DELAY_MIN", 1.0)) + hi = max(lo, config.get_float("STEP_DELAY_MAX", 3.0)) + await interruptible_sleep(random.uniform(lo, hi)) async def _scroll_wait() -> None: diff --git a/examples/simulator_browser_rpa/README.md b/examples/simulator_browser_rpa/README.md index b8ea8b4..c8f60e4 100644 --- a/examples/simulator_browser_rpa/README.md +++ b/examples/simulator_browser_rpa/README.md @@ -4,6 +4,8 @@ 本示例抽象自已跑通的「工行批量提交类」浏览器自动化 skill 的工程范式,但已**去业务化**——不包含真实银行/真实资金语义,也**不是** Amazon 或任何生产技能的复制。 +本示例只教学授权范围内的正常界面自动化;禁止把 sandbox 做法扩展为破解、逆向、私有协议、验证码绕过、Hook / 注入、自动换号或规避真实平台限制的实现。 + ## 适合什么场景 - 自有 **行业仿真系统** / `sandbox.jc2009.com` / 本地 `sandbox/demo_app.html` diff --git a/scripts/util/constants.py b/scripts/util/constants.py index f8ef584..ecb177a 100644 --- a/scripts/util/constants.py +++ b/scripts/util/constants.py @@ -1,6 +1,6 @@ """技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。""" SKILL_SLUG = "your-skill-slug" -SKILL_VERSION = "1.0.56" +SKILL_VERSION = "1.0.57" LOG_LOGGER_NAME = "openclaw.skill.your_skill_slug" PLATFORM_KIT_MIN_VERSION = "1.2.2" diff --git a/tests/test_development_policy_guard.py b/tests/test_development_policy_guard.py index 68708c0..34bb6bf 100644 --- a/tests/test_development_policy_guard.py +++ b/tests/test_development_policy_guard.py @@ -36,6 +36,7 @@ POLICY_IDS = ( "POLICY-RPA-002", "POLICY-RPA-003", "POLICY-RPA-004", + "POLICY-RPA-005", "POLICY-PACKAGING-001", "POLICY-PACKAGING-002", "POLICY-DOCS-001", @@ -155,6 +156,25 @@ RPA_004_LAUNCH_MARKERS = ( ) RPA_004_PICK_MARKER = "pick_web_account" +RPA_005_SOURCE = ( + "development/AI_RPA.md §4–§6; development/RPA.md §0.0/§0.3; " + "development/POLICY_MATRIX.md" +) +RPA_005_REQUIRED_DOC_MARKERS = ( + "AI Agent 是用户入口与业务编排者", + "RPA 是确定性执行器", + "破解", + "逆向", + "私有协议", + "验证码", + "人工处理", + "1~3 秒", + "状态等待", +) +RPA_005_STEP_DELAY_KEY_RE = re.compile( + r"(?m)^\s*(STEP_DELAY_MIN|STEP_DELAY_MAX)\s*=\s*([^\s#]+)" +) + LOGGING_001_SOURCE = "development/LOGGING.md; development/RUNTIME.md" LOGGING_002_SOURCE = "development/LOGGING.md; development/DEVELOPMENT.md" LOGGING_003_SOURCE = "development/LOGGING.md" @@ -669,6 +689,53 @@ class TestPolicyRpa004(unittest.TestCase): ) +class TestPolicyRpa005(unittest.TestCase): + def test_ai_rpa_governance_doc_has_required_boundaries(self) -> None: + skill_root = get_skill_root() + path = os.path.join(skill_root, "development", "AI_RPA.md") + self.assertTrue( + os.path.isfile(path), + msg=_policy_msg("POLICY-RPA-005", RPA_005_SOURCE, "development/AI_RPA.md missing"), + ) + text = _read_text(path) + missing = [marker for marker in RPA_005_REQUIRED_DOC_MARKERS if marker not in text] + self.assertEqual( + missing, + [], + msg=_policy_msg( + "POLICY-RPA-005", + RPA_005_SOURCE, + "AI_RPA.md missing markers: " + ", ".join(missing), + ), + ) + + def test_real_rpa_default_step_delay_is_one_to_three_seconds(self) -> None: + skill_root = get_skill_root() + env_path = os.path.join(skill_root, ".env.example") + values = { + key: value.strip().strip("\"'") + for key, value in RPA_005_STEP_DELAY_KEY_RE.findall(_read_text(env_path)) + } + self.assertEqual( + values.get("STEP_DELAY_MIN"), + "1.0", + msg=_policy_msg( + "POLICY-RPA-005", + RPA_005_SOURCE, + f"STEP_DELAY_MIN must default to 1.0, got {values.get('STEP_DELAY_MIN')!r}", + ), + ) + self.assertEqual( + values.get("STEP_DELAY_MAX"), + "3.0", + msg=_policy_msg( + "POLICY-RPA-005", + RPA_005_SOURCE, + f"STEP_DELAY_MAX must default to 3.0, got {values.get('STEP_DELAY_MAX')!r}", + ), + ) + + def _scan_sensitive_logging_assignments(skill_root: str) -> list[str]: offenders: list[str] = [] for path in _walk_files(skill_root, "scripts", suffix=".py"):