新しい不具合の報告が来たときに、過去の不具合チケット・修正のプルリクエスト・原因分析の記録から症状の近いものを探し、原因と修正箇所の候補をチケット番号付きで開発担当へ返す
新しい不具合が起票されると、その症状とエラーから過去の不具合チケット・修正のプルリクエスト・原因分析の記録を探し、原因と修正箇所の候補をチケット番号付きで担当の開発者に返します。
- 生成AI
- ChatGPT/Claude/Gemini
- AIサービス
- Azure AI/Google Vertex AI/OpenSearch
- 対象業界
- EC/IT・SaaS/製造/金融
- 対象部門
- 情報システム/研究開発
- 対象業務
- 情報検索/比較検討
- 主な課題
- 判断に時間がかかる/属人化している/情報が見つからない
- AIで行う処理
- 検索(RAG)
- 主な効果
- 対応スピード向上/属人化解消/検索時間短縮
- 導入難易度
- ★★★★☆
- 実装レベル
- 本格構成
- 費用感
- RAG・個別開発(大)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- サポート部門または開発者が、不具合のチケットを起票する
- 開発のリーダーが、担当の開発者を割り当てる
- 担当者が、チケットの検索で思いつく言葉を入れて過去のチケットを探す
- それらしいチケットが見つかれば、閉じたときのコメントから修正のプルリクエストを探し、変更されたファイルを見る
- 見つからなければ、言葉を変えて探し直すか、チャットで古参の開発者に「前にこういうのなかったっけ」と聞く
- 影響の大きそうなものは、原因分析の記録の置き場も探す
- 見つけた内容をチケットにコメントとして書き、再現と修正に取りかかる
- 人サポート部門または開発者が、不具合のチケットを起票する
- 自動起票をきっかけに、チケットの本文から例外の種類・エラーコード・落ちた関数・製品の部品・報告された版を取り出す
- 自動エラーの型で過去のチケットを完全一致で探す
- 自動症状の文章で、言葉の近い過去のチケットと原因分析の記録を探す
- 自動見つかったチケットごとに、修正のプルリクエストと変更されたファイル、直した版を引く
- 自動報告された版と直した版を比べ、「直っている」「再発の疑い」「似た症状」に分ける
- 自動候補と根拠を生成AIに渡し、原因と修正箇所の候補をチケット番号付きで並べさせる
- 自動結果をチケットのコメントとして書き込む
- 人担当の開発者が候補を読み、根拠のチケットとプルリクエストを開いて確かめる
- 人当たりの候補があれば、チケットに「関連」として記録し、再現と修正に進む
各工程の詳しい説明を読む
- サポート部門または開発者が、不具合のチケットを起票する
- 開発のリーダーが、担当の開発者を割り当てる
- 担当者が、チケットの検索で思いつく言葉を入れて過去のチケットを探す
- それらしいチケットが見つかれば、閉じたときのコメントから修正のプルリクエストを探し、変更されたファイルを見る
- 見つからなければ、言葉を変えて探し直すか、チャットで古参の開発者に「前にこういうのなかったっけ」と聞く
- 影響の大きそうなものは、原因分析の記録の置き場も探す
- 見つけた内容をチケットにコメントとして書き、再現と修正に取りかかる
(a)言葉が合わないと見つからない。 顧客の言葉で書かれたチケットを、開発者の言葉で探しても当たりません。「画面が真っ白になる」と「描画処理で例外」は同じ不具合でも、検索窓に入れる言葉が違えば別の結果になります。
(b)チケットから修正箇所へ辿れない。 閉じたチケットに「修正済み」とだけ書かれ、どのプルリクエストで直したかが無いものがあります。原因と修正箇所という、いちばん知りたい情報が、チケットの外にあります。
(c)版の関係を毎回調べ直す。 見つけた不具合が、報告された版で直っているのかいないのかを確かめるために、修正が入った版をリリースの記録から探し直します。 オンプレミス版の顧客が多いほど、この作業が増えます。
(d)知っているのが古参の開発者だけ。 5番目の「聞く」は早くて確実ですが、聞かれる人は毎週何件も聞かれ、その人が休むと止まります。
- 【人】 サポート部門または開発者が、不具合のチケットを起票する
- 【自動】 起票をきっかけに、チケットの本文から例外の種類・エラーコード・落ちた関数・製品の部品・報告された版を取り出す
- 【自動】 エラーの型で過去のチケットを完全一致で探す
- 【自動】 症状の文章で、言葉の近い過去のチケットと原因分析の記録を探す
- 【自動】 見つかったチケットごとに、修正のプルリクエストと変更されたファイル、直した版を引く
- 【自動】 報告された版と直した版を比べ、「直っている」「再発の疑い」「似た症状」に分ける
- 【自動】 候補と根拠を生成AIに渡し、原因と修正箇所の候補をチケット番号付きで並べさせる
- 【自動】 結果をチケットのコメントとして書き込む
- 【人】 担当の開発者が候補を読み、根拠のチケットとプルリクエストを開いて確かめる
- 【人】 当たりの候補があれば、チケットに「関連」として記録し、再現と修正に進む
9番目が、この設計の分かれ目です。 コメントに出るのは候補であって、答えではありません。似た症状の過去の不具合が、今回の原因と同じとは限らないので、担当者が根拠を開いて確かめます。
6番目を機械の比較で決めているのも、意図してのことです。 版の前後は、版番号の比較で確実に決まります。生成AIに「直っているか」を判断させると、もっともらしい推測が混ざります。 比べた結果だけを生成AIに渡します。
02今回想定するシステム構成
GitHub Issues(新しい不具合のチケット) ▼【トリガー】起票(ラベル bug の付与) AWS Lambda ── 例外の種類・エラーコード・関数・部品・版を取り出す ▼ Amazon OpenSearch Service(過去のチケット・原因分析の索引) ├─ エラーの型:keyword で完全一致(例外の種類・エラーコード・関数) ├─ 症状の言葉:more_like_this(Sudachi で分けた本文) └─ 部品で絞り込み ▼ AWS Lambda ── 候補ごとに修正のプルリクエスト・変更ファイル・直した版を引く │ 報告された版と直した版を比べて三つに分ける ▼ Claude(Amazon Bedrock)── 検索結果のブロックで渡し、引用付きで候補を並べる ▼ GitHub Issues にコメント(候補・根拠のチケット番号・修正箇所・版の関係)
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 検索基盤 | Amazon OpenSearch Service(Sudachi、keyword の完全一致、more_like_this) | Azure AI Search、Vertex AI Search(Agent Search) |
| 生成AI | Claude(Amazon Bedrock。検索結果のブロックを引用付きで並べる) | Gemini API、OpenAI API |
| 連携 | AWS Lambda(起票の受け取り、取り出し、GitHub の API の呼び出し) | AWS Step Functions |
| 保管 | Amazon S3(索引に入れる前のチケットと原因分析の記録の写し、検索の記録) | ― |
| チケット・コード | 既存の GitHub(Issues とプルリクエスト) | ― |
GitHub は新しく足すものではありません。 この構成がGitHubに書き込むのは、新しいチケットへのコメントだけです。過去のチケットを閉じたり、重複として扱ったり、ラベルを変えたりはしません。
症状の近さは、more_like_this で探します。 公式のドキュメントでは、more_like_this は与えた文書や文章を分析してそれを特徴づける語を選び、その語を含む別の文書を探すものです。like には自由な文章、索引の中の実在の文書、その場で作った文書を渡せます。新しいチケットの本文を like に渡せば、「この報告に似た過去のチケット」を探せます。
日本語の本文は、Sudachi で語に分けます。 Amazon OpenSearch Service の対応プラグインの一覧では、Sudachi Analysis が日本語向けに推奨とされています。more_like_this は、指定しなければ最初に挙げた項目の解析器で入力を処理するので、本文の項目に Sudachi を設定しておけば、新しいチケットも同じ分け方で語が選ばれます。
修正箇所は、GitHub のプルリクエストの API で引きます。 変更されたファイルの一覧を返す API があり、ファイルごとにファイル名、状態(追加・削除・変更・名前の変更など)、追加と削除の行数が返ります。
03どうやって実装するのか
処理の起点を決める
不具合のチケットに bug のラベルが付いたことを起点にします。 起票そのものを起点にすると、要望や質問のチケットまで探しに行きます。ラベルはサポート部門と開発者が起票のときに付ける運用なので、付いた時点で1件ずつ動かします。
本文が書き換えられたときにも、もう一度動かします。 起票の直後は「再現手順は追って書く」という本文のことが多く、エラーの全文が貼られるのは数時間後です。2回目以降は、前回のコメントを書き換える形にして、コメントが増えすぎないようにします。
索引の更新は別に動かします。 チケットが閉じられたとき、プルリクエストがマージされたとき、原因分析の記録が承認されたときに、その1件だけを索引に入れ直します。 夜にまとめて入れ直すと、昼に直した不具合が翌朝まで見えません。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 新しいチケット | 題名、本文、エラーの全文、報告された版、部品のラベル、起票者 | GitHub Issues |
| 過去のチケット | 題名、本文、閉じたときのコメント、閉じた日、部品、閉じた理由(修正・重複・再現せず) | GitHub Issues を索引にしたもの |
| 修正のプルリクエスト | 題名、説明、変更されたファイル、マージした日、マージ先 | GitHub のプルリクエスト |
| 原因分析の記録 | 起きたこと、原因、試験で見つからなかった理由、対策、関係するチケット番号 | 社内の文書の置き場 |
| 版の対応表 | 版ごとの公開日と、その版に入ったプルリクエストの番号 | リリースの記録 |
質を決めるのは、過去のチケットの「閉じた理由」です。 重複として閉じたものや、再現しなかったものまで候補に出すと、原因も修正箇所も無い候補が上位を占めます。 重複として閉じたものは、重複先のチケットに寄せてから索引に入れます。
原因分析の記録には、関係するチケット番号を必ず持たせます。 番号が無い記録は、症状の文章で見つかっても、どの修正に対応するかを辿れません。 書かれていない過去の記録は、最初の準備として番号を書き足します。
データの取得方法を決める
チケットとプルリクエストの対応は、まず GitHub の「リンク」で取ります。 プルリクエストの説明に Fixes #123 のようなキーワードを書くと、チケットとプルリクエストが結び付き、マージされるとチケットが自動で閉じます。 使えるキーワードは close/closes/closed、fix/fixes/fixed、resolve/resolves/resolved で、大文字小文字は区別されません。
ただし、リンクが作られるのはデフォルトブランチ向けのプルリクエストだけです。 公式の説明では、それ以外のブランチ向けではキーワードは無視され、リンクは作られず、マージしてもチケットに影響しません。 オンプレミス版のための修正を保守用のブランチに入れているなら、その修正はリンクから辿れません。
| 取るもの | どこから | 何に使うか |
|---|---|---|
| チケットとプルリクエストの対応 | プルリクエストの説明のキーワード | 修正のプルリクエストを特定する |
| 保守用ブランチの修正 | プルリクエストの題名・ブランチ名に書いたチケット番号 | リンクで辿れない修正を補う |
| 変更されたファイル | プルリクエストの変更ファイルの API | 修正箇所の候補 |
| 名前が変わったファイル | 同じ API の previous_filename | 今のファイルの場所に読み替える |
| 直した版 | 版の対応表 | 報告された版との前後を比べる |
保守用ブランチの修正は、チケット番号を題名に入れる決まりで補います。 「題名の先頭に [#123] を書く」と決め、それを読み取って対応を作ります。決まりができる前の修正は、最初に一度だけ手で対応を付けます。
変更されたファイルの API には、上限があります。 返るのは最大3,000ファイルで、1ページの既定は30件、最大100件です。大きなリファクタリングを含むプルリクエストは上限に当たることがあり、その場合は修正箇所の候補から外します。
AIへ渡す前に整形する
- エラーの型を取り出す … 本文から例外の種類、エラーコード、スタックトレースの上から数段の関数名を取り出します
- 行番号とアドレスを消す … スタックトレースの行番号、メモリのアドレス、日時、利用者のIDを消します。版が違うと行番号は変わるので、残すと一致しません
- 定型の見出しを除く … 「再現手順」「期待される結果」「実際の結果」など、起票のひな形の見出しを本文から外します
- 版をそろえる … 「v5.2」「5.2.0」「ver5.2」を同じ書き方にそろえます
- 部品を決める … 部品のラベルが付いていなければ、落ちた関数のファイルの場所から部品を推定します
- 個人の情報を外す … 顧客の名前、メールアドレス、画面の写しに写った顧客のデータは、索引に入れる前に消します
2番目を軽く見ないでください。 同じ不具合でも、版が一つ違えばスタックトレースの行番号はずれます。行番号を残したまま完全一致で探すと、同じ不具合の過去のチケットが一件も当たりません。 残すのは例外の種類と関数名の並びだけです。
3番目は、more_like_this のためです。 ひな形の見出しはすべてのチケットに出てくるので、残すとどのチケットも似ているように見えます。 more_like_this には、無視する語を並べる stop_words と、多くの文書に出る語を無視する max_doc_freq があり、どちらでも外せます。
AIに処理させる
検索は、二つの道を別々に走らせ、結果を合わせます。
| 道 | 探し方 | 向いている報告 |
|---|---|---|
| エラーの型 | 例外の種類・エラーコード・関数名を keyword の項目で完全一致 | 開発者が起票した、エラーの全文があるもの |
| 症状の言葉 | 本文を like に渡して more_like_this | 顧客の言葉で書かれた、エラーの無いもの |
more_like_this の既定値は、短いチケットに向いていません。 公式の既定では、入力の中で2回未満しか出ない語は無視され(min_term_freq が2)、5件未満の文書にしか出ない語も無視されます(min_doc_freq が5)。数行のチケットでは、ほとんどの語が1回しか出ないので、min_term_freq を1に下げます。語の数の上限 max_query_terms は既定で25、一致させる語の割合 minimum_should_match は既定で30%です。
生成AIにさせるのは、候補を並べ、それぞれの原因と修正箇所を根拠付きで書き出すことだけです。
| させること | 中身 |
|---|---|
| 候補の要約 | 過去のチケットごとに、症状・原因・修正の内容を1〜2文で |
| 似ている点 | 新しいチケットのどこが、過去のチケットのどこと似ているか |
| 違う点 | 似ているが違う点(部品・操作・エラーの種類) |
| 修正箇所 | プルリクエストで変更されたファイルのうち、原因に関係するもの |
| 確かめること | 担当者が再現のときに最初に確かめるべき点 |
| させないこと | 理由 |
|---|---|
| 原因の断定 | 似た症状でも原因が違うことは多い。決めるのは担当者 |
| 版の前後の判断 | 版番号の比較で機械的に決める |
| 重複としての処理 | チケットを閉じるかは開発のリーダーが決める |
| 修正のコードを書くこと | 候補を探す仕組みで、直す仕組みではない |
| 根拠に無い修正箇所 | 変更ファイルの一覧に無いファイルを挙げない |
4行目を守らせるのが、この構成の線引きです。 修正の案まで出すと、担当者は候補の確認を飛ばして案を試し始めます。探すことと直すことを分けておくほうが、誤った候補で時間を失わずに済みます。
指示内容を固定する
あなたは製品開発部で、新しい不具合のチケットに関係する過去の不具合を
整理する立場です。渡した検索結果だけを根拠にしてください。
【新しいチケット】{new_issue}
【報告された版】{reported_version}
【版の関係】候補ごとに、機械で比べた結果を渡します。
fixed_before ... 報告された版より前の版で修正済み
fixed_after .... 報告された版より後の版で修正(その版ではまだ直っていない)
no_fix ......... 修正の記録が無い
【やること】
1. 候補ごとに、症状・原因・修正の内容を1〜2文で書く
2. 新しいチケットと似ている点、違う点を書く
3. 修正のプルリクエストで変更されたファイルのうち、
原因に関係しそうなものを挙げる
4. 担当者が再現のときに最初に確かめるべき点を書く
【厳守事項】
- 検索結果に書かれていないことを書かないでください。
原因が書かれていない候補は、cause を「記載なし」としてください。
- 修正箇所は、変更されたファイルの一覧にあるものだけを挙げてください。
一覧に無いファイルを推測で挙げないでください。
- 版の関係は、渡した値をそのまま使ってください。
あなたが版番号を比べ直さないでください。
- 今回の原因がどれかを断定しないでください。
「同じ原因の可能性がある」までにしてください。
- 似ていない候補は、無理に関連付けず除外してください。
除外した候補は excluded に番号と理由を書いてください。
- 修正のコードや修正の方法は書かないでください。
- チケットを重複として閉じるべきかは書かないでください。
「変更されたファイルの一覧にあるものだけ」を明記しないと、それらしいファイル名が出ます。 症状の説明に「保存の処理」と書かれていれば、save_handler のようなありそうな名前を作って挙げます。担当者がそのファイルを探して時間を使うので、一覧の外を挙げることを禁じます。
「版番号を比べ直さない」も同じ理由です。 「5.10」と「5.9」を文字として比べると、5.10 のほうが古いと読むことがあります。比べた結果を渡し、使わせるだけにします。
検索結果は、Claude の検索結果のブロックで渡します。 公式の説明では、source・title・content を持つブロックで渡すと、自社の文書を引用付きで答えられ、Amazon Bedrock でも使えます。source にはチケット番号を入れます。引用はテキストのブロックが単位なので、症状・原因・修正を別のブロックに分けて入れておくと、どの部分を根拠にしたかが細かく分かります。
出力形式を固定する
次の形のJSONで受け取ります。
{
"new_issue": "#9812",
"reported_version": "5.9.2",
"candidates": [
{
"issue": "#7420",
"route": "error_signature | symptom_text",
"version_relation": "fixed_before | fixed_after | no_fix",
"fixed_in": "5.8.0",
"fix_pr": "#7433",
"summary": "",
"similar_points": "",
"different_points": "",
"cause": "",
"fix_files": ["src/export/csv_writer.py"],
"check_first": "",
"citations": ["#7420", "PR#7433", "RCA-2024-11"]
}
],
"excluded": [{ "issue": "#5102", "reason": "" }]
}
1つ目の理由は、route で探し方を残せることです。 エラーの型で当たった候補と、症状の言葉で当たった候補は、信用の度合いが違います。 前者は同じ例外で落ちている事実があり、後者は言葉が近いだけです。コメントでは前者を上に並べます。
2つ目は、version_relation で担当者の次の作業が決まることです。
version_relation | 担当者の次の作業 |
|---|---|
fixed_before | 報告された版より前に直っている。顧客の環境の版が本当にその版かを先に確かめる |
fixed_after | 後の版で直っている。版を上げてもらうか、修正を保守用ブランチへ移すかをリーダーと決める |
no_fix | 修正の記録が無い。似た症状の別の不具合として、ゼロから調査する |
1行目は、再発の疑いも含みます。 直した版より新しい版で同じ症状が出ているなら、修正が後の変更で壊れた可能性があります。 担当者はこの行を見て、修正のプルリクエスト以降の変更を確かめます。
3つ目は、excluded で外した理由が残ることです。 検索で出たのに外した候補が見えないと、担当者は「探し漏れがあるのでは」と自分で探し直します。外した理由が書いてあれば、探し直す必要がありません。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| GitHub Issues | Webhook と API | ラベルの付与を受け取り、コメントを書き込む |
| GitHub のプルリクエスト | API | 変更されたファイル、マージした日、マージ先を引く |
| Amazon OpenSearch Service | 検索の API | 過去のチケットと原因分析の記録を探す |
| 社内の文書の置き場 | 承認時の書き出し | 原因分析の記録を索引に入れる |
| Claude(Amazon Bedrock) | API呼び出し | 候補を引用付きで並べる |
GitHub への書き込みは、新しいチケットへのコメントだけにします。 そのための権限は、コメントを書ける最小のものにします。過去のチケットを閉じる・ラベルを変える権限は持たせません。 誤った候補が出ても、コメントを消せば元に戻ります。
検索の索引には、非公開のリポジトリのチケットも入ります。 社内の開発者なら誰でも検索できる作りにすると、セキュリティの脆弱性のチケットのように、一部の人だけが見るべきものまで候補に出ます。 脆弱性のラベルが付いたチケットは索引に入れないか、別の索引に分けます。
人が確認する
候補は、すべて担当の開発者が確かめます。 コメントは調査の出発点で、原因の結論ではありません。
error_signatureの候補から見る … 同じ例外で落ちている事実があるので、当たる見込みが高いほうから開きますversion_relationを見る …fixed_beforeなら、まず顧客の環境の版を確かめます- 根拠を開く … 過去のチケットと修正のプルリクエストを開き、原因の説明が今回の症状と合うかを読みます
- 結果を記録する … 当たった候補はチケットに「関連」として残し、外れた候補には外れた理由を一言書きます
4番目を省かないでください。 外れた理由が残ると、同じ組み合わせの候補が次に出たとき、すぐに外せます。 また、外れが続く部品があれば、索引の分け方か前処理を見直す材料になります。
目標は、1件10分です。 候補のコメントを読み、上位の2〜3件の根拠を開いて確かめるまでの時間です。候補が無かったときも、「無い」と分かるまでの時間が10分になります。 これまでは、無いと分かるまでに30分以上かかっていました。
例外に対処する
| 起きること | 対応 |
|---|---|
| 本文が短く、エラーも無い | 検索せず「エラーの全文と再現手順があれば探せる」とコメントする |
| 候補が1件も無い | 「似た過去の不具合は見つからなかった」と書く。見つからないことも結果として残す |
| 修正のプルリクエストが見つからない | fix_pr を空にして候補には残す。原因分析の記録があればそちらを根拠にする |
| 変更ファイルが3,000件の上限に当たる | 修正箇所の候補から外し、プルリクエストの番号だけを示す |
| ファイルの名前が変わっている | previous_filename から今の場所に読み替える |
| 版の書き方が読めない | version_relation を空にし、「版を確かめてください」と書く |
| 脆弱性のラベルが付いたチケット | 一般の索引では探さない。担当の限られた索引で別に探す |
| GitHub の API が応答しない | コメントを書かずに、時間をおいてやり直す |
上から2行目を、きちんと結果にしてください。 「見つからなかった」が書かれていないと、担当者は仕組みが動かなかったのか、本当に無いのかを区別できず、結局自分で探します。
記録を残す
- 新しいチケットの番号と、取り出したエラーの型・部品・版
- 二つの道それぞれの検索の条件と、返ってきた上位の候補
- 生成AIに渡した検索結果のブロックと、返ってきたJSONの全文
- 書き込んだコメントと、その日時
- 担当者が付けた「関連」と、外れた理由
- 最終的に原因となったチケット(後から分かったもの)
最後の行が、仕組みを良くする材料になります。 最終的な原因が候補の中にあったか、何番目にあったかを数えれば、探し方が効いているかが分かります。 候補に無かったのに過去に記録があった不具合は、言葉が合わなかった例として前処理と stop_words を見直す材料にします。
04実装レベルの3段階
半自動化で、①の15分が数分になります。 言葉が違っても似たチケットに当たるようになりますが、修正のプルリクエストを辿る②と、版の関係を確かめる作業は手で残ります。 本格構成で、ここまでを起票の時点でコメントに出し、1件10分にします。この段階が本記事の想定です。 段階を飛ばさないでください。 半自動化の検索を開発者が使うと、どの言葉で探して当たったか、外れたかの記録がたまります。それが stop_words と前処理を決める材料になり、本格構成で自動で探すときの外れが減ります。
05工数削減シミュレーション
導入後 240件 × 10分 ÷ 60 = 40 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 自社のソフトウェア製品を数年以上保守していて、不具合のチケットが数千件以上たまっている開発組織。チケット・プルリクエスト・原因分析の記録が別々の場所にあり、「前にも似た不具合があった気がする」の確認を古参の開発者に聞いて済ませている場合。顧客ごとに使っている版が違い、すでに直した不具合が古い版で報告されることがある場合。AWS を使っており、検索基盤と生成AIを同じ環境で動かせる場合。
- 製品が新しく、過去の不具合の記録がまだ数百件に満たない場合(似たものを探す元がありません)。チケットに症状と原因が書かれておらず、「直した」の一行で閉じられているものが大半の場合(先に起票と完了の書き方をそろえるのが先です)。プルリクエストとチケットの対応を取っておらず、どの変更がどの不具合を直したのかを後から追えない場合。なお、本当の原因が何か、どう直すかの判断は担当の開発者とレビューで行い、この構成はそれを代わりに行いません。
07最小構成で試す方法
- 先月起票された不具合のチケットから20件を選ぶ(うち数件は、過去に似た不具合があったと分かっているものを入れる)
- 過去1年分のクローズ済みの不具合チケットを、題名・本文・閉じたときのコメントでテキストに書き出す
- 手元のAIサービスに、書き出したものと新しいチケット1件を渡す
- 「新しいチケットに似た過去のチケットを最大5件挙げ、それぞれの症状・原因・修正のプルリクエストを、根拠のチケット番号付きで書いてください。書かれていないことは書かないでください」と指示する
- 出てきた候補を、実際に担当者が見つけた過去の不具合と突き合わせる
20件は必ずやってください。 索引を作る前に、「過去の記録に、探せば当たるだけの情報があるのか」を確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 担当者が見つけたものと同じ候補が出た | 索引と GitHub の連携に進む |
| 似た候補は出たが、原因が書かれていない | 過去のチケットの閉じ方の問題。閉じるときに原因を書く決まりを先に作る |
| 書き出しの量が多すぎて渡しきれない | 手で試せる量の上限。索引を作る段階の理由がはっきりした |
2行目が出ることは珍しくありません。 失敗ではなく、過去の不具合から原因を引けなかった理由が分かったということです。 その場合は、閉じるときに「原因」と「修正のプルリクエスト」の欄を埋める決まりを作り、3か月後にもう一度試してください。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| 同じ不具合なのに、エラーの型で当たらない | スタックトレースの行番号を消す。 残すのは例外の種類と関数名の並び |
| どのチケットも似ているように出る | 起票のひな形の見出しを除く。stop_words と max_doc_freq で外す |
| 短いチケットで何も出ない | min_term_freq の既定は2。1に下げる |
| 保守用ブランチの修正が辿れない | リンクはデフォルトブランチ向けだけ。題名にチケット番号を書く決まりを作る |
| 修正箇所に古いファイル名が出る | previous_filename で今の場所に読み替える |
| 生成AIが一覧に無いファイルを挙げる | 指示で禁じ、出力のファイル名を変更ファイルの一覧と機械で突き合わせる |
| 版の前後が逆になる | 版番号の比較は機械で行い、生成AIに比べさせない |
| 重複として閉じたチケットが上位に来る | 重複先に寄せてから索引に入れる |
| 脆弱性のチケットが候補に出る | 一般の索引に入れない |
| 候補を確かめずに修正を始める | 候補は答えではないとコメントに書き、確認の記録を残す |
上の2行が、この構成の失敗のほとんどです。 どちらも「探し方は合っているのに、入れ方が悪い」型の失敗で、前処理を直せば効きます。 生成AIを替えても直りません。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 不具合のチケットの本文、エラーの全文、ソースコードのファイル名と変更の内容、原因分析の記録、そしてチケットに貼られた顧客の環境の情報です。
- 顧客の情報を索引に入れない … チケットには、顧客の社名、利用者のメールアドレス、画面の写しに写った顧客のデータが入ることがあります。索引に入れる前に消します。 消し残しがあると、別の顧客の不具合の調査で候補として表示されます
- 脆弱性のチケットを分ける … 公開前の脆弱性の情報は、知る人を限るべきものです。一般の索引に入れず、担当の限られた索引で別に扱います
- 生成AIに渡すのは検索で当たった部分だけにする … ソースコードの全体は渡しません。渡すのはチケットの本文、原因分析の記録、変更されたファイル名までです
- GitHub の権限を絞る … この構成に持たせる権限は、チケットを読み、コメントを書く範囲にします。チケットを閉じる、コードを書き換える権限は持たせません
- 候補を答えとして扱わない … 原因の結論は、担当の開発者がレビューを経て決めます。この構成は、過去の記録を引いて並べるだけです
誤りが起きた場合のリスクは、外れた候補を前提に調査を進めることと、見るべきでない人に情報が表示されることの2つです。 前者は確認の手順と route の並べ方で抑え、後者は索引に入れる前に分けることで抑えます。どちらも、生成AIの前の段階で決まります。
10まず何から始めるか
1週目:閉じ方の決まりを作る
不具合のチケットを閉じるときに、「原因」と「修正のプルリクエスト」を書く欄をひな形に足します。保守用ブランチへの修正は、プルリクエストの題名の先頭にチケット番号を書くと決めます。過去の分は後回しにし、今日から閉じるものをそろえます。
2週目:20件で試す
先月の不具合のチケットから20件を選び、過去1年分のチケットを書き出して、手元のAIサービスで候補を挙げさせます。担当者が実際に見つけた過去の不具合と突き合わせます。
3週目:前処理を決める
スタックトレースから何を消して何を残すか、起票のひな形のどの見出しを外すかを、20件の結果を見て決めます。脆弱性のチケットと顧客の情報の扱いも、このときに決めます。
4週目:索引を作る
過去のチケットと原因分析の記録を Amazon OpenSearch Service に入れ、開発者が自分で検索できる画面を作ります。この時点ではコメントを自動で書かず、半自動化として使ってもらいます。
2か月目: 修正のプルリクエストと版の関係を付け、起票を起点にコメントを書く形にします。担当者が付けた「関連」と外れた理由を毎週数えます。3か月目以降: 最終的な原因が候補の何番目にあったかを数え、stop_words と前処理を見直します。1件30分が何分になったかを実測した時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| Amazon OpenSearch Service の対応プラグインの一覧で、Sudachi Analysis が日本語向けに推奨されていること | Amazon OpenSearch Service: Plugins by engine version | 2026-10-08 |
more_like_this が入力を分析して特徴的な語を選び、その語を含む文書を探すこと。like に自由な文章・索引の中の文書・その場で作った文書を渡せること。min_term_freq の既定が2、min_doc_freq の既定が5、max_query_terms の既定が25、minimum_should_match の既定が30%であること。stop_words・max_doc_freq・unlike があること。解析器の既定が最初の項目の解析器であること | OpenSearch Documentation: More like this | 2026-10-08 |
プルリクエストの変更ファイルの API がファイル名・状態・追加と削除の行数・previous_filename を返すこと。最大3,000ファイルで、1ページの既定が30件、最大100件であること | GitHub Docs: REST API endpoints for pull requests | 2026-10-08 |
| close/fix/resolve などのキーワードでプルリクエストとチケットを結べ、マージでチケットが閉じること。大文字小文字を区別しないこと。デフォルトブランチ向け以外ではキーワードが無視され、リンクが作られないこと | GitHub Docs: Linking a pull request to an issue | 2026-10-08 |
検索結果ブロック(source・title・content)で自社の文書を渡すと引用付きで答えること。引用がテキストブロックを単位に付くこと。引用の設定はすべての検索結果でそろえる必要があること。Amazon Bedrock でも使えること | Claude Docs: Search results | 2026-10-08 |
原因の判断と修正の方法は、自社の開発の手順とレビューに従ってください。 本記事は公開仕様で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0874)についてのご相談はこちらから。
