“当生产环境宕机,最棘手的不是找不到数据,而是你连不上这些数据。”这是我们团队在无数次深夜救火后达成的共识。你打开GitHub看最近的提交记录,切到Sentry查报错堆栈,再跳回Slack翻值班同事怎么说的,最后还得去Vercel确认刚是不是有人手滑发了版。四个标签页来回横跳,脑子里要手动对齐不同时区的时间戳,这哪里是排查问题,分明是在拼凑一块被打碎的镜子。

我们实在受够了,于是在“Coral-bean海盗”黑客马拉松上,撸出了一个叫Reef的东西。它的任务就一个:把上面这套手工作坊式的流程自动化。一次调查只产出一份报告,而且根据故障严重程度,还能选择是自动修还是摇人修。这篇文章算是我们的“船长日志”,记录整个搭建过程和用到的Coral框架,如果你也想搭一套类似的事故响应流水线,可以参考这份做法。

打开网易新闻 查看精彩图片

Reef本质上是一个生产事故情报探员。唤醒它的方式有三种。第一种,在仪表盘上用自然语言提问,或者直接丢给它一个Vercel的部署链接。第二种,接上Sentry的Webhook,只要新产生一个错误事件,它就自动开始调查。第三种,从Slack里用斜杠命令唤起——这个功能在后续的生产环境部署里也会开放。一旦被触发,Reef会进入一个有状态的调查循环:它先规划一条查询,通过Coral去执行这条SQL,再对拿到的证据做判定,如果不满意就继续追问,一直循环到它觉得有把握了,才生成最终报告。如果是Webhook触发,报告会直接甩到Slack频道里。

一份完整的Reef报告包含几个关键信息。它会给出一个根因假设,附上完整的多轮追查时间线,列出最可疑的几个提交记录。而且在报告的每一条查询结论后面,都挂着像“coral://query-run/1”这样的可追溯引证,不怕你事后复查。最后还会标出严重等级和对应的处置模式,模式分两种:一种是“autonomous_fix”,直接自己上手改;另一种是“human_agent_paired”,意思是它把证据摆好了,等你这个人类探员做最终判断再动手。

为什么我们选Coral做底座?在没接触Coral之前,你要想串起GitHub、Sentry、Slack、Vercel这些工具做联合诊断,通常得先集成四套不同的接口客户端,然后把各家五花八门的时间格式一一清洗对齐,在应用代码里手动拼表格,最后还得把超大坨的JSON对象硬塞进大语言模型的上下文窗口里。这套操作不但脏,而且脆,随便哪个接口改个字段就崩了。Coral的思路是把这个模型颠倒过来,它把每个外部服务都抽象成SQL表。GitHub是表,Sentry是表,Slack和Vercel也是表。

举个活生生的例子,我们想知道哪些代码合入主干之后,线上才爆出致命错误。用Coral写出来就是这个味道:SELECT g.title AS pr_title, g.number AS pr_number, s.title AS error_message, s.level AS error_level FROM github.pulls g JOIN sentry.issues s ON s.first_seen >= g.merged_at WHERE g.owner = ‘ your-org ’ AND g.repo = ‘your-repo’ AND s.level IN (‘fatal’, ‘error’) AND g.state = ‘closed’ ORDER BY s.first_seen DESC LIMIT 20; 一条查询就穿起了两个完全不搭界的数据源。没有中间仓库,不用搞什么ETL管道,凭证就安安静静留在你自己的机器上,Coral是在查询执行的那一刻才去即时解析接口的。这个带时间条件的关联——也就是找出合并之后才首次出现的错误——正是Reef所依赖的核心洞察逻辑。

如果用一张图来拆解整套架构,你会看到一个非常清晰的单向流动。最上层是三种触发器并行接入:仪表盘、Sentry Webhook和Slack命令。往下一层是调查编排器,它把调查轮次硬性控制在最多五轮,防止钻牛角尖。再拆开看每一轮的内部构成,是由规划器加执行器加裁判组成的闭环。规划器用的是Gemini模型,它负责把自然语言的调查意图转写成Coral能吃的SQL,投喂进Coral CLI去查各类数据源。拿回的原始证据丢给裁判,裁判用的是Groq上跑的Llama 3.3 70B模型,它对证据打分、挑刺、决定要不要再来一轮。这个过程中产出的所有证据