20_调试运维神器:写一个帮你定位Bug并给出修复建议的Skill
工程师喜欢做的一件事是:遇到 Bug,打开对话框,把几百行日志或几十个函数的代码一股脑粘进去,然后问"这是什么问题?"。运气好的时候模型能给出有用的线索,更多时候得到的是"这段代码看起来没有明显错误"或者一个完全偏离方向的猜测。这不是模型不够聪明,这是因为你的使用方式根本就不对。
一、"把日志扔给模型"为什么不管用?
直接把原始日志或代码上下文扔给模型,核心问题有两个:信息过载和信息缺失,而且通常两个问题同时存在。
1.1 信息过载与信息缺失并存
原始日志里有 90% 的内容是正常运行的噪音——健康检查、心跳日志、常规请求记录。模型需要从这堆噪音里识别出真正异常的几行,而这个"识别"过程本身就消耗了大量上下文窗口,还不一定准确。另一方面,日志通常只包含"发生了什么",缺少"当时的系统状态是什么"——哪些服务在运行、最近有没有部署变更、请求量是否异常。没有这些背景信息,模型的分析就是猜。
1.2 上下文爆炸与结构化预处理
一个典型的生产 Bug 场景:服务报错,你打开日志文件,几千行。你的本能反应是"全给模型看",但这会触发上下文窗口的瓶颈,而且大多数信息是无关的。更糟糕的是,代码和日志混在一起时,模型在两类信息之间跳来跳去,分析质量会显著下降。
正确的做法是在把信息交给模型之前做结构化预处理:错误信息单独提取、相关代码单独提取、系统状态单独描述。这就是 Bug 定位 Skill 存在的价值——它定义了"应该提供什么信息、以什么结构提供",让每次 Bug 分析都从一个干净的起点开始,而不是把混乱留给模型处理。工程师的"前期整理成本"降低了,模型的"分析质量"自然就上去了。
二、Bug 定位 Skill 的结构化设计
2.1 五步分析框架
Bug 定位不是单步操作,它是一个有明确逻辑顺序的分析过程。把它压缩成一步会让模型在没有充分信息的情况下跳到结论——这是"把日志扔给模型"失败的另一个根本原因。五步框架把分析过程显式化:信息采集 → 异常识别 → 根因假设 → 修复方案 → 验证建议。每一步有明确的输入和输出,前一步的输出是后一步的输入。
信息采集:从输入中提取关键信息,整理成标准化的 Bug 上下文。输出:错误类型、错误位置、复现条件、相关代码段。
异常识别:从错误信息和代码中识别直接异常点(症状)和潜在异常点(可疑位置)。输出:症状描述 + 可疑点列表。
根因假设:基于症状和可疑点,生成 2-3 个根因假设,每个假设附上支撑证据(来自输入信息)和置信度评估。不要只给一个假设——单一假设的自信输出在 Bug 分析里往往是最危险的,它会让工程师停止思考其他可能性。
修复方案:针对每个根因假设,提供对应的修复方向(不一定是完整代码,重要的是修复逻辑和关键改动点)。
验证建议:如何验证修复是否有效——具体的测试用例、监控指标变化、边界条件检查。
2.2 结构化输入的设计
Skill 的输入设计是控制信息质量的关键。不是让用户"把日志扔进来",而是引导用户提供已结构化的信息:
inputs:
error_message:
type: string
description: "错误消息或异常堆栈(仅错误相关部分,不包含正常日志)"
required: true
relevant_code:
type: string
description: "与错误直接相关的代码段(函数/方法级别,不超过 100 行)"
required: false
system_context:
type: object
description: "系统上下文:runtime(运行环境)、recent_changes(最近变更)、error_frequency(错误频率)"
required: false
reproduction_steps:
type: string
description: "复现步骤(如果已知)"
required: false
language_runtime:
type: string
description: "编程语言和运行时,如 'Python 3.11 / FastAPI'"
required: false
relevant_code 是 optional 而非 required,因为运维场景下工程师可能只有日志没有代码访问权限。Skill 应该在没有代码的情况下仍然能运行,只是分析深度有所降低——这个降级行为应该在 Skill 的 Notes 里明确说明,而不是静默地降质量。
三、完整 Skill 实现与使用示例
3.1 完整 SKILL.md 示例
---
name: bug-investigator
version: "1.0"
description: "结构化 Bug 定位与修复建议。五步分析框架,输出根因假设列表和针对性修复方案"
author: devops-tools
---
# Bug Investigator
## Overview
引导工程师提供结构化的 Bug 上下文,执行五步分析
(信息采集→异常识别→根因假设→修复方案→验证建议),
输出可操作的根因分析报告。不替代工程师决策,但显著加速根因定位过程。
## Inputs
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| error_message | string | 是 | 错误消息或异常堆栈(仅错误相关部分) |
| relevant_code | string | 否 | 直接相关代码段(函数/方法级别,≤100行) |
| system_context | object | 否 | 运行环境、最近变更、错误频率 |
| reproduction_steps | string | 否 | 已知复现步骤 |
| language_runtime | string | 否 | 编程语言和运行时,如"Python 3.11 / FastAPI" |
## Steps
### Step 1: 信息采集与标准化
从输入中提取并整理:
- 错误类型(异常类名 / HTTP 状态码 / 系统信号)
- 错误位置(文件名 + 行号,若可从堆栈中识别)
- 直接触发条件(从 reproduction_steps 或 error_message 上下文推断)
- 最近变更标记(若 system_context.recent_changes 非空,标记为高关注项)
输出标准化 Bug 上下文卡片,供后续步骤使用。
### Step 2: 异常识别
基于标准化上下文,识别:
- 直接症状:错误消息直接指向的代码位置或操作
- 潜在可疑点:与错误类型高度相关的常见根因位置
(如 NPE 通常来自未判 null 的对象访问;连接超时通常来自连接池耗尽或下游服务不可用)
若提供了 relevant_code,在代码中标注可疑行(用行号)。
### Step 3: 根因假设生成
生成 2-3 个根因假设,按置信度降序排列。每个假设格式:
假设 N(置信度:高/中/低):
- 根因描述:[具体的技术描述]
- 支撑证据:[来自输入信息的具体依据]
- 典型触发场景:[这类根因通常在什么条件下出现]
不要生成没有证据支撑的假设。如果信息不足以支撑假设,明确说明需要哪些额外信息。
### Step 4: 修复方案
针对每个根因假设,提供修复方向:
- 关键改动点(具体到函数/配置项层面)
- 修复逻辑说明
- 关键改动的代码片段或伪代码(若有)
- 副作用提示(此修复可能引入的新问题)
### Step 5: 验证建议
提供具体的验证方案:
- 功能验证:如何确认 Bug 已修复(具体测试用例)
- 回归验证:需要检查的相关功能点
- 监控验证:修复上线后观察哪些指标(错误率、延迟、资源使用)
- 边界条件:需要特别测试的边界场景
## Output Format
输出结构化 JSON,示例:
{
"bug_context": {
"error_type": "NullPointerException",
"error_location": "UserService.java:142",
"trigger_condition": "用户未完成邮箱验证时调用 getProfile()"
},
"hypotheses": [
{
"id": "H1",
"confidence": "高",
"root_cause": "user.getProfile() 在 emailVerified=false 时返回 null,调用方未做 null 检查",
"evidence": "堆栈指向 line 142 的 .getName() 调用;user 对象来自可能为 null 的 profileCache",
"fix_direction": "在 line 140 添加 null 检查,或在 getProfile() 中保证非 null 返回"
}
],
"verification": {
"test_cases": ["以未验证邮箱的用户调用 getProfile API,验证不再触发 NPE"],
"metrics_to_watch": ["NullPointerException 异常率", "getProfile 接口 5xx 率"]
}
}
## Error Handling
error_message 为空时拒绝执行并返回输入要求说明。
信息严重不足时,在 hypotheses 字段中说明需要补充的信息,而不是生成无依据的猜测。
## Notes
此 Skill 辅助定位,不替代工程师判断。修复方案需经过代码审查后再上线。
对于涉及安全漏洞的 Bug(如 SQL 注入、XSS),会在输出中添加 security_flag 标记。
3.2 一个实际使用场景
假设你有一个 Python FastAPI 服务,某个接口偶发 500 错误,错误消息是 AttributeError: 'NoneType' object has no attribute 'user_id',堆栈指向 payment_service.py 第 89 行。正确的使用方式是:把这个错误堆栈作为 error_message 传入,把第 85-95 行的相关代码作为 relevant_code 传入,在 system_context 里注明"昨天下午 3 点部署了 payment_service 的新版本,错误从部署后开始出现"。
有了这些结构化输入,Skill 的分析会直接指向:最近部署的变更引入了某个未处理 None 的代码路径,H1 置信度高。而如果你只是把错误消息扔进去,模型能给你的只是"可能是某个对象为 None,建议添加 None 检查"——这种废话你自己也能想到,用不着 AI。结构化输入的差异就是这么大。
四、总结
Bug 定位 Skill 的价值在于用结构强制信息质量。不是让模型更聪明,而是让提问更结构化。五步分析框架确保分析过程完整,结构化输入确保信息质量,多假设输出确保不会在信息不足时过度自信。对于开发和运维工程师来说,这个 Skill 真正有用的时刻,是凌晨两点生产环境报警、脑子转不动的时候——一个有框架的分析流程,比"把日志扔给模型祈祷出奇迹"可靠得多。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)