Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AI フレンドリーなエラー監視を TypeScript で実現する

AI フレンドリーなエラー監視を TypeScript で実現する

Ubie で取り組んでいる, AI フレンドリーなエラー監視の実践をお話しします

Avatar for Shinobu Hayashi

Shinobu Hayashi

June 03, 2026

More Decks by Shinobu Hayashi

Other Decks in Technology

Transcript

  1. Engineering Talk Error Monitoring TypeScript AI-friendly AI フレンドリーなエラー監視を TypeScript TypeScript

    で実現する エラーを「特定の人の暗黙知」から「チームで回せる仕組み」へ。 Sentry × Honeycomb × n8n × LLM の実践。 ~20 min talk
  2. 00 WHO AM I しにゃい Shinobu Hayashi Software Engineer X

    @Shinyaigeek GitHub @Shinyaigeek 好きな TC39 Proposal do expressions Hobby 料理 ワイン OSS AI フレンドリーなエラー監視 02
  3. THE PROBLEM Sentry は入っていた。 でも、回っていなかった。 導入済み エラーは記録されている。 ツールは入っている。 属人化 見ているのは勘所を持つご

    く少数のメンバーだけ。 そして障害へ 開発が加速した時期、ノイ ズに埋もれて気づけなかっ た。 なぜこうなるのか。構造的な理由が 4つ あります。 AI フレンドリーなエラー監視 03
  4. 理由 01 TOO MUCH NOISE ノイズが、多すぎる オオカミ少年問題 本物のアラートまで「どうせノイズ」と無視される。 Sentry を開くと

    数百件 の Issue。大半はアクション不要。 ネットワーク断・ブラウザ拡張・ResizeObserver・チャンク 失敗。 クリティカルなエラーを探すのは干し草から針を探すのと 同じ。 「全部見る」は精神論。経験者の暗黙知頼みになる。 200+ Issue のうち、 本当に見るべきは ごく一部 4つの構造的な理由 04
  5. 理由 02 THE USER IS OUT OF SIGHT エラーの向こう側のユーザーが見えない toC

    でも toB でも、自分たちの日常や業務プロセスに組み込まれていないと、 開発者は普段の使われ方が見えにくい。 「このエラーでユーザーがどう困っているか」に距離がある。 影響が分からない 再現が難しい。特に入力依存 のエラー。 → 優先度が付かない 影響度が分からないから判断 できない。 → 後回しになる 対処されないまま積み上が る。 4つの構造的な理由 05
  6. 理由 03 NOT MY ISSUE 担当外のエラーが、全部流れてくる モジュラーモノリス / マイクロサービスに複数機能が同居。 Sentry

    プロジェクトも共有 → 担当外のエラーも同じ画 面に。 「これ誰の管轄?」が分からない → スルーする。 全員がスルーする。機能が増えるほど悪化する。 shared Sentry project 機能 A のエラー 機能 B のエラー 機能 C のエラー 誰が見る? 4つの構造的な理由 06
  7. 理由 04 NO BANDWIDTH そして、余裕がない 機能開発に追われる中で、エラーを見て・読み解いて・分類して・対処す るのは重たい。 しかも理由 1〜3 のせいで、見に行っても成果が出にくい。

    これは 怠慢じゃない。構造の問題。 根性論では解決しない。 → 仕組みで解決する。 仕組みで解決する。 4つの構造的な理由 07
  8. 対策 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
  9. 対策 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
  10. 対策 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
  11. 対策 02 WHAT THE ATTRIBUTE AXIS REVEALED 属性軸で見えたもの 総エラー数 8,000

    3,200 ある属性に約 40% 集中 残りは全体に薄く分散 集中 → バッチ処理起因 分散 → コード側の問題 全体数だけ見ると「8,000 件?!」と焦る。 属性別に見れば、切り分けが一発でできる。 進行中 機能軸のタグ付け(W3C Baggage)で FE→BE に feature を伝 播。 「担当外が分からない」を機械的にルーティング。 対策2 — コンテキスト付与 11
  12. 対策 03 READ IT WITH AI · FIRST 「人が見に行く」モデルは、もう限界 再現が難しい

    顧客が見えない 担当外が分からない 余裕がない この4つを抱えたまま「人がエラーを見に行く」運用は、結局 属人化か放 置 に行き着く。 だから、人が見に行く前に、AI に先に読ませる。 人が見に行く前に、AI に先に読ませる。 しかも 既存の Sentry → Slack 通知を壊さずに、後付けで。 対策3 — AI パイプライン 12
  13. 対策 03 WHAT IS N8N そもそも n8n とは ノードを繋いでワークフローを組む、オープンソースの自動化ツール。今回の 「お膳立て役」に選んだ理由は3つ。

    🔌 ノーコード ⇄ コード管理 最初はノーコードで組んで素早く 検証、固まったら JSON でエクス ポートしてコード管理へ。行き来 できる。 🏠 セルフホスト可 自社環境で動かせる。医療データ を外に出さず、社内の認証・ネッ トワーク内で完結。 🤖 AI Agent ノード内蔵 LLM 呼び出しやツール実行をノー ドとしてそのまま組み込める。 対策3 — AI パイプライン 13
  14. 対策 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
  15. 対策 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
  16. 対策 03 GARBAGE IN, GARBAGE OUT AI も、ゴミを渡せばゴミを返す 自律的に調べてくれるとはいえ、出発点が荒れていれば精度は出ない。3つの 前提条件

    ── 対策1・2はそのお膳立てでもあった。 1 ノイズが除去されている 対策不要なエラーを読ませても、AI リ ソースの無駄。Sentry にノイズが溜ま れば Agent が取りに行くデータにも混 じる。 2 コンテキストが付いている 属性・コンテキストがあれば「環境起 因の可能性」まで言える。無ければ 「fetch failed が起きています」止ま り。 3 スタックトレースが readable ソースマップが効いて TypeScript とし て読める状態に。minified コードは AI にも読めない。 対策3 — AI パイプライン 16
  17. HUMAN POWER 最後は、人の手でガッと殴る AI 1次トリアージとコンテキスト付与。 「チーム の誰でも判断できる状態」をつくる。 + 人間 最終判断と修正。仕組みで拾い上げたもの

    に、パワーを集中投下する。 ゴールは「エラーゼロ」じゃない。 目指すのは 「新しいエラーにすぐ気づける状態を維持する」 「新しいエラーにすぐ気づける状態を維持する」こと。 人の手で 17
  18. SUMMARY 属人化 → 仕組み化 FE ignoreErrors / denyUrls / beforeSend

    で ノイズを消す BE Global Exception Filter に集約 + PII マスキン グ Context setTag で属性・コンテキスト / W3C Baggage で機能軸 AI n8n でディスパッチ → Agent が Sentry・トレ ーシング・コードを自律調査 「特定の人の暗黙知に依存した運用」を、仕組みに置き換える。 AI フレンドリー = チームフレンドリー。 AI フレンドリー = チームフレンドリー。 ありがとうございました 🌿 18
  19. 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