sop-generate — 业务 SOP 生成
Overview
给一个已部署、可访问的 Web 应用生成中文业务操作手册:谁在什么环节、在哪个页面、做什么操作、系统自动做什么、异常怎么办,并配真实截图与至少一个可复现的使用样例。
核心分工(参照 Flaex/web-app-tutorial-generator):脚本只管截图和抓 DOM/accessibility 摘要,Claude 只管读摘要写文案。绝不把整页截图喂给模型做文案——省 token,也省时间。
硬规则(贯穿全流程,违反即返工):
- 凭据绝不写入产出文档,也绝不经命令行参数传递。测试账号的用户名/密码/token 只能出现在你与用户的对话、本地
.env读取、或传给降级脚本的环境变量(SOP_USER/SOP_PASS)里;docs/SOP-*.md、docs/sop-images/及其任何提交物中一律不出现真实凭据。手册里提到登录时写"使用测试账号登录"而非具体值。调用<本 skill base directory>/scripts/crawl.mjs时凭据只经环境变量传入(SOP_USER=... SOP_PASS=... node ...),不出现在--user/--pass命令行参数里——argv 会落进 shell history、ps aux可见的进程列表、以及会话 transcript,即使脚本本身不回写文件,凭据也已经泄漏到这几处。 - 业务黑话首次出现必须解释(如"红点/非红点"这类项目内部术语)。
- 页面矩阵必须全覆盖——遍历到的每个页面、每个功能点都要在矩阵里出现,不允许"看起来不重要就跳过"。
- 样例必须真实走一遍,不能编造操作结果;截图即证据。
技术路线
- 优先:
microsoft/playwright-mcp(Apache-2.0)。检查是否已配置:
若已配置,直接用 MCP 工具做导航/快照/截图,不写脚本。claude mcp list | grep -i playwright - 降级:未配置 MCP 时,用本 skill 自带的原生 Playwright Node 脚本
<本 skill base directory>/scripts/crawl.mjs(登录→遍历→截图三段式;用绝对路径调用,因为执行时 cwd 是被测项目根目录,相对路径scripts/crawl.mjs解析不到)。首次用需要npm install playwright或已有全局安装;脚本会自检并报缺失依赖的安装命令,不擅自静默安装。凭据经环境变量传入(见硬规则 1),例如:
能力落差:该脚本只负责静态页面的首轮采集,每页产出一张全页截图 + accessibility 摘要,不做步骤 3 要求的"关键操作前/后两张"截图——那需要脚本感知具体的点击/表单提交动作。脚本支持可选的SOP_USER='<测试账号>' SOP_PASS='<密码>' node <本 skill base directory>/scripts/crawl.mjs --url <部署URL> --out docs/sop-images--actions <json文件>参数,传入一份动作清单([{name, url, click}],可选 before/after 字段仅作截图文件名后缀;权威格式见 scripts/crawl.mjs 文件头注释)即可对指定操作做前/后两张截图;不传时关键操作的 before/after 需改走 MCP 手动截取,或临时写一段一次性 Playwright 片段,不能只靠full.png交差。 - 反检测浏览器(browser-use/camoufox 等)已在 2026-08-03 调研中排除:对确定性遍历的内网/已授权系统是负收益,不引入。
- 省 token 设计(借鉴 westpoint-io/mimik):每页产出两样东西——
- accessibility snapshot 或精简 DOM 摘要(可交互元素 role/name/位置)→ 喂给 Claude 写操作说明;
- 截图文件 → 只存盘、只在最终 SOP 里以
![]()引用路径,不整图上传给模型做文案。
五步流程
1. 输入采集
- 项目根目录:读
HANDOVER.md(若已由交接文档包生成)、BUSINESS.md、REQUIREMENTS.md,提炼业务流程与角色列表(谁、在什么环节)。没有这些文档就问用户要业务背景。 - 部署 URL:优先从
HANDOVER.md/DEPLOYMENT.md或.env里的APP_URL/BASE_URL类变量取;取不到就问用户。 - 测试账号:优先从项目
.env(本地读取,不外传)取;没有就问用户要一个专用测试账号,并向用户确认"这不是真实业务账号"。读到即用,绝不回显在任何写盘文档里;走降级脚本时通过SOP_USER/SOP_PASS环境变量传入,不写进命令行参数(见硬规则 1)。
2. 页面清单
- 用测试账号登录后,从导航结构(顶栏/侧栏菜单、路由表若可读)枚举全部页面。
- 与步骤 1 提炼的功能清单对照,产出一张"页面 × 功能"矩阵(先在草稿里列出,验收时核对全覆盖)。
3. 遍历截图
- 建议前置:若已安装
ui-sweep插件,批量截图前先跑一遍全站交互遍历(把每屏可交互元素系统性点一遍),能提前揪出交互异常,避免截图记录了带缺陷的界面状态而不自知;未安装则跳过此步,不影响后续流程。 - 逐页面逐功能截图,存
docs/sop-images/<页面slug>/(页面 slug 用页面英文路由名或拼音,不用中文文件名避免部分工具乱码)。 - 关键操作(提交表单、导出报表、触发批处理等有副作用或状态变化的操作)截操作前/操作后两张,文件名加
-before/-after后缀。 - 每张截图旁边记一句该页/该状态的 accessibility 摘要要点(供步骤 4 写文案用,不必逐字保留全量摘要)。
4. 成文
产出 docs/SOP-<业务名>.md,按业务流程顺序组织,不是按页面顺序——同一个业务环节可能横跨多个页面,合在一节里讲。每个业务环节包含:
- 谁(角色)
- 在哪个页面(链接/路由 + 截图)
- 做什么操作(配截图,步骤化)
- 系统自动做什么(免得读者以为要手工做本该自动的事)
- 异常怎么办(常见报错、边界情况、找谁兜底)
- 每份 SOP 至少一个真实使用样例——用测试数据完整走一遍业务流程的记录,附截图,证明手册可复现
若旧版 SOP 已存在(如某报表系统项目里的《SOP-报表系统全流程》),对照校准:旧版通常缺页面截图和使用样例这两块,这是新版必须补齐的差距,其余内容(口径、术语解释)可参考旧版但要按新结构重组,不是简单拼接。
5. 验收自检
产出后逐条自查,任一项不过就回到对应步骤补:
- 页面矩阵全覆盖(步骤 2 的矩阵里每一项在正文里都能找到对应段落)
- 每个功能点至少一张截图,关键操作有前/后两张
- 至少一个使用样例,且步骤可按文档复现(自己按文档说的点一遍,能得到一致结果)
- 全文搜索一遍确认无真实凭据(用户名/密码/token/API key)残留
- 业务黑话首次出现有解释
- UTF-8 无乱码
网络不可达时的降级交付
若目标部署 URL 在当前环境不可达(如需要 Tailscale/内网,当前会话连不上):
- 不产出 SOP 正文,改为产出可执行 runbook:
docs/SOP-<业务名>-runbook.md,按<本 skill base directory>/references/runbook-template.md填写——内容是"网络恢复后按此脚本/步骤跑一遍即可自动生成 SOP 草稿",包含已采集好的业务流程骨架(角色/环节/页面清单,能提前从文档拿到的部分)+ 待执行的遍历截图命令。不要脱离模板重新手搓结构,避免与模板漂移。 - 明确告知用户这是待办,列出触发条件(如"接入 Tailscale 后重跑
<本 skill base directory>/scripts/crawl.mjs")。 - 不得为了交付而编造截图或臆造页面结构。
试点策略
首次使用时,优先在有旧版手册的项目上打样,用旧版校准新版的详略程度和术语解释粒度,再推广到没有旧版参照的项目。校准过程中若发现新旧口径冲突(如旧版某个数字/规则已过时),以项目当前文档(HANDOVER.md/DECISIONS.md/代码现状)为准,SOP 里不沿用旧版的过时说法。
Common mistakes
| 错误 | 纠正 |
|---|---|
| 把整页截图传给模型写文案 | 只传 accessibility/DOM 摘要;截图只存盘引用 |
| SOP 按页面顺序罗列("首页有什么、报表页有什么") | 必须按业务流程顺序——同一环节跨页面时合并讲 |
| 测试账号密码写进 SOP 方便"以后照着填" | 绝不写入任何产出文档,只在对话/本地 .env 里出现 |
| 网络不通就跳过、什么都不产出 | 降级产出 runbook,骨架用已有文档提前搭好 |
| 术语("红点"这类)不解释直接用 | 首次出现必须一句话解释业务含义 |
| 只截"正常路径"没有异常截图 | 关键操作要前/后对照;异常怎么办至少文字说明,有截图更好 |
| 有旧版 SOP 就直接复制改个格式 | 旧版只用于校准详略/术语粒度,截图和样例必须重新做 |
调用 crawl.mjs 时用 --user/--pass 传密码图省事 |
用 SOP_USER/SOP_PASS 环境变量;argv 会落进 shell history 与 ps aux,即使脚本不落盘也已经泄漏 |
| 遍历导航链接时把"退出登录"也点了 | 脚本已按关键词/同源/协议过滤,若自己临时写遍历代码也要照做,否则 session 作废后续全是登录页截图 |
hash 路由 SPA 只信 domcontentloaded/networkidle 就截图 |
客户端内路由跳转不触发浏览器原生导航事件,这两个事件几乎立即通过,而页面数据是路由切换后才由前端异步发起的;实测除首次真实整页加载外,后续每个 hash 内跳转截图都会拍到"加载中…"半成品。crawl.mjs 已在每次 goto 后追加 waitForAppReady(轮询等待"加载中"类文案消失)兜底,自己写遍历代码时也要照做,不能只等 networkidle |
忽略登录页(/login 等独立路由)不在矩阵里 |
遍历脚本按设计不会顺着已登录会话把登录页也走一遍(会拿到"已登录自动跳转"的假页面),登录页需要额外用无 cookie 的新 context 单独截图,且要覆盖登录失败/异常态,不能只写一句"用账号登录" |