以下の内容はhttps://tech.enechange.co.jp/entry/2026/03/18/193500より取得しました。


Claude Code カスタムスキルでアラート対応を効率化する

こんにちは、ENECHANGEエンジニアの藤巻です。

私たちのチームでは、本番環境のアラート対応にBugSnag と CloudWatchを使っています。
既知のアラートについては Notion に対応方針をまとめているのですが、慣れていないメンバーにとっては、Notion を検索して該当記事を探し、手順を読み、本番環境を確認するという一連の流れがなかなか大変です。

この記事では、Claude Code のカスタムスキル機能を使って、アラートの対応を効率化した事例を紹介します。

はじめに

私が所属するチームでサービスのバックエンドでは、BugSnag によるアプリケーションエラー監視と CloudWatch によるインフラ監視を行っています。
アラートは Slack に通知され、エンジニアが対応します。

対応方針は Notion のデータベースに蓄積されており、手順自体は整理されています。
実際にアラートが来たときの作業はこんな感じです:

  1. Slack 通知からエラーの種類・発生箇所を読み取る
  2. Notion でキーワード検索して、既知のアラートか確認する
  3. 該当する記事を開いて、確認手順を読む
  4. 本番環境で状況を確認する
  5. 結果を判断して、必要なら関係者に報告する

これを日常的に対応しているメンバーは問題なくこなせますが、普段対応していないメンバーにとっては、どこから手をつければいいか迷うことがあります。
「このエラーメッセージ、Notion のどの記事に対応してるんだっけ?」「確認コマンドはどう打てばいい?」といった具合です。

そこで、アラートメッセージを貼り付けるだけで、既知アラートの突合から確認手順の提示までを自動で行う Claude Code スキルを作りました。

スキル全体のワークフローは以下の通りです:

Claude Code スキルとは

Claude Code には「スキル」というカスタマイズ機能があります。SKILL.md というMarkdownファイルにワークフローを記述すると、Claude Code がその手順に従って動作します。

.claude/skills/my-skill/
└── SKILL.md    # スキル定義(ワークフロー)

スキルの起動方法は 2 種類あります。ユーザーがスラッシュコマンドで明示的に呼び出す方法と、ユーザーの発言内容から Claude Code が自動的に判断して起動する方法です。 自動起動の判断には、SKILL.md の frontmatter に記載する description フィールドが使われます。ワークフロー本体(markdown 部分)は、起動後に初めて読み込まれます。

今回のスキルの frontmatter は以下のようになっています:

---
name: alert-triage
description: BugSnag/CloudWatchアラート発生時の初動対応をフォローする。アラートメッセージを貼り付けると、既知アラートDBと突合し、対応方針・確認手順を表示。
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, mcp__notion__*
---

description にアラート対応である旨を書いておくことで、Slack 通知を貼り付けるだけでスキルが自動起動します。allowed-tools にはファイル操作系のツールに加え、Notion MCP のツールを指定しています。

設計: 5つのフェーズ

スキルのワークフローは 5 つのフェーズで構成しました。

アラート貼り付け → 解析 → 突合 → 対応提示 → (未知なら調査) → (事後処理)

Phase 1: アラートメッセージ解析

BugSnag の Slack 通知は、改行なしの 1 行で届くことが多く、人間が読むにはやや辛いフォーマットです。

Event in production:prod from my-project - prod in users#create (details)Handled errorActiveRecord::RecordNotFound: Couldn't find User with [WHERE ...]Locationapp/services/user_registration_service.rb:54 - register

SKILL.md にパースルールを定義しておくことで、Claude Code がこのメッセージから情報を自動抽出します。実際の SKILL.md には、以下のようなテーブルでセパレータと抽出方法を定義しています:

**形式1: BugSnag Slack通知**

Event in production:prod from <プロジェクト名> - prod in <コンテキスト> (details)Handled error<エラークラス>: <メッセージ>Location<ファイルパス> - <メソッド名> 

| パート | 抽出方法 |
|--------|---------|
| 対象サーバー | `from my-project` → サーバーA |
| コンテキスト | `in``(details)` の間のテキスト |
| エラークラス | `Handled error` の直後、`:` の前 |
| エラーメッセージ | エラークラスの `:` 以降、`Location` の前 |
| 固有パラメータ | メッセージ中の `user_id:`, `charger_id:` 等 |
| 発生箇所 | `Location` 以降のファイルパスとメソッド名 |

このルールに基づき、先ほどの通知からは以下が抽出されます:

項目 抽出結果
対象サーバー サーバーA
コンテキスト users#create
エラークラス ActiveRecord::RecordNotFound
エラーメッセージ Couldn't find User with [WHERE ...]
発生箇所 user_registration_service.rb:54

Slack 通知と BugSnag ページからのコピーの 2 つのフォーマットに対応しており、どちらの形式かは自動判定されます。

Phase 2: 既知アラート突合

解析結果をもとに、既知アラートを検索します。検索は 3 段階のフォールバック構成です。

Step 1: ローカルインデックス検索

スキルと同梱している alerts/_index.md のキーワードテーブルで部分一致検索します。

| キーワード | サーバー | ドキュメント | 即時対応 |
|-----------|---------|-------------|---------|
| RecordNotFound, User, user_key | server-a | record-not-found-user.md | check |
| Max retries, ExternalAPI, ResponseCode | server-b | max-retries-external-api.md | check |
| ...(数十件) |

Step 2: Notion DB 検索(MCP 連携時のみ)

ローカルでヒットしない場合、Notion MCP を使ってデータベースを直接検索します。チームの誰かが Notion に新しい記事を追加していれば、ローカルに同期されていなくても見つかります。

Step 3: キーワード緩和

それでもヒットしない場合、エラークラス名だけ、コントローラ名だけなど条件を緩めて再検索し、類似候補を提示します。

Phase 3: 既知アラート対応

既知アラートが見つかった場合、ローカルドキュメントの内容に基づいて以下を提示します:

  • 即時対応要否: required(即時対応)/ check(状況確認)/ none(対応不要)
  • 確認手順: DB 確認コマンドやログ検索コマンドなど
  • 判断方法: どういう状況なら対応が必要で、どういう状況なら様子見でよいか
  • 関連アラート: 連鎖して発生する可能性のある別のアラート

Phase 4: 未知アラート調査

既知アラートが見つからない場合は、コードベースを調査して初動情報を提供します。SKILL.md に調査の手順(Grep でエラー発生箇所を特定 → Read で処理フローを読み解き → 確認コマンドを生成)を記述しているため、Claude Code が自律的に調査を進めます。

Phase 5: 事後処理

対応完了後、新しいアラートドキュメントの作成や既存ドキュメントの更新を行います。ローカルの Markdown ファイルと Notion 記事の両方を更新できます(Notion 更新は MCP 連携時のみ)。

実装のポイント

ローカルドキュメントの設計

各アラートの対応方針は、frontmatter 付きの Markdown ファイルとして管理しています。

---
title: "Slack通知メッセージをそのまま使用"
notion_url: "https://www.notion.so/..."
server: server-a       # 対象サーバーの識別子
urgency: check         # required | check | none
keywords:
  - "RecordNotFound"
  - "User"
last_synced: "2026-03-02"
---

## 概要
- ある条件下で該当レコードが見つからない場合に発生するエラー

## 確認方法
### 1. Rails console でレコードの状態を確認
```bash
# ECS タスクに接続
aws ecs execute-command --cluster my-cluster --task <task-id> \
  --container app --interactive --command "/bin/bash"
```
```ruby
# エラーメッセージに含まれるキーで該当レコードを検索
User.find_by(key: "abc-123-def-456")
```

### 2. CloudWatch Logs でエラー前後のログを確認
```bash
aws logs start-query \
  --log-group-name /ecs/my-service \
  --start-time $(date -v-1H +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, @message
    | filter @message like /RecordNotFound/
    | sort @timestamp desc | limit 50'
```

## 判断方法
- 複数ユーザーで同時多発 → 外部APIの障害の可能性、先方に共有
- 単一ユーザー → 様子見で問題なし

ポイントは以下の通りです:

  • keywords: 突合に使うキーワード。エラークラス名やコンテキスト名など、Slack 通知に含まれる文字列を指定
  • urgency: 即時対応要否。スキルはこの値を見て、対応の優先度を表示する
  • notion_url: 対応する Notion 記事の URL。同期の追跡に使用
  • title: Slack 通知メッセージそのまま。検索しやすさのためにこの形式を採用

ファイル構成

.claude/skills/alert-triage/
├── SKILL.md                 # ワークフロー定義
├── README.md                # 使い方
├── templates/
│   └── alert_doc.md         # 新規ドキュメントのテンプレート
└── alerts/
    ├── _index.md            # キーワードテーブル + 関連アラート対応表
    ├── server-a/            # サーバーAのアラート
    │   ├── typeerror-nil-value.md
    │   ├── push-notification-error.md
    │   └── ...
    └── server-b/            # サーバーBのアラート
        ├── record-not-found-user.md
        ├── external-api-500-error.md
        └── ...

スキルのファイルはすべてリポジトリに含まれるため、git pull するだけでチーム全員が最新のアラート対応ナレッジを使えます。

MCP 連携の有無による動作の分岐

チームメンバー全員が Notion MCP を設定しているとは限りません。そこで、MCP 連携の有無に応じて動作を分岐させています。

機能 MCP 連携あり MCP 連携なし
アラート検索 ローカル + Notion DB ローカルのみ
事後処理 ローカル + Notion 記事 ローカルのみ
Notion → ローカル同期 可能 不可

MCP 非連携でも、ローカルに同期済みのドキュメントで基本的な対応はカバーできます。

関連アラート対応表

あるアラートが発生した場合、別のアラートも連鎖して発生することがあります。例えば、外部サービスがエラーを返すと、後続の処理でもエラーになる、という連鎖です。

_index.md に関連アラートの対応表を定義しておくことで、スキルが関連するアラートも合わせて提示します。

## 関連アラート対応表

| ドキュメント | 関連先 | 関係 |
|-------------|--------|------|
| downstream-error.md | external-api-500-error.md | 外部APIエラーで処理が失敗 → 後続処理でもエラー |
| external-api-500-error.md | downstream-error.md | 本アラートの後続でエラーが連鎖発生する |

実際の動作例

Slack に届いた BugSnag 通知をそのまま Claude Code に貼り付けます。

入力:

Event in production:prod from my-project - prod in users#create (details)Handled errorActiveRecord::RecordNotFound: Couldn't find User with [WHERE ...]Locationapp/services/user_registration_service.rb:54 - register

出力(要約):

スキルが自動で起動し、以下の流れで対応が進みます:

  1. Phase 1(解析): メッセージをパースし、エラークラス・発生箇所・対象サーバーを抽出
  2. Phase 2(突合): ローカルインデックスでキーワード RecordNotFound, User, user_key にヒット
  3. Phase 3(対応提示):
    • 即時対応要否: check(状況確認が必要)
    • 確認手順: 分析ツールでユーザーの挙動確認 → 不審な場合は DB でレコード検索
    • 判断方法: 複数ユーザーで同時多発 → 外部API側に共有 / 単一ユーザー → 様子見
    • 関連アラート: 参考手順として関連ドキュメントを提示

アラートを貼り付けてから対応方針が表示されるまで、体感で 10 秒程度です。

導入の効果

Before

  • Slack 通知を見て、Notion を開いて検索して、該当する記事を見つけて、確認手順を読んで……という一連の作業に数分かかっていた
  • 慣れていないメンバーは「このアラート、前にも見た気がするけどどの記事だっけ?」と迷いやすい

After

  • アラートメッセージを貼り付けるだけで、既知/未知の判定から確認手順まで一括で提示される(確認時間の短縮)
  • 誰が対応しても同じ品質で対応しやすくなった

SKILL.md を書くときに意識したこと

1. フォールバックを設計する

検索がヒットしない場合のフォールバック(キーワード緩和、MCP 非連携時のローカルのみ動作)を明示的に記述しました。「見つからなかったら終わり」ではなく、次に何をするかを定義しておくことが重要です。

2. 人間の判断ポイントを残す

スキルが提示するのは情報と選択肢であり、最終的なアクション(関係者への連絡、本番環境での操作など)は人間が判断します。SKILL.md にも「ユーザーの承認を得てから実行すること」と明記しています。

おわりに

Claude Code のカスタムスキルは、繰り返し行う作業の中にある「手順は決まっているけど、毎回調べながらやっている」部分を効率化するのに向いていると感じました。

今回のアラート対応スキルは、Notion に蓄積していたナレッジを SKILL.md のワークフローとローカルドキュメントという形で構造化し直すことで、Claude Code が活用できる形にしたものです。ナレッジ自体は以前からあったので、新しく何かを作ったというよりは、既存の資産を別の形で活かせるようにした、という感覚です。

同じように、チーム内で手順書やナレッジベースを持っているけれど、それを毎回手動で参照している……という場面があれば、スキル化を検討してみるとよいかもしれません。




以上の内容はhttps://tech.enechange.co.jp/entry/2026/03/18/193500より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14