
はじめに
こんにちは、ZOZOTOWN開発本部リプレイスバックエンドブロックのばやです。普段はZOZOTOWN BFFのリプレイス開発を担当しています。
システムリプレイスのプロジェクトでは、実装に入る前段階として既存コードの調査が必ず発生します。特にレガシーシステムの場合、ドキュメントが整備されていなかったり、仕様が暗黙知として埋もれていたりすることが多く、コードを読み解くことでしか仕様を把握できないケースも少なくありません。
一方で、この調査フェーズは成果物の形式や進め方が属人化しやすく、プロジェクト全体の生産性に大きな影響を与えるポイントでもあります。調査に時間がかかればプロジェクト全体のスケジュールに影響しますし、調査品質が低ければ後工程での手戻りにつながります。
本記事では、リプレイスにおける既存コード調査の課題に対し、調査業務をテンプレート化しその後、Claude CodeでAgent Skillsに落とし込むことで効率化した取り組みをご紹介します。
目次
背景
リプレイスにおける既存コード調査の重要性
リプレイスでは、既存システムの仕様や振る舞いを正しく理解することが不可欠です。
特に以下のような情報は、後続の設計・実装の品質を大きく左右します。
- 実際に使われている機能・使われていない機能
- 暗黙的な仕様や例外的な処理
- データ構造や依存関係
- パフォーマンスや運用上の注意点
そのため、既存コード調査は「とりあえず読む」ではなく、一定の品質を担保した成果物として残す必要があります。
成果物として残すことで、レビューしプロジェクト全体で品質を担保できます。
調査フェーズが抱えていた課題
一方で、従来の調査フェーズには次のような課題がありました。
- 調査結果の形式がメンバーごとに異なる
- どこまで調査すれば十分なのか判断基準が曖昧
- 調査内容の抜け漏れがレビューまで発覚しない
- キャッチアップコストが高く、経験者と未経験者で工数差が大きい
- タスクの見積もりが人によって大きくブレる
人による改善:既存コード調査業務の標準化
これらの課題を解決するために、まず着手したのは既存コード調査業務の標準化です。具体的には、以下の2つを行いました。
調査対象コードのコピーによるスコープ明確化
調査対象のコードを、元のリポジトリから現開発環境のリポジトリにコピーします。
単純ではありますが、確認するコードを限定することで作業者とレビュアの双方にとって範囲が明確になり、作業効率が向上しました。
当時はAgent Skillsの導入を意識していたわけではありませんでしたが、結果的にこの運用がAgent Skillsへの移行をスムーズにしました。対象コードが分析用ディレクトリにまとまっていたことで、Agent Skillsが旧コードベースを読み込んで解析できる状態が既に整っていました。
調査テンプレートの設計
私たちのチームでは、BFFを開発する上で最低限必要となる情報の調査に特化したテンプレートを使用しています。
## API名 ## 概要シーケンス ## リクエスト例 ## リクエストパラメータおよび変換処理 ## コード内での呼び出しAPI / 呼び出しテーブル ## エラーレスポンス ## レスポンス例 ## レスポンスパラメータおよび変換処理
テンプレートにより「何を調べるべきか」「何を書けばよいか」が明確になり、調査の抜け漏れを防げるようになりました。また、成果物の形式が統一されたことで、レビューもしやすくなりました。
テンプレート化だけでは解決できなかった課題
テンプレート化により「何を書けばよいか」は明確になりましたが、以下の課題は依然として残っていました。
経験者と未経験者の工数差
レガシーコードに慣れている経験者は効率的に調査を進められますが、未経験者は同じテンプレートを埋めるのにも時間がかかってしまいます。テンプレートは「何を書くか」を示してくれますが、「どうやって調べるか」までは教えてくれません。
調査結果の粒度とレビュー工数のバランス
レビュアの既存コード調査レビューはそれなりに工数を伴います。リプレイスする機能は多岐に渡り、1つの機能がどのような機能かを詳細に把握することは大変です。
一方で一機能のリリースにおける、最序盤のタスクである既存調査に対してプロジェクトとしてはあまり工数をかけたくなく、既存調査の情報粒度は2〜3日程度で完成できる程度としていました。
必然的にレビュアの負担をかけることで、品質を担保するようにしていました。
これにより、レビューが重なったタイミングなどはレビュー遅延による待ちなどが発生して、プロジェクト全体の遅延が懸念されました。
これらの課題を解決するために、次にAgent Skillsの導入を検討しました。
AIによる改善
Agent Skillsとは
Agent Skillsは、Claudeの機能を拡張するモジュール型の機能です。指示、メタデータ、およびオプションのリソース(スクリプト、テンプレートなど)をパッケージ化し、Claudeが関連するタスクで自動的に使用できるようにします。
Agent Skillsを使う主な利点は以下の3点です。
- 専門知識を注入し、暗黙知を削減: 既存知識をドキュメントに移譲することで、暗黙知となっていた業務知識を公開ドキュメントとできる
- 繰り返しを削減する: 一度作成すれば、複数の会話で同じガイダンスを繰り返す必要がなくなる
- 機能を組み合わせる: 複数のSkillsを組み合わせて複雑なワークフローを構築できる
Agent SkillsはSKILL.mdファイルとして定義します。YAMLフロントマターでメタデータを記述し、本文に具体的な指示を記載します。Claude Codeでは、このファイルを.claude/skills/ディレクトリに配置することで、Claudeが自動的に検出して使用します。
なぜAgent Skillsを選んだのか
Claude Codeには、カスタマイズのための複数の仕組みがあります。今回の用途に適した方式を選ぶため、それぞれの特徴を比較しました。
| 方式 | 特徴 | 用途 |
|---|---|---|
| CLAUDE.md | 起動時に常に読み込まれる | 常に必要な情報 |
| Skills | 必要に応じて読み込まれる | 特定の作業タイミングでのみ必要な指示 |
| Slash Commands | ユーザーが明示的に呼び出す | 定期的に実行したいタスクのショートカット |
| Subagents | 独立したタスクを別エージェントに委譲 | 調査過程が膨大になる場合の結果のみ取得 |
現状Agentの呼び出し方法には複数の選択肢があり、チームではSlash Commands + Skills の組み合わせを採用しました。
- エントリーポイント: Slash Command
- 業務知識の保存: Skills(詳細な調査手順とテンプレート)
Slash Commandをエントリーポイントとしてのみの薄い層とし、実際の調査テンプレートや調査方法はSkillsに格納しました1。
「Slash Command + Skills」を採用した理由
常時コンテキストを圧迫することを防ぐ
CLAUDE.mdへの記載は、常時コンテキストを圧迫することになるので避けました。
Anthropic公式のSkills作成のSkillsが存在した
我々のチームでは、CLAUDE.mdなどを読み込ませる際に、どのような文章構成がよりAgentの性能を上げてくれるのかが手探りの状態でした。
導入当時、Skillsは公式が作り方をサポートしてくれるSkillsを作成していました2。こちらに沿って作成すればスムーズにSkillsを作成でき、最適な形であることが保証できました。
Anthropic公式のマーケットプレイスも参照ください。
専門知識を一般化された状態で格納できる
作成した既存調査のSkillsは更新・改善を見込んでいます。このように階層に分けたドキュメント配置が公式から指定されていることで、我流のドキュメント配置を抑制できます。一般化された階層を誰もが実現でき、可読性が高い状態を維持できます。
なお、当時はSkillsを明示的に呼び出すことができなかったため、呼び出し部分だけSlash Commandで作成しました。結果的にSkills側に専門知識を寄せたことにより、現状のSlash CommandとSkillsの統合への変更が最小限で済みました。
Slash Command内で並列化することにより、いくつかのSkillsはSubagent的な役割を実現させています。これは個人的な意見にはなりますが、SubagentもいずれSkillsに統合され、Skillsを同期的に呼ぶか非同期で呼ぶかという観点のみが残るような気がしています。
Agent Skillsの実装
調査テンプレートをAgent Skillsとして定義しました。複数のSkillsを組み合わせ、以下の流れで調査を自動化しています。
ディレクトリ構成
{plugin-name}/
├── commands/ # エントリーポイント
│ └── analyze.md # 分析実行コマンド
├── skills/ # Skills本体(詳細な手順)
│ ├── find-dependencies/ # 依存関係調査
│ ├── analyze-code/ # コード詳細分析
│ ├── extract-files/ # ファイル抽出
│ └── generate-readme/ # ドキュメント生成
│ └── templates/ # 出力テンプレート
└── agents/ # Subagents定義(並列実行用)
実行フロー
1. /analyze を実行(Slash Command) ↓ 2. find-dependencies(依存関係調査) ↓ 3. 並列実行: ├─ analyze-code(コード詳細分析) └─ extract-files(ファイル抽出) ↓ 4. generate-readme(ドキュメント生成) ↓ 5. 成果物出力
この構成にした理由
1. LSPがないレガシー言語への対応
旧コードにはLSP(Language Server Protocol)が存在しないため、「定義へジャンプ」や「参照検索」といった機能が使えません。関数の検索方法や依存関係の追跡方法をドメイン知識としてSkillsに注入する必要がありました。find-dependenciesを最初に実行することで、後続の処理に必要な情報を確実に収集します。
2. コンテキストが膨大な処理の並列化
従来の手作業では、既存コードのコピーとテンプレートへの情報抽出を順番に行っていました。どちらもコードベース全体を読み込む必要があり、コンテキストが膨大になります。これらをanalyze-codeとextract-filesとして分離し、並列実行することで処理時間を短縮しています。
3. 中間ドキュメントによる精度向上
依存関係の調査結果をanalyze-codeで中間ドキュメント(markdown)として出力し、後続のSkillsが参照する構成にしています。一度にすべてを処理するのではなく、段階を踏むことでAIの出力精度が向上します。
各Skillの役割
| Skill | 役割 |
|---|---|
| find-dependencies | 関数検索、依存関数の追跡、グローバル変数の特定 |
| analyze-code | 入力パラメータ、出力データ、データアクセス、変換処理を抽出。旧フローのテンプレート化に相当 |
| extract-files | メイン関数、依存関数を個別ファイルに分離。旧フローのコードコピーに相当 |
| generate-readme | テンプレートに準拠した調査結果ドキュメントを生成。旧フローのテンプレート化に相当 |
成果物
実行後、以下の成果物が出力されます。
output/{対象関数名}/
├── README.md # 調査結果(テンプレート準拠)
├── 01.{メイン関数}.ext # メイン関数
├── 02.{依存関数1}.ext # 依存関数
└── ...
調査結果のREADME.mdは、先述のテンプレートに沿った形式で出力されます。依存関数も個別ファイルとして抽出されるため、レビュー時にコード全体を把握しやすくなります。
運用フロー
この仕組みにより、調査担当者は以下の流れで作業できるようになりました。
1. 対象リポジトリやディレクトリを指定 2. Agent Skillsを実行 3. 出力された調査結果を確認・修正 4. レビューを実施 5. 必要に応じて追加調査
従来は「コードを読む → 理解する → まとめる」という一連の作業をすべて人間が行っていました。Agent Skillsを活用することで「AIが下書きを作成 → 人間が確認・修正」という流れに変わりました。
導入効果
定量的な効果
Agent Skillsの導入により、調査作業のリードタイムは大きく改善しました。
| 項目 | 従来 | 導入後 |
|---|---|---|
| 調査の実行時間 | 数時間〜数日 | 数分程度 |
| 全体のリードタイム | 2〜5日 | 数時間 |
| 成果物の形式 | バラバラ | 統一 |
調査結果の確認・修正・レビューを含めても数時間で完結するようになりました。従来の「数日かかる調査タスク」と比較すると、大幅な短縮です。
また、レビュー体験も改善しました。成果物の形式が統一されているため、レビュアは「何がどこに書いてあるか」を把握しやすくなり、内容の精査へ集中できるようになりました。
特にリードタイムの短縮は顕著で、これまでボトルネックになっていた調査フェーズがスムーズに進むようになりました。
定性的な効果
定量的な効果に加えて、以下のような定性的な効果も得られました。
- メンバー間で調査観点が揃い、レビューがしやすくなった
- 情報粒度が上がったので、細かい内容まで記載があって、レビューがしやすくなった
- 新しく参加したメンバーでも、同じ品質で調査できるようになった
特に、新規メンバーのキャッチアップコストが下がったことは大きな効果でした。従来は既存システムの知識がないと調査に時間がかかっていましたが、Agent Skillsを使うことで、知識の有無に関わらず一定品質の調査が可能になりました。
見えてきた課題
Agent Skillsの導入により多くの効果が得られた一方で、新たな課題も見えてきました。
コンテキストの欠落
従来は時間をかけて調査することで、各メンバーが暗黙的な知識を蓄積していました。「なぜこのような実装になっているのか」「過去にどのような経緯があったのか」といった背景知識は、コードを読み込む過程で自然と身についていました。
しかし、AIによる高速な調査では「調べた結果」は得られるものの、「理解」を伴わないケースもあります。具体的には以下のような問題に直面しました。
- 実装フェーズで想定外の考慮漏れが発生する
- 全体像を把握していないことによる手戻り
- 調査結果に書いてあることしか把握していない状態
この課題に対しては、調査結果を「読むだけ」で終わらせず、チーム内で共有・議論する時間を設けることが重要だと感じています。
AIが作成した調査結果をベースに、チームで同期的な理解の時間を設けることで後のフェーズである、設計・実装の部分でスムーズな進行ができると感じました。
ハルシネーションの見落とし
AIが大量の情報を要約して出力するため、全項目を精査することが難しくなります。結果として、誤った情報がそのままレビューを通過してしまうリスクがあります。
これはLLMを使っている以上避けては通れないリスクではありますが、現状、根本的な解決策は見つかっていません。
レビュイー・レビュア双方による注意深い確認が重要だとされがちです。しかし、それでは業務負荷が作成からレビューに移行しただけで、AI駆動開発の恩恵を受けられません。
今後の展望
見えてきた課題を踏まえ、今後は以下の取り組みを進めていく予定です。
検証プロセスの強化
AIの出力をより効率的に検証するため、現在以下の取り組みを行っています。
より人間がわかりやすいドキュメントを再作成する
既存調査 → 新規設計 → 実装という形でフェーズが進行しており、レビュアが見やすい粒度・構成の設計書を模索しながら作成しています。
新規実装やテストコードと旧コードのマッピング
レビュイー本人も漏れを防ぐため、リプレイス後のコードに旧コードのGitHub上での該当箇所URLをコメントすることで擬似チェックリストのようなものを再現しています。愚直ではありますが、これによって実装者が漏れを把握して未然にバグを防げたので、有効性は確認できています。
今後は以下の仕組みも検討しています。
- 調査結果と実際のコードを自動で照合するスクリプトの作成
- 重要度の高い項目(データ構造、エラーハンドリングなど)のチェックリスト化
- 実装フェーズでの差分検出と調査結果へのフィードバックループ
Agent Skillsの継続的な改善
プロンプトの精度向上や、新たな観点の追加を継続的に行います。
- 調査対象のコードパターンに応じたプロンプトの分岐
- よくある誤りパターンの収集と、それを防ぐための指示の追加
- チームからのフィードバックに基づくテンプレートの更新
他チームへの展開
現在は特定のチームで運用していますが、他のリプレイスプロジェクトへの展開も視野に入れています。
- Agent Skillsの汎用化と、プロジェクト固有の設定の分離
- 導入ガイドやベストプラクティスの整備
- 成功事例・失敗事例のナレッジ蓄積
まとめ
本記事では、リプレイスにおける既存コード調査の課題に対し、以下のアプローチで業務を効率化した事例を紹介しました。
- 調査業務をテンプレート化し、「何を調べるか」「何を書くか」を明確にする
- その手順をAgent Skillsに落とし込み、AIによる調査の自動化を実現する
結果として、調査タスクのリードタイムを大幅に短縮しつつ、品質の安定化も実現できました。
一方で、「コンテキストの欠落」や「ハルシネーションの見落とし」といった新たな課題も見えてきました。これらは、AIを活用した業務効率化において避けて通れない課題であり、運用の工夫や検証プロセスの改善によって対処していく必要があります。
リプレイスでは「調査」は避けて通れない工程だからこそ、人に依存しない形で品質とスピードを両立させることが重要だと考えています。AIの活用はその有力な手段の1つですが、AIの出力を鵜呑みにせず、人間による検証とチームでの知識共有を組み合わせることが成功の鍵です。
既存コード調査やリプレイスに課題を感じている方の参考になれば幸いです。
ZOZOTOWN開発本部リプレイスバックエンドブロックでは、大規模なシステムリプレイスを推進するエンジニアを募集しています。AIを活用した開発プロセスの改善や、レガシーシステムのリプレイスに興味のある方、ぜひご応募ください。