10年分のコードとの対話
2014年から個人でiOSアプリを開発し続けてきました。壁紙アプリを中心に、累計5,000万ダウンロードを超えるアプリ群に育ってきましたが、その分だけコードの歴史も積み重なっています。
先日、Antigravityの Background Agentを使って、10年以上運用してきた壁紙アプリのコードベースを整理してみました。結論から言うと、「AIが賢い」というより「AIとコードの対話の仕方が、人間同士とは根本的に違う」と感じました。予想と全然違う形で、気づかされることがありました。
Background Agentが最初に指摘したこと
アプリのリポジトリをAntigravityに読み込ませた直後、Background Agentが自動的に問題を検出して報告してきました。予想していたのは「古いAPIの使用箇所」や「非推奨の構文」でした。実際に来たのは、こんな指摘でした。
⚠️ 検出: 類似パターンが47箇所
UICollectionView のデータソース実装に一貫性のないパターンが混在しています。
2016年〜2024年にかけて書かれたセクション間でアーキテクチャが異なります。
そうなのです。10年開発していると、そのときどきのSwiftのベストプラクティスが混在します。2016年に書いたコードはObjective-Cからの移行期で、2020年のコードはSwiftUIへの過渡期、2024年のコードはSwift Concurrency対応済みという具合です。
人間の開発者がコードレビューをすると、「このファイルは古いから後回しにしよう」という判断をします。しかしAntigravityは時系列ではなくパターンとして捉えていました。これは人間にはない視点で、最初に少し驚きました。
AIが苦手だったこと:「なぜこう書いたか」の文脈
面白かったのが、Background Agentの限界でした。ある実装について、こちらが意図を伝えずに「整理してください」とだけ頼んだところ、次のような変更案が返ってきました。
// Before(Agentによる変更前)
func downloadWallpaper(id: String) async throws -> UIImage {
// 特定のCDNエンドポイントに対して3回リトライ
for attempt in 1...3 {
do {
return try await fetchFromCDN(id: id, endpoint: .primary)
} catch {
if attempt == 3 { throw error }
try await Task.sleep(nanoseconds: 500_000_000)
}
}
fatalError("unreachable")
}// After(Agentの提案)
func downloadWallpaper(id: String) async throws -> UIImage {
// シンプルな1回呼び出しに変更
try await fetchFromCDN(id: id, endpoint: .primary)
}Agentから見れば「冗長なリトライロジックをシンプルにした」改善でした。しかし実際には、このCDNは海外サーバーからのリクエストで不安定になりやすく、リトライが実運用で必要なことが分かっていました。コードにコメントはあったものの、「なぜ3回なのか」「なぜ0.5秒待機なのか」という文脈はコードから読み取れなかったのです。
意図を AGENTS.md に記述してから再度依頼すると、正確な判断が返ってきました。
# ダウンロード実装について
CDNの特性上、海外からのリクエスト(全体の約30%)でタイムアウトが発生しやすい。
リトライ間隔0.5秒は実測値から設定。3回は「ユーザーが待てる上限」として決定した値。
この数値を変更する場合は必ずCDNのエラーレートログと照合すること。AGENTS.mdの書き方と活用パターンはこちらで詳しく説明しています。
想定外だったこと:古いSwiftコードへの理解精度
実は一番驚いたのが、Background Agentの「古いコードへの理解精度」でした。
2016年〜2018年頃のObjective-Cスタイルが残ったSwiftコード(@objc アノテーション多用、NSArrayの混在)に対して、「このパターンはObjective-C時代の慣習が残っており、Swift 6の厳格な並行性モデルと相性が悪い箇所があります」と正確に指摘してきました。
自分でも把握しきれていなかった部分を、Agentが棚卸ししてくれる感覚がありました。10年以上の開発者でも「このコードがいつ書かれたか」「なぜこうなったか」の全ては覚えていないものです。アプリの歴史を外から整理してもらうような、少し不思議な体験でした。
実際の改善効果と、手放せなかった部分
3日間かけてBackground Agentに整理させた結果、コード行数は約15%減少しました。しかし数字より印象的だったのは別の点です。
Agentが指摘した「非推奨APIの使用箇所」の一部は、実はiOSの特定バージョンでの動作を意図的に保証するために残してあったものでした。これらをAgentが「修正済み」と判断して置き換えた箇所が3件ありました。
自動的な変更をそのままマージしていたら、iOS 15以前のデバイスで画面が崩れていたはずです。Background Agentの変更はすべてブランチで提案され、手動でのレビューとマージが必要だったため、事前にキャッチできました。
「AIが判断するから自分は確認しなくていい」ではなく、「AIが仕事を80%やってくれるから、人間は残り20%の文脈判断に集中できる」という分担だと実感しました。Background Agentをより深く使いこなすための手順はBackground Agentの基本的な使い方で解説しています。
個人開発者がBackground Agentを使うときの準備
大規模なリファクタリングをBackground Agentに依頼するときは、以下の準備が役立つと実感しています。
# AGENTS.md に書いておくべきこと
## 設計上の意図的な判断
- なぜ非推奨APIを残しているのか
- なぜこの実装は複雑になっているのか
- 変更してはいけないファイル・関数(例: 決済フロー、セキュリティ処理)
## 対応OSバージョンの意図
- 最小サポートバージョンとその理由
- 古いAPIを残している理由
## 外部サービスの特性
- 不安定なCDN・APIとその対処パターン
- リトライ回数・待機時間の根拠10年の開発経験が詰まったコードには、「なぜそうなっているか」という文脈が必ずあります。Antigravityはコードを読めますが、その背景にある判断の歴史は自分から伝えないと届きません。逆に言えば、文脈さえ渡せれば驚くほど正確に動いてくれます。
祖父が宮大工だったこともあり、「手を動かすことが一つの信心」という感覚が私の中にあります。AIに作業を委ねることは怠けることではなく、より重要な判断に集中するための準備だと考えています。
まずは小さなユーティリティファイルやテストコードから試してみてください。予想していなかった気づきが、必ずあります。