Sanskar121543/Smoke-Jumper
GitHub: Sanskar121543/Smoke-Jumper
SmokeJumper 是一个自动化生产事件分诊系统,在告警触发后自动完成严重程度评估、可疑提交排序、runbook 检索、Slack 简报生成和复盘报告撰写的全流程。
Stars: 0 | Forks: 0
# SmokeJumper
[](https://github.com/Sanskar121543/smokejumper/actions/workflows/ci.yml)
**自动化事件响应:告警输入,分诊输出,结束时生成复盘。**
**自动化事件响应:告警输入,分诊输出,结束时生成复盘。**
当生产环境告警触发时,在人类加入频道之前,SmokeJumper 就会回答最初的四个值班问题:*情况有多糟*(严重程度 + 影响范围),*发生了什么变更*(排序后的可疑提交,或明确的“这不是代码问题”),*我们该怎么办*(正确的 runbook),以及*需要通知谁*(Slack 简报)。当事件解决时,它会根据一路记录的结构化事件日志,撰写一份无指责的复盘。
Smokejumper(空降消防员)是指在发现森林大火的那一刻,就伞降到现场的消防员。他们的工作职责也是如此。
```
Alertmanager / PagerDuty webhook
│
▼ ┌──────────────────────────────┐
parse ▸ dedup ▸ impact ▸ SEV1-4 │ culprit ranking over git log │──▸ abstain if no
│ │ + deploys (feature model) │ commit is plausible
▼ └──────────────────────────────┘
runbook retrieval (BM25) ▸ narrator (template | Claude) ▸ Slack Block Kit brief
│
▼
incident record ── resolve() ──▸ postmortem markdown
```
## 测量结果
所有数据均通过 `make eval` 重新生成 —— 包含 200 个留出的故障注入事件(种子 2000-2199),从未在调优过程中见过。完整报告:[`benchmarks/REPORT.md`](benchmarks/REPORT.md)。方法论与有效性威胁:[`docs/DESIGN.md`](docs/DESIGN.md)。
**问题提交识别**(150 起由代码引起的事件,每起包含 40-90 个候选提交;SmokeJumper 的弃权计为漏报):
| 系统 | Top-1 | Top-3 | Top-5 | MRR |
|--------|-------|-------|-------|-----|
| **SmokeJumper** | **76.7%** | **84.7%** | **87.3%** | **0.809** |
| 关键词重叠 | 43.3% | 53.3% | 60.0% | 0.495 |
| 最近提交 | 16.7% | 58.0% | 82.7% | 0.409 |
| 随机 | 0.7% | 4.0% | 7.3% | 0.027 |
| 任务 | 结果 |
|------|--------|
| 基础设施事件的弃权(“无代码元凶”) | F1 0.647(精确率 63.5%,召回率 66.0%) |
| Runbook 检索,包含文档腐化的 100 篇文档语料库 | P@1 77.5%,recall@3 **100%**(词频统计基准:0% —— 塞满的遗留文档每次都会骗过它) |
| 严重程度分类(SEV1-4) | 87.5% 精确匹配,**100% 误差在一级以内** |
| 影响范围估算 vs 隐藏的真实情况 | 23.9% MAPE |
| 分诊延迟(完整 pipeline,每起事件) | **p50 1.5 ms**, p95 2.1 ms |
| 测试 | 88 个测试,96% 覆盖率,受 CI 卡点保护 |
客观解读:训练集 MRR 为 0.944,而测试集为 0.809 —— 这是一个真实的泛化差距,我们将其如实报告而不是掩盖。依赖项升级是最弱的类别(Top-1 为 33.3%),因为罪魁祸首从未触碰过受警报影响的服务的代码 —— 这恰恰是人类也最难处理的事件。按类别划分的详细数据请见报告。
## 快速开始
```
git clone https://github.com/YOUR_USERNAME/smokejumper && cd smokejumper
make install # pip install -e ".[dev]"
make demo # replay a synthetic SEV1 end to end
make test # 88 tests + coverage
make eval # regenerate every number in this README (~10 s)
```
`make demo` 会重放事件种子 2003 —— 一次 API gateway 上的错误部署:
```
SEV1 on gateway: error rate since 00:39 UTC, degrading roughly 30,640 users/min
(26% of traffic). Most likely change: `53571cad` — "add ratelimit fast path" by
june (confidence 71%). Rollback is the fastest mitigation if confirmed.
Suggested runbook: gateway: responding to error rate.
Ground truth culprit: 53571cad... → MATCH (triage took 2.3 ms)
```
将其作为服务运行:
```
make serve # or: docker build -t smokejumper . && docker run -p 8080:8080 smokejumper
curl -X POST localhost:8080/webhook/alert -H 'content-type: application/json' \
-d @examples/sample_alert.json
# → 严重程度、影响范围、嫌疑 commit、runbook、适用于 Slack 的简报(JSON)
curl -X POST localhost:8080/incidents/INC-20260515-001/resolve \
-H 'content-type: application/json' -d '{"note": "rolled back"}'
# → 完整的 postmortem markdown
```
将其指向真实的代码仓库:设置 `SMOKEJUMPER_REPO=/path/to/repo`,SmokeJumper 就会根据实际的 `git log` 历史记录进行分诊(通过 `--numstat` 解析每个文件的代码变动率)。设置 `SLACK_WEBHOOK_URL` 以实际发送简报;若不设置,简报将写入 `out/`(模拟运行)。设置 `ANTHROPIC_API_KEY`(`pip install -e ".[llm]"`)可让 Claude 润色简报和复盘文案 —— 每一个*决策*都保持确定性,并且在任何 API 故障时,模板叙述器都会接管。
## 工作原理
**罪魁祸首排序是一个经过调优的特征模型,而不是 LLM 调用。** 每个提交包含六个信号 —— 时间衰减、部署相关性(它是否在受警报影响的服务的上一次部署中?)、服务拓扑亲和性(拥有该服务 / 依赖项 / 共享库)、告警指纹与 diff 之间的 token 重叠度、代码变动量以及高风险变更标记。权重来自于在独立的 120 个场景训练集上进行的网格搜索 + 坐标上升([`weights.json`](src/smokejumper/data/weights.json) 附带其来源记录)。如果没有提交达到调优后的阈值,SmokeJumper 会明确指出这一点 —— 在真实的基础设施事件中,点出一个无辜的提交会误导响应人员,因此弃权被作为一个独立的任务进行评分。
**Runbook 检索是从零开始的 BM25**(无搜索依赖项),并带有字段加权(标题 x3,标签/服务 x2,正文 x1)。基准测试语料库包含已废弃的 runbook 副本和旧的复盘文档 —— 真实的文档腐化使得单纯的词频统计评分器的 P@1 锁定在 0%,而 BM25 的长度归一化使得当前的 runbook 100% 的时间都能留在 3 篇文档的候选短名单中。
**影响和严重程度是可审计的算术运算。** 受影响的用户/分钟数来自服务目录的流量速率 x 特定症状的退化程度;基于 99.9% SLO 的错误预算消耗;针对影响、层级、影响范围比例和区域数量的严重程度评级规则。每个估算结果都带有其计算依据字符串(`"120,000 rpm x 38% degraded x 67% of regions"`),以便响应人员一眼就能进行合理性检查。
**基准测试在设计上是对抗性的** —— 无辜的提交与罪魁祸首处于同一部署批次中,看起来有风险但其实无辜的提交在事件发生前夕被部署到了受影响的服务上,指纹丢失了 25-55% 的 token 并获得了来自无关服务的干扰信息,且 25% 的事件根本没有罪魁祸首。真实事件的影响情况包含了估算器无法观察到的噪声。详细信息与有效性威胁:[`docs/DESIGN.md`](docs/DESIGN.md)。
## 仓库结构
```
src/smokejumper/
ingest/ alert parsing (Alertmanager + generic), fingerprinting, dedup
triage/ commit_ranker, BM25 runbooks, impact, severity — the measured core
narrate/ template narrator (default) | Claude narrator (optional)
notify/ Slack Block Kit briefs, webhook delivery w/ backoff, dry-run
postmortem/ Google-SRE-style blameless postmortem generator
evals/ scenario generator, baselines, metrics, tuner, benchmark runner
sources.py change sources: in-memory | real git log (--numstat)
pipeline.py the orchestrator; every stage timed
server.py FastAPI: /webhook/alert, /incidents/{id}, /incidents/{id}/resolve
benchmarks/ committed results.json + REPORT.md (regenerate: make eval)
tests/ 88 tests incl. a real-git integration test and benchmark smoke gate
```
## 局限性
这是一个在合成事件上进行评估的系统项目,README 对此直言不讳。生成器和排序器共享相同的信号词汇表(路径、部署、token);真实的事件更加混乱 —— 多因并发、不稳定的告警、反复回滚 —— 因此在真实环境中预期数值会更低。检索有时会优先选择已废弃的 runbook 副本并将其排在第 1 位(具有状态感知的加权是显而易见的修复方法)。依赖项升级事件需要排序器目前尚不具备的日志/trace 特征。CI 将基准测试作为回归卡点运行(排序器必须持续超越每一个基准),因此各项改进都是经过测量的,而非凭空感觉。
## 许可证
MIT
标签:AIOps, 事故管理, 故障排查, 自动化响应, 请求拦截, 逆向工具