Skip to content

mufans/AppSmartInspector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

223 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SmartInspector

AI 驱动的跨平台移动端性能分析 CLI 工具。通过自然语言交互,自动采集设备性能 trace,分析性能瓶颈,并将热点归因到源码。

当前已实现 Android 平台完整支持,HarmonyOSiOS 平台支持规划中。

特性

  • 🧠 自然语言交互 — 用中文描述性能问题,AI 自动路由到对应分析流程
  • 📊 全量分析流水线 — 自动采集 → 分析 → 源码归因 → 报告生成
  • 🔍 SI$ 源码归因 — 通过 TraceHook tag 将性能热点精确归因到源码位置(含 IO 切片归因)
  • 🛡️ 健壮性保障 — 全链路异常处理,Agent 崩溃不丢会话状态
  • Token 效率优化 — SQL 结果智能压缩(统计摘要+异常采样)、消息窗口裁剪、路由 token 限制、流式输出
  • 分析质量验证 — L1 格式检查 + L2 一致性验证,自动检测 LLM 输出遗漏和不一致,支持重试补充
  • 🔒 Release 零开销 — Release 变体为纯 no-op stubs,编译器内联后零运行时开销
  • 💬 实时通信 — WebSocket CLI↔App 双向通信,支持心跳检测和断线重连
  • 🖥️ Perfetto UI 交互 — 自托管 Perfetto UI + SI Bridge 插件,框选时间范围即可 AI 分析
  • ⌨️ 交互增强 — Tab 补全、全局异常保护、启动前置条件检查
  • 🚀 冷启动分析 — 自动识别启动阶段(进程启动→Application.onCreate→Activity.onCreate→首帧),定位启动瓶颈
  • 🤖 Headless/CI 模式 — 非交互式运行全量分析流水线,支持 JSON 结构化输出,可直接集成 CI/CD
  • 🌐 IO 追踪 — 默认启用网络/数据库/图片加载 IO Hook,独立收集 IO 切片并归因到源码
  • 🔬 Perfetto Stdlib 模块 — 11 个 stdlib 模块深度分析:锁竞争、Binder 事务、启动指标(TTID/TTFD)、GC 事件、ANR 检测、Slice CPU 时间、输入延迟分解、调度延迟、OOM/RSS/Swap、CPU 利用率、SurfaceFlinger 帧匹配
  • 🧩 维度注册体系 — 7 个可扩展分析维度(锁竞争/调度延迟/GC/文件IO/内存趋势/Binder/CPU降频),插件式架构,@register_dimension 装饰器自动注册
  • 📚 Prompt Skill 系统 — 知识/指令分离架构,维度专家知识按需注入 LLM,每个 Agent 只加载所需领域知识

快速开始

# 安装依赖
uv sync

# 配置 LLM(复制示例配置并填入 API Key)
cp .env.example .env
# 编辑 .env: SI_API_KEY=your-api-key

# 启动 CLI(自动检查 adb/API key,启动 WS server + adb reverse)
uv run smartinspector --src /path/to/your/app/source

# adb连接手机

# 交互式使用(支持 Tab 补全 slash 命令)
# 自然语言开启采集和分析
you> 分析冷启动耗时
# 指令开启采集分析
you> /full
# 冷启动分析(跳过等待,直接开始采集)
you> /full --no-wait
# 打开perfetto ui
you> /open

CI/Headless 模式

非交互式运行全量分析流水线,适合 CI/CD 集成:

# 分析已有 trace 文件,输出 JSON 报告到 stdout
uv run smartinspector --ci --trace trace.pb --format json --src ./app/src

# 从设备采集 trace 并生成 Markdown 报告到文件
uv run smartinspector --ci --target com.example.app --duration 5000 --output report.md

# JSON 格式输出示例(适合自动化解析)
uv run smartinspector --ci --trace trace.pb --format json | jq '.issues[] | select(.severity == "P0")'

MCP Server

SmartInspector 提供 Model Context Protocol (MCP) Server,将所有分析指令暴露为 MCP Tools,供外部 AI Agent(Claude Desktop、OpenClaw、Cursor 等)直接调用。

安装与启动

# 安装依赖(mcp 已包含在项目依赖中)
uv sync

# 启动 MCP Server(stdio transport)
uv run si-mcp

si_init 统一初始化

首次使用时调用 si_init 完成会话配置,参数在整个会话中持久化:

si_init(
    source_dir="/path/to/app/source",   # 源码目录(源码归因需要)
    target_process="com.example.app",   # 默认目标包名
    debug=False,                        # 启用 debug 日志
    api_key="your-api-key",             # LLM API Key(也可通过环境变量设置)
    base_url="https://api.deepseek.com", # API Base URL
    model="deepseek-chat"               # LLM 模型名
)

核心工具

工具 说明
si_full 全量流水线:采集 → 分析 → 源码归因 → 报告
si_trace 采集 + 分析 trace(跳过归因)
si_analyze 分析已有 trace 文件
si_startup 冷启动分析(自动 force-stop + 启动 App)
si_quick 快速确定性分析(不调用 LLM,秒级完成)
si_ci_analyze CI/自动化非交互分析,支持 JSON 输出
si_compare 对比两份分析报告

完整工具列表(23 个)和参数说明见 docs/mcp-server.md

Claude Desktop 配置

~/Library/Application Support/Claude/claude_desktop_config.json 中添加:

{
  "mcpServers": {
    "smartinspector": {
      "command": "uv",
      "args": ["run", "si-mcp"],
      "env": {
        "SI_API_KEY": "your-api-key"
      }
    }
  }
}

OpenClaw 配置

mcp_servers:
  - name: smartinspector
    command: uv
    args:
      - run
      - si-mcp
    env:
      SI_API_KEY: your-api-key

架构概览

SmartInspector 架构图

全量分析管线:collector (Trace 采集 + SQL) → analyzer (LLM 性能解读) → attributor (SI$ → 源码归因) → reporter (Markdown / JSON 报告)

Perfetto UI 交互分析

用户在 Perfetto UI 框选时间范围
  → SI Bridge Plugin (WebSocket client)
  → BridgeServer (ws://127.0.0.1:9877/bridge)
  → frame_analyzer agent (查询切片 → 源码归因 → LLM 分析)
  → 结果回传 Perfetto UI 展示(实时进度 + Markdown 报告)

Perfetto UI 交互帧分析

使用 /open 启动自托管 Perfetto UI 后,在时间轴上拖选一段范围,点击右侧 SI Frame Analysis 面板中的 Analyze with SI Agent 按钮。分析过程中实时显示查询进度、源码归因工具调用(Glob/Grep/Read)和 LLM 分析状态,最终在面板中展示 Markdown 格式的帧分析报告。

  • /frame ts=X dur=Y CLI 直接分析指定时间范围
  • 插件自动重连,进度实时推送,归因过程透明可见

构建 Perfetto UI 插件

使用 perfetto-plugin/build.sh 构建包含 SI Bridge 插件的自托管 Perfetto UI:

前置条件: Node.js >= 18、npm、git

# 首次构建(clone Perfetto + 复制插件 + 编译)
./perfetto-plugin/build.sh

# 后续构建(跳过 clone,仅重新编译)
./perfetto-plugin/build.sh --skip-clone

构建脚本会自动完成以下步骤:

  1. Clone Perfetto 仓库(shallow clone)到 perfetto-build/
  2. 复制 SI Bridge 插件到 Perfetto 插件目录
  3. default_plugins.ts 中注册插件
  4. 执行 ui/build 编译(含依赖安装、TypeScript 编译、WASM)

构建产物输出到 perfetto-build/ui/out/dist/,可通过 /open 命令启动自托管 Perfetto UI。

注意: 脚本会自动移除 PATH 中的 Android NDK strip 以避免 macOS 上 Mach-O arm64 兼容性问题。如需代理,请提前设置 http_proxy/https_proxy

健壮性设计

全链路异常处理,确保单节点失败不影响整体会话:

REPL 主循环 ─── 全局 try/except,异常后保留 state 继续输入
  └── graph.stream() ─── try/except,异常后打印 [error] 不崩溃
       └── orchestrator LLM ─── try/except,失败走 fallback
            └── 各节点 ─── node_error_handler 装饰器统一捕获

详细架构见 ARCHITECTURE.md

维度注册体系

维度注册体系提供插件式架构,将性能分析能力拆分为独立的、自包含的分析维度。每个维度封装了从 SQL 采集到预计算结论的完整逻辑。

架构

AnalysisDimension (ABC)
  ├── collect(tp) → dict        # SQL 查询采集
  ├── compute_hint(data, ctx)   # 确定性预计算(不调用 LLM)
  ├── format_section(data)      # Markdown 格式化(供 LLM 消费)
  ├── metric_filter(data)       # Metric QA 数据过滤
  ├── skill_name                # 关联的专家知识文件
  └── metric_triggers           # 自然语言触发词

已注册维度(7 个内置维度):

维度 SQL 数据源 Hint 触发条件 Metric 触发词
lock_contention __intrinsic_thread_state (futex) 主线程 >5ms,其他 >10ms 锁竞争/lock/futex
sched_latency sched.runnable stdlib 模块 平均延迟 > 帧预算 50% 调度延迟/runnable
gc_events slice (GC/GarbageCollector) pause >10ms 或超过帧预算 gc/垃圾回收
file_io __intrinsic_thread_state (io_wait) 主线程 IO >5ms 文件io/磁盘
memory_trend process_counter_track (mem.rss) RSS 增长 >20% 内存趋势/内存泄漏
binder_ipc __intrinsic_thread_state (binder) 主线程 binder 等待 >10ms binder/ipc/跨进程
cpu_throttling cpu_counter_track + counter 平均频率 < 最大频率 50% 降频/throttling

扩展新维度

  1. 创建 src/smartinspector/collector/dimensions/<name>.py
  2. 继承 AnalysisDimension,用 @register_dimension 装饰
  3. 实现 collect() 方法(必需),可选实现 compute_hint()/format_section()/metric_filter()
  4. 添加专家知识到 prompts/skills/dimensions/<name>.md
  5. 下次流水线运行时自动发现(DimensionRegistry.discover()

Prompt Skill 系统

Prompt Skill 系统将 LLM 指令与领域知识分离,实现按需加载:每个 Agent 只注入其所需的专业知识,避免无关上下文干扰。

目录结构

prompts/
├── *.txt                          # LLM 指令模板(行为定义)
└── skills/
    ├── SKILL.md                   #   Skill 索引
    ├── shared/                    #   共享知识(所有 Agent 共用)
    │   ├── si-tag-system.md       #     SI$ 标签体系说明
    │   └── search-strategy.md     #   源码搜索策略
    └── dimensions/                #   维度专家知识(按需注入)
        ├── lock-contention.md     #     锁竞争分析知识
        ├── cpu-scheduling.md      #     CPU 调度分析知识
        ├── cpu-throttling.md      #     降频分析知识
        ├── gc-analysis.md         #     GC 分析知识
        ├── io-analysis.md         #     IO 分析知识
        ├── memory-analysis.md     #     内存分析知识
        ├── binder-ipc.md          #     Binder IPC 分析知识
        ├── startup.md             #     启动分析知识
        └── ui-jank.md             #     UI 卡顿分析知识

API

函数 用途
load_prompt(name) 加载 prompts/{name}.txt 指令模板
load_skill(name, category) 加载 prompts/skills/{category}/{name}.md 知识文件(缓存)
load_prompt_with_skills(name, *skills) 加载指令 + 追加多个 skill 知识

Skill 引用格式

  • "gc-analysis"prompts/skills/dimensions/gc-analysis.md
  • "shared:si-tag-system"prompts/skills/shared/si-tag-system.md

设计原则

  • 知识/指令分离:指令(.txt)定义 Agent 行为规则,知识(.md)提供领域事实
  • 按需加载:Agent 根据当前分析任务动态组合需要的知识文件
  • 维度关联:每个维度通过 skill_name 属性自动关联对应的专家知识

平台支持

平台 状态 Trace 采集 方法 Hook 源码归因
Android 已实现 Perfetto + adb Pine AOP 支持
HarmonyOS 规划中 hdc + hiperf/hitrace
iOS 规划中 Instruments + Xcode

Android

  • Trace 采集:Perfetto (ftrace + atrace + CPU callstack + Java heap + 系统级 CPU + 11 个 stdlib 模块 + 7 个维度注册模块)
  • 方法 Hook:Pine AOP 框架,运行时 hook Activity/Fragment/RecyclerView 等框架方法
  • 卡顿检测:BlockMonitor (BlockCanary-style),监测主线程每条 Message 耗时,容量限制防 OOM
  • 通信:WebSocket (adb reverse),CLI ↔ App 实时配置同步 + 数据传输
    • Ping/Pong 心跳检测僵尸连接
    • 配置下发带 msg_id + ACK 确认
    • WS server ready event 防止启动竞态条件
    • WS server 启动异常不再静默吞掉
  • Release 变体:纯 no-op stubs,编译器内联后零运行时开销
  • Hook 安全:嵌套深度保护防 atrace 溢出,Tag 超 127 字节自动截断

HarmonyOS (规划)

  • Trace 采集:hdc + hiperf/hitrace
  • 方法 Hook:待定
  • 已有 prompt 模板:reference-hdc-commands.txt

项目结构

smartinspector/
├── src/smartinspector/              # Python CLI + Agent
│   ├── cli.py                      #   CLI 入口 (argparse)
│   ├── graph/                      #   LangGraph 编排 (模块化包)
│   │   ├── __init__.py             #     公共导出 (create_graph, run_graph, main)
│   │   ├── builder.py              #     LangGraph 图构建 (节点+边+条件路由)
│   │   ├── cli.py                  #     CLI REPL 主循环 (prompt_toolkit, Tab补全, 全局异常保护)
│   │   ├── state.py                #     AgentState + RouteDecision + pass-through
│   │   ├── streaming.py            #     图流式执行 (_stream_run, MemorySaver, 错误处理)
│   │   └── nodes/                  #     LangGraph 图节点
│   │       ├── orchestrator.py     #       路由分类 + fallback (few-shot, 异常处理)
│   │       ├── android.py          #       Android Expert (trace 采集+分析)
│   │       ├── analyzer.py         #       性能分析 (perf_analyzer_node + analyzer_node)
│   │       ├── explorer.py         #       源码搜索 (grep/glob/read)
│   │       ├── collector.py        #       设备 trace 采集 (PerfettoCollector, WS+SQL block events 合并)
│   │       ├── attributor.py       #       源码归因 (SI$ slice → 源码定位, 结构化输出)
│   │       └── reporter/           #       报告生成
│   │           ├── __init__.py     #         reporter_node 入口 (流式输出)
│   │           ├── generator.py    #         LLM 报告生成 (流式+重试)
│   │           ├── formatter.py    #         数据格式化 (perf+归因→Markdown)
│   │           ├── json_formatter.py #       JSON 结构化报告格式化
│   │           └── persistence.py  #         报告文件保存
│   │
│   ├── agents/                     #   Agent 定义 (LLM + Tools)
│   │   ├── android.py              #     Android Expert Agent
│   │   ├── explorer.py             #     Code Explorer Agent
│   │   ├── perf_analyzer.py        #     Perf Analyzer (单次 LLM 调用 + 验证重试)
│   │   ├── attributor.py           #     源码归因 Agent (run_attribution)
│   │   ├── frame_analyzer.py       #     帧分析 Agent (Perfetto UI 交互归因)
│   │   ├── deterministic.py        #     确定性预计算 + SQL Summarizer (减少 LLM token)
│   │   └── verifier.py             #     分析质量验证 (L1 格式 + L2 一致性, 0 token)
│   │
│   ├── collector/perfetto.py       #   PerfettoCollector (adb→SQL→JSON, CPU调用链, 系统级CPU, 11 stdlib modules, 7 维度注册, context manager)
│   ├── collector/dimensions/       #   维度注册体系 (插件式分析维度)
│   │   ├── __init__.py             #     DimensionRegistry + @register_dimension
│   │   ├── base.py                 #     AnalysisDimension ABC + HintContext
│   │   ├── lock_contention.py      #     锁竞争维度 (futex)
│   │   ├── sched_latency.py        #     调度延迟维度
│   │   ├── gc_events.py            #     GC 事件维度
│   │   ├── file_io.py              #     文件 IO 维度
│   │   ├── memory_trend.py         #     内存趋势维度
│   │   ├── binder_ipc.py           #     Binder IPC 维度
│   │   └── cpu_throttling.py       #     CPU 降频维度
│   ├── collector/startup.py        #   冷启动分析器 (启动阶段切分, 关键路径提取, 瓶颈识别)
│   ├── collector/memory.py         #   内存分配分析器 (heap_graph, 泄漏检测, 内存趋势)
│   ├── headless.py                 #   Headless/CI 非交互式运行器 (全量流水线, JSON/Markdown 输出)
│   ├── storage/store.py            #   报告存储层 (基线管理, 历史查询, 对比数据源)
│   ├── commands/                   #   Slash 命令 (注册表模式)
│   │   ├── __init__.py             #     命令注册表 (handle_slash_command)
│   │   ├── attribution.py          #     SI$ tag 解析 + 归因提取
│   │   ├── device.py               #     设备管理 (/devices, /connect)
│   │   ├── hook.py                 #     Hook 配置 (/config, /hooks)
│   │   ├── orchestrate.py          #     编排命令 (/full, /report)
│   │   ├── session.py              #     会话管理 (/help, /clear)
│   │   └── trace.py                #     Trace 采集 (/trace, /record, /open, /close, /frame)
│   │
│   ├── tools/                      #   LangChain 工具 (grep/glob/read/perfetto)
│   │   └── path_utils.py           #     共享路径校验 (防目录遍历)
│   ├── ws/server.py                #   WebSocket Server (心跳检测, ready event, 动态端口)
│   ├── ws/bridge_server.py         #   Perfetto UI Bridge Server (自托管 UI + WS 桥接)
│   ├── prompts.py                  #   Prompt 文件加载器
│   ├── config.py                   #   全局配置 (LLM 模型, source dir, hook config 持久化, 环境变量覆盖)
│   ├── token_tracker.py            #   LLM Token 使用量追踪
│   └── perfetto_compat.py          #   macOS IPv4 兼容修复
│
├── platform/                       # 平台 SDK
│   └── android/tracelib/           #   Android SDK (AAR)
│       └── src/main/java/.../tracelib/
│           ├── TraceHook.java          # Pine AOP 方法 hook (深度保护, Tag截断, 系统widget过滤)
│           ├── ComposeHook.kt          # Compose 重组追踪 (TracerImpl hook, API 31+)
│           ├── BlockMonitor.java       # 主线程卡顿检测 (容量限制防OOM, Fragment泄漏修复)
│           ├── SIClient.java           # WebSocket 客户端
│           ├── HookConfig.java         # 配置模型 (JSON 序列化, BuildConfig.DEBUG守卫)
│           └── HookConfigManager.java  # 配置管理 (SP 持久化)
│
├── perfetto-plugin/                # Perfetto UI SI Bridge 插件
│   ├── com.smartinspector.Bridge/  #   插件源码 (TypeScript)
│   └── build.sh                    #   构建脚本 (clone Perfetto + 复制插件 + build)
│
├── prompts/                        # LLM Prompt 模板
│   ├── *.txt                      #   指令模板 (attributor, report-generator, perf-analyzer 等)
│   └── skills/                    #   Skill 知识文件 (按需加载)
│       ├── SKILL.md               #     索引文件
│       ├── shared/                #     共享知识 (SI$ 标签, 搜索策略)
│       └── dimensions/            #     维度专家知识 (9 个 .md 文件)
├── bin/                            # trace_processor_shell
├── reports/                        # 生成的性能报告 (Markdown)
├── tests/                          # 单元测试
├── Dockerfile                      # 多阶段 Docker 构建 (si-analyzer / si-mcp)
├── docker-compose.yml              # Docker Compose (ci/dev/mcp/prod profiles)
└── docker/healthcheck.sh           # 容器健康检查脚本

Hook 体系 (Android)

SDK 通过 Pine AOP 框架 hook 框架方法,用 SI$ 前缀的 Trace.beginSection 标记用户代码调用,Perfetto atrace 采集后由 CLI 分析。

Hook 类别

Hook 默认 Tag 格式 说明
Activity Lifecycle ON SI$ActivityClass.onCreate Activity 生命周期
Fragment Lifecycle ON SI$FragmentClass.onCreateView Fragment 生命周期 (AndroidX + app)
RV Pipeline ON SI$RV#[viewId]#[Adapter].dispatchLayoutStep2 RecyclerView 管线
RV Adapter ON SI$RV#[viewId]#[Adapter].onBindViewHolder Adapter 数据绑定
Layout Inflate OFF SI$inflate#[layout]#[parent] 布局加载
View Traverse OFF SI$view#[ViewClass].measure View measure/layout/draw
Handler Dispatch OFF SI$handler#[msgClass] Handler 消息分发
Block Monitor ON SI$block#[MsgClass]#[dur]ms 主线程卡顿检测 (≥100ms)
Network IO ON SI$net#[Class].execute OkHttp / HttpURLConnection
Database IO ON SI$db#[Class].query#[table] SQLiteDatabase / Room
Image Load ON SI$img#[Class].into Glide / Coil
Compose Recomposition ON SI$compose#[Composable]#recompose Compose 重组追踪 (API 31+)

IO Hook 说明:Network/DB/Image hook 在所有线程执行,使用独立前缀 (SI$net#/SI$db#/SI$img#),Python 端单独收集到 io_slices,不污染主线程 view_slices 分析。

源码归因流程

Trace → SI$ slices → 过滤系统类 → 提取 class+method → Glob→Grep→Read 搜索源码 → LLM 归因

归因系统通过两层过滤排除系统/框架代码:

  1. FQN 包名匹配android.*、androidx.*java.*
  2. 短类名模式匹配ChoreographerFragmentManagerViewRootImpl 等(Perfetto atrace 截断 FQN 时)

CLI 命令

CI/Headless 模式参数

uv run smartinspector --ci [选项]
参数 说明
--ci 启用非交互式 CI 模式
--trace <path> 指定已有 trace 文件(跳过设备采集)
--target <package> 目标进程包名
--duration <ms> 采集时长(默认 10000ms)
--output <path> 输出文件路径
--format markdown|json 报告格式(默认 markdown)
--src <path> 源码目录
--debug 启用 debug 日志

Slash 命令

命令 说明
/full [--no-wait] 全量分析流水线 (采集→分析→归因→报告)。--no-wait 跳过等待 App 连接,适用于冷启动耗时分析
/quick 快速分析(纯确定性,不调用 LLM,秒级完成)。无 API Key 时自动降级
/compare <r1> <r2> 对比两份报告,生成 before/after 趋势报告
/trace [duration_ms] [pkg] 采集 + 自动分析 Perfetto trace
/record [duration_ms] [pkg] 只采集不分析,返回 .pb 文件路径
/analyze [path] 分析 trace 文件(无参数时分析上次采集结果)
/frame ts=X dur=Y 分析指定时间范围的帧(ts/dur 为纳秒,CLI 直接分析)
/open [path] 启动 Perfetto UI + Bridge Server,交互式框选帧分析
/close 关闭 Perfetto UI Bridge Server
/report [path] 生成性能报告(可选输出到文件)
/config 查看当前 hook 配置(通过 WS 从 App 获取)
/config <json> 推送 JSON 配置到 App(如 {"rv_adapter": false}
/config reset 恢复 hook 默认配置
/config source_dir <path> 设置源码目录(自动持久化)
/hooks 查看所有 hook 点开关状态
/hook on <hook_id> 开启指定内置 hook 点(如 layout_inflate
/hook off <hook_id> 关闭指定内置 hook 点
/hook add <class> <method> 添加自定义 hook 点
/hook rm <class> 删除自定义 hook 点
/devices 列出已连接 adb 设备
/connect <host:port> 通过 adb TCP 连接设备
/disconnect 断开 TCP 设备连接
/status 查看当前会话状态(WS 连接、perf 数据等)
/summary 查看 perf_summary 摘要
/tokens 查看 token 使用量
/clear 清除所有分析状态和对话
/debug 打开设备端 Hook 调试配置面板
/help 帮助信息(支持 Tab 补全)

自然语言路由

Orchestrator 通过 LLM 分类将用户请求路由到对应 Agent:

  • 全面分析 (full_analysis): "全面分析列表滑动性能" / "分析冷启动耗时" / "测一下应用启动时间" / "冷启动性能怎么样" → collector → analyzer → attributor → reporter
  • 平台采集 (android): "采集 trace 分析 FPS" / "采集一下 trace" / "帮我看看 CPU 和内存指标" → Platform Expert Agent
  • 性能解读 (analyze): "解读这份数据" / "分析一下刚才采集的数据" / "解读一下这个 perf_summary" → Perf Analyzer
  • 源码搜索 (explorer): "搜索 XXX 类源码" / "查看 LazyForEach 的实现" / "定位 DataManager.loadData 方法" → Code Explorer
  • 通用问答 (end): "什么是卡顿" / "怎么优化列表滑动" / "你好" → Fallback 回复
  • 指标追问 (metric_qa): "CPU 占用率怎么样" / "帧率怎么样" / "内存有没有泄漏" / "性能怎么样" → Metric QA(需要先完成分析)

Metric QA 指标

在已有 perf_summary 数据的基础上,用自然语言追问具体性能指标:

类别 指标 ID 触发词
CPU cpu, cpu_hotspot, sched, blocked cpu占用/热点/调度/阻塞
内存 memory, heap 内存/RSS/堆/泄漏
UI frame, rv, view, compose, inflate, startup 帧率/列表/绘制/重组/布局/启动
IO io, network, db, image io/网络/数据库/图片
系统 thread_state, sys, input 线程状态/系统/触摸
维度 lock_contention, sched_latency, gc_events, file_io, memory_trend, binder_ipc, cpu_throttling 锁竞争/调度延迟/GC/文件IO/内存趋势/Binder/降频
总览 overview 性能总览

前置条件:必须先通过 /full/trace/analyze 等命令完成分析。

报告示例

全量分析流水线(/full/full --no-wait 或自然语言触发 full_analysis)会生成 Markdown 性能报告,保存到 reports/ 目录。以下为实际生成的报告摘要:

## 问题列表

**源码归因结果共包含6条记录,已全部生成对应问题条目。**

### P0 CpuBurnWorker 主线程执行CPU密集型计算导致卡顿

**现象**:`CpuBurnWorker.startMainThreadWork$run` 在主线程执行耗时 145.00ms。该方法在主线程循环执行100,000次 `Math.sqrt` 计算,是导致主线程卡顿的直接原因。

**原因**:根据源码归因,该方法是CPU烧录测试代码,在主线程上执行密集的数学运算,每次循环约5ms,每200ms执行一次,严重阻塞了主线程的UI渲染。

**调用链**:`CpuBurnWorker.startMainThreadWork$run 145ms`

**位置**:`app/src/main/java/com/smartinspector/hook/worker/CpuBurnWorker.kt:41-49`

**建议**:
1.  **移除或禁用测试代码**:在正式发布版本中,应移除或禁用此类用于测试的CPU烧录代码。
2.  **移至后台线程**:如果该逻辑是应用功能所需,必须将其移至后台线程(如使用 `CoroutineScope(Dispatchers.Default).launch` 或 `ExecutorService`)执行,避免阻塞主线程。
3.  **降低计算频率和强度**:如果必须在主线程执行,应大幅减少循环次数(例如从100,000次减少到1,000次以内)或延长执行间隔。

### P0 DemoAdapter.onBindViewHolder 存在多项耗时操作导致列表滑动卡顿

**现象**:`DemoAdapter.onBindViewHolder` 单次调用最高耗时 74.95ms,在测试期间共调用7次,累计耗时 202.29ms。该方法是导致帧#111严重卡顿(267.25ms)和 RecyclerView `dispatchLayoutStep2` 耗时 229.07ms 的主要原因。

**原因**:根据源码归因,该方法内存在多个阻塞主线程的耗时操作:
1.  `doExpensiveWork()` 中调用了 `Thread.sleep(20)` 进行强制等待。
2.  `repository.loadItemsSync(5)` 进行同步数据加载。
3.  执行了30次字符串拼接循环。
4.  进行了 `Bitmap` 解码操作。

**调用链**:`LinearLayoutManager.onLayoutChildren 228.97ms → RV OnBindView 75.05ms → DemoAdapter.onBindViewHolder 74.95ms`

**位置**:`app/src/main/java/com/smartinspector/hook/adapter/DemoAdapter.java:40-64`

**建议**:
1.  **移除 Thread.sleep**:在主线程中绝对禁止使用 `Thread.sleep()`,应立即移除。
2.  **异步加载数据**:将 `repository.loadItemsSync(5)` 改为异步加载(如使用 `LiveData`、`RxJava` 或 `Coroutine`),在数据准备好后再通知 `Adapter` 更新。
3.  **优化字符串构建**:使用 `StringBuilder` 替代多次 `+` 操作进行字符串拼接。
4.  **异步加载与缓存图片**:将 `Bitmap` 解码移至后台线程,并使用 `Glide`、`Picasso` 等图片加载库进行异步加载和缓存,避免每次绑定都解码。

### P1 MainActivity.onCreate 中延迟任务过多且存在潜在风险

**现象**:`MainActivity.onCreate` 耗时 14.67ms。方法中启动了多个 `Handler.postDelayed` 任务。

**原因**:根据源码归因,方法中启动了多个延迟任务:1) 5秒后加载数据,2) 500ms间隔的循环padding调整,3) 8秒后显示详情Fragment。过多的延迟任务可能阻塞主线程,500ms的循环任务可能造成不必要的性能开销,且使用 `Handler.postDelayed` 有潜在的内存泄漏风险。

**调用链**:`MainActivity.onCreate 14.67ms`

**位置**:`app/src/main/java/com/smartinspector/hook/MainActivity.java:31-67`

**建议**:
1.  **合并或优化任务**:评估500ms循环任务的必要性,考虑是否可以合并或由事件驱动(如监听视图状态)来触发。
2.  **使用 View.post**:对于需要在主线程执行的延迟UI操作,优先使用 `View.post()` 或 `View.postDelayed()`,这可以自动处理 `View` 生命周期,降低内存泄漏风险。
3.  **使用 Lifecycle-aware 组件**:对于需要在特定生命周期执行的任务,考虑使用 `Lifecycle` 和 `Coroutine` 等现代架构组件来管理。

### P1 DemoAdapter.onCreateViewHolder 加载复杂布局耗时

**现象**:`DemoAdapter.onCreateViewHolder` 单次调用最高耗时 4.89ms,在测试期间共调用7次,累计耗时 10.49ms。

**原因**:根据源码归因,该方法加载了复杂布局 `item_complex`。布局的复杂度直接影响 `inflate` 和后续测量、布局的速度。

**调用链**:`DemoAdapter.onCreateViewHolder 4.89ms`

**位置**:`app/src/main/java/com/smartinspector/hook/adapter/DemoAdapter.java:33-37`

**建议**:
1.  **检查并简化布局**:使用 Layout Inspector 或 `ConstraintLayout` 的布局优化工具,检查 `item_complex.xml` 的层级,减少不必要的嵌套。
2.  **使用 ViewStub**:对于列表中并非立即显示的复杂部分,可以考虑使用 `ViewStub` 进行延迟加载。
3.  **启用视图复用**:确保 `RecyclerView` 和 `Adapter` 正确设置了 `setHasStableIds(true)` 并实现了 `getItemId()`,以优化视图复用。

### P1 item_complex.xml 布局嵌套过深导致inflate耗时

**现象**:`item_complex.xml` 的 inflate 操作单次最高耗时 4.77ms,在测试期间共执行7次,累计耗时 9.80ms。

**原因**:根据源码归因,该布局有4层嵌套,并且包含自定义视图 `HeavyDrawView`。深层级的嵌套会导致测量和布局过程计算量增大。

**调用链**:`inflate#item_complex 4.77ms`

**位置**:`app/src/main/res/layout/item_complex.xml:1-64`

**建议**:
1.  **使用 ConstraintLayout 扁平化布局**:将根布局替换为 `ConstraintLayout`,利用其约束关系减少嵌套层级,目标是控制在2层以内。
2.  **优化 HeavyDrawView**:分析 `HeavyDrawView` 的 `onDraw` 方法,确保其绘制操作高效,避免在 `onDraw` 中分配对象或进行复杂计算。
3.  **使用 merge 标签**:如果该布局被 `include`,考虑在根节点使用 `<merge>` 标签以消除一层冗余的 `ViewGroup`。


## 附录

**采集工具**:Smart Inspector
**原始数据位置**:`/var/folders/tb/6pgk76d11bd278v01zfqkq540000gn/T/tmpatm5lr_x.pb`
  [reporter] Report generated
  [reporter] Report saved to /xx/xx/reports/perf_report_20260415_232256.md (7.8KB)

Token usage:
Stage                   Input   Output    Total  Calls
------------------------------------------------------
orchestrator              456        3      459      1
perf_analyzer            2.9k      415     3.3k      1
attributor              59.1k     3.3k    62.4k     24
reporter                 3.1k     1.3k     4.4k      1
------------------------------------------------------
TOTAL                   65.6k     5.0k    70.6k     27

技术栈

组件 技术
Agent 编排 LangGraph + LangChain
LLM DeepSeek / Claude / OpenAI (通过 SI_MODEL 配置)
Android Trace Perfetto + atrace (ftrace + CPU callstack + Java heap)
HarmonyOS Trace hiperf + hitrace (规划)
方法 Hook (Android) Pine AOP Framework
CLI 交互 prompt_toolkit (Tab 补全, REPL) + argparse (CI 模式)
通信 WebSocket (CLI ↔ App, 心跳检测, 动态端口)
Trace 分析 trace_processor_shell (SQL, v55.1 multi-arch)
容器化 Docker multi-stage build (AMD64/ARM64)
状态管理 LangGraph MemorySaver (get_state)

LLM 配置

通过 .env 文件或环境变量配置 LLM 提供商:

cp .env.example .env
变量 说明 默认值
SI_MODEL 全局默认模型 deepseek-chat
SI_BASE_URL API Base URL (OpenAI 兼容) https://api.deepseek.com
SI_API_KEY API Key (回退到 OPENAI_API_KEY)
SI_ATTRIBUTOR_MODEL 归因 Agent 模型覆盖 (代码理解) SI_MODEL
SI_TOOL_TIMEOUT 工具子进程超时 (grep/glob) 30
SI_READ_MAX_LINES Read 工具最大返回行数 2000
SI_READ_MAX_BYTES Read 工具最大返回字节数 51200
SI_READ_MAX_LINE_LENGTH Read 工具单行最大字符数 2000
SI_REPORT_MAX_TOKENS 报告生成最大输入 token 4000
SI_WS_PING_TIMEOUT WebSocket ping 超时 (秒) 30

切换到 Claude 示例:

SI_MODEL=claude-sonnet-4-20250514
SI_BASE_URL=https://api.anthropic.com
SI_API_KEY=sk-ant-xxx

归因用更强模型示例:

SI_MODEL=deepseek-chat
SI_ATTRIBUTOR_MODEL=claude-sonnet-4-20250514

归因环节需要代码理解能力,建议使用更强的模型。其他环节(路由、报告)用 DeepSeek 即可。

环境要求

  • Python 3.12+
  • macOS / Linux / Windows (通过 Docker)
  • Android: 设备 API 28+,开启 USB 调试,adb 已加入 PATH
  • HarmonyOS: hdc 已加入 PATH (规划)
  • iOS: Xcode + Instruments (规划)

Docker 部署

SmartInspector 提供多阶段 Docker 构建,支持 AMD64ARM64 架构,内置 Perfetto v55.1 trace_processor_shell,可直接在 CI/CD 环境中运行。

构建

# 默认构建 (analyzer 镜像)
docker build -t smartinspector:latest .

# 指定目标
docker build --target si-analyzer -t smartinspector:analyzer .
docker build --target si-mcp -t smartinspector:mcp .

# ARM64 平台构建
docker build --build-arg TARGETARCH=arm64 -t smartinspector:arm64 .

Docker Compose

提供四种运行 Profile,按场景选择:

Profile 用途 命令
ci CI/Headless 分析 docker compose --profile ci run --rm si-analyzer smartinspector --ci ...
dev 开发环境(挂载源码,暴露 WS 端口) docker compose --profile dev up
mcp MCP Server(stdio transport) docker compose --profile mcp up -d si-mcp-server
prod 生产环境(资源限制 + 日志轮转) docker compose --profile prod up -d

CI 模式示例

# 1. 配置环境变量
cp .env.docker.example .env
# 编辑 .env 填入 SI_API_KEY

# 2. 分析已有 trace 文件,输出 JSON 报告
docker compose --profile ci run --rm \
  -e SI_API_KEY=$SI_API_KEY \
  si-analyzer \
  smartinspector --ci --trace /traces/trace.pb --format json --src /source

# 3. 生成 Markdown 报告到文件
docker compose --profile ci run --rm \
  -e SI_API_KEY=$SI_API_KEY \
  si-analyzer \
  smartinspector --ci --trace /traces/trace.pb --output /app/reports/report.md

卷挂载

宿主机路径 容器路径 用途
${TRACE_DIR:-./traces} /traces Trace 文件输入(只读)
./reports /app/reports 报告输出
${SOURCE_DIR:-./src} /source 源码目录(归因用,只读)

镜像结构

python:3.12-slim (builder)
  └── uv install dependencies → /opt/venv
      └── si-analyzer (runtime)
          ├── /opt/venv (Python dependencies)
          ├── /app/bin/trace_processor_shell (Perfetto v55.1, multi-arch)
          ├── /app/src/smartinspector/ (application code)
          ├── /app/prompts/ → /opt/venv/lib/python3.12/prompts (symlink)
          └── ENTRYPOINT ["smartinspector"]
              └── si-mcp (extends si-analyzer)
                  └── ENTRYPOINT ["si-mcp"]

路线图

P1 — 已完成 (2026-04-24)

# 项目 说明 状态
P1-1 Compose 重组追踪 追踪 Jetpack Compose 重组次数和耗时,定位不必要的 recomposition ✅ 已完成
P1-2 内存分配分析 基于 heap_graph 数据源分析内存分配热点,定位内存抖动和泄漏 ✅ 已完成
P1-3 历史对比与趋势 多次分析结果对比,生成 before/after 报告和性能趋势图 ✅ 已完成
P1-4 智能一键分析 纯确定性快速分析,不调用 LLM,30 秒内完成轻量分析 ✅ 已完成
P1-5 ExtraHook 参数自动推断 自动推断所有重载签名,无需手动配置方法参数 ✅ 已完成
P1-6 SQL Summarizer 压缩 SQL 查询结果为统计摘要+异常采样,降低 60-80% token 消耗 ✅ 已完成
P1-7 Analysis Verifier L1 格式检查 + L2 一致性验证,自动检测遗漏和不一致,支持重试 ✅ 已完成

平台扩展

  • HarmonyOS collector (hdc + hiperf/hitrace)
  • iOS Instruments 集成
  • Native C/C++ 代码覆盖

工程优化

  • Docker 容器化部署 (multi-stage build, AMD64/ARM64, CI/CD 集成)
  • 帧严重度阈值区分刷新率 (120Hz 设备帧预算 8.33ms)
  • 输入事件关联 (touch event → frame jank 因果)
  • RV Instance 区分 create vs bind 开销
  • Perfetto android.surfaceflinger.frame 维度 (CPU vs GPU 瓶颈)
  • 自适应阈值 (基于设备能力动态调整)
  • thread_state N+1 查询优化 → 已完成:重写为 __intrinsic_thread_state 表,支持 blocked_function/io_wait/waker_utid
  • LLM 实例统一管理 (LLMFactory)

✅ 已完成 (2026-04-24 P1 改进)

P1-1: Compose 重组追踪

  • ComposeHook.kt: Hook Compose Runtime 的 TracerImplstartRestartGroup/endRestartGroup
  • 切片前缀 SI$compose#,Tag 格式:SI$compose#ComposableName#recompose / SI$compose#ComposableName#first
  • Python 端新增 collect_compose_slices() 查询和重组分析

P1-2: 内存分配分析

  • collector/memory.py: MemoryAnalyzer 基于 heap_graph 表分析 Java 堆内存
  • 按类名聚合对象数量和总大小,检测 Activity/Fragment 泄漏嫌疑
  • 内存增长趋势追踪(RSS / anon 随时间变化)

P1-3: 历史对比与趋势

  • commands/compare.py: /compare 命令,多次分析结果对比
  • storage/store.py: 报告存储层,支持基线管理和历史查询
  • 生成 before/after 报告,自动标注回归项和改善项

P1-4: 智能一键分析

  • commands/quick.py: /quick 命令,纯确定性快速分析(不调用 LLM)
  • 仅运行 fast-path 归因 + compute_hints,秒级完成
  • 无 API Key 时自动降级为 quick 模式

P1-5: ExtraHook 参数自动推断

  • TraceHook.java 改进 hookExtraClasses():自动推断所有重载签名
  • 遍历 getDeclaredMethods() 匹配方法名,替代原先的只尝试无参签名

P1-6: SQL Summarizer

  • deterministic.py 新增 summarize_sql_result() — 将 SQL 查询结果压缩为统计摘要 (count/min/max/avg/p95/p99) + 分布直方图 + 异常采样 + 去重聚合
  • deterministic.py 新增 compress_perf_json() — 对 perf JSON 中的大列表字段 (slowest_slices/block_events/frame_timeline/thread_state) 自动应用压缩
  • 集成到 perf_analyzer.py (perf_json 传入前压缩) 和 frame_analyzer.py (slices 列表压缩)
  • Token 消耗降低 60-80%,减少 LLM 在大量数据中的幻觉

P1-7: Analysis Verifier

  • agents/verifier.py 新增分层验证系统 (0 token,纯规则)
  • L1 格式检查:数值存在性、方法名引用、长度合理、P0/P1/P2 分级
  • L2 一致性验证:P0 问题覆盖、关键数据点数值一致性 (±20%)、热点方法覆盖
  • 集成到 perf_analyzer.pyframe_analyzer.py,L2 失败时自动重试一次补充遗漏
  • VerificationResult 包含 score/issues/warnings/l1_passed/l2_passed 属性

✅ 已完成 (2026-04-24 P0 改进)

P0-1: IO Hooks 启用

  • Network/DB/Image IO Hook 默认开启
  • IO 切片独立收集到 io_slices,不污染主线程 view_slices 分析
  • collect_io_slices() 方法从所有线程收集 SI$net#/SI$db#/SI$img# 切片

P0-2: 冷启动专项分析

  • collector/startup.py: StartupAnalyzer 将启动序列切分为 4 个阶段
    • pre-main (进程启动 → Application.attachBaseContext)
    • Application.onCreate → first Activity.onCreate
    • Activity.onCreate → 首帧 doFrame
    • 首帧渲染
  • graph/nodes/startup.py: 图节点集成,输出 Markdown 格式的启动分析报告
  • 关键路径提取 + 瓶颈识别 + 自动优化建议

P0-3: Headless/CI 模式

  • headless.py: HeadlessRunner 非交互式运行全量分析流水线
  • CLI 参数: --ci 启用,--trace/--target/--duration/--output/--format/--debug
  • 支持 Markdown 和 JSON 两种输出格式
  • 无 API Key 时降级为纯确定性分析(跳过 LLM)

P0-4: JSON 报告格式

  • graph/nodes/reporter/json_formatter.py: 结构化 JSON 报告
  • 包含 summary(FPS/CPU/jank)、issues(P0/P1/P2 分级)、metrics(详细指标)
  • 自动关联 attribution 结果到 issue 的 source 字段
  • 适合 CI/CD 自动化解析

P0-5: IO 切片归因

  • agents/attributor.py 支持 IO 类型切片(SI$net#/SI$db#/SI$img#)归因
  • commands/attribution.py 解析 IO tag 提取 class/method 用于源码搜索
  • 归因结果包含 io_type 字段(network/database/image)

✅ 已完成 (2026-04-05 重构)

Collector 采集层

  • 修复内存数值单位错误(/1024 转换问题)
  • 修复 Block Events 数据覆盖(WS+SQL 合并)
  • CPU 热点添加调用链重建
  • sched 添加阻塞原因分析
  • 新增系统级 CPU 指标采集
  • HookConfig 透传 + Tag 截断保护
  • PerfettoCollector 支持 context manager 协议

Agents 编排层

  • Orchestrator LLM 调用异常处理
  • REPL 主循环全局异常保护
  • graph.stream 循环防崩溃
  • node_error_handler 统一节点错误处理
  • 路由支持 enum 和 string 双模式
  • 路由 prompt few-shot 提升准确率
  • 路由 LLM max_tokens=5 减少 token 浪费
  • Reporter 输入 token 估算和截断
  • Attributor 消息窗口裁剪防 O(n²) 增长
  • Fallback 消息窗口过滤仅 Human/AI
  • Reporter 真正流式输出防重复打印
  • 用 get_state()+MemorySaver 替代手动 state 重建
  • Attributor 结构化输出 + 文本解析 fallback
  • 清理无引用的 prompts/main.txt
  • Agent LLM 单例双重检查锁线程安全

SDK 层

  • Release 变体替换为纯 no-op stubs
  • PineConfig.debug=true 替换为 BuildConfig.DEBUG
  • FragmentLifecycleCallbacks registered 集合内存泄漏修复
  • BlockMonitor.blockEvents 容量限制防 OOM
  • view_traverse 过滤系统 widget
  • SI$ Tag 超 127 字节自动截断
  • 高频 hook Log.d BuildConfig.DEBUG 守卫
  • Trace 嵌套深度保护防 atrace 溢出

基础设施层

  • REPL 全局异常保护
  • WS server 启动异常不再静默吞掉
  • WebSocket ping/pong 心跳检测
  • WS server ready event 防止启动竞态
  • streaming graph 迭代错误处理
  • state 合并重构为 AgentState 驱动
  • 硬编码端口 9876 替换为 get_ws_port()
  • Slash 命令 Tab 自动补全
  • 版本号从 package metadata 读取
  • /clear 清理所有分析状态字段
  • 启动前置条件检查 (adb + API key)
  • 所有依赖添加版本上限
  • /report 支持文件输出
  • Hook config 持久化到本地文件
  • send_config msg_id + ACK 机制
  • 硬编码配置值集中到 config.py,支持环境变量覆盖
  • 工具共享路径校验提取到 path_utils 模块
  • Collector 全链路异常日志补全
  • WS 异常日志替换静默吞掉

About

AI 驱动的移动端性能分析 CLI 工具 — 通过自然语言交互自动采集 trace、分析性能瓶颈并归因到源码

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors