ふくふくHukuhuku Inc.
EP.01Legacy Revival 13分公開: 2026-07-22

仕様書のない旧システムを LLM で読み解く ── コード考古学の6ステップ

「動いているが、誰も触れない」システムを前に、いきなり作り直してはいけない。まず必要なのは、失われた仕様と依存関係を掘り起こす“コード考古学”だ。LLM を使って旧コード・ストアド・バッチを読み解き、挙動を特性化テストで固定し、投資判断に繋げるまでの6ステップを、現場の順序でまとめる。

#レガシー#LLM#コード解析#技術的負債#移行
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

「動いているが、誰も中身を説明できない」—— を前にした担当者から、私たちが最初に相談されるのはたいていこの状態だ。作った人はもう社内におらず、仕様書は無いか、あっても実物と食い違っている。ここでいきなり作り直しに走るのが一番危ない。まず必要なのは、失われた仕様と依存関係を掘り起こす作業——いわばコード考古学だ。本稿では、 を武器にした読み解きの手順を、現場で踏む順番のまま6ステップで整理する。

「動いているから」は判断ではなく先送り

塩漬けは無料ではない。 の利息(改修コスト・障害リスク・属人化)は複利で膨らみ、 が近づくほど選択肢は減る。まず現状を「見える化」しないと、刷新すべきかどうかすら判断できない。

ステップ1:外堀から埋める ── 何が動いているかの棚卸し

コードを1行目から読み始めてはいけない。先に「このシステムは何と繋がっているか」を外側から把握する。入口(誰が叩くか)、出口(どこに書くか)、実行契機(cron・イベント・手動)を洗い出すと、内部を読む前に全体の輪郭が見える。

  • 入力:画面・API・アップロードされるファイル・受信メール・他システムからのバッチ連携
  • 出力:DB テーブル・出力ファイル・帳票・外部 API 呼び出し・通知
  • 実行契機:cron / ジョブスケジューラ / 常駐プロセス / 手動キック
  • 周辺依存:参照している共有ディスク、ハードコードされた IP・ホスト名、期限切れ間近の証明書

ステップ2:LLM に「要約」させる ── ただし鵜呑みにしない

個々のソース・ストアドプロシージャ・シェルスクリプトを に読ませ、「このコードは何をしているか」を平易な日本語で要約させる。、秘伝の Perl バッチのように、書ける人が減った言語ほど LLM 要約の恩恵は大きい。ポイントは、要約をそのまま信じず「仮説」として扱うこと。LLM は自信ありげに間違える。

読み解き用プロンプトの型
次のソースコードについて、(1) 全体で何をする処理か、(2) 入力と出力、(3) 参照している外部リソース(DB テーブル・ファイル・API)、(4) 分岐や例外処理で読み取れる“隠れた業務ルール”、(5) 読み手が誤解しやすい点、を日本語で整理してください。推測が入る箇所は「推測」と明記してください。

```
<ここに対象コードを貼る>
```
想定される実行結果(例示)
この処理は月次の請求データを集計し、締め日をまたぐ取引を前月扱いに補正しています。
・入力: TBL_TORIHIKI(取引明細)
・出力: TBL_SEIKYU(請求)
・隠れた業務ルール(推測): 手数料が 3 万円未満の取引は集計から除外(IF 文の閾値 30000 より)。この閾値の根拠はコードからは不明。
“隠れた業務ルール”こそ本命

レガシーの価値は、コードの中に沈殿した業務ルール(この閾値・この例外・この特別扱い)にある。仕様書に載らないまま何年も正しく動いてきたロジックを拾い上げることが、再生の肝になる。

ステップ3:依存関係とデータフローを図にする

要約が溜まったら、モジュール間の呼び出しとデータの流れを1枚の図に落とす。どのバッチがどのテーブルを更新し、それを誰が読むか。ここで「実は使われていない死んだコード」「1箇所だけがボトルネックになっている密結合」が浮かび上がる。図にできて初めて、刷新の単位(どこから切り出せるか)が見えてくる。

可視化で埋めていく主な観点
観点掘り起こすもの再生への意味
呼び出し関係誰が誰を呼ぶか(バッチ→SP→テーブル)切り出せる境界を見つける
データフローどのデータがどこで生成・加工・消費されるか移行時に守るべき整合性
デッドコード実行されていない分岐・未使用テーブル作り直しの対象から外せる
密結合点1箇所に集中する依存段階移行の順番を決める

ステップ4:現状の挙動を「特性化テスト」で固定する

仕様書が無いなら、「今こう動いている」という事実そのものをテストにする。これが だ。正しいかどうかは一旦問わない。現在の入力に対する現在の出力を記録し、改修で挙動が変わったら即座に検知できる安全網を張る。これがあるかないかで、この先の作り直しの怖さがまるで違う。

特性化テストの最小形:現状の出力をゴールデンとして固定する
Python
def test_characterize_monthly_billing():    # 本番から採取した代表的な入力サンプル    inputs = load_fixture("billing_samples.json")    for case in inputs:        actual = legacy_billing(case["input"])        # 「正しい期待値」ではなく「現状の出力」をそのまま固定する        assert actual == case["current_output"], (            f"挙動が変わった: {case['id']}"        )
バグも含めて固定する

特性化テストは「現状のバグ」も一旦そのまま固定する。長年の運用が“そのバグ込み”で回っている場合があるからだ。直すのは、挙動を把握し、影響範囲を握ってから。まず固定、次に判断、の順番を崩さない。

ステップ5:塩漬け vs 作り直しを、コストで判断する

ここまでで、ようやく意思決定に必要な材料が揃う。「このまま維持するコスト(保守工数・障害リスク・)」と「作り直すコスト・リスク」を並べ、どの方針が事業にとって得かを判断する。全部作り直す必要はない。移行の選択肢は一つではない。

  • Replace(刷新):作り直す。業務ルールを引き継ぎつつモダンスタックへ
  • Rehost(移設):ロジックはそのまま、動く土台だけ新しくする(EOL 回避が主目的なら有力)
  • Refactor(部分改修):密結合をほどき、触れる部分から段階的に
  • 現状維持:あえて手を入れない。ただし「判断した上での維持」であること

ステップ6:引き継げる資産として仕上げる

再生のゴールは「動く」ことではなく、「5年後の人にも引き継げる」ことだ。読み解きで復元した仕様、特性化テスト、そして のようなドキュメント化された構成——これらが揃って初めて、システムは属人化した爆弾から引き継げる資産に変わる。段階移行するなら で、旧システムを動かしたまま新機能で1つずつ包み込んでいく。

6ステップの通し

① 外堀=繋がりの棚卸し → ② LLM で要約(仮説) → ③ 依存とデータフローを図に → ④ 特性化テストで挙動を固定 → ⑤ コストで移行方針を判断 → ⑥ 仕様・テスト・IaC を揃えて引き継げる資産に。読み解きを飛ばした作り直しは、たいてい同じ地雷をもう一度踏む。


次回以降は、各ステップを実務レベルで掘り下げていく。LLM 要約の精度を上げるチャンキングとプロンプト設計、特性化テストの採取自動化、そして「塩漬けコスト」を経営に説明する試算の作り方まで。続編は読者リアクションに応じて随時追加していく。「うちのあのシステム、まさにこれだ」という方は、レガシー刷新・資産化支援 から解析だけの小さなスコープでも相談してほしい。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp