Skip to content

AI 辅助 C# 报错、Bug 与回归定位

内容类型:方法说明难度:进阶适合:项目出现报错、异常行为、偶发设备问题或版本回归的开发者阅读时间:约 12 分钟

AI 最容易犯的调试错误不是“不会猜原因”,而是太早把一个看起来可疑的代码点当成根因。V10 把 Bug 调查分成普通故障和 Temporal Regression 两条路径,并要求结论强度跟证据走。

1. 先判断:普通 Bug 还是回归

普通 Bug

没有明确 known-good,或者问题一直存在:

text
现象 → 最小反馈环 → 假设 → 证据 → 最小修复

Temporal Regression

用户说:以前正常、昨天改完后变了、旧版本可以、新版本不行、最近才出现、这次修改后又坏了。

第一动作不是分析当前代码“哪看起来不对”,而是:

text
known-good
→ changed files
→ relevant method/config/protocol diff
→ behavior delta

“当前代码看起来不合理” ≠ “它造成了本次回归”。

2. Temporal Regression:known-good first

2.1 确定比较基线

优先:

  1. 用户指定的旧目录/旧安装包;
  2. Git known-good commit/tag;
  3. 最后一次正常日志;
  4. 上一次稳定配置;
  5. 现场记录。

2.2 先看相关变更,不全仓库漫游

text
症状相关 changed files
→ 最相关方法 diff
→ 配置/协议 diff
→ 必要测试差异

一个假设默认最多 3 组高价值证据查询。仍没有结论时,先输出:

text
已排除:
尚未确定:
下一关键证据:

再继续,而不是无限 rg / Get-Content / git diff

2.3 行为差异表

项目known-good当前是否与症状相关
调用入口
设备配置
协议/SCPI
状态条件
参数/配置
采样/时序

只有“发生了差异”并且差异能解释症状,才进入候选根因。

3. 普通 Bug:先建立最便宜的 Feedback Loop

上位机现场问题不一定能先写自动测试,因此 V10 不强制“没有 red test 就不能分析”。按成本从低到高选择:

text
已有 focused test
→ Fake / Simulation
→ Replay
→ 日志 / 时间线 / known-good diff
→ 最小 harness
→ 安全且获授权的只读真实设备验证
→ HITL 现场验证

目标不是必须自动化,而是让“修复前/修复后”有一个尽可能快、稳定的区分信号。

4. 日志多时先建时间线

如果现场已经有 App、设备、TX/RX、MES 等多源日志,不要只搜最后一条 Error。

text
收窄异常时间窗
→ 对齐多源时间
→ 找第一个异常点
→ 看异常前 3–10 个关键事件
→ Evidence / Inference / Unknown

例如日志里“没有 RX”只证明当前日志没有观察到 RX;只有日志覆盖接收链本身被证明完整时,才有资格进一步推断设备没发送。

完整方法:日志与时间线诊断

5. EvidenceGrade:结论必须和证据强度匹配

等级典型证据允许结论
A稳定自动复现 + 修复后通过RootCauseConfirmed
B稳定模拟/回放 + 代码证据高置信软件侧根因
C日志、时间线、known-good、代码共同指向强候选/条件性确认
D代码可疑点、单次现象、经验判断只能写“怀疑/候选”

D 级不能写“已经定位根因”。

6. 自恢复问题:重试后好了,不等于根因已确认

真实仪器常见:第一次应用参数异常第二次正常、断线后重连恢复、Burst/触发状态残留、设备命令偶发未就绪、UI/采集线程偶发竞争。

先标记:

text
SuspectedTransient

下一次优先捕获:实际下发命令、错误队列、关键输出/触发状态、时间戳、连接/重连状态、上一轮残留配置。

不要仅因为“重试好了”就写“确认是设备状态残留”。

7. 上位机 Bug 需要额外看什么

Bug 类型核心证据专项入口
串口/TCP/Modbus原始 TX/RX、时间戳、超时、重连、设备状态通信证据包
示波器/信号源SCPI、错误队列、触发模式、输出状态、采样配置日志时间线
状态误判状态机、阈值、上一状态、恢复条件行为语义
UI 卡死UI 线程、等待链、定时器、设备 I/O、取消令牌性能与长稳
数据保存路径、Schema、文件锁、权限、磁盘容量数据追溯
长稳问题时间线、内存/CPU、资源创建释放、重复任务性能与长稳

8. 测量值异常:先确认数值语义

text
RawValue
EngineeringValue
Conversion
ThresholdBasis
Aggregation
LoggedUnit

例如原始 CH2 峰值可能是 V,探头灵敏度是 V/A,工程电流是 A。量纲不清时,不要先改阈值。

详见 测量值语义

9. “连续 N 次”相关 Bug 要检查状态边界

检查:

  • 正常一帧是否清零;
  • 无效帧是否清零/忽略;
  • 一个窗口是否只报一次;
  • 新一轮什么时候复位;
  • 触发后是否继续采集;
  • AlarmOnly 还是 InterlockFault。

10. 调查阶段和修复阶段分开

调查阶段允许:增加临时日志、比较旧版、画最短调用链、建时间线、加 simulation/replay。

只读真实设备查询也必须满足安全且获授权;改变真实设备状态的动作进入单独的 HardwarePending/HITL 流程。

不要一边调查一边顺手重构。

进入修复至少满足:

  1. 当前最早异常位置足够明确;
  2. 根因/强候选能解释正常路径和失败路径;
  3. 有修复前/修复后可区分的反馈方式。

11. 最小修复卡

text
现象:
known-good / 复现基线:
已确认差异:
EvidenceGrade:
根因状态:Confirmed / StrongCandidate / SuspectedTransient
准备修改:
不修改:
验证:
HardwarePending(如有):
残余风险:

12. 回退不等于修复

如果撤销新改动后恢复到旧版正常状态,准确描述是:

text
RolledBackToKnownGood

它证明“新改动范围与问题有关”的可能性提高,也恢复了可信基线,但不能自动证明精确根因已经找到。

只有针对根因/强证据候选做了修改,并通过匹配反馈环,才写 RegressionFixed

13. 案例:信号源“昨天改后输出不一样”

错误做法:先看当前预充电代码,发现某个周期参数可疑,就直接推断是昨天改坏的。

正确做法:

  1. 用户明确“以前正常、昨天后异常”,进入 Temporal Regression;
  2. 以旧目录或 known-good commit 为基线;
  3. 比较信号源驱动、应用配置路径、预充参数和配置文件;
  4. 如果可疑参数旧版也完全一样,把它从“本次回归根因”中排除;
  5. 再查真正变化的时序、状态、配置或现场设备状态。

一个设计可能值得以后改进,但它不一定是本次 regression cause。

14. 可直接复制的 Prompt

普通 Bug

text
$host-computer-dev
帮我调查这个 Bug,先不要改代码。

现象:
复现步骤:
日志:
最近改动:

请先选择最便宜的 Feedback Loop,输出已确认事实、证据等级、候选根因和下一关键证据。

版本回归

text
$host-computer-dev
这个功能以前正常,最近修改后异常。
旧版:D:\...\old
当前版:D:\...\current

请进入 Temporal Regression:先比较 known-good 与当前版本的相关 changed files、方法和配置;
不要先从当前代码里找“看起来不合理”的地方直接下结论。

偶发自恢复

text
$host-computer-dev
这个问题重试后又正常了。
先按 SuspectedTransient 处理,不要把原因写死;
告诉我下次出现时最应该抓哪些命令、错误队列、状态和时间戳。

15. 验收标准

  • 普通 Bug 有足够证据支持当前结论;
  • Regression 明确 known-good 与当前的行为差异;
  • 自恢复问题没有被过度宣称 RootCauseConfirmed;
  • 修复只覆盖有证据的范围;
  • focused test / simulation / replay / 手工验证与风险匹配;
  • 只读真机查询满足授权和安全条件;
  • 改变真实设备状态但尚未执行的验证明确 HardwarePending
  • Git Diff 没有计划外修改。

下一步

别来无恙 · C# 上位机 AI 实战站 · 从零到交付 · QQ 群:1016188499