はじめに
生成AIを開発現場に入れたら、コードも設計書も議事録もテストケースも、作る速さは確かに上がった。一方で、生成物を十分に検証しないまま採用すると、不具合・脆弱性・保守不能化・判断経緯の消失が起きる。
このあたりの危機感は、もう共有されていると思う。
本稿では、品質保証の観点から対策を組み直す。よく挙がる崩壊パターンは次のようなものだ。
- 誰もコードを理解していない
- 責任の所在がない
- スキルが空洞化する
- 意思決定のコンテキストが断絶する
現場で起こり得る話だ。ただ、対策を次のように置くと、別の属人化を生む。
- 実装者が自分の言葉で説明できるかを重視する
- AIを使った本人へ責任を集中させる
- AIを使わない時間を設ける
- 人間が判断経緯を文章として残す
補助策としては有効だが、品質保証の中心には置けない。
AI時代に必要なのは、全コードを実装者が口頭で説明できる状態ではない。要求、設計判断、コード差分、テスト、解析結果、既知障害との照合、承認記録を追跡可能にし、属人的な理解ではなく再現可能な品質保証プロセスで成果物を評価できる状態である。
1. 「説明できること」は重要だが、品質保証そのものではない
1.1 説明能力と成果物品質は一致しない
「このロジックを自分の言葉で説明してください」と聞くのは悪くない。理解せずに生成コードを貼るのを抑えられるし、障害時の初動も早くなる。
ただ、説明が上手い人のコードが安全とは限らない。人間が流暢に説明できるコードに、次の欠陥は普通に残る。
- 境界値の見落とし
- 異常系の考慮不足
- 認可漏れ
- SQLインジェクションなどの脆弱性
- 排他制御の不備
- 既存機能への副作用
- 性能劣化
- ロールバック不能なデータ更新
- 運用監視の不足
逆に、AIが生成したコードでも、要求との対応が追跡でき、テスト・静的解析・レビュー・回帰確認・承認を通過していれば、品質について客観的な根拠を示せる。
| 観点 | 主な目的 | 単独で品質保証になるか |
|---|---|---|
| 実装者による説明 | 理解度、保守性、教育効果の確認 | ならない |
| 検証可能な証跡 | 要求適合性、欠陥検出、再現性の確保 | 品質保証の基盤になる |
1.2 AI自身に説明させればよいのか
AIは、生成したコードの意図、採用した方式、代替案、想定した異常系、影響範囲を説明できる。実装者がゼロから説明資料を書くより効率的なので、積極的に使うべきだ。
ただし、AIの説明文をそのまま正しさの証拠にしてはいけない。もっともらしい説明を生成するだけで、説明とコードが整合しているとは限らない。コードと要求が整合しているとも限らない。
GitHubの公式ドキュメントでも、Copilotによるコードレビューは問題を見逃す可能性があり、誤検知もあり得ると説明されている。生成された修正案についても、見た目が妥当でも意味的・構文的に正しくない場合や、脆弱性を含む場合があるため、レビューとテストが必要とされている1。
AIの説明は、レビューを効率化するための入力資料であって、正しさを証明する証拠ではない。
1.3 NIST SSDFは「人間だけのレビュー」を要求していない
NISTのSecure Software Development Framework(SSDF)Version 1.1では、コードの脆弱性検出とセキュリティ要件への適合確認について、コードレビューとコード解析を組み合わせる考え方が示されている。
PW.7.1では、組織が次の手段を選択するとしている。
- 人間がコードを直接確認するコードレビュー
- ツールによるコード解析
- 人間とツールを組み合わせた解析
PW.7.2では、静的解析ツール、レビュー用チェックリスト、継続的な自動検出、検出事項の記録とトリアージなどが例示されている2。
重要なのは「誰かがすべてを口頭説明できること」ではなく、組織として定めた基準に沿って、人間とツールを組み合わせ、検証結果を記録し、問題を修正できることだ。
2. 「動いたからOK」はAI固有の問題ではない
2.1 「動いた」の意味を分解する
「テストは通っています」「動きました」は、品質判定として曖昧だ。しかもこの問題は、AIが登場する以前からあった。
次の状態は、すべて「動いた」と言えてしまう。
- 正常系を1件だけ手動確認した
- 単体テストだけが通過した
- 結合テストは未実施である
- 権限の異なる利用者では未確認である
- 大量データでは性能劣化する
- 既存機能の回帰テストを行っていない
- 障害時に復旧できない
- ログが不足しており原因調査できない
「動いた」という言葉を禁止する必要はない。何をもって合格とするかを工程ごとに定義するのが先だ。
2.2 ウォーターフォール、V字モデル、W字モデルの本質
ウォーターフォール型の開発を単純化すると、要求定義、設計、実装、テスト、リリースという流れになる。V字モデルでは、上流の成果物と検証するテスト工程の対応を明確にする。W字モデルでは、テスト工程に入ってから検証内容を考えるのではなく、上流工程の段階からテスト設計や検証観点を作り込む。
この構造の利点は、「担当者がなんとなく動いたと感じたか」ではなく、成果物ごとに検証対象、観点、合格条件、差戻し条件を定義できることだ。
IPAの「組込みソフトウェア開発における品質向上の勧め[テスト編〜事例集〜]」では、テストに完全を求めても潜在バグをゼロにすることはできないとした上で、品質要求とコストのバランスを踏まえ、品質メトリクスの基準値、目標値、終了条件を考える必要があると説明されている3。
品質ゲートを設けても不具合が必ず検出されるわけではない。目的は、属人的な「動いた」を排除し、欠陥の検出可能性と判断の再現性を高めることにある。
2.3 AI生成コードにも既存の品質保証を適用する
AI生成コードだけを特別扱いする必要はない。人間が書いたコードと同様に、変更リスクに応じて品質ゲートを適用すればよい。
| 工程 | 主な検証対象 | 合格条件の例 |
|---|---|---|
| 要求確認 | 要求、制約、対象外範囲 | 要求ID、受入条件、対象外条件が明記されている |
| 設計レビュー | 方式、影響範囲、例外設計 | 代替案、影響箇所、リスク、ロールバック方針が確認済み |
| 実装レビュー | コード差分、可読性、セキュリティ | チェックリスト、静的解析、レビュー指摘が解消済み |
| 単体テスト | 関数、API、モジュール | 正常系、異常系、境界値が確認済み |
| 結合テスト | モジュール間連携 | インターフェース、データ変換、障害系が確認済み |
| システムテスト | 業務シナリオ、性能、運用 | 受入条件、性能目標、監視、復旧手順が確認済み |
| リリース判定 | 既知課題、残存リスク | 未解決事項が承認済み、切戻し可能、証跡が保存済み |
この表にAI使用率は出てこない。AIを80%使ったか20%使ったかは、品質の説明変数として弱いからだ。
3. 「AI使用率」より「変更リスク区分」を見る
3.1 AI使用率は品質指標として弱い
プルリクエストに「AI使用率」を書く運用は、利用状況の把握には使える。品質ゲートを決める指標としては弱い。
比較してみてほしい。
- AIが90%生成した社内ツールの文言修正
- 人間が100%手書きした本番環境の認可処理変更
一般に、後者の方が慎重な検証を要する。重要なのは生成主体ではなく、変更の性質だ。
3.2 リスクベースで品質ゲートを変える
変更リスク区分を定義すれば、レビュー強度を合理的に変えられる。
| リスク区分 | 変更例 | 必須ゲートの例 |
|---|---|---|
| Low | 文言修正、表示順変更、開発用スクリプト | 単体確認、差分レビュー、CI通過 |
| Medium | 一般的な業務ロジック、帳票、バッチ処理 | 要求トレース、単体・結合テスト、回帰テスト、静的解析 |
| High | 認証、認可、個人情報、金額、在庫、外部公開API、不可逆なDB更新 | 設計レビュー、セキュリティレビュー、異常系、性能確認、ロールバック検証、複数承認 |
| Critical | 人命、安全、法令、社会インフラ、重大な財務影響 | 独立した検証、監査証跡、段階リリース、運用監視、経営判断を含む承認 |
構成ファイルで表現するなら、こんな形になる。
change_risk:
class: high
reasons:
- authorization_logic_changed
- personal_data_access_changed
required_evidence:
- requirement_trace
- design_review
- unit_test_normal_abnormal_boundary
- integration_test
- regression_test
- static_analysis
- security_review
- rollback_plan
- monitoring_plan
- two_approvals
「AI使用率80%なので危険」と判断するより、こちらの方が実務に効く。
4. 「責任」を精神論にしない
4.1 責任という言葉は分解しないと機能しない
「AIが作ったコードの責任は、AIを使った人間が持つ」という表現は、AIを免罪符にしてはいけない、という意味では理解できる。
ただ、ソフトウェア開発の問題は、単一の実装者だけに還元できないことが多い。障害の原因は、例えば次のように分かれる。
| 問題 | 主に確認すべき工程 |
|---|---|
| 顧客要求が曖昧だった | 要求定義、顧客合意 |
| 想定外の業務パターンがあった | 業務分析、受入条件 |
| 設計方式に欠陥があった | 設計レビュー |
| 実装ミスがあった | 実装、単体テスト |
| 回帰テストが不足した | テスト設計、QA |
| リリース判断が不適切だった | リリース承認 |
| 障害検知が遅れた | 監視、運用設計 |
問題が起きたあとに「誰の責任か」だけを問うと、個人への責任転嫁で終わる。先に定義しておくべきは、誰が作業し、誰が判断し、誰が承認し、誰へ相談・報告するか。そして、何を根拠に合格とし、どの証跡を残すかだ。
4.2 役割と責務を工程ごとに割り当てる
RACIを簡略化すると、次のように設計できる。
| 成果物・判断 | 実装担当 | レビュアー | QA | PO・顧客側 | リリース承認者 |
|---|---|---|---|---|---|
| 要求と受入条件 | 参照 | 参照 | 参照 | 作成・合意 | 参照 |
| 設計方式 | 作成 | 検証 | 参照 | 必要に応じ確認 | 参照 |
| コード差分 | 作成 | 検証 | 参照 | - | 参照 |
| テスト計画 | 協力 | 参照 | 作成・検証 | 必要に応じ確認 | 参照 |
| 残存リスク | 説明 | 確認 | 確認 | 必要に応じ合意 | 承認 |
| リリース可否 | 参照 | 参照 | 判定材料を提示 | 必要に応じ合意 | 最終判断 |
NIST AI RMF Coreでは、AIリスクのマッピング、測定、管理に関する役割、責任、連絡経路を文書化し、個人とチームに明確にすることが示されている。人間とAIの構成に応じて役割と責任を区別するための方針・手順も求めている4。
責任とは、問題が起きた後に個人を探すことではない。問題が起きる前に、工程、役割、判断基準、証跡、承認フローを定義しておくことだ。
5. コンテキストの断絶は「トレーサビリティ」で防ぐ
5.1 人間が全部書く必要はない
AIが仕様案、設計案、コード、テストケースを生成すると、判断経緯が失われる危険はある。ただ、解決策を「人間が毎回ゼロから文章を書くこと」に限定する必要はない。
AIに次の資料を生成させればよい。
- 要求IDと変更コードの対応表
- 採用した実装方式
- 却下した代替案と却下理由
- 想定した正常系、異常系、境界値
- 影響範囲
- 既知障害との類似点
- 追加したテスト
- 未解決リスク
- 切戻し方法
- 監視方法
人間は、その資料とコード、テスト結果、設計書、実行証跡の整合性を確認する。
5.2 トレーサビリティの対象
IPAの「高信頼化ソフトウェアのための開発手法ガイドブック」では、トレーサビリティを実現することで、ソフトウェアの一部を修正した際に影響を受ける構成部品や関連箇所を特定でき、修正漏れや矛盾を防げると説明されている5。
AI時代には、この考え方を次のように拡張できる。
GitHubのCopilot cloud agentに関する公式ドキュメントでも、エージェントによる作業を監査可能・追跡可能にするため、コミットの作成者、タスクを開始した開発者、署名、セッションログ、監査ログ、コミットからセッションログへのリンクを残す仕組みが説明されている6。
AI生成物だから追跡できないのではない。追跡可能性を開発プロセスへ組み込んでいないから追跡できない。
6. 過去の障害を「チームの検証能力」に変換する
6.1 レビュアーの記憶に依存しない
経験豊富なレビュアーは、過去の障害を思い出しながらレビューする。有効だが、その人が不在になると品質が落ちる。
俗人化を防ぐには、過去の障害を次の形へ変換する。
- チェックリスト
- 回帰テスト
- 静的解析ルール
- Lintルール
- アーキテクチャテスト
- コーディング規約
- 設計テンプレート
- 監視アラート
- AIレビュー用のカスタム指示
NIST SSDFのRV.3では、発見された脆弱性の根本原因を分析し、時間の経過に伴うパターンを確認し、将来の同種問題を自動検出する仕組みや手動プロセスへ反映し、類似脆弱性を予防的に修正する考え方が示されている2。
6.2 障害から品質ゲートを育てる
この仕組みを入れると、品質は「特定の人の勘」から「チームの資産」へ移る。AIもこの資産を利用できる。
例えば、AIへ次のように指示できる。
この変更について、過去障害DBとレビュー観点一覧を参照し、
類似障害、境界値、異常系、権限制御、データ更新の不可逆性、
ログ不足、監視不足、回帰リスクを列挙してください。
各指摘について、関連する要求ID、コード箇所、追加すべきテスト、
検出方法、未解決リスクを示してください。
ここでも、AIの回答をそのまま正解にするのではない。組織知を検索し、レビュー観点を広げる補助者として使う。
7. スキル空洞化の対策は「AI禁止」だけでは足りない
7.1 懸念自体は妥当
若手が生成コードを貼り付けるだけになれば、スキルは空洞化する。AIなしで考える時間を作ることも、基礎訓練としては有効だ。
ただ、AI禁止時間を設けるだけでは、AI時代に必要な能力は育たない。
7.2 育成対象を変える
今後のエンジニアに必要なのは、単にコードを手で書く速度だけではない。
- 要求を分解する力
- 制約を明文化する力
- 受入条件を定義する力
- AIへ適切なコンテキストを渡す力
- 生成結果を疑う力
- 影響範囲を読む力
- 境界値、異常系、障害系を設計する力
- ログから原因を切り分ける力
- セキュリティ上の危険箇所を見つける力
- 設計判断を記録する力
- 品質ゲートを改善する力
AIなし演習とAIあり演習を分けると、教育効果を確認しやすい。
| 演習 | 目的 |
|---|---|
| AIなしで小規模実装 | 基本文法、アルゴリズム、デバッグの基礎を確認する |
| AIありで実装 | 指示設計、検証、影響分析、品質保証を学ぶ |
| AI生成コードのレビュー | 誤りを見抜く力を育てる |
| 過去障害からテスト追加 | 組織知を品質ゲートへ変換する |
| 障害対応演習 | ログ、監視、切戻し、原因分析を学ぶ |
AIを使わないこと自体が目的ではない。目的は、AIがあってもなくても、要求、設計、検証、運用を自律的に考えられるエンジニアを育てることだ。
8. 実務で使えるAI生成コード向けPRテンプレート
AIを利用した変更で使えるプルリクエストテンプレートを置いておく。AI使用率ではなく、変更リスクと検証証跡を中心にする。
## 1. 変更目的
- 関連Issue:
- 要求ID:
- 解決したい問題:
- 対象外とする事項:
## 2. 変更リスク区分
- [ ] Low
- [ ] Medium
- [ ] High
- [ ] Critical
### リスク理由
- [ ] 認証・認可を変更する
- [ ] 個人情報・機密情報を扱う
- [ ] 金額・在庫・契約情報を変更する
- [ ] 外部公開APIを変更する
- [ ] DB更新を伴う
- [ ] 不可逆な処理を含む
- [ ] 性能へ影響する可能性がある
- [ ] 既存機能への影響範囲が広い
- [ ] その他:
## 3. 設計判断
- 採用した方式:
- 代替案:
- 代替案を採用しなかった理由:
- 影響範囲:
- ロールバック方法:
## 4. AI利用情報
- 使用したAIツール:
- AIへ与えた主な制約:
- AIが生成した主な成果物:
- 人間が修正・判断した箇所:
- AIの説明とコード・設計・テストの整合性を確認したか:
## 5. 検証証跡
- [ ] 正常系テスト
- [ ] 異常系テスト
- [ ] 境界値テスト
- [ ] 結合テスト
- [ ] 回帰テスト
- [ ] 静的解析
- [ ] セキュリティ確認
- [ ] 性能確認
- [ ] ロールバック確認
- [ ] ログ・監視確認
### 実行結果
- CI結果:
- テスト結果:
- 解析結果:
- 未解決事項:
## 6. 過去障害との照合
- 参照した障害・レビュー観点:
- 類似障害の有無:
- 追加した回帰テスト・検出ルール:
## 7. 残存リスク
- 残存リスク:
- 許容理由:
- 承認者:
実装者を問い詰めるためのものではない。レビュー時に必要な情報を先に揃え、レビュアーがコードの行単位だけでなく、要求、設計、テスト、運用まで確認できるようにするためのテンプレートだ。
9. AI時代の品質ゲート全体像
AIを開発へ組み込むなら、次の流れが現実的だ。
AIを排除する設計でも、人間の役割を消す設計でもない。役割を分ける。
| AIが得意なこと | 人間が担うべきこと |
|---|---|
| コード案の生成 | 要求と制約の決定 |
| 変更説明の下書き | 説明と成果物の整合確認 |
| テスト候補の列挙 | テスト戦略と合格基準の決定 |
| 既知障害との類似検索 | 残存リスクの受容判断 |
| 静的解析結果の要約 | 例外判断と承認 |
| ドキュメント更新案 | 顧客・利用者との合意形成 |
10. 避けるべき運用
最後に、AI活用チームで避けたい運用をまとめる。
「説明できたからOK」 — 説明は重要だが、テスト、解析、要求トレースの代替にはならない。
「AI使用率が高いから危険」 — 生成比率より、変更リスクと影響範囲を見る。
「テストが通ったからOK」 — テストの種類、観点、網羅性、終了条件、残存リスクを確認する。
「AIが書いたので担当者の責任」 — 実装担当、レビュー、QA、顧客合意、リリース承認、運用監視の責務を分ける。
「AIの説明があるから追跡可能」 — 説明文だけでは足りない。要求、Issue、設計判断、差分、テスト、解析、承認、リリース、障害記録をつなぐ。
「ベテランが見れば分かる」 — ベテランの知見を、チェックリスト、回帰テスト、解析ルール、監視へ移植しないと、俗人化は解消しない。
おわりに
AIを使える人が増えると、チームが崩壊する可能性はある。ただ、原因は「AIを使ったこと」ではない。個人の理解、記憶、経験、責任感に依存したまま、生成速度だけを上げたときに起きる。
人間による説明も、AIによる説明も、どちらか一方では足りない。必要なのは次の状態だ。
- 要求と受入条件が明確である
- 変更リスクに応じて品質ゲートが変わる
- 人間とツールが組み合わされている
- 検証結果が証跡として残る
- 責務が工程ごとに分担されている
- 顧客や関係者との合意が記録されている
- 過去障害が回帰テストや解析ルールへ変換される
- AI生成物も追跡可能である
目指すのは、AIを使わないチームではなく、AIを使っても品質保証が崩れないチームだ。
参考資料
-
GitHub Docs, Application card: GitHub Copilot Agents. 特に Limitations および Best practices.
https://docs.github.com/en/copilot/responsible-use/agents ↩ -
NIST, Secure Software Development Framework (SSDF) Version 1.1: Recommendations for Mitigating the Risk of Software Vulnerabilities, NIST SP 800-218, 2022. 特に PW.7 および RV.3.
https://csrc.nist.gov/pubs/sp/800/218/final ↩ ↩2 -
独立行政法人情報処理推進機構(IPA), 『組込みソフトウェア開発における品質向上の勧め[テスト編〜事例集〜]』, 2012.
https://www.ipa.go.jp/archive/publish/secbooks20121112-2.html ↩ -
NIST AI Resource Center, AI RMF Core. 特に GOVERN 2.1、GOVERN 3.2、GOVERN 4.1〜4.3.
https://airc.nist.gov/airmf-resources/airmf/5-sec-core/ ↩ -
独立行政法人情報処理推進機構(IPA), 『高信頼化ソフトウェアのための開発手法ガイドブック ―予防と検証の事例を中心に―』, 2010. 特にトレーサビリティに関する解説.
https://www.ipa.go.jp/archive/files/000004550.pdf ↩ -
GitHub Docs, Risks and mitigations for GitHub Copilot cloud agent. 特に監査可能性、セッションログ、署名付きコミットに関する説明.
https://docs.github.com/en/copilot/concepts/agents/cloud-agent/risks-and-mitigations ↩