Keyguard Analyzer — 锁屏 Bug 分析 Skill 架构与安装
基于 Claude Code 的 MIUI/HyperOS 锁屏问题分析工具。内置知识库自动匹配 + 多 Agent 交叉质疑 + 3-5Why 根因分析 + 视频转场检测(SSIM+CLIP) + 个人技能蒸馏。
一、项目概述
解决什么问题
锁屏 bug 分析耗时长、依赖经验、新人上手慢。本系统:
- 内置 350+ 日志 TAG 定位信息,自动匹配已知模式
- 采用 多 Agent 交叉质疑,结论必须经受互相推翻才能输出
- 视频 SSIM+CLIP 转场检测,自动定位异常帧并生成三联图
- Phase 过渡卡点,结构性防止跳过验证步骤
- 个人技能蒸馏,团队分析经验自动提取、共享复用
- 强制日志+时间点,杜绝无依据猜测
核心指标
| 指标 | 数据 |
|---|---|
| Skill 版本 | v3.11.0 |
| 知识库模块 | 13 个 |
| 日志 TAG 定位 | 350+ 条(含 file:line) |
| 功能点覆盖 | 200+ |
| 已知模式 | P1-P25 |
| 时序陷阱 | T1-T16, AT1-AT11 |
| 分析案例 | Case-001 ~ Case-022 |
| 自动化脚本 | 5 个(extract/init/grep/kb-match/prep) |
| 视频分析 | SSIM + CLIP 语义(走 hf-mirror.com 国内镜像) |
二、安装
Linux / macOS / WSL:
git clone git@git.n.xiaomi.com:keyguard/keyguardknowledge.git /tmp/kb-install && bash /tmp/kb-install/install.sh && rm -rf /tmp/kb-installWindows(Git Bash 中执行,不是 PowerShell):
git clone git@git.n.xiaomi.com:keyguard/keyguardknowledge.git "$TEMP/kb-install" && bash "$TEMP/kb-install/install.sh" && rm -rf "$TEMP/kb-install"安装时需要输入 MiuiSystemUI 和 MiuiAod 的代码路径。安装过程自动完成:
- 写入 SKILL.md + 部署 5 个核心脚本
- 部署视频分析工具 (video-analyzer)
- 安装 Python 依赖 (opencv + numpy)
- 后台安装 CLIP 语义增强 (torch + open-clip-torch + ViT-B-32 模型)
- CLIP 安装完成后下次分析自动启用 SSIM+CLIP 模式
💡 仓库为 private,需要 SSH Key。失败请联系管理员开通权限。
三、使用方式
触发
| 方式 | 说明 |
|---|---|
| 自动 | 消息中出现锁屏/Keyguard/指纹/人脸/FOD/AOD 等关键词时自动加载 |
| 手动 | 输入 `/keyguard-analyzer` |
必须提供
| 项目 | 要求 | 缺少则 |
|---|---|---|
| 日志文件 | bugreport.zip / .7z / .log | 拒绝分析 |
| 问题时间点 | 精确到秒 | 拒绝分析 |
| 设备型号 | 建议(可自动提取) | 从 bugreport 提取 |
| 视频/截图 | UI 类建议 | 日志不够时要求补充 |
使用示例
分析这个指纹解锁后锁屏和设置页面重叠的问题。(问题描述要写清楚)
bugreport: /home/mi/下载/bugreport-2026-05-14.zip
时间点: 22:48:55
视频: /home/mi/下载/recording.mp4
管理命令
| 命令 | 功能 |
|---|---|
| `/keyguard-analyzer set-repo <仓库地址>` | 切换知识库仓库 |
| `/keyguard-analyzer set-code | 切换代码目录 |
四、分析流程
流程总览
Phase 0: 前置检查(keyguard-extract.sh 一键完成)
├→ git pull 知识库 + 版本自动更新
├→ 强制校验: 日志 + 时间点
├→ 一键处理: 解压→版本提取→分支切换→日志预过滤→视频SSIM/CLIP检测
├→ 预计算: TAG频率统计 + 状态跳变提取 + git commit定位 + 问题域推荐
└→ 轻量画像匹配(grep 关键词,~200 tokens)
Phase 1: 规划
├→ keyguard-kb-match.sh 脚本化匹配(替代 AI 读 274 行 index.md)
├→ 现象→原因快速映射
├→ 置信度评估
└→ ★ Phase 1→2 过渡卡点(强制输出"待验证声明")
Phase 2: 多 Agent 竞争 + 交叉质疑
├→ Agent A/B/C 并行输出假设
├→ 交叉质疑(5 条必问,淘汰答不上来的)
├→ Evaluator 评分(从幸存者中选最优)
└→ ★ Phase 2→3 过渡卡点(强制输出"质疑验证表")
Phase 3: 3-5Why 根因分析
└→ 每层日志+代码双证据,到达 file:line 即停
Phase 4: 自审(10 项检查清单)
Phase 5: 输出 + 沉淀
├→ 结构化报告(强制按 output-format.md 模板)
├→ 知识库沉淀(用户确认后 push)
└→ 个人画像蒸馏
4.1 Phase 0: 一键预处理 + 预计算
~/.claude/skills/keyguard-analyzer/scripts/keyguard-extract.sh <bugreport> <时间点> [视频]脚本输出 JSON 包含:
| 字段 | 说明 | 减少 token |
|---|---|---|
| `device` | 设备/版本/构建日期 | — |
| `branches` | 目标分支+当前分支+是否已切换+commit SHA | 省去 AI 执行 git 命令 |
| `suggested_domain` | 问题域推荐(fingerprint/face/aio/charge/transition…) | 省去 AI 扫描判断 |
| `tag_frequency` | TOP 12 TAG 出现频率 | 省去 AI 逐行统计 |
| `state_transitions` | 关键状态跳变序列(前20条) | 省去 AI 逐行扫描 |
| `video_result` | 视频分析 result.json 路径 | — |
| `heuristic_matches` | 画像启发式命中结果 | — |
视频分析优先级:
- `keyguard-video-analyze` 二进制(SSIM+CLIP,最快)
- `python3 video_analyzer.py`(SSIM+CLIP,需 opencv+torch)
- ffmpeg 基础抽帧(兜底)
4.2 Phase 1→2 过渡卡点(防跳过规则)
🎁 历史教训:binder 延迟 4017ms 看起来是根因,但实际上即使没有延迟按键也会被防误触拦截——把”伴随现象”当成了”根因”。
Phase 1 结束时必须输出:
当前假设: <一句话>
置信度: X%
可能推翻此假设的质疑点:
1. 如果去掉这个异常事件,问题是否仍然会发生?
2. 这个事件是"原因"还是"伴随现象/结果"?
3. 这个触发条件每次操作都满足吗?
4. 是否有其他更上游的原因导致了这个事件?
Phase 2 需要验证: Agent A 查..., Agent B 查..., Agent C 查...
Phase 2 结束时必须输出:
质疑验证表:
| # | 质疑 | 回答 | 证据 |
|---|------|------|------|
| 1 | 去掉这个异常问题仍发生? | 否,因为... | [时间戳] TAG: ... |
| 2 | 原因还是伴随现象? | 原因,因为... | file:line ... |
| 3 | 触发条件每次都满足? | ... | ... |
| 4 | 能解释"发生"和"不发生"? | ... | ... |
| 5 | Phase 1 质疑都已验证? | 是 | 逐条确认 |
任何一条为空 → 不得进入 Phase 3,回到 Phase 2 补充。
4.3 Phase 2: 三 Agent + 交叉质疑 + 评分
三 Agent 并行
| Agent | 视角 | 核心策略 | 输出 |
|---|---|---|---|
| A: 白盒 | 纯日志推理 | TAG 组合过滤,不看知识库 | 事件时间线 + 假设 |
| B: 知识驱动 | 匹配已知模式 | 启发式 + 版本校验 | 模式编号 + 证据 |
| C: 代码追踪 | 从非预期事件反向追踪 | 6 种异常类型分类 | 调用链 + file:line |
交叉质疑(核心机制)
不是”选最好的”,而是”互相推翻→收敛→才输出”。5 条质疑必问:
| 问题 | 目的 |
|---|---|
| 截图内容属于你说的这个对象吗? | 排除找错目标 |
| 截图时间点该对象确实可见吗? | 排除已消失对象 |
| 去掉这个事件问题仍发生吗? | 排除伴随现象 |
| 触发条件每次都满足?为什么只出现一次? | 验证偶现性 |
| 能同时解释”出现”和”正常不出现”吗? | 验证充分必要性 |
Evaluator 评分
| 维度 | 权重 | 说明 |
|---|---|---|
| 证据完整性 | 30% | 每层 Why 有日志+代码双证据 |
| 解释力 | 25% | 能解释所有异常日志 |
| 可验证性 | 20% | 修复方案有具体 file:line |
| 偶现性解释 | 15% | 精确解释为什么只出现一次 |
| 排他性 | 10% | 排除了其他可能根因 |
4.4 Phase 3: 3-5Why 根因分析
层数不强制 5 层,到达可修复 file:line 即停。每层必须有日志 + 代码双证据:
Why-1: 为什么锁屏不消失?
→ 日志: [22:48:55.433] KeyguardViewMediator: useMiuiKeyguardUnlockHide
→ 代码: KeyguardViewMediatorInjector.kt:799 — 进入 MIUI 解锁隐藏流程
Why-2: 为什么解锁流程卡住?
→ 日志: 有 "onBegin" 但 39s 后才被 purge(无 onComplete)
→ 代码: KeyguardUnlockAnimationControllerExt.kt:229 — onComplete 未触发
Why-3: 为什么 onComplete 未触发?
→ 日志: [22:48:55.512] miuix_anim: task:null failed
→ 代码: SurfaceControl 已 release,Folme 动画回调永远不触发
4.5 视频转场检测
工具:`tools/video-analyzer/video_analyzer.py`(自研,不依赖第三方视频分析服务)
核心概念解释
| 术语 | 通俗解释 | 在锁屏分析中的作用 |
|---|---|---|
| SSIM(结构相似性指数) | 比较两帧画面”有多像”的算法。值 0~1,1=完全一样,<0.5=画面剧烈变化。比逐像素对比更接近人眼感知 | 自动找到视频中”画面突然变化”的时刻(如闪帧、黑屏、界面切换),不需要人工逐帧查看 |
| CLIP(对比语言-图像预训练) | OpenAI 开源的 AI 模型,能理解”图片内容和文字描述是否匹配”。给它一张图+一句话,它打分说明匹配程度 | 用文字描述(如”密码页面""黑屏""指纹图标”)过滤出语义相关的帧,从几百帧中精准定位问题画面 |
| 三联图 | 转场前(before) → 变化帧(change) → 转场后(after) 三张截图组合 | AI 直接看三张图就能理解”发生了什么变化”,不需要看完整视频 |
| 动态阈值 | `mean(SSIM) - 1.5 × std(SSIM)`,根据视频自身特征自动计算”什么程度的变化算异常” | 不同视频(手持晃动 vs 固定录屏)有不同的”正常变化幅度”,动态阈值自适应,避免误报 |
| hf-mirror.com | HuggingFace 国内镜像站,下载 AI 模型用 | CLIP 模型约 350MB,走国内镜像下载快,不需要翻墙 |
算法流程
输入视频 + 问题时间点
↓
1. 屏幕自动检测(边缘检测 + 宽高比过滤,裁掉手/桌面)
↓
2. 抽帧(问题时间点 ±10秒,2fps)
↓
3. 逐帧计算 SSIM(与前一帧对比)
↓
4. 动态阈值筛选(低于阈值 = 画面突变 = 可能的异常)
↓
5. [可选] CLIP 语义过滤(用 --query "黑屏" 等文字进一步筛选)
↓
6. 输出 TOP 3 转场的三联图 + result.json
输出示例
/tmp/keyguard-analyze/frames/
├── result.json # 转场列表(时间戳/SSIM值/类型sudden|gradual)
├── transition_1_before.jpg # 转场前一帧
├── transition_1_change.jpg # 画面突变的那一帧
├── transition_1_after.jpg # 转场后一帧
├── transition_2_before.jpg
├── ...
`result.json` 示例:
{
"transitions": [
{"time": 45.5, "ssim": 0.32, "type": "sudden", "frame_number": 91},
{"time": 47.0, "ssim": 0.65, "type": "gradual", "frame_number": 94}
],
"total_frames": 40,
"threshold": 0.72
}- `ssim: 0.32` = 画面剧烈变化(比如从相机界面突然变黑屏)
- `type: sudden` = 突变(1帧内完成),`gradual` = 渐变(多帧过渡)
降级策略
| 环境 | 可用能力 | 说明 |
|---|---|---|
| opencv + torch + open-clip 全装 | SSIM + CLIP 语义 | 最佳体验,能用文字搜索画面 |
| 仅 opencv + numpy | 仅 SSIM | 能检测画面突变,不能语义搜索 |
| 仅 ffmpeg | 定时抽帧 | 每 0.5 秒截一张,AI 逐帧看 |
| 什么都没有 | 跳过视频 | 仅分析日志 |
五、分析纪律(10 条强制规则)
| # | 规则 |
|---|---|
| 1 | 双证据原则:每个结论必须同时有日志+代码证据,缺任一不输出 |
| 2 | 不猜测:证据不足立即停下,告知缺什么+怎么采集 |
| 3 | 版本必须对:代码分支必须与 bugreport 版本对应 |
| 4 | 覆盖全异常:显示/动画/触控/亮息屏/AOD/壁纸/功耗/崩溃 |
| 5 | 深度结合架构:AllInOne/StateFlow/Folme/Dagger/高通/MTK/玄戒 |
| 6 | 区分必现/偶现:必现→确定性条件;偶现→竞态/时序/生命周期 |
| 7 | 深挖隐性异常:流程断点/线程阻塞/状态不一致/重复执行 |
| 8 | 专注锁屏:只深入 Keyguard+SystemUI,其他模块定位到边界 |
| 9 | 精准定性:代码 Bug / 时序缺陷 / 配置错误 / 平台适配 / 设计缺陷 |
| 10 | 边界场景覆盖:低内存/待机/冷热启动/功能开关/多用户/折叠 |
总原则:宁缺毋滥 —— 错误的知识比没有知识更有害。
六、个人技能蒸馏
分析完成后 AI 自动提取认知,格式化呈现给用户确认。
蒸馏内容
| 类型 | 含义 | 精准要求 |
|---|---|---|
| 心智模型 (M) | 分析时的思考框架 | 三重验证 + ≥2 场景验证 |
| 决策启发式 (H) | “看到 X→大概率 Y” | 含 grep 关键词 + 案例验证 |
| TAG 组合 | 特定问题的日志过滤 | 本次分析验证有效 |
| 排查路径 (P) | 固定排查步骤 | 每步可执行 + 有终止条件 |
| 反模式 (A) | 踩过的坑 | 说明为什么是弯路 + 正确做法 |
蒸馏触发条件
分析完成后自动执行蒸馏检查(5 个条件任一命中则触发):
- 方向性转折(分析过程中推翻了初始假设)
- 用户纠正 AI(最高优先级沉淀)
- 知识库未覆盖的新模式
- 排查路径优于通用流程
- 二次验证已有候选
跨人复用
分析时 grep 所有画像的关键词行,命中时提示:
“huyubao 的启发式 H3 命中(miuix_anim task:null),是否参考其排查路径?“
七、知识库
结构
keyguardknowledge/(GitLab 仓库)
├── install.sh # 安装脚本(版本号控制自动更新)
├── index.md # 总索引
├── scripts/ # 核心脚本(安装时复制到 skill 目录)
│ ├── keyguard-extract.sh # Phase 0 一键处理
│ ├── keyguard-init.sh # 版本检查+画像匹配
│ ├── keyguard-grep.sh # 精准日志过滤
│ └── keyguard-kb-match.sh # 知识库关键词匹配
├── tools/ # 工具(安装时部署)
│ └── video-analyzer/ # SSIM+CLIP 视频转场检测
│ ├── video_analyzer.py
│ ├── requirements.txt
│ ├── build.sh
│ └── README.md
├── LockscreenUnlock/ # 解锁(指纹/人脸/密码/其他)
├── LockscreenUI/ # 显示(转场/AIO/画报/充电/触摸/渲染)
├── aod/ # AOD
├── device/ # 设备适配
└── common/
├── analysis-methodology.md # 分析方法论
├── output-format.md # 输出格式模板
├── symptom-cause-map.md # 现象→原因映射表
├── feature-tree.md # 200+ 功能点
├── rules.md # 工作规范
├── distill-rules.md # 蒸馏规则
└── analyst-profiles/ # 个人画像(按 git 用户名)
自动更新
`install.sh` 顶部 `INSTALLER_VERSION` 控制版本。改内容+改版本号→push→全员下次分析时自动更新(包括脚本和工具)。
八、Token 优化策略
| 优化项 | 方式 | 节省 |
|---|---|---|
| 预计算注入 | extract.sh 输出 TAG频率/状态跳变/commit/domain | ~2,500 tokens |
| KB 匹配脚本化 | keyguard-kb-match.sh 替代读 274 行 index.md | ~4,000 tokens |
| grep 输出精简 | MAX_LINES 默认 50(原100) | ~2,000 tokens |
| Phase 过渡卡点 | 强制输出结构化验证(而非自由推理) | 减少无效推理 |
总计节省约 8,500 tokens/次分析,整体减少 ~20%。
九、常见问题
Q: 安装后没有识别 skill? 重启 Claude Code 或确认 `~/.claude/skills/keyguard-analyzer/SKILL.md` 存在。
Q: CLIP 安装很慢? 后台下载 ~2GB,不影响使用。安装完成前用 SSIM 模式分析视频,完成后自动切换 SSIM+CLIP。
Q: Windows 报错? 必须在 Git Bash 中执行,不是 PowerShell。
Q: git clone 失败? 仓库为 private,需要 SSH Key + GitLab 权限。联系管理员。
Q: 如何卸载?
rm -rf ~/.claude/skills/keyguard-analyzer