Share
Embed
AI フレンドリーなエラー監視を TypeScript で実現する
Ubie で取り組んでいる, AI フレンドリーなエラー監視の実践をお話しします
Shinobu Hayashi
June 03, 2026
Transcript
19 slides
-
Engineering Talk Error Monitoring TypeScript AI-friendly AI フレンドリーなエラー監視を TypeScript TypeScript
で実現する エラーを「特定の人の暗黙知」から「チームで回せる仕組み」へ。 Sentry × Honeycomb × n8n × LLM の実践。 ~20 min talk -
00 WHO AM I しにゃい Shinobu Hayashi Software Engineer X
@Shinyaigeek GitHub @Shinyaigeek 好きな TC39 Proposal do expressions Hobby 料理 ワイン OSS AI フレンドリーなエラー監視 02 -
THE PROBLEM Sentry は入っていた。 でも、回っていなかった。 導入済み エラーは記録されている。 ツールは入っている。 属人化 見ているのは勘所を持つご
く少数のメンバーだけ。 そして障害へ 開発が加速した時期、ノイ ズに埋もれて気づけなかっ た。 なぜこうなるのか。構造的な理由が 4つ あります。 AI フレンドリーなエラー監視 03 -
理由 01 TOO MUCH NOISE ノイズが、多すぎる オオカミ少年問題 本物のアラートまで「どうせノイズ」と無視される。 Sentry を開くと
数百件 の Issue。大半はアクション不要。 ネットワーク断・ブラウザ拡張・ResizeObserver・チャンク 失敗。 クリティカルなエラーを探すのは干し草から針を探すのと 同じ。 「全部見る」は精神論。経験者の暗黙知頼みになる。 200+ Issue のうち、 本当に見るべきは ごく一部 4つの構造的な理由 04 -
理由 02 THE USER IS OUT OF SIGHT エラーの向こう側のユーザーが見えない toC
でも toB でも、自分たちの日常や業務プロセスに組み込まれていないと、 開発者は普段の使われ方が見えにくい。 「このエラーでユーザーがどう困っているか」に距離がある。 影響が分からない 再現が難しい。特に入力依存 のエラー。 → 優先度が付かない 影響度が分からないから判断 できない。 → 後回しになる 対処されないまま積み上が る。 4つの構造的な理由 05 -
理由 03 NOT MY ISSUE 担当外のエラーが、全部流れてくる モジュラーモノリス / マイクロサービスに複数機能が同居。 Sentry
プロジェクトも共有 → 担当外のエラーも同じ画 面に。 「これ誰の管轄?」が分からない → スルーする。 全員がスルーする。機能が増えるほど悪化する。 shared Sentry project 機能 A のエラー 機能 B のエラー 機能 C のエラー 誰が見る? 4つの構造的な理由 06 -
理由 04 NO BANDWIDTH そして、余裕がない 機能開発に追われる中で、エラーを見て・読み解いて・分類して・対処す るのは重たい。 しかも理由 1〜3 のせいで、見に行っても成果が出にくい。
これは 怠慢じゃない。構造の問題。 根性論では解決しない。 → 仕組みで解決する。 仕組みで解決する。 4つの構造的な理由 07 -
対策 01 KILL THE NOISE · FRONTEND FE のノイズを消す sentry.client.config.ts
Sentry.init({ ignoreErrors: [ 'TypeError: Failed to fetch', // 回線 'TypeError: Load failed', // Safari 'ResizeObserver loop limit exceeded', 'ChunkLoadError', // リロードで解消 /^chrome-extension:\/\//, // 拡張由来 ], denyUrls: [/extensions\//i], beforeSend(event) { const msg = event.exception?.values?.[0]?.value; if (msg?.startsWith('Object captured')) return null; return event; }, }); ignoreErrors 文字列+正規表現でメッセージをマッチ。日本 語・Safari 差分も忘れずに。 denyUrls / beforeSend 発生元 URL を弾き、SDK 由来のノイズを直前にド ロップ。 判断基準 「開発者がアクションできるか?」 No なら消す。 対策1 — ノイズ除去 08 -
対策 01 KILL THE NOISE · BACKEND BE のノイズを消す —
エラー集約ゲートウェイ error-gateway.ts — 全エラーが通る1箇所 function handleError(error: unknown, req: Request) { if (!shouldReport(error)) return; // 送るか判定 Sentry.withScope((scope) => { // 文脈を付与 scope.setTag('account_id', req.accountId); Sentry.captureException(error); }); } function shouldReport(error: unknown): boolean { if (isAbortedRequest(error)) return false; // 切断 const status = getStatusCode(error); // 4xx=ユーザー起因 / 503=意図的停止 → 除外 return status >= 500 && status !== 503; } before-send.ts — PII mask function beforeSendForSentry(event: Sentry.Event) { // ヘルスチェックは除外 if (event.request?.url?.includes('/health')) return null; // 患者名・電話・メール等をマスク const sensitiveFields = [ 'name', 'phone', 'email', 'birthday', 'address', 'patientId', 'message', ]; return maskFields(event, sensitiveFields); } 5xx だけ送る 集約ゲートウェイに1箇所集約 AI に読ませるなら PII マスクは必須 対策1 — ノイズ除去 09 -
対策 02 ADD CONTEXT · USER ATTRIBUTES ユーザーの属性・コンテキストを付与する BE —
認証成功時 // リクエストスコープ内の全エラーに付与 Sentry.setTag('account_id', actor.account.id); FE — PageView (遷移ごと) useEffect(() => { Sentry.setUser({ id: account.id, username: account.name }); Sentry.setTag('account_id', account.id); }, [account]); ⚠ ハマりどころ setUser() だけでは ダッシュボードの タグ集計に出てこない。 集計・フィルタに使うなら setTag() を併 用する。 ドキュメントには明記されていない。 対策2 — コンテキスト付与 10 -
対策 02 WHAT THE ATTRIBUTE AXIS REVEALED 属性軸で見えたもの 総エラー数 8,000
3,200 ある属性に約 40% 集中 残りは全体に薄く分散 集中 → バッチ処理起因 分散 → コード側の問題 全体数だけ見ると「8,000 件?!」と焦る。 属性別に見れば、切り分けが一発でできる。 進行中 機能軸のタグ付け(W3C Baggage)で FE→BE に feature を伝 播。 「担当外が分からない」を機械的にルーティング。 対策2 — コンテキスト付与 11 -
対策 03 READ IT WITH AI · FIRST 「人が見に行く」モデルは、もう限界 再現が難しい
顧客が見えない 担当外が分からない 余裕がない この4つを抱えたまま「人がエラーを見に行く」運用は、結局 属人化か放 置 に行き着く。 だから、人が見に行く前に、AI に先に読ませる。 人が見に行く前に、AI に先に読ませる。 しかも 既存の Sentry → Slack 通知を壊さずに、後付けで。 対策3 — AI パイプライン 12 -
対策 03 WHAT IS N8N そもそも n8n とは ノードを繋いでワークフローを組む、オープンソースの自動化ツール。今回の 「お膳立て役」に選んだ理由は3つ。
🔌 ノーコード ⇄ コード管理 最初はノーコードで組んで素早く 検証、固まったら JSON でエクス ポートしてコード管理へ。行き来 できる。 🏠 セルフホスト可 自社環境で動かせる。医療データ を外に出さず、社内の認証・ネッ トワーク内で完結。 🤖 AI Agent ノード内蔵 LLM 呼び出しやツール実行をノー ドとしてそのまま組み込める。 対策3 — AI パイプライン 13 -
対策 03 ARCHITECTURE · N8N DISPATCHES, THE AGENT INVESTIGATES n8n
はディスパッチャー、調査するのは AI Agent n8n DISPATCHER 軽量・状態を持たない S Sentry Alert → Slack 既存 n8 検知・抽出・プロンプト構成 Slack を polling → Issue URL を抽出 ↩ スレッドで Agent をメンション プロンプトを添えて投げるだけ @infra-agent → 手渡す AI AGENT(infra-agent) 自律的に調査 AI AGENT(infra-agent) 自律的に調査 メンションを受けた Agent が、自分で必要な情報を取りに 行く。 S Sentry — issue 詳細・スタックトレース H トレーシング基盤(Honeycomb 等)— リクエストの流れ { } コードベース — 該当箇所・直近の変更 → 分類・原因仮説・影響範囲・対処案を同じスレッドに返信。 対策3 — AI パイプライン 14 -
対策 03 INSIDE THE N8N WORKFLOW ディスパッチャーの中身 ① Schedule 1分ごとに
polling ② Slack API 対象chの新着を取 得 ③ Filter & Extract & Match Sentry を判定 → Issue URL・プロジェクト名を抽 出 → 設定にマッチ ④ GitHub Releases 直近のリリースを 文脈に ⑤ Compose Prompt プロンプトに統合 ⑥ Slack 返信 スレッドで @infra-agent project-config.ts — 設定を as-code で管理 export const PROJECT_CONFIG: Record<string, Cfg> = { 'web-frontend': { mention: '@infra-agent', prompt: 'FE 観点で重視して', autoFix: false, // PR まで出すか }, 'billing-api': { mention: '@oncall', autoFix: true }, }; mention 呼ぶ Agent / 当番を切り替え prompt チーム固有の観点を注入 autoFix Agent に修正 PR まで出させる 対策3 — AI パイプライン 15 -
対策 03 GARBAGE IN, GARBAGE OUT AI も、ゴミを渡せばゴミを返す 自律的に調べてくれるとはいえ、出発点が荒れていれば精度は出ない。3つの 前提条件
── 対策1・2はそのお膳立てでもあった。 1 ノイズが除去されている 対策不要なエラーを読ませても、AI リ ソースの無駄。Sentry にノイズが溜ま れば Agent が取りに行くデータにも混 じる。 2 コンテキストが付いている 属性・コンテキストがあれば「環境起 因の可能性」まで言える。無ければ 「fetch failed が起きています」止ま り。 3 スタックトレースが readable ソースマップが効いて TypeScript とし て読める状態に。minified コードは AI にも読めない。 対策3 — AI パイプライン 16 -
HUMAN POWER 最後は、人の手でガッと殴る AI 1次トリアージとコンテキスト付与。 「チーム の誰でも判断できる状態」をつくる。 + 人間 最終判断と修正。仕組みで拾い上げたもの
に、パワーを集中投下する。 ゴールは「エラーゼロ」じゃない。 目指すのは 「新しいエラーにすぐ気づける状態を維持する」 「新しいエラーにすぐ気づける状態を維持する」こと。 人の手で 17 -
SUMMARY 属人化 → 仕組み化 FE ignoreErrors / denyUrls / beforeSend
で ノイズを消す BE Global Exception Filter に集約 + PII マスキン グ Context setTag で属性・コンテキスト / W3C Baggage で機能軸 AI n8n でディスパッチ → Agent が Sentry・トレ ーシング・コードを自律調査 「特定の人の暗黙知に依存した運用」を、仕組みに置き換える。 AI フレンドリー = チームフレンドリー。 AI フレンドリー = チームフレンドリー。 ありがとうございました 🌿 18 -
APPENDIX · FURTHER READING もっと知りたい人へ ― 関連記事 本編で触れた infra-agent と
n8n の詳細は、Ubie テックブログに記事があり ます。 infra-agent Slack 上でインフラのトラブルシューティング ができる Agent の設計と実装 Cloud Run × Claude Agent SDK の Bot。透過プロキシ (mitmproxy + VPC 分離)で自律 Agent を安全に。導入2週 で問い合わせ −20% / 解決時間 −31%。 Teruya Ono zenn.dev/ubie_dev/…/b712ec88 n8n n8n を用いて社内業務のドラスティックな業務 改善を狙おう! 〜導入編〜 今回のディスパッチャー基盤の土台。n8n の導入と運用の勘 所、セルフホストでの社内業務自動化の進め方。 syucream zenn.dev/ubie_dev/…/ccd18a2f Appendix 19