ai-bug-triage について
ai-bug-triageは、障害の分類、重複排除、チケット作成を行うワークフロー型スキルです。重複排除には決定論的な指紋を使い、LLMが重大度評価や説明、チケット作成を担い、実行前に人が確認します。
主な機能
- 01ログの正規化と安定要素の抽出
- 02決定論的な障害指紋の作成
- 03類似障害のクラスタリング
- 04LLMによる分類と重大度評価
- 05構造化されたバグチケットの作成
- 06低信頼度の結果を人の確認へ回送
活用シーン
- 01CIログ内の失敗を重複排除
- 02アプリ・テスト・環境の障害を分類
- 03分類結果から確認用チケットを作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill ai-bug-triageインストール後、Claude Code で/ai-bug-triageを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/ci-failure-analysis.mdclassification-taxonomy.mdpipeline-prompts-and-integration.md詳細
重要な捉え直し: LLMは重複排除ではなく、説明と振り分けに適しています。パイプラインそのものになるのではなく、パイプラインを設計するようエージェントに教えます。
調査時の質問
まず .agents/qa-project-context.md を確認してください。ここには、分類精度を高める技術スタック、コンポーネントの対応関係、既知の不安定な箇所が記載されています。その情報を活用し、すでに回答が記載されている項目は省略してください。そのうえで、次の点を確認します。
-
障害の発生元は何ですか?
- CI パイプラインのログ(GitHub Actions、GitLab CI、Jenkins、CircleCI)
- テストフレームワークの出力(Playwright、Jest、pytest、Vitest)
- 本番環境のエラー監視(Sentry、Datadog、Bugsnag)
- QA チームまたはユーザーからの手動のバグ報告
-
チケットの作成先はどこですか?
- Jira、Linear、GitHub Issues、Azure DevOps、Shortcut
- 必須フィールドは何ですか?(コンポーネント、重大度、優先度、ラベル)
- どのようなワークフローがありますか?(トリアージボード、自動割り当てルール)
-
重複排除の範囲はどの程度ですか?
- 同じテスト実行内ですか?同じスプリント内ですか?同じリリース内ですか?それとも全期間ですか?
- すでにフィンガープリント処理を導入していますか?現在の重複率はどの程度ですか?
-
どのような承認ワークフローが必要ですか?
- チケットを自動作成し、人がレビューしますか?
- 作成前に、チケットを提案して人の承認を得ますか?
- 重複チケットを自動的にクローズしますか?(危険なため、承認が必要です)
-
どのような過去データがありますか?
- 解決情報を含む過去のバグ報告はありますか?
- 不安定なテストの履歴や、既知の環境問題はありますか?
- コンポーネントの担当者との対応関係はありますか?
基本原則
-
まず決定論的な処理を行い、次にLLMを使います。 重複排除とクラスタリングには、安定して再現可能なフィンガープリント処理を使います。LLMは、重大度の分類、根本原因の仮説、人が読みやすいチケットの作成など、理解を必要とするタスクにのみ使います。
-
比較する前に正規化します。 生のCIログにはタイムスタンプ、ポート番号、プロセスID、ランダムなサフィックスが多数含まれており、同じ障害が異なるものに見えてしまいます。フィンガープリントを作成する前に、ノイズをすべて取り除きます。
-
フィンガープリントは安定した要素を基準にします。 例外の種類、スタックトレースの先頭フレーム、テスト名、エラーメッセージのテンプレート、URLパターンは安定した要素です。タイムスタンプ、リクエストID、一時的なポートは安定した要素ではありません。
-
破壊的な操作の前に人の承認を得ます。 チケットを重複として自動的にクローズしたり、報告を自動的に統合したりするには、人による確認が必要です。誤った重複判定は、手動でトリアージするよりも多くの時間を浪費します。
-
分類を振り分けに活用します。 トリアージの価値はラベルそのものではなく、それによって可能になる振り分けの判断にあります。たとえば、どのチームに割り当てるか、優先度をどうするか、SLAをどう設定するかです。
-
トリアージの精度を追跡します。 自動分類が人の判断と一致する割合を測定します。精度が85%を下回る場合は、パイプラインの調整が必要です。
パイプライン
CI Log / Error Report
│
▼
Step 1: NORMALIZE
Strip timestamps, process IDs, ports, random suffixes, ANSI codes
│
▼
Step 2: EXTRACT STABLE ANCHORS
Exception type, top N stack frames, test name, error message template, URL pattern
│
▼
Step 3: HASH CANONICAL FORM
Deterministic fingerprint from ordered anchors
│
▼
Step 4: CLUSTER NEAR-DUPLICATES
Similarity scoring for non-identical but related failures
│
▼
Step 5: LLM CLASSIFY
Severity, component, suspected root cause, failure category
│
▼
Step 6: LLM GENERATE TICKET
Title, description, repro steps, evidence, suggested assignee
│
▼
Step 7: HUMAN APPROVAL
Review before create/close/merge
ステップ1:正規化
同じ障害が異なるものに見えてしまう原因となるノイズを取り除きます。
正規化ルール(次の順序で適用):
1. Strip ANSI color codes: \x1b\[[0-9;]*m → ""
2. Strip timestamps: \d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z? → "<TIMESTAMP>"
3. Strip UUIDs: [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} → "<UUID>"
4. Strip process IDs: pid[=: ]\d+ → "pid=<PID>"
5. Strip port numbers: :\d{4,5}(?=[\s/,)\]]|$) → ":<PORT>"
6. Strip temp file paths: /tmp/[^\s]+ → "<TMPPATH>"
7. Strip memory addresses: 0x[0-9a-f]{8,16} → "<ADDR>"
8. Strip random suffixes: [-_][a-z0-9]{6,8}(?=\.) → "<RAND>"
9. Strip request IDs: (?:request[_-]?id|trace[_-]?id|correlation[_-]?id)[=: ]["']?[a-zA-Z0-9-]+ → "<REQ_ID>"
10. Collapse whitespace: \s+ → " "
例:
Before: 2025-03-22T14:32:01.456Z [pid=42891] Error: Connection refused at 127.0.0.1:54321
request_id=abc-123-def-456
After: <TIMESTAMP> [pid=<PID>] Error: Connection refused at 127.0.0.1:<PORT>
<REQ_ID>
ルール5はポートを取り除きますが、ループバックIPアドレスそのものは取り除きません。127.0.0.1 はフィンガープリントに残ります。同じホストで発生した障害であれば問題ありませんが、異なるホストにバインドする2つのランナー(例:127.0.0.1 と 0.0.0.0)では、フィンガープリントが別々になります。異なるホストが混在する環境を実行している場合は、バインドアドレスも正規化するルールを追加してください。
ステップ 2:安定したアンカーを抽出する
正規化したログから、環境やタイミングに左右されずに失敗を特定できる要素を抽出します。
アンカーの種類(優先順位順):
| アンカー | 例 | 安定性 |
|---|---|---|
| 例外の種類 | TypeError、AssertionError、HTTP 500 | 非常に高い |
| エラーメッセージのテンプレート | Cannot read property 'X' of undefined | 高い |
| スタックフレームの上位 3 件 | at processOrder (order.ts:142) | 高い |
| テスト名 | checkout.spec.ts > completes payment | 非常に高い |
| URL パターン | POST /api/orders | 高い |
| HTTP ステータスコード | 500、429、503 | 非常に高い |
| 終了コード | exit code 1、SIGKILL | 高い |
| アサーションの差分 | Expected: 200, Received: 500 | 中程度 |
抽出ルール:
- 関数名は維持しますが、行番号は削除します(編集によって変わるためです)
- URL パスは維持しますが、クエリパラメーターとパス内の ID は削除します(
/api/orders/<ID>) - エラーメッセージの構造は維持し、動的な値はプレースホルダーに置き換えます
- テストファイル名とテスト名は、そのまま維持します
ステップ 3:正規形をハッシュ化する
抽出したアンカーから、決定論的なフィンガープリントを生成します。
アルゴリズム:
1. Sort anchors alphabetically by type
2. Concatenate: exception_type + "|" + message_template + "|" + top_frames + "|" + test_name
3. SHA-256 hash the concatenated string
4. Take first 16 hex characters as fingerprint
フィンガープリントの特性:
- 同じ失敗からは常に同じフィンガープリントが生成されます(決定論的)
- 異なる失敗からは異なるフィンガープリントが生成されます(衝突耐性)
- ログ形式に軽微な変更があっても、フィンガープリントは変わりません(安定性)
- Jira のラベルや GitHub のタグに使える短さです
例:
Anchors:
exception_type: "TypeError"
message_template: "Cannot read property 'vendorId' of undefined"
top_frames: "processOrder|groupByVendor|checkout"
test_name: "checkout.spec.ts > multi-vendor checkout"
Canonical: "TypeError|Cannot read property 'vendorId' of undefined|processOrder|groupByVendor|checkout|checkout.spec.ts > multi-vendor checkout"
Fingerprint: a3f8b2c1e9d04567
ステップ 4:類似する重複をグループ化する
完全一致のフィンガープリントで同一の失敗を検出します。類似度スコアリングでは、わずかに異なる関連する失敗(同じ根本原因で、異なる形で現れたもの)を検出します。
類似度の判定基準:
| 項目 | 重み | 一致条件 |
|---|---|---|
| 例外の種類 | 0.30 | 完全一致 |
| エラーメッセージ | 0.25 | レーベンシュタイン距離がメッセージ長の 20% 未満 |
| スタックフレーム | 0.25 | 上位 5 件のフレームのジャッカード類似度が 0.6 超 |
| コンポーネント/ファイル | 0.10 | 同じディレクトリまたはモジュール |
| テスト名 | 0.10 | 同じ describe ブロックまたはテストファイル |
グループ化のしきい値: 類似度スコアが 0.75 を超える場合は、重複の可能性が高いため、統合を提案します。
人によるレビューが必要なケース:
- スコアが 0.60~0.75(曖昧な場合)
- 新しいフィンガープリントの初回検出時(比較対象となる履歴がない場合)
- 断続的な問題が確認されているコンポーネントでの失敗
ステップ 5:LLM で分類する
決定論的なフィンガープリント生成とグループ化の後、LLM を使って失敗を分類します。プロンプトには、例外、メッセージ、スタックフレームの上位 5 件、テスト名、CI コンテキストを入力し、次の 5 項目を出力するよう求めます。
- 失敗カテゴリ —
test bug | application bug | environment issue | flaky test | build failure - 重大度 —
critical | major | minor | trivial(下記の重大度マトリックスを参照) - コンポーネント — スタックトレースとファイルパスから推定
- 根本原因の推定 — 1~2 文の仮説
- 確信度 —
high | medium | low。確信度が低い場合、解決に必要な追加情報を LLM が示します
確信度の低い分類は自動処理せず、人によるレビューに回します。プロンプト全文は references/pipeline-prompts-and-integration.md を、プロンプトで参照するバグカテゴリ、重大度、コンポーネントのマッピング定義は references/classification-taxonomy.md を参照してください。
失敗カテゴリ(詳細は references/ci-failure-analysis.md を参照):
| カテゴリ | 説明 | 一般的な対応 |
|---|---|---|
| アプリケーションのバグ | アプリが正常に動作しない | バグチケットを作成し、担当チームに割り当てる |
| テストのバグ | テストに誤りがある | テストを修正する。アプリの変更は不要 |
| 環境の問題 | CI インフラ/ネットワーク/サービスの停止 | 再試行し、インフラチームに通知する |
| 不安定なテスト | 断続的で非決定論的 | 隔離し、根本原因を調査する |
| ビルドの失敗 | コンパイル、依存関係、設定 | ビルドを修正する。通常はブロッキング要因 |
ステップ 6:LLM によるチケット生成
分類したら、LLM を使って人が作成したような品質のバグチケットを生成します。プロンプトには、分類結果に加えて正規化したエラー、ログの抜粋、関連するクラスターのフィンガープリントを渡し、次の内容を生成します。
- タイトル — 簡潔で検索しやすく、コンポーネント名を含みます(80 文字未満)
- 説明 — 何が起きたかを平易な言葉で説明します(生のログは使用しません)
- 再現手順 — テスト名とログのコンテキストから導きます
- 証拠 — 関連するログ行、アサーションの差分、利用可能な場合はスクリーンショット
- 推奨ラベル —
[component, severity, failure-category, fingerprint] - 推奨担当者 — コンポーネントの担当チームが分かっている場合は、そのチームに基づいて割り当てます
今後の重複検出で照合できるよう、fingerprint はチケットに(ラベルと Fingerprint フィールドに)設定してください。完全なプロンプトとバグ報告テンプレートについては、references/pipeline-prompts-and-integration.md を参照してください。
ステップ 7:人による承認
レビューなしに自動で処理しないでください。 パイプラインは提案し、人が判断します。
承認時の判断:
- チケットを作成 — 新しい障害で、根本原因が明確な場合は、チームに割り当てます
- 既存のチケットに統合 — 既知の問題との重複である場合は、既存のチケットに証拠を追加します
- テストを隔離 — 不安定なテストで、アプリのバグではない場合は、テストを隔離して調査を予定します
- 再試行して監視 — 環境の問題である場合は、CI を再試行し、問題が続く場合に通知します
- 却下 — 保留中のデプロイですでに修正済みの既知の問題、または明らかな修正方法があるテストのバグの場合は、却下します
重大度/優先度マトリックス
重大度は影響を、優先度は緊急性を示します。この 2 つは独立した指標です。
重大度の定義
| 重大度 | 定義 | 例 |
|---|---|---|
| Critical | システムが使用不能、データ損失、セキュリティ侵害、回避策がない | 決済処理に失敗する、ユーザーデータが漏えいする、アプリの起動時にクラッシュする |
| Major | 中核機能が壊れている、ユーザー体験が低下している、回避策がある | 検索結果が誤っている、チェックアウトにページの再読み込みが必要、戻るボタンを押すとフォームデータが失われる |
| Minor | 中核以外の機能に影響がある、機能面の影響を伴う見た目の問題 | 並べ替え設定が保持されない、モバイルでツールチップが切れて表示される、二次操作に失敗する |
| Trivial | 見た目のみの問題で、機能面への影響はない | ラベルの誤字、1px の位置ずれ、大文字・小文字の不統一 |
優先度の定義
| 優先度 | 定義 | SLA(例) |
|---|---|---|
| P0 | ただちに修正し、リリースまたは本番環境へのデプロイを妨げる | 当日中 |
| P1 | 今回のスプリントで修正し、ユーザーに大きな影響がある | 今回のスプリント |
| P2 | 次回のスプリントで修正し、中程度の影響がある | 次回のスプリント |
| P3 | 都合のよいときに修正し、影響が小さい | バックログ |
重大度と優先度の判断ガイド
| Critical | Major | Minor | Trivial | |
|---|---|---|---|---|
| すべてのユーザーに影響 | P0 | P0 | P1 | P2 |
| 一部のユーザーに影響(>10%) | P0 | P1 | P2 | P3 |
| 少数のユーザーに影響(<10%) | P1 | P1 | P2 | P3 |
| エッジケースのみ | P1 | P2 | P3 | P3 |
バグ報告テンプレート
自動生成か人が作成したものかにかかわらず、すべてのバグ報告で同じテンプレートを使用してください。不具合の見出しに加えて、重大度/優先度/コンポーネント/環境/フィンガープリント/報告者のメタデータを記載し、その後に「説明」「再現手順」「期待される動作/実際の動作」「証拠」「発生頻度」「根本原因の推測」「関連する問題」を記載します。コピーして使える完全な Markdown テンプレートについては、references/pipeline-prompts-and-integration.md を参照してください。
重複排除のパターン
| パターン | 検出方法 | 対応 |
|---|---|---|
| 完全一致の重複 | フィンガープリントが同一 | 既存のチケットに統合し、証拠を追加 |
| 類似した重複 | 同じクラスター(類似度 > 0.75) | チケットをリンクし、人によるレビュー用に統合を提案 |
| 根本原因は同じで症状が異なる | 異なるテストで例外の種類が同じ、かつフレームが重複 | 症状を記録したチケットをリンクする親チケットを作成 |
| 修正済みバグの再発 | フィンガープリントがクローズ済みチケットと一致 | チケットを再オープンし、リグレッションとしてフラグを付け、優先度を上げる |
| 不安定な再発 | CI の実行間で同じフィンガープリントが断続的に発生 | 不安定としてタグ付けし、発生率が 10% を超える場合は隔離 |
CI 失敗の分析
包括的なパターンについては、references/ci-failure-analysis.md を参照してください。主な判断基準は、一貫して発生する失敗 = テストのバグまたはアプリのバグ、断続的な失敗 = 不安定なテストまたは環境、多数の失敗が同時に発生 = 環境または共有コンポーネント、ビルドの失敗 = コードまたは依存関係の問題です。
統合パターン
パイプラインの出力は課題管理ツールに依存しません。ステップ 6 では、タイトル、説明、ラベル、重大度、コンポーネントを生成し、どの課題管理ツールのフィールドにも対応付けられます。gh issue create / フィンガープリント重複排除コマンド、GitHub Actions の「失敗時にトリアージ」ワークフロー、Jira/Linear/Azure DevOps の REST/GraphQL 統合に関する注記については、references/pipeline-prompts-and-integration.md を参照してください。
購入するか、構築するか
パイプライン全体を実装する前に、ホステッドプラットフォームですでに必要な作業をカバーできないか確認してください。現在は、ステップ 4〜6 と直接重複する、AI 駆動のテストトリアージ機能を備えたツールがいくつかあります。
| プラットフォーム | 対応範囲 | 備考 |
|---|---|---|
| Trunk Flaky Tests | フィンガープリント、クラスタリング、重大度に基づく振り分け、ネイティブな PR コメント + Webhook | トリアージ専用の Agents 機能を提供します。文書化された隔離ワークフローがあり、このスキルのパイプラインに最も近い既製の代替手段です |
| CloudBees Smart Tests | フィンガープリント、ML ベースの優先順位付け、テスト影響分析 | 以前の名称は Launchable です。古いドキュメントを探すエージェントは、以前の名称を見つける場合があります |
| Datadog Test Optimization | 不安定なテストの管理(自動再試行、早期の不安定検出、失敗したテストのリプレイ)、テスト影響分析 | Bits AI Dev Agent が修正 PR を自動生成するようになり、Flaky Test Policies は 30 日後に自動隔離してから無効化するようになりました。すでに Datadog を利用している場合は、Datadog APM と組み合わせられます |
| Sealights | 品質インテリジェンスとテスト影響に基づくゲーティング | エンタープライズ向けで、規制の厳しい業界に特に強みがあります |
(a)オンプレミスまたはエアギャップ環境へのデプロイが必要な場合、(b)課題管理ツールとの統合方法が特殊な場合、または(c)コンプライアンス対応のために AI プロンプトの明示的な監査証跡が必要な場合は、スキル内のパイプラインを使用してください。それ以外の場合は、フィンガープリント処理とクラスタリングを再構築するより、購入する方が通常は安価です。
モデル選択に関するコストの注意
分類(ステップ 5)には Sonnet 4.6 / Haiku 4.5 を使用してください。安価で、十分な性能があります。クラスターが新規のもの、失敗が曖昧なもの、または提案された根本原因の信頼度が低い場合に限り、Opus 4.8 に切り替えてください。すべてのトリアージに Opus を使うのは無駄です。
アンチパターン
1. 重複排除に LLM を使用する
LLM は非決定論的です。同じ 2 つのエラーを 2 回比較すると、異なる類似度スコアが得られる場合があります。重複排除には決定論的なフィンガープリント処理を使用し、LLM は説明と分類にのみ使用してください。
2. レビューなしで自動クローズする
フィンガープリントの一致に基づいてチケットを「重複」として自動クローズすると、別々の問題が統合されるおそれがあります。クローズや統合の操作には、必ず人による確認を求めてください。
3. 重大度を過剰に分類する
すべてが「重大」なら、何も重大ではありません。重大度のマトリックスに厳密に従ってください。見た目だけの誤字は、誰かを苛立たせるものであっても軽微です。
4. 環境に起因する失敗を無視する
Docker の OOM、ネットワークのタイムアウト、ディスク容量の不足など、CI インフラストラクチャの問題が多く発生しているのに、すべての失敗を「アプリのバグ」とラベル付けすることです。環境の問題は別に分類してください。必要な修正方法が異なります。
5. フィードバックループがない
パイプラインを一度構築しただけで、精度を測定しないことです。自動分類の精度、重複の誤検出率、開発者によるチケット品質の評価を追跡してください。
6. チケットに生ログを貼り付ける
CI の出力を生のまま 500 行、バグチケットに貼り付けることです。正規化して関連する行を抽出し、重要な 5~10 行を提示してください。
7. 正規化せずにフィンガープリントを作成する
生のログ行をハッシュ化すると、実行のたびに変わる不安定なフィンガープリントが生成されます。同じ失敗でも毎回異なるフィンガープリントになるため、重複排除が機能しません。正規化は必須です。フィンガープリントの作成前に必ず正規化し(ステップ 1)、生ログからフィンガープリントを作成しないでください。
8. コンポーネントの担当チームの対応付けがない
振り分けを伴わない分類は役に立ちません。分類されたバグが適切な担当者に届くよう、コンポーネントとチームの対応付けを管理してください。
検証
フィンガープリント生成処理は中核となる部分です。重複排除を信頼する前に、正しく機能することを証明してください。実装に対して、references/ci-failure-analysis.md にある 5 つの安定性アサーションを実行してください。
- 同じエラーで、タイムスタンプが異なる場合 → 同じフィンガープリントになる。
- 同じエラーで、PID とポートが異なる場合 → 同じフィンガープリントになる。
- 同じエラーで、行番号が異なる場合(コードが編集された場合)→ 同じフィンガープリントになる。
- 異なるエラー(例:
TypeErrorとRangeError)→ 異なるフィンガープリントになる。 - 同じ例外の型で、メッセージプロパティが異なる場合(
'name'と'email')→ 異なるフィンガープリントになる。
テスト 1~3 では 1 つのハッシュに集約され、テスト 4~5 では異なるハッシュが生成されなければなりません。ここで失敗する場合は、正規化(ステップ 1)のノイズがハッシュに混入しているか、安定した識別要素が取り除かれています。クラスタリングの調整に進む前に修正してください。クラスタリングの重み(0.30 / 0.25 / 0.25 / 0.10 / 0.10)の合計は 1.00 でなければなりません。
完了条件
failures.json内のすべての失敗で、severity、component、categoryフィールドが null 以外の値になっている。- 上記の 5 つのフィンガープリント安定性アサーションに合格している(テスト 1~3 は同じハッシュ、テスト 4~5 は異なるハッシュ)。
- 重複が統合またはリンクされ、それぞれが正規チケットのフィンガープリントラベルを参照している。
- すべての P0/P1 チケットに担当者が設定されている。
- 自動分類の精度が測定・記録されている(目標値は 85% 超。
qa-metricsを参照)。
関連スキル
qa-metrics— トリアージの精度、重複率、分類までの平均時間、欠陥流出率を追跡します。ci-cd-integration— テスト失敗時のトリアージ実行、並列実行、レポート作成に関するパイプライン設定です。test-reliability— 不安定なロケーター 1 つに対する、テスト実行中の修復と隔離です。トリアージは失敗を分類し、test-reliability は実行中に個々のテストを修正します。observability-driven-testing— 逆の方向に進み、本番環境のテレメトリーから新しいテスト設計を作成します。本番環境のエラーからチケットではなくテストを作成する場合に使用してください。qa-project-context— コンポーネントマップ、既知の問題、担当者など、分類の精度を高めるプロジェクトコンテキストです。ai-test-generation— トリアージ済みのバグレポートから回帰テストを生成します。
参照ファイル(references/ 内)
- pipeline-prompts-and-integration.md — LLM による分類とチケット生成のプロンプト(ステップ 5~6)、バグレポートの完全な Markdown テンプレート、トラッカー連携コード(GitHub Issues、CI ワークフロー、Jira/Linear に関する説明)。
- classification-taxonomy.md — バグのカテゴリ、重大度の定義、コンポーネントの対応付けルール、根本原因のカテゴリ。
- ci-failure-analysis.md — CI ログの解析パターン、失敗カテゴリの判定ツリー、フィンガープリントアルゴリズムの詳細。