Unity 日志一多就像看天书?AI 很适合帮你做第一轮异常归因

Unity 项目做久了,大家对日志通常会进入两种状态。

一种是完全不看。

另一种是出了问题以后,被一大坨日志按在地上看。

尤其线上问题、测试服问题、低端机偶发问题,一旦日志量上来,排查体验很容易从“定位 bug”变成“读经”。

这时候 AI 的一个很实际用途就出来了。

它不一定能直接替你修 bug。

但它非常适合先做第一轮异常归因,把一大堆碎日志整理成“可能是哪几类问题”。

这个价值在实际项目里比很多人想得更大。

一、AI 在日志分析里最适合做什么

不是直接告诉你最终根因。

而是先帮你做这几件事:

  • 按错误类型归类
  • 提取高频堆栈
  • 合并重复报错
  • 标记可能的时间先后关系
  • 给出优先排查方向

说白了,它更像一个第一轮分诊助手。

日志越碎、问题越多、人工越烦的时候,这个角色越有用。

二、最差的问法:我这个日志报错了,帮我看

这个问法的问题,和前面说性能分析时一样。

太糊。

如果你只甩一段日志给 AI,没给上下文,它大概率会:

  • 先解释报错字面意思
  • 再给一堆通用排查建议
  • 最后礼貌收尾

不能说错。

但经常不够值钱。

日志分析真正有价值的地方,不是翻译英文报错,而是把“这段日志在项目语境里意味着什么”讲清楚。

三、更有效的提示词,是把日志放进场景里问

如果我想让 AI 帮我做 Unity 日志的第一轮分析,我通常会把这些信息一起给出去:

  1. Unity 版本和平台。
  2. 问题发生在哪个功能场景。
  3. 这是测试服、线上、开发环境还是编辑器环境。
  4. 报错前后做了什么操作。
  5. 希望 AI 输出什么格式。

比如这种提示词就很实用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
你是资深 Unity 客户端问题排查工程师。
请帮我分析一段 Unity 线上日志,并做第一轮异常归因。

背景:
1. Unity 2021 LTS,Android,二合游戏主棋盘。
2. 玩家反馈问题发生在“完成订单后返回主棋盘”阶段。
3. 日志来自线上测试包,不保证完整,但包含错误栈和部分业务日志。

请按以下格式输出:
1. 先按错误类型归类。
2. 标出最可能的 3 个主要问题。
3. 对每个问题说明它更像是资源问题、UI 状态问题、空引用、时序问题,还是数据问题。
4. 给出建议排查顺序。
5. 如果日志不足,请明确指出还缺哪些上下文。

这种问法的核心,不是让 AI“看懂日志”,而是让它按工程排查思路整理日志。

四、日志先做结构化,再喂给 AI,效果通常更稳

现实里很多原始日志都很乱。

混着这些东西:

  • Unity 默认异常栈
  • 第三方 SDK 输出
  • 业务日志
  • 网络日志
  • 打点日志

你如果整包直接扔给 AI,信息噪声会很高。

更稳一点的做法,是先自己或先用脚本把日志做一轮基础清洗:

  • 去掉明显重复行
  • 按时间或关键字分块
  • 提取 Exception、Error、Warning
  • 保留异常前后若干行上下文

这样 AI 分析的命中率会高不少。

五、一个很适合先让 AI 帮忙补的日志整理小工具

这类工具不难,但挺烦。

所以很适合让 AI 起草一版。

比如先写一个简单的编辑器脚本,把日志文件里的异常块提取出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

public static class UnityLogExtractor
{
[MenuItem("Tools/Logs/Extract Error Blocks")]
public static void ExtractErrorBlocks()
{
var inputPath = EditorUtility.OpenFilePanel("Select Log File", string.Empty, "log");
if (string.IsNullOrEmpty(inputPath))
{
return;
}

var lines = File.ReadAllLines(inputPath);
var blocks = new List<string>();
var currentBlock = new StringBuilder();
var capturing = false;

foreach (var line in lines)
{
if (line.Contains("Exception") || line.Contains("Error") || line.Contains("NullReferenceException"))
{
if (currentBlock.Length > 0)
{
blocks.Add(currentBlock.ToString());
currentBlock.Clear();
}

capturing = true;
}

if (capturing)
{
currentBlock.AppendLine(line);

if (string.IsNullOrWhiteSpace(line))
{
blocks.Add(currentBlock.ToString());
currentBlock.Clear();
capturing = false;
}
}
}

if (currentBlock.Length > 0)
{
blocks.Add(currentBlock.ToString());
}

var outputPath = Path.Combine(Path.GetDirectoryName(inputPath) ?? string.Empty, "error_blocks.txt");
File.WriteAllLines(outputPath, blocks);
Debug.Log($"Extracted {blocks.Count} error blocks to: {outputPath}");
}
}

这类代码本身不高级。

但它能把“混乱整包日志”变成“更适合继续喂 AI 的结构化样本”。

六、第二轮提示词,适合让 AI 做“归因 + 排查建议”

有了整理过的异常块之后,我更喜欢这样问:

1
2
3
4
5
6
下面是从 Unity 日志里提取出的异常块,请你不要只逐条解释。
请做工程化归因:
1. 合并重复异常。
2. 判断哪些异常可能是同一个根因引起的连锁报错。
3. 标出最值得先排查的那一条。
4. 给出我下一步应该补采哪些日志字段或埋点。

这个问法特别有用。

因为真实项目里,最烦人的往往不是“有没有异常”,而是“这一串异常到底谁是因、谁是果”。

AI 在这种初步整理上,通常比人肉一条条翻快不少。

七、AI 在日志分析里最容易翻车的点

这几条得提前防一下:

  1. 它可能把后续连锁异常误判成根因。
  2. 它可能忽略第三方 SDK 的噪声日志。
  3. 它会倾向从字面解释异常,而不是结合玩法时序。
  4. 它不知道你项目里的自定义日志字段语义,除非你告诉它。

所以它最适合用来做第一轮筛查,不适合直接代替最终结论。

八、最后一句

Unity 日志一多,人工排查最先累的,往往不是技术判断,而是信息整理。

而这恰好是 AI 很适合帮忙切一刀的地方。

你先把日志清洗和上下文准备好,再让它做第一轮归类、归因和排查优先级整理,效率通常会比纯手翻高很多。

别把它当神探。

把它当一个不会喊累的第一轮分诊助手,反而更实用。