☰
AI Agent 接入故障定位:上下文喂法、聚类裁剪与三道护栏(附代码与真实案例)
2026/10/14 15:58:15 网站建设 项目流程

一、案例:Agent 按数量排序,指错了根因

平台是一条全自动流水线:告警 → 接入层 → 预处理 → 根因分析 → 自动派单 → 工单。

那天上午,自动派单成功率 92% →31%,工单积压 80+,根因分析响应 2s →45s。值班同事把最近半小时的日志和告警不加工直接丢给 Agent:什么原因?先处理哪个?

Agent 回答:优先排查工单模块,积压 80 多条,影响面最大。

方向全错。真凶在管道最头上:接入层一个微服务实例内存泄漏触发熔断,告警根本进不来。入口一断,根因分析、派单、工单全是连锁反应——工单积压看着最吓人,是末端的结果,不是原因。

气人的是:那个实例的异常日志只出现了3 次,被2000 多条"派单超时"淹得干干净净。Agent 按数量/显眼程度排序,谁多它看谁。

二、第一种减分:把 Agent 当高级搜索框

"把日志丢给大模型问一问"——这和案例里犯错的是同一个水平。两个致命问题:

  1. 同一份日志问两遍,可能得到两个结论。它说连接池满了,值班照着扩容,扩错了,这二十分钟算谁的?
  2. 日志不能直接丢。原始日志对模型是噪声:重复行、无关 traceback、和故障无关的常规输出,会稀释掉真正的那 3 条关键异常。

改造后的喂法,分三步。

2.1 第一步:按调用链聚类,不按数量

def build_context(alerts, logs, traces): # 1. 按调用链聚组: 同一条 trace 的告警/日志归到入口服务 groups = defaultdict(list) for item in alerts + logs: groups[item.trace_id].append(item) # 2. 组内取首次异常时间 —— 排序依据, 不是条数! for g in groups.values(): g.first_error = min(e.ts for e in g if e.level == "ERROR") g.entry_svc = g[0].root_service # 调用链入口 # 3. 首次异常早的组排前面 (案例里接入层那组只有 3 条, 但时间最早) ranked = sorted(groups.values(), key=lambda g: g.first_error) return [summarize(g) for g in ranked] def summarize(g): return { "entry_service": g.entry_svc, "first_error_ts": g.first_error, "error_samples": sample(g.errors, n=3), # 每组最多 3 条异常样本 "downstream": g.downstream_services, # 它影响谁 (连锁关系) "count": len(g), # 条数只作参考, 不作排序依据 }

十万行日志压成几百行带依赖关系的摘要——这一步之后,Agent 直接指到了入口那个实例。隔离重启,5 分钟全链路恢复。

2.2 第二步:喂给模型的指令模板

你拿到的是按调用链聚类、按首次异常时间排序的故障摘要, 不是原始日志。 任务: 从候选项中选出最可能的根因, 给出排序和证据。 要求: - 每个候选原因必须挂证据(日志样本 ID / 指标名), 没有证据的不要说 - 只输出候选排序, 不下最终结论 —— 结论由人复核 - 禁止编造日志中不存在的细节 - 涉及变更的建议只标注"需要审批", 不要给执行方案

2.3 第三步:让 Agent 排候选,人拍板

别让它直接下结论。它给候选原因排序、每个挂证据,最后拍板的是人——案例里重启入口实例,就是人点的确认。

三、第二种减分:只讲架构,不讲失败

架构图人人会画,面试官想听的是另一半:Agent 判断错了怎么办?生产上至少要有三道闸(配置片段):

agent: tools: allowlist: # 工具白名单: 只注册查询类, 写操作不开 - query_metrics - query_logs - query_traces - query_topology limits: tool_timeout_seconds: 10 # 单次工具调用超时 max_steps_per_session: 15 # 单会话步数封顶: 防它在错误分支转圈烧 token session_timeout_seconds: 300 circuit_breaker: max_consecutive_failures: 3 # 连续失败自动停手 fallback: human_oncall # 降级回人工 policy: read_only_during_triage: true # 定位阶段全程只读, 重启/扩缩容必须人确认

超时和步数上限这两条最容易被忽略:没有它们,Agent 能在同一个错误分支上"调一次、看一眼、再调一次",把 token 预算和排查窗口一起烧光。

四、第三种减分:只谈技术,不谈人和流程

值班同事凭什么信 Agent 的结论?它建议重启入口实例,谁有权批?赶上业务高峰它建议主从切换,出了事谁兜底?

答案是把 Agent塞进现有 oncall 流程,不另起炉灶:

  • 结论必须带证据链接,值班的人自己点开验;
  • 涉及变更的建议,走原有审批流,不给它开特权通道;
  • 每一条建议和执行都留审计日志,复盘能完整回看。

Agent 可以提建议,但它不能变成绕过流程的后门——这条在生产上是当红线守的。

五、面试怎么答:四层结构

  1. 数据怎么接:告警、日志、指标、变更怎么对齐到同一次故障(trace_id / 时间窗对齐);
  2. 上下文怎么喂:聚类裁剪、首次异常排序、摘要压缩(本文第二节);
  3. 护栏怎么设:白名单、只读、超时熔断、步数上限(第三节);
  4. 人机怎么分工:Agent 排候选给证据,人确认、人执行;全程留痕可回放。

把它讲成一次你自己救火的经历,比背十张架构图都管用。

总结

案例的核心教训一句话:喂法决定 Agent 的下限。没聚类直接喂,模型按显眼程度给答案(3 条真异常输给 2000 条噪声);按调用链聚类、按首次异常时间排序之后再喂,它直接命中入口。护栏决定 Agent 的上限:白名单、只读、超时熔断让它错了也错不出去;证据链接和审批流让它进得了流程、绕不过流程。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询