关于 gjalla-debug
gjalla-debug 是供 Agent 使用的调试技能,强调先核实现象、追查根因并记录证据,再提出修复方案。对于复杂改动,它会引导转交给 gjalla-spec。
主要功能
- 01精确定义故障现象
- 02复现问题或明确说明未复现
- 03区分观察事实与推断
- 04分析根因和影响范围
- 05通过测试验证诊断
- 06生成结构化诊断报告
适用场景
- 01调查偶发或描述模糊的故障
- 02核实疑似原因是否有证据支持
- 03查找代码库中重复出现的缺陷
- 04为复杂修复准备经过验证的交接
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gjalla/ engineering --skill gjalla-debug安装后在 Claude Code 中输入/gjalla-debug确认已加载。
详细介绍
调试
你的工作暂时不是修复问题,而是查明实际情况,并能够展示调查过程。自信地给出错误诊断,比没有诊断代价更高,因为之后基于它做的一切都得推倒重来。
整个过程中都要警惕一种失误:过早形成理论,然后只看能证实它的内容。身处其中时,片面的调查感觉和完整的调查完全一样。
流程
1. 准确界定症状
动代码之前,先弄清楚实际观察到了什么:谁在什么界面上,以哪些输入,多久遇到一次,从什么时候开始。“出问题了”和“同一会话中的第二次保存会返回过期数据”会引出截然不同的调查。
如果报告很含糊,首先要做的不是修复,而是把问题描述得更准确。
2. 复现问题,或者坦白说无法复现
运行程序。既然可以观察实际行为,就不要只推理代码会如何运行。仅靠阅读代码追踪流程,容易让 Bug 藏在条件分支、描述早已不存在的代码的过期注释,以及只在生产环境中出现的数据形态后面。
如果无法复现,就明确说明,并转而收集不需要复现的证据:日志、遥测数据、数据库状态、错误报告。无法复现的 Bug 仍然可以诊断,但置信度不同,报告时也应该明确说明。
3. 确认你读到的是当前版本
这很容易做到,但如果跳过,就可能让整场调查失去意义。确认检出的代码与已部署版本一致,没有在查看过期的工作树或供应商副本,并且查阅的缓存产物近期重新生成过。废弃分支上的 grep 结果,看起来和现行代码中的 grep 结果一模一样。
4. 提出理论之前先收集背景信息
查看 gjalla 中已有的知识:规则、记忆和变更历史往往记载着你即将重新发现的确切陷阱,而架构信息会告诉你哪些组件实际处于调用路径中。可能已经有人遇到过这个问题,并记录了原因。
5. 将观察结果与推断分开
在自己的笔记和报告中都要明确区分。“响应正文为空”是观察结果。“序列化器丢弃了该字段”是推断。推断得到确认之前,需要对照代码或数据进行验证;如果某项推断始终未获确认,报告时就要将其标明为推断。
6. 找到根本原因,而不是只找能让症状消失的第一处问题
要追问为什么会进入故障状态,而不只是找出是哪一行代码造成的。缺少保护通常只是表面症状,背后往往是某种机制没有自然地强制维持不变量。
调整任何限制、超时、重试次数或预算之前,先查看 git 历史和注释,确认其设计意图。这些数值往往是有意设定的,而且可能是因为之前发生过事故才设定的。
7. 在整个代码库中梳理 Bug 的表现形式
确认缺陷的表现形式后,在整个代码库中搜索其模式:未使用保护措施就调用的方法、未使用的辅助函数,以及重复出现的类似模式。然后报告数量。只修复你发现的一处,而放任其他三处留存,过一个月同样的问题就会再次被报告。
如果该模式跨越服务边界,也要检查其他代码库。
8. 证明你的判断
证明你找到了真正原因的方式,是编写一个现在会失败、修复后会通过的测试,而且通过的原因正确。条件允许时,应在修复前先写测试。如果拟议的修复没有改变测试结果,那么无论这个说法听起来多么可信,原因都找错了。
输出
- 症状:具体观察到了什么,以及在什么条件下出现。
- 根本原因:问题发生的机制,并提供文件:行号作为证据。
- 为何会出现这种情况:是什么让这种状态得以存在,而不只是问题在哪里显现。
- 影响范围:列出所有其他出现这种情况的地方,并注明数量。
- 置信度:哪些内容是你直接验证的,哪些是推断的,哪些无法确定。
- 建议修复方案:包括用于验证修复效果的测试。
如果修复并非简单,或涉及系统原语,请在此处停止,并将工作移交给 gjalla-spec,而不要直接实施。
原则
- 证据胜于推理。 能运行、观察或查询时,就去做,而不是只根据代码推断。
- 如实报告未知项。 “我无法复现此问题,诊断依据是一条日志”是有用且诚实的发现。盲目自信不是。
- Bug 很少出现在最初显现的位置。 堆栈跟踪会告诉你问题在哪里变得可见,而这通常比问题实际发生的地方晚好几层。
- 保存你的发现。 非显而易见的原因正是应该记入 gjalla 记忆的内容,这样下一个 Agent,或未来的你,就不必重新发现它:
gjalla memory add "<the fact>" -n "<short-name>"。