GitHub Copilotを使い始めて、コードを書く時間は明らかに短くなった。
関数のたたき台が数秒で作られる。
テストケースの候補も出てくる。
Pull Requestを作れば、Copilotが短時間でレビューコメントを返してくれる。
それなら、開発全体も同じように速くなるはずだった。
しかし、自分がPythonやRustでOSSを開発していると、思ったほど作業時間が減らないことがあった。
Copilotの回答を待っているわけではない。
コードの生成もレビューも速い。
それなのに、なぜかPull Requestが完成するまでの時間はあまり変わらない。
最初は、単純にCopilotの精度が足りないのだと思っていた。
だが、実際の作業を振り返ると、別の問題が見えてきた。
Copilotによって減ったのは、主にコードを書く時間だった。
その代わり、AIが作った変更や指摘を確認するための検証負債が増えていた。
Copilotが遅いわけではなかった
自分が開発しているPython・Rust製のOSSでは、Copilotのレビューに助けられたことが何度もある。
Copilotが短時間で見つけてくれるのは、たとえば次のような問題だ。
- 未使用のimportや変数
- 実装とドキュメントの不一致
- 非同期処理の終了方法
- テストされていない異常系
- GitHub Actionsや依存関係の更新漏れ
- 危険なデータベース設定
これらは、無視してよい指摘ではない。
内容を確認し、必要なら実装やドキュメントを修正し、テストを再実行する。
Copilotは、人間だけでは見落としていた可能性のある問題を、短時間で表面化させてくれる。
それでも、Pull Requestは一瞬では完成しない。
なぜなら、Copilotがコメントを出したあとに、こちら側で次の判断が必要だからだ。
本当に不具合なのか
↓
現在の設計意図と矛盾しないか
↓
修正方法は後方互換性を壊さないか
↓
別の問題を発生させないか
↓
どのテストで確認できるか
Copilotが7件の指摘を30秒で出したとしても、7件を30秒で安全に直せるわけではない。
ここで生まれていた「検証負債」
自分は、この状態を検証負債と考えるようになった。
技術的負債は、短期的な速さのために設計や保守性の問題を後回しにすることで積み上がる。
検証負債は少し違う。
AIが作ったコードや判断について、正しいと確認できていない項目が積み上がった状態
だ。
たとえばCopilotが100行の変更を生成した場合、その100行すべてが負債になるわけではない。
しかし、変更の中に次のような判断が含まれていれば、確認が必要になる。
- 新しいAPIを使っている
- 既存の例外処理を変えている
- テストされていない分岐を追加している
- データベース設定を変更している
- 公開関数の振る舞いを変えている
- 新しい依存関係を導入している
AIはコードと同時に、検証しなければならない前提も生成する。
コード生成が速くなるほど、検証能力が追いつかなければ負債は増える。
「レビューが必要なのは当たり前」では終わらない
ここまで読んで、
AIが書いたコードをレビューするのは当たり前では?
と思うかもしれない。
その通りだ。
しかし、自分が見落としていたのは「レビューが必要」という事実ではない。
AIによって、レビューへ流れ込む量だけが先に増えることだった。
人間だけで実装していたときは、30分で書ける量のコードしかレビュー対象にならない。
AIを使うと、同じ30分で数倍の変更案を作れる。
ところが、次の速度は同じ割合では上がらない。
- コードを読む速度
- 仕様と照合する速度
- テストを設計する速度
- 性能を測定する速度
- 後方互換性を判断する速度
つまり、ボトルネックが移動する。
AI導入前:
実装が遅い → 実装がボトルネック
AI導入後:
実装は速い → 検証がボトルネック
Copilotを使っても速くならなかったのは、Copilotが仕事をしていなかったからではない。
最も遅い工程が、実装から検証へ移ったからだった。
実は、以前の開発が「速く見えていただけ」だった
ここで、もう一つ気づいたことがある。
Copilotを使う前は、Pull Requestを早く完成させられていたのではない。
検証していない問題が見えていなかっただけかもしれない。
Copilotが指摘しなければ、そのままマージしていた可能性のある項目もある。
その場合、Pull Requestの完了時刻だけを見れば速い。
しかし、問題が後から発生すれば、次の作業が必要になる。
- 不具合の再現
- 原因調査
- 修正版の作成
- 再テスト
- 利用者への説明
- 新しいリリース
開発時間をPull Requestのマージまでで切ると、Copilotは遅く見えることがある。
開発時間を不具合対応まで含めて見ると、評価は変わる。
Copilotを使って開発が速くならなかった理由は、保存できた時間を失ったからではない。
今まで払っていなかった品質の費用を、マージ前に払うようになったからだった。
これは、Copilot導入の失敗とは言い切れない。
短期的な速度を、将来の手戻りを減らすために使ったとも考えられる。
Copilotの効果には3種類ある
Copilotによる時間の変化は、三つに分けて考えると分かりやすい。
1. 直接減った時間
- 定型コードを書く時間
- テストのたたき台を作る時間
- ドキュメントの初稿を作る時間
- 既存コードを調査する時間
これは比較的見えやすい。
2. 別の工程へ移った時間
- 生成コードを読む時間
- 余計な変更を取り除く時間
- 指摘が正しいか判断する時間
- 追加テストを作る時間
自分が「速くならない」と感じた主な原因はここだった。
3. 将来から消えたかもしれない時間
- リリース後の不具合調査
- 後方互換性の修正
- セキュリティ問題への対応
- 誤ったドキュメントによる問い合わせ対応
これは効果を測りにくい。
発生しなかった不具合は、数字として残らないからだ。
Copilotの効果をコード生成時間だけで測ると、1しか見えない。
Pull Requestの所要時間だけで測ると、2によって遅くなったように見える。
本当に知りたいのは、1、2、3を合計した結果だ。
検証負債を増やした依頼
以前の自分は、Copilotへ次のように依頼することがあった。
この機能を実装してください。
テストとドキュメントも追加してください。
一見、効率的に見える。
しかしこの指示では、AIが決めなければならない範囲が広い。
- どの設計を採用するか
- どのファイルを変更するか
- 公開APIを変えてよいか
- どの異常系を扱うか
- どこまでリファクタリングするか
結果として、大きな差分と大量の判断待ちが返ってくる。
AIへ多くを任せたのに、人間側の確認事項も増えてしまう。
「テストも追加してください」と書くだけでは、検証をAIへ任せたことにはならない。
AIが実装とテストを同じ誤解に基づいて作れば、間違った仕様をテストが保証してしまう。
検証負債を増やさないために変えたこと
自分は、Copilotの使用量を減らしたわけではない。
代わりに、生成される判断の量を減らした。
1. 最初はコードを書かせない
いきなり実装させる前に、調査だけを頼む。
まだコードを変更しないでください。
次の内容を報告してください。
1. 関係するファイル
2. 現在の処理の流れ
3. 変更が必要になる公開API
4. 後方互換性への影響
5. 必要になるテスト
6. 想定される失敗パターン
前提が間違っていれば、コードが増える前に修正できる。
2. 変更しないものを先に書く
今回、次のものは変更しないでください。
- 公開API
- データベースの形式
- 既存の例外型
- Pythonの最低対応バージョン
- 無関係なファイル
「何を作るか」だけでなく、「何を触らないか」を渡す。
これだけで、レビュー対象を減らしやすくなる。
3. 一度に生成させる差分を小さくする
大きな機能を一度に任せず、次のように分割する。
- テストを追加する
- 最小限の実装を加える
- 異常系を処理する
- ドキュメントを更新する
問題が起きたとき、どの変更が原因かを追いやすくなる。
4. AIとは別の仕組みで判定する
Copilotが生成し、Copilotがレビューし、Copilotが「問題ありません」と言っても、それだけでは検証にならない。
- pytest
- Ruff
- Pyrightやmypy
- cargo test
- Clippy
- ベンチマーク
- IDEのインスペクション
- 人間による差分確認
など、別の仕組みで判定する。
AIを疑うために別のAIを呼ぶだけでは、同じ誤解を共有する可能性がある。
何を測れば「速くなった」と言えるのか
以前は、Copilotの効果を次のような感覚で見ていた。
- コードがすぐ出た
- 一日の変更行数が増えた
- Pull Requestを作るまでが早かった
しかし、変更行数が増えても、マージできなければ価値にならない。
現在は、次の項目を見るほうがよいと考えている。
| 指標 | 見たいもの |
|---|---|
| Issue完了までの時間 | 実際のリードタイム |
| レビュー後の修正回数 | 手戻りの量 |
| AIが変更した行の採用率 | 無駄な生成の割合 |
| テスト失敗から修正まで | 検証の速さ |
| リリース後の不具合 | 将来へ回した負債 |
| 無関係な変更の数 | 指示の精度 |
| 人間が差分を理解する時間 | 判断の負担 |
AI時代の生産性は、生成されたコード量では測れない。
安全に採用できた変更量
で測る必要がある。
Copilotで本当に速くなった作業
検証負債という言葉を使ったが、Copilotが常に遅くするわけではない。
次のような作業では、現在も明確に助けられている。
- 既存パターンに沿ったテストの追加
- 型ヒントやdocstringの補完
- 小さく、入出力が明確な関数
- Pull Requestの最初のレビュー
- 未使用importや説明の不一致の発見
- 変更箇所の調査
- 既存コードの要約
共通しているのは、正しいかどうかを短時間で判断できることだ。
生成時間が短い
+
検証時間も短い
=
本当に速くなる
反対に、要件が曖昧で、変更範囲が広く、正解をテストで表現しにくい作業では、検証負債が増えやすい。
まとめ
GitHub Copilotを使っても開発が速くならなかったのは、コード生成が遅かったからではない。
- 実装のボトルネックが検証へ移った
- AIがコードと同時に、確認すべき前提も生成していた
- レビュー量だけが先に増えた
- 今まで見えていなかった問題を、マージ前に処理するようになった
- Pull Requestの速度だけでは、将来減った手戻りを測れない
- AIへ任せる範囲を狭めると、検証負債も減らせる
- 生産性はコード量ではなく、安全に採用できた変更量で測るべき
Copilotを導入しただけでは、開発工程全体は速くならない。
コードを書く工程が速くなれば、次に遅い工程が表へ出てくる。
自分の場合、それが検証だった。
ただし、これはCopilotが役に立たなかったという話ではない。
むしろ逆だ。
Copilotを使って遅くなったのではなく、今まで見逃していた仕事が見えるようになった。
そして現在は、AIへさらに多く書かせることより、生成された変更を速く確かめられる環境を作るほうが、開発を速くすると考えている。
Copilotは、開発者を無条件に速くする道具ではない。
検証できる量を超えずに使ったとき、初めて速くなる道具なのだと思う。