2026年7月30日 1 分钟阅读

事故排障时不要只盯仪表盘:SITREP 如何把屏幕线索、Tempo 与 Agent 证据串起来

tinyash 0 条评论

线上事故发生时,信息并不总在一个可检索的地方。你可能刚在 Grafana 面板看到一次尖峰,又在日志窗口扫到半截 trace ID;切去 Slack 回答同事后,原来的面板被覆盖,下一分钟已很难复述「刚才看到的那条证据」。日志、指标和追踪本身也许都在,但人对屏幕瞬时信息的记忆已经断开。

SITREP 是一个面向 macOS 的实验性事故协作工具。它不是替代 Grafana 的告警系统,也不是自动执行修复的自治 Agent;它把事故期间经授权捕捉到的屏幕画面整理为本地时间线,再让一个受限的问答循环从时间线、截图以及 Grafana 的 Tempo/Prometheus 数据中取证。对于「五分钟前那个 trace ID 是什么、慢在何处」一类问题,这种把屏幕线索与后端观测数据接起来的做法很有价值。

先理解它保存的是什么

启动事故会话后,SITREP 通过 Electron 的桌面捕捉能力定期取帧。默认约 15 秒一次,但 README 给出的配置范围是 5 秒到 5 分钟。它不会把每一帧都交给模型:本地会用缩小后的灰度图计算 12×8 的 tile 变化图,并用变化阈值、内容区域和一个六码帧环形缓冲区过滤静止画面及切换窗口后重现的旧画面。

留下的画面会由视觉模型提取为结构化观察:摘要、应用上下文、trace ID、错误文本、服务名、指标、URL、仪表盘和日志行等。结果以 JSONL 和 PNG 存放在用户目录下的 SITREP session 中。这里的关键边界是:JSONL 是本地可检查的事故记忆,而不是一个不可见的向量库;README 说明其初始检索采用本地 token-overlap 打分,因此不必为找回屏幕线索额外调用模型。

对高敏感场景,工具提供 Blackout:暂停后不调用操作系统的 capture API,意味着密码管理器或客户资料窗口不会被新建为帧。恢复前的旧证据仍可查,聊天界面也可继续使用。这个设计不能替代企业数据分级和屏幕录制政策,但比「先全量录下、再事后删除」更适合事故现场。

从屏幕记忆到可核查答案

SITREP 的 Agent 并不直接访问桌面或执行命令。模型只能申请五类由程序实现的工具:search_timelineinspect_frametempo_searchtempo_get_traceprom_query。代码先校验参数并执行,再把结果作为下一轮上下文交回模型;README 设定了最多 8 轮、20 次工具调用与 5 美元上限。

一次典型排障路径是:先用 search_timeline 在提取后的观察中定位「payments-api timeout」;如果字段不完整,再用 inspect_frame 让视觉模型只转录该截图中的完整 trace ID;随后用 tempo_get_trace 取回该 trace 的 span、耗时和错误状态。最终答复不仅可以引用截图帧,还能展开原始 span 树。引用并非让模型在文字里自称「有证据」:工具实际打开帧后,界面才追加对应的证据标记。

Tempo 查询有一个容易忽略的正确性点。SITREP 会从事故会话导出起止时间,并将该时间窗传给 Tempo 的查询。这样既限制了查询范围,也避免 Tempo 只查到当前 ingester、遗漏较早数据后,模型把「没找到」误说成「没有」。对于指标,prom_query 可带一个事故窗口内的时间点,从而回答「工程师看到那张图的瞬间,指标读数是多少」,而不是只给当前值。

用本地 LGTM 栈跑通演示

项目的 README 给出了可复现的本地演示条件:Node.js 20+、macOS;如需接入 Grafana,可先运行单容器 LGTM 栈:

docker run -d --name lgtm \
  -p 3000:3000 -p 4317:4317 -p 4318:4318 \
  grafana/otel-lgtm:latest

接着安装依赖、复制环境变量文件并启动开发模式:

npm install
cp .env.example .env
npm run dev

未设置 ANTHROPIC_API_KEY 时,项目会进入 mock mode:捕捉、去重、时间线、聊天 UI 与工具循环仍执行,但模型响应由确定性的替身提供。这适合先验证权限、会话目录和交互路径。要制造 README 中的演示事故,可安装 OpenTelemetry Python 包并运行:

pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
python scripts/demo-incident.py

随后在 Grafana Explore 的 Tempo 中查看 { .service.name = "payments-api" && status = error },让该页面处于已授权的屏幕捕捉范围,再在 SITREP 中发问。开发机首次运行 Electron 时,需要在 macOS「隐私与安全性 → 屏幕录制」中授权,授权后重启应用。

Agent 自身也应成为可观测对象

SITREP 一个值得借鉴的工程点是自观测。它把模型调用和工具调用通过 OpenTelemetry 发往同一个 LGTM 栈:模型调用使用 GenAI semantic conventions 中的 gen_ai. span 和 token 使用量指标,同时用自己的 sitrep.operation 区分 ingest_frameinspect_framelocate 与聊天操作。README 特别说明没有把自定义美元成本塞入保留的 gen_ai. 命名空间,而是使用 sitrep.gen_ai.cost

这让排障助手本身也能被问责:一次答案消耗了多少 token、哪一次截图复读产生了成本、某次工具调用是否失败,都可以回到同一套观测平台查看。

落地时先划清数据、权限与运行边界

把屏幕作为事故数据源,最大的风险不是模型回答得不够漂亮,而是采集范围失控。建议将 SITREP 的会话视作一次有期限的调试工件:只在明确的事故窗口启用;开始前由值班人员确认当前显示器和窗口没有不应采集的业务资料;结束后检查 session 目录,并按团队留存策略清理 PNG 与 JSONL。Blackout 很适合处理临时打开的密钥、身份信息或客户控制台,但它依赖操作者主动触发,不能把它当成自动脱敏能力。

第二个边界是 Grafana 凭据。项目通过 Grafana datasource proxy 访问 Tempo 与 Prometheus,因此示例中的账号只应出现在隔离的本地演示环境。接入真实环境时,更稳妥的做法是配置只读、范围受限的服务账号,限制可访问的数据源和组织,并将事故窗口作为查询的额外约束。不要因为 Agent 能生成 TraceQL 或 PromQL,就给予它写入告警规则、修改仪表盘或访问无关租户的权限;程序侧固定能力集合,仍应比系统提示词中的「请勿执行危险操作」可靠得多。

第三个边界是证据的可信度。视觉提取会受字体缩放、遮挡、滚动和半截文本影响。SITREP 的提取提示会要求模型不要补全只看见一部分的值,实际排障中仍应把截图识别出的 trace ID 当作线索,并用 tempo_get_trace 返回的原始 span 再确认。相同原则也适用于模型的归因结论:截图告诉你有人看到了什么,Tempo、日志和指标才是用来确认「为什么慢、从哪里失败」的后端证据。

它仍有明确局限:独立工具调用在当前实现中串行执行;后端查询卡住时没有墙钟超时;达到轮数上限时会返回固定提示而非最佳中间答案。因此它更适合辅助人工事故指挥,而非作为无人值守的修复系统。

一个更稳妥的值班使用顺序

如果要把这类工具放入值班流程,建议先从低风险、可复盘的用法开始。事故开始后,由一名工程师负责启动会话并记录会话编号;另一名工程师仍按既有流程确认告警、影响面和缓解动作。SITREP 最适合承担「找回线索」而非「决定动作」:例如把某个错误峰值附近看到的面板、trace ID 或错误码串回时间线,再由人打开原始 Grafana 查询链接确认。

问问题时也应从窄问题开始。与其问「根因是什么」,不如先问「在 14:05 到 14:15 间出现过哪些 payments-api trace ID」「对应 trace 中最长的 span 是哪一个」「该时刻错误率读数是多少」。前两个问题分别落在本地时间线与 Tempo,最后一个落在按时间点求值的 PromQL;每一步都能展示中间证据,下一步的输入也更清楚。确认链路后再讨论根因、回滚或扩容,能减少模型将相关性包装成结论的风险。

会话结束时,导出或保留的应是有明确用途的证据:最终使用的 trace、关键截图帧、关联查询与人工决定。不要把整个屏幕时间线当成长久知识库。事故复盘文档仍应由工程师把事实、时间线、影响范围和行动项整理成正式记录;SITREP 的价值在于减少回忆和窗口切换造成的取证损耗。

SITREP 展示的核心不是「让 AI 看屏幕」本身,而是把短暂视觉线索、可追溯后端证据、调用边界和成本记录放进一个可审计的事故会话。若团队正在处理跨窗口、跨工具导致的上下文丢失问题,可以借鉴它的分层方式:先本地筛选和结构化,再按需调用昂贵模型;先让程序控制数据源和时间范围,再让模型决定下一步问什么。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。