banner
NEWS LETTER

给 AI 一份可复现的故障证据包:Android 与 Linux 排查实践

Scroll down

把一段报错直接贴给 AI,往往能得到十几种“可能原因”。这些答案未必错,却很难立刻用于工程现场:它不知道问题发生在哪次构建、设备处于什么状态,也不知道日志前后发生了什么。

高效排障的关键,不是提供更多文字,而是提供一份边界清楚、可以复查的故障证据包。它既让 AI 少猜,也让接手问题的人能沿着同一条路径复现和验证。

一、证据包要回答四个问题

一份有用的证据包不必很大,但至少要回答:

  1. 对象是什么:应用、进程、服务、设备和构建产物分别是谁。
  2. 问题何时发生:触发动作、时间窗口和稳定复现步骤是什么。
  3. 预期与实际有何差异:不要只写“失败了”,要说明期望观察到什么。
  4. 已经验证过什么:哪些假设已被排除,使用了什么证据。

例如,“应用偶尔卡死”几乎无法缩小范围;而“从后台返回后点击同步,界面在 5 秒内无响应,主线程堆栈停在数据库事务”已经形成了可验证的线索。

二、先固定现场,再收集日志

日志的价值依赖上下文。同一条超时错误,在网络切换、服务重启和锁竞争场景下会指向完全不同的方向。因此,先创建一个独立目录,保存本次排查的静态信息:

1
2
3
4
5
6
7
8
case_dir="debug_case_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$case_dir"

{
printf 'captured_at=%s\n' "$(date -Iseconds)"
printf 'kernel=%s\n' "$(uname -a)"
printf 'git_commit=%s\n' "$(git rev-parse --short HEAD 2>/dev/null || true)"
} > "$case_dir/context.txt"

这里记录的是“这一次现场”,而不是机器永远不变的说明。后续即使代码、设备或系统状态变化,也能知道证据对应哪个时间点。

Android 问题还可以补充设备和应用信息:

1
2
3
4
adb get-serialno > "$case_dir/device_serial.txt"
adb shell getprop ro.build.fingerprint > "$case_dir/build_fingerprint.txt"
adb shell dumpsys package com.example.app \
> "$case_dir/package.txt"

采集命令应根据问题裁剪。排查启动失败不需要完整电池报告,分析网络异常也不必默认导出所有系统服务。无关信息越多,真正的时间线越容易被淹没。

三、用时间窗口代替“整份日志”

最常见的低效做法,是把几万行日志交给 AI,然后让它自行寻找异常。更稳妥的方法是明确执行顺序:

  1. 清理或标记日志起点。
  2. 执行最短复现步骤。
  3. 记录问题出现的准确时间。
  4. 立即停止采集并保存原始输出。

Android 场景可以这样保留一次干净的复现:

1
2
adb logcat -c
adb logcat -v threadtime > "$case_dir/logcat.txt"

复现完成后终止采集,再从 logcat.txt 中提取目标进程、异常栈及前后事件。Linux 服务则可以围绕明确时间段导出日志:

1
2
3
journalctl -u example.service \
--since "10 minutes ago" \
--no-pager > "$case_dir/service.log"

不要只保留筛选结果。原始日志负责追溯,精简片段负责分析,两者用途不同。错误的过滤条件可能恰好删掉根因。

四、给 AI 的不是附件,而是任务说明

证据齐全后,还需要约束 AI 的输出。一个实用的提问模板可以是:

1
2
3
4
5
6
7
8
9
10
11
12
目标:定位同步操作导致界面无响应的首要原因。
环境:见 context.txt 与 package.txt。
复现:启动应用 -> 进入同步页 -> 切到后台 -> 返回并点击同步。
预期:2 秒内显示进度。
实际:界面约 5 秒无响应。
证据:logcat.txt、main_thread.txt。

请完成:
1. 只根据证据列出按可能性排序的 3 个假设;
2. 每个假设引用对应日志行或堆栈;
3. 给出一个成本最低的验证动作;
4. 区分“已确认事实”和“仍需验证的推断”。

这种格式把“请帮我看看”变成了一个可验收的分析任务。特别是要求引用证据,可以及时发现模型是否把经验性判断写成了现场事实。

五、先验证假设,再修改代码

AI 给出的第一个解释通常只是候选假设。收到分析后,不要马上开始大范围重构,而应优先设计最小验证动作。

如果怀疑主线程等待锁,可以增加一次线程转储;如果怀疑某个 Binder 调用变慢,可以测量调用边界;如果怀疑 Linux 服务被系统终止,可以检查服务状态和内核日志。验证动作最好只改变一个变量,并且能产生新的可观察证据。

可以把排查过程记录成一个小表格:

假设 支持证据 反对证据 下一步验证 结果
主线程等待数据库锁 堆栈停在事务入口 尚未发现持锁线程 采集全部线程堆栈 待验证
网络请求阻塞 UI 点击后出现请求日志 主线程栈不在网络调用 增加调用耗时埋点 待验证

表格的意义不是写报告,而是防止排查在聊天中失去状态。当新证据推翻旧判断时,也能清楚知道为什么转向。

六、分享前必须做脱敏

日志可能包含访问令牌、账号、设备序列号、内网地址、文件路径和业务数据。把证据交给任何外部工具之前,都应先检查并生成脱敏副本,原始材料只保留在受控位置。

可以先用搜索定位常见敏感字段:

1
rg -n -i 'token|authorization|cookie|password|secret|serial' "$case_dir"

但关键词扫描只能作为提醒,不能替代人工审阅。脱敏时还要保持同一标识符的一致性,例如把同一个用户 ID 始终替换成 USER_A,否则事件关联会被破坏。

七、把一次排查沉淀成可复用流程

问题解决后,证据包不应只是被压缩归档。值得保留的内容包括:

  • 最短复现步骤;
  • 真正有区分度的采集命令;
  • 根因对应的关键证据;
  • 修复后的验证结果;
  • 下次可以自动化的检查项。

对于重复出现的问题,可以把采集命令做成只读脚本,并在输出中记录时间、命令和退出状态。脚本负责稳定采集,AI 负责归纳线索,人负责验证假设和决定修改,这三者边界越清楚,排障越不容易变成碰运气。

结语

AI 能加快故障分析,但它无法替代现场证据。真正提升效率的做法,是把模糊现象整理成一个可复现、可引用、可验证、已脱敏的证据包。

当每个结论都能回到日志或实验结果,AI 就不再只是原因生成器,而会成为排查流程中可靠的分析助手。

其他文章
目录导航 置顶
  1. 1. 一、证据包要回答四个问题
  2. 2. 二、先固定现场,再收集日志
  3. 3. 三、用时间窗口代替“整份日志”
  4. 4. 四、给 AI 的不是附件,而是任务说明
  5. 5. 五、先验证假设,再修改代码
  6. 6. 六、分享前必须做脱敏
  7. 7. 七、把一次排查沉淀成可复用流程
  8. 8. 结语
请输入关键词进行搜索