Expedia 如何用 AI 遥测分析平台加速生产事故排查

2026-07-23 22 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

生产事故排查通常不是“没有数据”,而是数据分散在日志、指标、链路追踪和事件记录中。工程师需要在高压状态下快速建立时间线、筛选异常服务,并判断哪些信号最可能指向根因。Expedia Group 引入的内部平台 STAR,正是围绕这一过程构建的 AI 辅助可观测性工具。

STAR 将服务遥测数据、结构化调查流程和大语言模型结合起来,帮助工程师分析生产事故、生成根因评估,并支持事件响应。它并没有把最终判断交给模型,而是让工程师保持在决策闭环中。

STAR 解决的不是“看不到”,而是“看不完”

大型服务系统的事故调查往往包含几个重复步骤:

  1. 确定事故发生的时间窗口和受影响服务。
  2. 对比错误率、延迟、吞吐量等关键指标。
  3. 检查相关日志和分布式调用链。
  4. 关联部署、配置变更或依赖服务异常。
  5. 汇总证据,形成根因假设并持续验证。

这些步骤本身并不神秘,但人工执行时容易受到三个因素影响:数据源数量多、调查过程不一致,以及工程师需要在告警噪声中迅速抓住关键变化。

STAR 的价值在于把这些动作组织成结构化工作流。平台可以通过 Datadog 获取服务遥测数据,让 Celery 执行异步分析任务,以 Redis 承担任务队列或状态存储,再通过 Langfuse 记录和观测 LLM 调用。FastAPI 则可以提供面向工程师或其他内部系统的服务接口。

LLM 适合做证据整理,不适合直接拍板

在事故响应中,LLM 的优势通常体现在信息归纳和模式匹配:

  • 将多个服务的异常指标整理成时间线。
  • 从大量日志片段中提取共同错误模式。
  • 对比事故开始前后的遥测变化。
  • 把多个候选原因按照证据强弱排序。
  • 生成适合人工复核的根因评估和下一步建议。

但模型输出仍然可能受到上下文缺失、遥测采样、错误关联和提示词偏差的影响。因此,STAR 采用“工程师在环”的思路更为关键。模型可以提出假设,工程师需要确认证据是否充分,并决定是否执行缓解操作、回滚部署或升级事件等级。

一个可靠的调查结果不应只有一句“可能是数据库故障”,而应包含可追溯证据,例如:

  • 哪个服务在什么时间开始出现错误率上升。
  • 哪些下游调用同时出现超时。
  • 相关部署或配置变更发生在何时。
  • 当前结论是已验证、待验证,还是仅为候选假设。

可以这样设计一次 AI 辅助调查

下面是一个可以改造成内部原型的最小示例。假设已有一个遥测查询函数,它从 Datadog 或其他观测系统获取指定时间窗口内的服务数据;示例使用 FastAPI 接收调查请求,并通过 Celery 异步执行分析任务。LLM 客户端部分用抽象函数表示,接入具体模型时替换 call_llm 即可。

安装依赖:

python -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn celery redis

保存为 app.py

from datetime import datetime
from typing import Any

from celery import Celery
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI(title="Telemetry Investigation API")
celery_app = Celery(
    "star-demo",
    broker="redis://localhost:6379/0",
    backend="redis://localhost:6379/1",
)


class InvestigationRequest(BaseModel):
    service: str
    start: datetime
    end: datetime
    question: str = "What changed and what is the most likely root cause?"


def query_telemetry(service: str, start: datetime, end: datetime) -> dict[str, Any]:
    # 实际接入时,在这里调用 Datadog API,返回指标、日志摘要和依赖信息。
    return {
        "service": service,
        "window": {"start": start.isoformat(), "end": end.isoformat()},
        "signals": [
            "error_rate increased from 0.4% to 8.7%",
            "p95 latency increased from 220ms to 1.9s",
            "downstream payment-api timeout count increased",
        ],
    }


def call_llm(prompt: str) -> str:
    # 替换为实际的 LLM SDK 调用,并记录 trace、耗时和 token 使用量。
    return (
        "候选根因:payment-api 超时可能导致当前服务错误率和延迟上升。"
        "需要工程师核对部署时间、下游健康状态和相关日志。"
    )


@celery_app.task
def investigate(request: dict[str, Any]) -> dict[str, Any]:
    telemetry = query_telemetry(
        request["service"],
        datetime.fromisoformat(request["start"]),
        datetime.fromisoformat(request["end"]),
    )
    prompt = f"""
You are assisting a production incident investigation.
Return: timeline, evidence, candidate causes, confidence, and next checks.
Do not claim a cause is confirmed unless the evidence proves it.
Question: {request['question']}
Telemetry: {telemetry}
"""
    assessment = call_llm(prompt)
    return {"telemetry": telemetry, "assessment": assessment}


@app.post("/investigations")
def create_investigation(request: InvestigationRequest) -> dict[str, str]:
    if request.start >= request.end:
        raise HTTPException(status_code=400, detail="start must be earlier than end")

    task = investigate.delay(request.model_dump(mode="json"))
    return {"task_id": task.id, "status": "queued"}


@app.get("/investigations/{task_id}")
def get_investigation(task_id: str) -> dict[str, Any]:
    result = investigate.AsyncResult(task_id, app=celery_app)
    if result.failed():
        raise HTTPException(status_code=500, detail="investigation failed")
    return {"task_id": task_id, "status": result.status, "result": result.result}

启动 Redis、Celery worker 和 API:

redis-server
celery -A app.celery_app worker --loglevel=INFO
uvicorn app:app --reload --port 8000

提交调查请求:

curl -X POST http://127.0.0.1:8000/investigations \
  -H 'content-type: application/json' \
  -d '{
    "service": "booking-api",
    "start": "2025-01-15T10:00:00Z",
    "end": "2025-01-15T10:15:00Z",
    "question": "Is the incident caused by a recent deployment or a downstream dependency?"
  }'

这个原型体现了几个值得保留的边界:遥测查询和模型调用彼此分离,调查任务异步执行,接口先返回任务 ID,最终结果包含证据和待核对事项,而不是只返回一个未经解释的结论。

落地时要控制三个风险面

数据上下文必须可控。 不要把整个日志系统无差别交给模型。应根据服务、时间窗口、严重级别和关联请求筛选数据,并限制单次上下文大小。必要时先做聚合,再把代表性样本提供给模型。

结果必须可追溯。 每个候选根因都应关联原始指标、日志查询条件、时间范围和模型版本。Langfuse 这类 LLM 可观测工具可以帮助记录提示词、调用延迟和输出,但敏感信息仍需要脱敏和访问控制。

自动化动作必须分级。 生成调查报告可以自动化;执行回滚、扩容、切流或修改配置则应保留审批、权限校验和审计记录。AI 辅助排查的目标是缩短认知路径,不是绕过生产变更流程。

一份适合团队采用的检查清单

  • 为每类事故定义固定的时间窗口、服务范围和关键指标。
  • 要求模型输出时间线、证据、候选原因、置信度和下一步检查项。
  • 把“已确认”和“待验证”作为不同状态保存。
  • 记录遥测查询、提示词、模型输出和人工修订结果。
  • 用历史事故回放评估根因排序的准确性和调查耗时。
  • 为日志、用户数据、令牌和内部配置增加脱敏与权限控制。
  • 让工程师在关键生产操作前明确确认,而不是让模型直接执行。

STAR 所代表的方向并不是用一个聊天窗口替代监控平台,而是把已有的可观测性数据编排成可重复的调查流程。对于拥有大量微服务和多种遥测系统的团队,真正值得衡量的指标包括从告警到形成首个可靠假设的时间、人工翻查数据量、候选根因的验证率,以及事故复盘中可复用的调查步骤。AI 只有嵌入这些工程流程,才能从“会总结”变成能实际缩短事故恢复时间的工具。


相关推荐