← 返回全部文章
AI / 工程 · 2026-08-18

一个真正能查问题的 Oncall 助手应该怎么设计?

21 min read
说明

先说结论

这篇文章从一个典型的线上指标异常排查场景讲起,想说明一件事:**Oncall 里绝大多数「查问题」,本质是一项高重复、强套路、可以拆解的结构化劳动。**既然是套路活,那自然就想到:能不能交给机器?但真正决定它能不能被托管的,不只是「诊断方法」本身,还有触发、上下文、源码、平台证据、回群闭环这几件事是不是全都够得着。设想中的无人值守链路是这样的:「有人在群里明确 @ → 一个命令行 Agent(类似 Claude Code 那种)在远端开机 → 唤醒一个常驻诊断 Agent → 机器人回复原消息」。难点不在「能不能唤醒」,而在补齐群历史、源码路由、业务能力和案例回放,让它从「会自动响应」升级为「能稳定查出根因」。这篇就把方法论、这条链路的设计,以及还没闭合的源码那一环,放在同一张图里讲清楚。

一个「指标突然大面积取到 -1」的场景

先讲个具体的。设想这样一次告警:一个前端性能指标的值,突然大面积变成了 -1,而且占比一路往上涨,影响了整套性能数据的准确性,被定成高优先级。

这里的 -1 不是「页面加载耗时是负数」,也不是「性能变差了」,而是一个兜底值——上报链路没采到这个字段,系统给它填了个 -1 占位。这个定性,决定了整个排查的方向:到底是去查性能,还是去查采集链路。方向错了,后面全白费。

最后查出来的根因,说破了很简单:某个 A/B 实验,在实验组里把某个「计算这个指标的开关」关掉了。开关一关,字段生成不出来,下游派生指标只能兜底成 -1。实验放量的那一刻,就是曲线的拐点。

但过程一点都不简单。它是一条一路收窄的链,每一步只回答一个问题、只淘汰一种可能,而不是抓着几个猜想同时乱试:

flowchart TD
    A["定性: 是兜底值<br>不是变慢"] --> B["收窄时间: 拆到分钟<br>找到拐点"]
    B --> C["判定端: 单端问题"]
    C --> D["对应版本 + 翻源码<br>排除客户端本体"]
    D --> E["版本/渠道/入口逐维收窄<br>指向公共采集链路"]
    E --> F["拆源字段<br>两个底层字段同步缺失"]
    F --> G["锁定: 计算链路被关闭"]
    G --> H["候选实验逐个对质<br>分组验证实锤真凶"]

几个转折点值得单独拎出来,它们既是这次能查出来的关键,也是后面方法论的来源:

  • **定性先于一切。**先想清楚 -1 是「没采到」而不是「耗时为负」,才知道该去查采集链路。这一步想岔了,后面越查越远。
  • **「单端问题」不等于「这个端的客户端代码有问题」。**确认是单端之后,第一件事是把异常时间窗对到具体的客户端版本,再翻本地代码库看那段时间相关模块有没有改动。翻完发现客户端本体解释不了这个拐点,才把这条线往后放——是验证过再排除,不是拍脑袋跳过。
  • **多个版本一起涨,不等于是发布导致的。**几个版本同步上涨,更可能是流量结构的关系。判断元凶要看异常率、看是不是某个版本独有,而不是看绝对的量。
  • **派生指标出问题,往回拆源字段。**把这个 -1 往下拆成两个底层字段,发现它俩同步缺失、而且集中在「加载其实成功了」的样本里。方向就此从「性能/业务」锁死到「计算链路被人关了」。
  • **实验只认分组数据,不认名字。**好几个名字听起来很像的实验,拿实验组和对照组一分组对比,缺失率没差别,全排除;只有真凶那一个,在时间、影响范围、分组数据三条线上同时对得上,才算实锤。

从这一个案例,我看到了什么普适规律

把上面那个案例的具体细节全部抹掉,你会发现它的骨架跟「性能指标」这四个字毫无关系。它能被抽象成两条通用规律,而这两条规律,恰好都落在机器擅长的地方。这也是我判断「这活能交给机器」的理论支点。

说明

**规律一:一切异常,背后都有一个「动作」**任何指标异常的背后,几乎都能找到某个可枚举的「动作」在触发它:一次发布、一次配置下发、一次实验放量、一段代码变更。排查的实质,就是拿异常的特征(起始时间、端、版本、影响范围)去跟一堆候选动作的特征做匹配,找出时间、范围、命中条件全部对得上的那一个。上面的案例,最后就是收敛到「某个实验在某一刻的放量」这一个动作上。 [!NOTE] 规律二:特征越清晰,越好查异常的特征越清楚,匹配越快。上面的案例时间拐点精确、端也明确,所以几步就收敛了。但不是所有问题都这么友好:影响范围极大的实验、潜伏很久才发作的问题、客户端稳定性问题,它们的时间和端往往很模糊,常规下钻对不上,得靠更重的分析手段(全链路追踪、云端诊断这类)。所以「好不好查」本身是有先验的,取决于特征清不清晰。 两条合起来,就划出了一条很清楚的分工线:**特征明确的动作归因,是高重复、强套路的活,机器不但能干,还比人稳定;只有那些特征模糊、得靠重型工具深挖的疑难杂症,才真正需要人上。**而现实里,Oncall 的绝大多数,都是前者。这就是自动化能撬动的那块价值。

把它整理成一套谁都能用的下钻流程

下面这套流程,是上面案例的直接沉淀。但它不只对性能指标管用,而是覆盖业务指标、性能指标、埋点漏斗等一切「指标类异常」。它同时也是后面训练机器归因能力的知识底座。

步骤动作这一步在回答什么 / 淘汰什么
1定性异常是值异常、量异常、比例异常,还是字段缺失兜底?这决定了去查性能还是查链路
2收窄时间拆到小时甚至分钟,好跟发布、配置、实验的放量时间对表
3判定端单端还是双端?记住单端不等于该端代码;双端更偏服务端 / 配置 / 公共链路
4看版本是不是某个版本独有?多版本同涨要看异常率而不是绝对量,别急着甩锅给发布
5看渠道线上 / 灰度 / 内测 / 自动化,先把流量污染排掉
6看入口链路是单一入口致因,还是多个入口一起异常、共同指向公共链路
7看分子分母只看异常量会被大流量维度带偏,得看异常率和拐点前后的变化
8拆源字段派生指标往回拆底层字段,定位真正缺失的那个点
9逐个验证候选每个发布 / 配置 / 实验都问一句:它的影响范围能不能盖住异常范围?
10分组验证拿实验组 / 对照组分组对比异常率,名字和时间只是线索、不是证据
11回源码解释机制把相关性升级成因果,说清这个动作为什么会导致这个字段异常
12评估影响面是局部业务问题还是基础链路问题?要不要让 owner 止损
说明

**一句话记忆:**先定性,再对表;端 → 版本 → 渠道 → 入口逐维收窄;拆到源字段找转折;拿分组数据实锤;回源码解释;最后量影响面。

不止指标异常:先分类,再对套路

上面那套下钻流程,只是针对「指标类异常」的一个具体套路。把视角再抬高一层就会发现:Oncall 问题可以按「特征形态」分成好几类,每一类都对应一套自己的归因套路和工具集。指标异常只是其中之一。

所以真正能复制的,不是那一套指标下钻流程本身,而是「先给问题分类,再匹配对应的归因套路」这个元方法。

问题类型典型特征 / 信号对应套路与工具
指标异常(上面的案例)某指标的值 / 量 / 占比在某个时间点跳变维度下钻 + 动作匹配 + 分组验证
崩溃 / 异常率上涨崩溃曲线抬升,常伴随版本或机型聚集堆栈聚类 + 版本 / 机型下钻 + 变更比对
接口错误 / 成功率下跌错误码占比上升,服务端曲线联动错误码下钻 + 上下游链路追踪 + 发布对齐
漏斗 / 转化率异常某个环节转化率突然下降逐事件拆解 + 埋点有效性核查 + 分端分版本
稳定性 / 性能劣化特征模糊、潜伏期长、没有明显拐点重型能力:全链路追踪、云端诊断、长周期归因

这张表本身就是一份可以不断扩充的「归因套路库」。每新增一类问题,就沉淀一套对应的判定信号和工具编排。**问题分类越细、每类套路越成熟,机器能自动覆盖的面就越广。**这是把单点经验放大成体系能力的关键。

既然是套路活,能不能交给机器

既然特征明确的动作归因是套路活,机器又比人稳定,那顺理成章的下一步就是:能不能让一个 Agent 把「从接手问题到给出止损建议」这段闭环接过去?

设想用一个常驻的诊断 Agent(跑在类似 Claude Code 那种命令行 Agent 上)来接这件事。最初它得靠开发者坐在图形界面前手动开任务,更理想的形态是让它脱离个人的在线状态:常驻在一台远端机器上,由协作群里的一个明确求助信号主动唤醒。

说明

说明:这里的「离线化」不是断网运行,而是脱离某个人在不在线。事件一到就启动任务,人只在权限、证据缺口、高风险决策这几个点上介入。

整条链路是这样的,把「触发、上下文、源码、诊断、回复」拆成彼此可验证的环节:

flowchart TD
    A[邀请机器人入群] --> B["只登记待命<br>不执行 不发言"]
    C["真人明确 @ + 行动意图"] --> D[IM 事件总线]
    D --> E["按消息 ID 唯一认领 (SQLite)<br>防止重复执行"]
    E --> F[拉取群历史 附件 链接]
    F --> G[源码路由与证据源选择]
    G --> H["本地预置仓库<br>主路径"]
    G --> I["代码平台远程查询<br>补充路径"]
    G --> J["无源码<br>只初诊并声明缺口"]
    H --> K["CLI 工具唤醒远端 iLoop Agent"]
    I --> K
    J --> K
    K --> L[病例 多假设 逐条取证]
    L --> M[机器人回复原消息]
    M --> N[新消息继续进入同一病例]
  1. **受控触发。**邀请机器人入群只是「布防」,它不启动任务也不发言;只有真人真正 @ 它、并且表达了「看一下 / 排查 / 处理」这类行动意图,才会执行。光 @ 一下、打个招呼、机器人自己发的消息、单纯拉进群,全都过滤掉,也避免图形界面里的任务和远端任务互相唤醒。
  2. **上下文自动收集。**按群拉取历史消息、截图、视频、文件和链接,攒成一份问题简报。这一步要用「用户身份」去读群,远端授权补齐后才能从「代码就绪」变成「现场可用」。
  3. **源码路由。**根据「群到仓库」的显式映射,选中对应的本地预置仓库;本地仓为主,代码平台的定向查询为辅。没有源码时只做初诊、并明确说清缺口,绝不把「平台上看到的相关性」冒充成「源码层面的机制根因」。
  4. **远端 Agent 唤醒。**事件总线对每条消息 ID 做唯一认领(用 SQLite 落主键,避免同一条消息被消费两次),再通过一个伪终端拉起远端的 CLI 工具;主 Agent 必须显式调用 iLoop 子 Agent,而不是把一句「@iloop」当成已经切过去了。
  5. **持续诊断。**问题简报进入一份共享病例;Agent 保留多个假设,每一轮生成一条最该验证的检查,按本机实际能用的能力(数据平台、实验平台、日志、源码等)挑下一条最有价值的证据。
  6. **回群与续诊。**机器人以自己的身份回复原消息、并回读消息 ID 确认发出;后续新证据继续进入同一份病例。而提交代码、发布、回滚、关单这些高风险写操作,始终留着人工闸门。
说明

**这条链的价值:**它把这样一个 Agent 从「开发者在线时主动去用的提效工具」,往「事件一到就自动开工的值守能力」推了一步。但要诚实:调度和回复的主链跑通,跟「能稳定完成业务根因定位」是两码事——后者还得看群历史、业务源码、平台证据这些是不是全都够得着。

持续诊断,而不是「一次分科」

说明

**核心变化:**通用诊断路由不再试图一次判断「这是什么问题」,而是持续判断「下一条最值得取的证据是什么」。路由的对象是下一次检查,不是整个案件。

真实问题经常只有一个模糊的表象:「按钮不太对」「偶发白屏」「指标突然涨了」。如果初诊一上来就把整个问题永久交给某个专家模块,一旦分科错了,后面就会朝着错误方向越查越深。

所以架构上换了个思路:诊断主治 + 方法专家 + 平台适配器 + 共享病例。主治保留多个候选根因,专家只回答被限定的那个问题,平台只负责产出证据,新证据回来后允许重新分诊。

五层职责,各管各的

层负责什么明确不负责什么
协作层从群、链接、截图、用户输入接上下文;回群、@ owner、持续观察不凭「消息来自哪个群」就直接判定根因领域
诊断主治症状归一化、假设管理、选择检查、证据收敛、下最终结论不亲自实现所有平台查询
方法专家指标、数据有效性、UI、接口、发布、实验、代码等限定问题不从局部视角接管整个案件
平台适配器各类数据 / 实验 / 崩溃 / 代码 / 日志平台产出原始证据不把平台输出直接当成因果结论
执行层修复、编译、验证、回滚、止损不重复做根因初诊

依赖方向始终指向通用的诊断协议:平台和专家可以依赖病例和会诊协议,但诊断内核不能反过来依赖某个具体平台。这样新增一个检查平台,只要注册一下能力,不用去改诊断状态机。

共享病例:让跨领域的证据进同一个上下文

复杂问题会在不同时间调用多个专家。要是没有共享病例,数据平台的结论、代码判断、实验验证、群里的追问就会散落在一堆不同对话里。所以每个复杂问题都建一份病例,统一记录症状、假设、证据、会诊、路由历史、下一步和最终结论。这份文件用的是 JSON 兼容的 YAML——它本身就是 JSON 的超集,标准库能稳定读写,人和命令行也能直接看,不用额外引 YAML 解析依赖:

case_id: 2025xxxx-example
status: diagnosing
symptom:
  raw: 某指标突然大面积取到 -1
routing:
  primary_expert: metric_anomaly       # 主诊:指标异常
  consult_experts:                      # 会诊
    - data_validity                     #   数据有效性
    - experiment_causality              #   实验因果
hypotheses:
  - id: H001
    statement: 源字段没有生成
    status: active
    confidence: low
    evidence_for: []
    evidence_against: []
evidence:
  - id: E001
    kind: metric_query
    relation: supports
    hypothesis_ids: [H001]
next_action: 拿到实验分组后做对照组验证

动态路由:直接症状优先,关联专家只做会诊

  1. **先认来源。**先识别证据来自哪里(群、数据平台、实验平台、代码、截图)。来源只决定「有哪些检查工具能用」,不决定根因。
  2. **直接命中方法专家。**按钮 / 页面优先 UI,指标 / 占比优先指标,崩溃优先稳定性,接口字段优先数据契约。
  3. **补充关联会诊。**UI 问题常常要拉接口、代码、发布来会诊;指标问题常常要拉数据有效性、实验、发布、代码会诊。
  4. **直接命中优先于关联加权。**比如「按钮不响应」必须以 UI 为主诊,不能因为 UI 常跟接口相关,就被接口专家抢了主诊。
  5. **只选下一条高价值检查。**优先那些能证伪假设、成本低、结果可复现的检查,不默认把所有工具跑一遍。
  6. **允许换科。**专家返回「跨领域」、证据互相打架、或者连着两轮都没能增强或排除任何假设时,就重新初诊。

专家会诊协议:给个限定问题,不是「把整个案子解决掉」

专家收到的是一个限定问题,返回值必须显式区分「支持 / 反驳 / 证据不足 / 跨领域」,并给出剩余的不确定性和下一条检查:

{
  "verdict": "supports | contradicts | inconclusive | cross_domain",
  "summary": "这个专家建立了什么",
  "evidence_ids": ["E001"],
  "remaining_uncertainty": "还不知道什么",
  "suggested_experts": ["code_impact"],
  "next_test": "下一条最有区分度的检查"
}

专家不许拿一个局部平台结果就宣布整案解决;当自己的证据解释不了完整影响范围时,必须返回 cross_domain,让主治换科或者追加会诊。

根因收敛 Gate:四条都闭合,才能结案

闸门要求
时间匹配异常拐点跟版本、实验、配置或发布的时刻对得上
范围匹配候选根因能盖住异常的平台、版本、入口、页面、人群,不能用局部变化解释全局现象
机制匹配代码、配置或数据行为能解释具体字段或运行表现
反事实证据条件允许时,比一比实验对照组、没受影响的版本 / 入口、或变化前后的窗口
说明

四条没闭合时,只能标「支持」或「证据不足」,不能结案。这个约束是为了避免把相关性写成因果,也避免某个平台专家拿自己的局部视角顶替最终结论。

光有诊断逻辑不够,还得够得着源码和证据

上面那个案例本身就说明了一件事:指标、实验、日志只能把候选范围收窄;要把「相关性」升级成「机制因果」,最后还是得靠源码来解释。所以一条无人值守的链路,不能只有事件和平台查询,还必须有一条独立的源码平面——它得知道「该看哪份代码」。

难点在大型客户端工程上尤其突出。一个超大的单体仓库动辄几十 GB,本地副本很容易就落后于远端最新分支好多天。这里最容易踩的坑是:调度链路即便跑通了,如果远端机上的本地仓还停在很久以前、或者群还没绑定到具体仓库,任务进的就是一个只有版本控制元信息的空工作区——也就是说,**只证明了「能被唤醒」,还没证明「读到了源码」。**如果 Agent 拿着一份过时的代码去解释今天的问题,那还不如不解释。所以源码这条线得单独设计策略:

源码路径适用场景边界
本地预置仓库跨文件检索、调用链、生成配置、历史比对、工程接入和后续修复;客户端大仓应该以这个为主不在故障发生时临时拉代码。接入阶段就提前下载、鉴权、更新,并做「新鲜度」检查;任务只读用稳定快照或隔离副本
代码平台远程查询查仓库元信息、最新提交、指定文件、改动记录、CI 证据;本地仓没就绪时快速补一条定向证据适合「已知仓库 / 文件 / 提交」的精确查询,替代不了大范围本地检索、工程生成、依赖解析和构建验证
无源码降级只根据群消息、指标、日志、实验和配置做初诊必须打上「缺源码上下文」的标记,不能给源码根因下定论;提示补仓库路由
说明

**推荐策略:**本地仓为主、代码平台为辅、没源码就诚实降级。

仓库的准备,应该发生在业务接入期,而不是 Oncall 的关键路径上:一次性准备好专用的只读副本,记清楚仓库地址、默认分支、目标版本、更新时间、以及哪些群可以访问它;每来一个事件,只做「群 → 仓库别名 → 本地快照」的解析。如果一个群同时牵涉客户端、服务端、配置好几个仓,那路由的目标就应该是一组候选仓,而不是一个写死的单一映射。

安全上有几条红线:不允许根据群消息里的任意链接自动拉代码;不在共享的开发者工作区里执行切换分支、拉取或清理;仓库必须来自接入时确认好的白名单;自动任务默认只读。远端 Linux 机器可以做静态分析和平台取证,真要客户端编译或真机验证时,再委托给专门的构建机去做。

工具可以换,经验才决定怎么组合

说明

**一句提醒:**上面案例里用到的数据平台、实验平台、监控平台、源码,都是那一次实际选中的检查工具,不是写死的通用流水线。换个 case 完全可以选别的平台。诊断内核只关心两件事:「下一条要验证什么」和「哪个能力能产出这类证据」。

层次负责什么举例
输入适配把用户给的材料转成能诊断的上下文,不判断根因群消息、文字、截图、视频、平台链接;视频可以先抽关键帧和时间线
诊断方法定义某类问题该查什么、要什么证据、什么结果支持或反驳假设指标异常、数据有效性、实验因果、发布变更、接口契约、UI 行为、稳定性
平台能力通过各平台执行查询、返回原始证据;新增平台只注册能力,不改主治状态机数据 / 实验 / 崩溃 / 监控 / 代码 / 日志 / UI 树等平台
编排经验根据当前假设和证据挑下一条检查;决定继续收窄、扩大范围、换方向还是找人补信息分组对比否掉候选后就扩大实验搜索;局部代码解释不了全局影响面时转查共享配置

所以一个 case 不是固定流程,而是在「诊断方法 × 平台能力」这张图上走出来的一条动态路径。同一个平台可以查很多次、每次回答不同问题;某次检查没证明候选根因,也要作为负证据写回病例,免得后面重复绕路。真正该沉淀的不是「先查 A 再查 B 再查 C」这个顺序,而是四类可复用资产:完整轨迹(含负证据)、换方向的决策规则、每类问题的检查方法、平台调用与证据格式。

分几步走:一条老实的路线

说能力,得把话说准,别把一次跑通夸成生产成熟。按完成口径,可以把它分成三段:

阶段目标完成口径难点所在
P0无人值守调度主链明确 @ 后,事件被唯一消费;远端命令行 Agent 启动并调用诊断子 Agent;机器人回复原消息;重复事件不重复执行相对好落地,是整条链的地基
P1真实业务诊断闭环远端能以用户身份读群历史和附件;群能路由到新鲜、可读的业务仓库;数据 / 实验 / 日志 / 源码等证据真实重跑;追问进入同一病例真正的硬骨头,决定能不能独立归因
P2跨业务规模化一键部署、仓库目录与多仓路由、能力体检、业务扩展包、案例回放、资源配额、开机自恢复和灰度治理,形成标准产品工程量最大,属于长期建设
说明

**P1 才是关键:**重点不是继续堆平台数量,而是先补齐远端用户读群授权、业务大仓的更新与群路由、案例的数据 / 实验 / 源码重跑,以及追问续诊。它们决定「能自动响应」能不能升级成「能独立归因」。

跨业务复制:共用底座,但不承诺零配置

把这套东西搬到另一个业务的远端机上,基础设施成本不高,但业务接入成本不会为零。事件消费、防重复、Agent 唤醒、病例、证据 Gate、回群、安全闸门——这些都能复用。真正需要业务方自己提供的,是这四样:

接入层要做什么成本
通用运行底座装好 Agent 运行环境、IM 应用与事件、常驻服务、权限、资源和健康检查一次性、低,大部分能自动化,人工只处理账号授权
业务源码与上下文预置仓库,配好「群 → 仓库 / 版本 / owner」的路由;把产品文档、黑话、接口、验收口径喂进去中等,这是从「能响应」到「能定位」的关键
领域诊断包用独立扩展声明业务流程、检查方法、领域脚本和专家角色;装好对应平台能力并验证权限随业务复杂度增长,优先从高频、特征明确的两三类问题开始
生产验收拿历史 case 离线回放,再在测试群验证触发、取证、追问、回复、资源、恢复和失败止损不可省,它决定能不能从 Demo 进入托管

架构上不需要为每个业务推翻内核。公共机制留在核心;业务定制通过独立的扩展目录隔离——业务流程写「这类问题怎么查」,领域脚本处理结构化计算,角色定义子 Agent,业务材料单独进输入,长期工程红线单独进约束。扩展可以独立建仓、独立升级,核心更新不会覆盖业务包。

说明

**注意:**自动化不追求「对所有业务零配置、对所有问题开箱即用」。公共底座负责可靠触发、病例、证据和安全边界;业务得提供仓库、上下文、领域能力和验收 case。宁可先把高频、特征明确的类型做深做稳,也别做一个覆盖面广、却缺源码、缺权限、天天误判的黑盒。

结语:可复用的到底是什么

回头看开头那个案例:如果它只被记成一句「某个实验翻错了开关」,那对下一个指标、下一个业务就毫无价值——换个场景还得从头再查一遍。真正能沉淀下来、能跨场景复用的,不是某一次的结论,而是三层资产。

资产层是什么复用方式
一套诊断方法学先分类再匹配套路,指标类走十二步下钻,其它类型各有各的归因编排;主治保留多假设、逐条取证、四门收敛才结案沉淀成套路库,越用越厚,不绑定具体业务
一条无人值守的闭环事件触发、防重、唤醒、病例、取证、回群,人只在权限和高风险决策处介入基础设施可直接搬到别的业务的远端机上
一批可安装的业务能力包源码路由、领域上下文、诊断脚本、专家角色、验收 case,按业务独立建仓随业务接入,插件式装载,不覆盖公共内核

这三层的边界很清楚:方法学和闭环是公共底座,一次投入长期受用;业务能力包是每个业务自己的成本,决定了这套东西在这个业务上到底能查到多深。把它们混在一起,就会得到一个「看起来什么都能查、实际什么都查不准」的黑盒。

说明

**最后一句:**不要把它包装成「一个零配置的通用 Agent」。它更诚实的形态是——公共底座 + 可安装的业务能力包 + 可回放的验收 case。底座保证它能可靠地开工,业务包决定它能查到多深,验收 case 决定它能不能从 Demo 走进托管。当前无人值守调度已经跑通,下一步就用完整的 case 回放和第二个业务接入,来验证这条复制路径。

100%