Claude Code スキルで CloudWatch エラーレポートの Issue トリアージを自動化する
背景
本番環境の ECS コンテナで発生したエラーは、CloudWatch Logs → Lambda → GitHub Issue という流れで自動起票される仕組みを運用しています。
タイトルは [prod][myapp] errors detected、ラベルは CloudWatchLog で統一されており、1つの Issue に複数のエラーブロックがまとまって届きます。
## Error Report - 2026-02-12 01:32:28 UTC
- **Environment**: prod
- **Log Group**: `/ecs/myapp-prod-ecs`
- **Error Blocks**: 3
### [1] 2026-02-12 01:32:26 UTC - `application`
(スタックトレース)
### [2] 2026-02-12 01:45:10 UTC - `application`
(スタックトレース)
### [3] 2026-02-12 02:01:33 UTC - `application`
(スタックトレース)
この Issue をそのまま放置すると、異なるエラーが混在したまま溜まっていきます。手作業で分類・個別 Issue 化するのは地味に面倒で、後回しにしがちでした。
解決策: /errors-import スキル
Claude Code のスキル機能を使って、エラーレポート Issue のトリアージを自動化しました。
やっていること
[prod][myapp] errors detectedのオープン Issue を検索- エラーブロックを抽出し、例外クラス+発生箇所でグルーピング
- 既存 Issue(open / closed 両方)と重複チェック
- 新規エラーのみ個別 Issue を作成
- 元 Issue に分析サマリをコメントしてクローズ
使い方
# オープンなエラーレポート Issue を自動検索して処理
/errors-import
# 特定の Issue 番号を指定
/errors-import 21
スキルの実装
.claude/skills/errors-import/SKILL.md に処理手順を Markdown で記述するだけです。bash スクリプトは不要で、Claude が gh CLI を使って GitHub 操作を行います。
---
name: errors-import
description: "CloudWatch エラーレポート Issue を分析し、個別 Issue に分離してクローズする"
---
ポイントは、エラーの分類と重複判定を LLM に任せている点です。
- スタックトレースのパターンマッチングではなく、意味的な類似性で既存 Issue との重複を判定
- 「Truncated Traceback」(CloudWatch のログ分割で途切れたトレース)も、同一時間帯の完全なトレースと照合してグルーピング
- 重大度の判定(高/中/低)や優先度の提案も含めて出力
実行結果の例
ケース 1: 既存 Issue と重複する場合
/errors-import 21
エラーブロックが1件で、既に OPEN の Issue #20(Session UpdateError)と同一パターンだった場合:
## 分析サマリ
Issue #21 に集約された 1 件のエラーレポート(2026-02-12)を分析しました。
### スキップした課題(既存 Issue あり)
| 既存 Issue | エラー種別 | 状態 |
|-----------|-----------|------|
| #20 | Session UpdateError / DatabaseError | OPEN |
### 結論
全エラーが既存 Issue #20 と同一パターンのため、新規課題の作成は不要。
→ 新規 Issue は作らず、コメントだけ残してクローズ。
ケース 2: 複数エラーを分離する場合
646件のエラーが混在した Issue を処理した例:
## 分析サマリ
### 作成した課題一覧
| # | タイトル | 件数 | 重大度 |
|---|---------|------|--------|
| #11 | GraphQL schema の Resolver404 ログ抑制 | 438 | 低 |
| #12 | cp932 エンコードエラー: NFD 結合文字の処理漏れ | 45 | 中 |
| #13 | ReportBuilder: file_params が None で AttributeError | 2 | 高 |
| #14 | WeasyPrint: CSS の読み込み失敗 | 12 | 中 |
| ... | ... | ... | ... |
### 優先度の提案
1. **高**: #13(簡単な修正で安定性向上)
2. **中**: #11(ノイズ削減でエラー監視の精度向上)
なぜスキルで実装するのか
当初は bash スクリプト + 正規表現で実装しようとしましたが、以下の理由でスキル(SKILL.md)にしました。
| bash スクリプト | Claude Code スキル | |
|---|---|---|
| エラー分類 | 正規表現でパターンマッチ | スタックトレースの意味を理解してグルーピング |
| 重複判定 | タイトル完全一致 | 意味的な類似性で判定 |
| サマリ生成 | テンプレート埋め込み | 傾向分析・優先度提案を含む自然文 |
| 不完全なログ | 処理できない | 他のログと照合して補完 |
| メンテナンス | コード修正が必要 | Markdown の手順書を編集するだけ |
スキルの実体は「Claude への指示書」なので、処理を変えたければ Markdown を書き換えるだけで済みます。
プロジェクトローカルなスキル
このスキルはグローバル(~/.claude/skills/)ではなく、プロジェクトの .claude/skills/ に配置しています。
my-project/
├── .claude/
│ └── skills/
│ └── errors-import/
│ └── SKILL.md
├── CLAUDE.md
└── ...
リポジトリごとにエラーレポートのフォーマットや Issue の運用ルールが異なるため、プロジェクトローカルにしておくと他のリポジトリに影響しません。汎用的なスキル(tmux 連携など)はグローバルに、ドメイン固有のスキルはローカルに、という使い分けが便利です。
まとめ
- CloudWatch → GitHub Issue の自動起票は便利だが、トリアージが手作業のボトルネックだった
- Claude Code スキルで
/errors-importを作り、分類・重複チェック・Issue 作成・クローズを自動化 - LLM の意味理解を活かすことで、正規表現ベースでは難しい柔軟な分類が可能に
- SKILL.md(Markdown)で定義するため、メンテナンスコストが低い