こんにちは。iOSアプリチームの scenee です。
アプリ運用において、クラッシュ対応は避けて通れません。しかし、ログの収集、原因の特定、修正案の作成という「一次調査」には多大な工数がかかります。
今回、私はAIエージェントであるDevinと監視ツールのNew Relicを連携させ、毎週自動で「クラッシュ上位3件の修正案(Draft PR)」を作成する仕組みを構築しました。

1. なぜDevinなのか?
iOSアプリで発生するクラッシュの多くは、意図しない例外(Objective-C Exception)やOptionalの強制アンラップ失敗といったロジックエラー・メモリエラーに起因しています。これらの不具合はUIの変更を伴わないケースが多いため、適切なスタックトレースとソースコードさえあれば、ビルドを行わずとも十分に原因の特定と対策の立案が可能です。
事前の検証において、Devinはコードレベルで非常に「筋の良い」修正案を提示できることが確認されました。さらに、Devinのスケジュール機能がリリースされたことで、New Relic MCPなどの外部ツールを自律的に組み合わせて動かす運用基盤が整い、懸念されたACU(計算リソース)の消費も最小限に抑えられる見通しが立ちました。
たとえ調査ベースの自動化であっても、エンジニアが「ゼロから調査を開始する時間」を劇的に削減し、人間がより本質的なレビューやテストに集中できる環境を構築できると確信し、今回の運用を開始しました。
2. 役割分担と運用フロー
このシステムは、Devinが「下ごしらえ」を行い、開発チームが「最終判断」を下すという協力体制で運用しています。
- Devinの役割: 週次の一次調査とDraft PR作成を担当
- 毎週月曜 9:00 (JST)に自動で稼働。
- New Relicからクラッシュ情報を取得し、原因をコードベースから推定。
- 修正案を含んだDraft PRをGitHubに作成。
- 開発チームの役割: Draft PRからリリースまでを担当
- 毎週火曜のコードレビュー会で、Devinが作成したPRを精査。
- 問題がなければDraftを外して担当者をアサインし、マージまで進行。
3. 技術的な工夫
1. スタックトレースの取得
Devinがより効果的な修正ができるように、クラッシュのエラーメッセージだけではなく、スタックトレースも渡すようにしています。
New Relic MCP の list_entity_error_groups のクラッシュ一覧にはスタックトレースが含まれないので、 execute_nrql_query からMobileCrash テーブルよりクラッシュしたスレッドのスタックトレースを別途取得するようにしました。(クラッシュしたスレッド以外は取得できません)
以下がその疑似コードです。
list_entity_error_groups tool call
mcp_tool(
command="call_tool",
server="...",
tool_name="list_entity_error_groups",
tool_args={"entity_guid": "...", "start_time_ms": START_TIME_MS, "end_time_ms": END_TIME_MS}
)
execute_nrql_query tool call
mcp_tool(
command="call_tool",
server="...",
tool_name="execute_nrql_query",
tool_args={
"account_id": ...,
"nrql_query": "SELECT crashFingerprint, crashLocation, crashLocationClass, crashLocationMethod, crashLocationFile, crashException, crashMessage, appId, appVersion, osVersion, occurrenceId, device FROM MobileCrash WHERE {WHERE_clause_from_event_query} SINCE {START_TIME_MS} UNTIL {END_TIME_MS} LIMIT 5"
}
)
- Mobile Crash REST API v1も存在しますが、New Relicの方から古いAPIとのことでNRQLの
MobileCrashテーブルを使うよう教えていただきました WHERE_clause_from_event_queryは、list_entity_error_groupsのレスポンスに含まれるevent_queryのWHERE句です
2. GitHubを用いた状態管理
Devinが同じクラッシュに対して二重にPRを作成しないよう、GitHubのPRをデータベースとして活用しています。 PRのDescriptionに、以下のようなメタデータを隠しタグ(コメントアウト)として埋め込んでいます。
- New RelicのエラーグループID
- クラッシュの指紋(Fingerprint)
- 影響ユーザー数や対象期間
<!-- New Relic Crash Metadata - DO NOT EDIT --> <!-- New Relic-group-id: ...--> <!-- crash-fingerprint: ... --> <!-- New Relic-account-id: ...--> ... <!-- generated-by: devin-weekly-crash-fix -->
これにより、Devin自身が現在の対応状況を自律的に判断できるようになっています。
4. 運用してみた結果
1. スピード感ある運用サイクル
すでに毎週開かれていたコードレビュー会にタイミングを合わせることで、「月曜にPRが上がり、火曜にレビュー、早ければその週にリリース」という理想的なサイクルが回り始めています。
2. 「GitHub Checks」との組み合わせでコード品質を担保
Devinの実行環境はLinuxですが、iOSアプリのビルドにはmacOSが必要です。この「Linuxだとビルド確認ができない」という制約を、GitHubのPR Checks(CI)との連携で解決しました。
- Devinが修正コードを書き、PRを作成。
- GitHub Actions等のCIが走り、macOS環境でビルドとユニットテストを実行。
- DevinがそのCheck結果(ログ)を自ら確認。
- 失敗していれば、エラー内容を分析して自動で修正を繰り返す。
このループにより、LinuxベースのAIでありながら、最終的にはしっかりとビルドが通り、テストをパスする、信頼性の高いPRが届くようになっています。
3. 導入にかかった期間
この仕組みを2月上旬に考えてから、まず数時間の検証でDevinの修正精度に手応えを掴みました。その後、YappdateDayという社内改善イベントを活用して本格的に着手し、Playbookの作成と初期設定に約1日、動作確認とプロンプトのブラッシュアップに約1日と、合計2〜3日程度で実運用に入ることができました。なお、PlaybookはDevinに実際にMCPを利用させながら対話的に改修していったため、プロンプトの質を効率よく高めることができました。
その後は毎週の運用の中でプロンプトや手順を少しずつ改善しています。「まず試してみる」のハードルは想像より低く、段階的に育てていける仕組みだと感じています。
4. 運用2週間での成果:6件中3件がマージ、1件が進行中
これまで2週間稼働させた中で、6件のPRが作成されました。その質は非常に高く、以下のような結果となっています。
- 3件:すでにマージ完了。
- 1件:進行中の別のPRにパッチとして適用され、リリース予定。
残りのPRも、ロジックの「筋」が非常に良く、修正のベースとして十分に活用可能な状態でした。また、1回の実行あたりのACU消費は5 ACU以内に収まっており、コスト面でも想定の範囲内で運用できています。
5. 運用上の懸念事項と対策
Devinでの運用を進める中で、いくつかの課題も見えてきました。
- ワークフローの優先順位: Devinにはシステムデフォルトのワークフローがあるそうです(Pull Request Workflow等)。これによってPlaybookのルールを無視してしまうことがありました。こちらはPlaybookのプロンプト内で「Playbookの指示を最優先すること」を明記することで解消できました。
- Schedule実行時のPlaybook読み込み: 指定したPlaybookが読み込まれないケースが発生しました。頻度は多くないため、Devinの不具合である可能性が高く、様子見の状態です。
まとめ:AIは「自律的な調査パートナー」へ
適切なコンテキスト(スタックトレースとコード)さえあれば、UIの変更を伴わないロジックエラーはAIでも十分な精度で修正案を出せることが証明されました。
クラッシュのような不具合修正において、エンジニアが調査から着手する時間を削減し、より本質的な設計・レビューなどの作業に集中できる環境を作る。これがYappliにおけるAIを活用したこれからの開発スタイルになっていくかもしれません。