LangGraph Sentry · 前端性能日报 Agent
English: An automated Web Vitals daily report pipeline: pull real traffic Top-N pages from Sentry, detect anomalies with Core Web Vitals thresholds, deep-dive with a LangGraph ReAct agent (official samples → trace-meta → trace spans), and push a Markdown report to Feishu (Lark).
中文: 基于 LangGraph 的 Sentry 前端性能监控 Agent。每天自动拉取 真实访问量 Top N 页面的 Web Vitals,规则检测异常后,由 ReAct Agent 调用 Sentry 官方样本 API 与 Trace 接口做根因分析,并将日报推送到 飞书群。
为什么值得用 LangGraph?
很多团队会用「cron + 脚本 + 一次 LLM 调用」做日报。本项目在指标异常时会进入 多步、可分支、可调用工具 的调查循环——这正是 LangGraph 比直线脚本更合适的地方:
| 能力 | 直线脚本 | 本项目(LangGraph) |
|---|---|---|
| 无异常时跳过 LLM | 需手写 if | 条件边 detect → generate_report |
| LCP/CLS/INP 分别深挖 | 难维护 | 每指标选最差页面 + 并行 ReAct |
| 证据链(样本 → trace) | 需硬编码顺序 | Agent 自主调用 3 个 Tool |
| 状态与错误收敛 | 散落变量 | 统一 PerfState |
功能亮点
- 真实访问量 Top N:先按
span.op:pageload的count()排序取 Top N 页面,再拉这些页面的 Web Vitals(避免把交互 span 误当 PV)。 - 完整 Web Vitals:
dataset=spans,覆盖 LCP / FCP / INP / CLS / TTFB 与 Sentryperformance_score。 - 规则 + AI 双层分析:Core Web Vitals 阈值检测(warning / critical);异常时进入深挖。
- 官方样本 API 深挖:使用 Sentry Dashboard 同口径的
browser.web_vital.*.value样本(sort=-timestamp),避免按指标值排序捞到极端离群 trace。 - ReAct 工具链:
get_web_vital_samples— 官方过滤样本get_trace_meta— Trace 概览get_trace_spans— 耗时 TopN spans(定位大图、长任务、第三方脚本等)
- 多指标并行深挖:LCP / CLS / INP 各取该指标最差的一页,守护线程并行,整体超时后仍出报告。
- 飞书推送:群机器人 Webhook + 交互卡片(支持签名校验)。
- 定时任务:
main.py schedule每天 09:00(Asia/Shanghai)自动跑。
架构
flowchart TB
subgraph schedule [Scheduler 不在图内]
CRON[APScheduler 每天 09:00]
end
CRON --> RUN[main.py run]
subgraph graph [LangGraph StateGraph]
F[fetch_sentry_metrics]
A[aggregate_metrics]
D[detect_anomalies]
AI[ai_analysis]
G[generate_report]
S[send_to_feishu]
F --> A --> D
D -->|有异常| AI
D -->|无异常| G
AI --> G --> S
end
subgraph react [ai_analysis 内部 ReAct Agent]
T1[get_web_vital_samples]
T2[get_trace_meta]
T3[get_trace_spans]
T1 --> T2 --> T3
end
AI -.-> react
F --> Sentry[(Sentry API)]
react --> Sentry
S --> Feishu[(Feishu Webhook)]
AI --> LLM[(OpenAI-compatible LLM)]
数据流(Sentry 侧)
- Top N 页面:
pageload计数降序 → 得到真实 PV 最高的 transaction 列表。 - 页面指标:对上述页面用 spans 查询拉
p75(LCP/FCP/INP/CLS/TTFB)。 - 深挖样本(每个异常指标 1 页):
has:browser.web_vital.<metric>.value+transaction:[page]+sort=-timestamp- 从最近样本中选
score_ratio最低的一条 → 得到trace_id trace-meta/{id}+trace/{id}→ 证据喂给 LLM
快速开始
环境要求
- Python 3.13+
- uv(推荐)或 pip
- Sentry 组织级 Auth Token(需
event:read、project:read) - 支持 Function Calling 的 OpenAI 兼容 API(默认示例为 DeepSeek / 火山方舟)
- 飞书群机器人 Webhook
安装
git clone git@github.com:zjhlsp/langgraph-sentry.git
cd langgraph-sentry
uv sync
cp .env.example .env
# 编辑 .env 填入 Sentry / LLM / 飞书 配置
运行
# 立即执行一次完整流程(拉数 → 检测 → 深挖 → 报告 → 飞书)
uv run main.py run
# 常驻进程,每天 09:00 (Asia/Shanghai) 触发
uv run main.py schedule
成功时终端会打印报告 Markdown,并显示 已推送飞书: True。
配置说明
复制 .env.example 为 .env:
| 变量 | 说明 | 示例 |
|---|---|---|
SENTRY_BASE_URL | Sentry API 根地址 | https://sentry.io |
SENTRY_ORG | 组织 slug | your-org |
SENTRY_PROJECT | 项目 slug 或数字 ID | my-frontend 或 1234567890123456 |
SENTRY_AUTH_TOKEN | Org/User Auth Token(不是 DSN key) | sntrys_xxxxxxxx... |
SENTRY_ENVIRONMENT | 可选,过滤环境;留空=全环境 | production |
SENTRY_STATS_PERIOD | 统计窗口 | 24h / 7d / 30d |
SENTRY_TOP_N | 只监控访问量最高的前 N 个页面 | 10 |
DEEP_DIVE_TIMEOUT_S | 并行深挖整体超时(秒) | 150 |
DEEPSEEK_API_KEY | LLM API Key | — |
DEEPSEEK_BASE_URL | OpenAI 兼容 Base URL | https://api.deepseek.com |
LLM_MODEL | 模型名(需支持 tools) | deepseek-chat |
FEISHU_WEBHOOK_URL | 飞书群机器人 Webhook | https://open.feishu.cn/open-apis/bot/v2/hook/... |
FEISHU_SECRET | 可选,开启签名校验时填写 | — |
获取 Sentry Token
在 Sentry:Settings → Organization → Auth Tokens(或 User Auth Tokens)创建,勾选:
event:readproject:readorg:read
注意:DSN 里的 32 位 hex 不能用于 REST API,会返回
401 Invalid token。
默认阈值(Core Web Vitals)
在 app/config.py 的 Thresholds 中定义,可通过改代码调整:
| 指标 | 默认阈值 | critical 条件 |
|---|---|---|
| LCP p75 | 2500 ms | > 3750 ms |
| FCP p75 | 1800 ms | > 2700 ms |
| INP p75 | 200 ms | > 300 ms |
| CLS p75 | 0.1 | > 0.15 |
| TTFB p75 | 800 ms | > 1200 ms |
项目结构
langgraph-sentry/
├── main.py # 入口:run / schedule
├── app/
│ ├── graph.py # LangGraph 装配(条件边:无异常跳过 AI)
│ ├── nodes.py # 6 个节点 + 并行深挖逻辑
│ ├── state.py # PerfState / PageMetric / Anomaly
│ ├── config.py # 环境变量与阈值
│ ├── clients.py # Sentry / LLM / 飞书 HTTP 客户端
│ └── tools.py # ReAct 调查工具 + create_react_agent
├── .env.example
├── pyproject.toml
└── uv.lock
深挖 Agent 工作方式
当 detect_anomalies 发现 LCP / CLS / INP 超阈值时:
- 每个指标只选 1 个页面:该指标 p75 最差的那条 transaction(不做 TopK 多页,控制成本)。
- 并行启动 最多 3 个 ReAct 调查(守护线程),共享截止时间
DEEP_DIVE_TIMEOUT_S。 - Agent 按提示调用工具:
- 拉官方 Web Vitals 样本 → 选
score_ratio最低的 trace - 拉 trace-meta / trace-spans → 输出根因与验证手段
- 拉官方 Web Vitals 样本 → 选
- 超时线程不阻塞进程退出;超时项写入报告「调试信息」。
仅 FCP / TTFB 异常、且无 LCP/CLS/INP 异常时,回退为单次 LLM 短文总结(不拉 trace)。
报告示例(节选)
**📊 前端性能日报 · 2026-06-02**
采集页面数:10 | 异常项:5
**⚠️ 异常明细**
🟡 `/` — lcp_p75 = 2637.74 (阈值 2500.00)
🔴 `/products/example` — cls_p75 = 0.32 (阈值 0.10)
**🤖 AI 原因分析**
**🔎 LCP 深挖 · `/`**
...(Hero 大图 + Shopify WPM 阻塞等证据链)...
常见问题
Q: 为什么 Top10 和 Sentry UI 的 Slowest Pageloads 不一致?
A: 我们按 pageload 真实 PV 排序取 Top N,再查性能;不是按 LCP 最慢排序。
Q: INP 为什么是 null?
A: 必须用 dataset=spans 且查询包含 ui.interaction.*;仅 event.type:transaction 拿不到 INP。本项目已处理。
Q: 深挖很慢?
A: 单次完整流程约 2–3 分钟(含 1–3 次 ReAct + 多次 Sentry API)。可调低 DEEP_DIVE_TIMEOUT_S 或只监控更少页面。
Q: 能用 OpenAI / 其他模型吗?
A: 可以,只要 API 兼容 OpenAI Chat Completions 且支持 tools(function calling)。
路线图
- 支持多 Sentry 项目合并日报
- 阈值与环境变量可配置化
- LangSmith 追踪与可观测性
- 钉钉 / Slack Webhook
- GitHub Actions 定时任务示例
贡献
欢迎 Issue / PR!请先不要提交 .env 或真实 Token。
uv sync
uv run main.py run
License
MIT
github:github.com/zjhlsp/lang…