GitHub Copilot 逆向工程教學手冊(Java Web)

版本:3.0

最後更新:2026-09-01

適用對象:資深工程師、架構師、技術主管

技術棧:Java 21 LTS(既有系統延續)/25 LTS(新專案建議)|Spring Boot 4.1.x(現行建議,最新 patch 4.1.1)/4.0.x(維護中;3.x 系列已於 2026-06-30 全面 EOL)|VS Code 1.135+GitHub Copilot(Chat/Agents/Plan/Cloud Agent/CLI/MCP/Agent Plugins)

本版重點:全面對齊 2026-09-01 現況——收錄 VS Code 1.135 Agents 視窗、Agent Plugins 1.0、Copilot Code Review 能力擴充;修正 MCP、Agent Skills、Hooks 三處已變更的設定路徑(舊寫法照抄會失效);更新 2026-09-01 生效的模型下架清單與計費政策。逐條佐證見 附錄 E。


📑 目錄


第 1 章 概論

1.1 什麼是逆向工程(Reverse Engineering)

逆向工程是指從「已存在的系統產出物(程式碼、執行檔、資料庫)」出發,反向推導出系統的:

  • 需求規格(What the system does)
  • 系統設計(How the system is structured)
  • 商業邏輯(Why the system behaves this way)
flowchart LR
    A[舊系統<br/>程式碼/執行檔] --> B[逆向分析]
    B --> C[需求文件<br/>SRS]
    B --> D[架構文件<br/>SDS]
    B --> E[資料模型<br/>ERD]
    B --> F[API 規格<br/>OpenAPI]
    C --> G[新系統開發<br/>Spring Boot]
    D --> G
    E --> G
    F --> G

在軟體工程的脈絡中,逆向工程不同於「破解」或「反編譯」等灰色行為。企業合法逆向工程是指:

合法場景不合法場景
自有系統文件重建繞過授權保護機制
Legacy 系統現代化竊取競爭對手商業邏輯
維護無文件的老舊系統違反軟體授權條款
安全漏洞分析(授權範圍)未經授權反組譯第三方軟體

1.2 Legacy System 現代化挑戰

企業面對 Legacy System 時,通常遭遇以下痛點:

mindmap
  root((Legacy System<br/>現代化挑戰))
    技術面
      語言過時(VB6, COBOL, Delphi)
      框架不再維護
      平台 EOS(End of Support)
      安全弱掃無法通過
    人員面
      原始開發者已離職
      無人理解完整商業邏輯
      知識斷層嚴重
    文件面
      無 SRS / SDS
      無架構圖
      無測試文件
      需求文件過時
    營運面
      無法滿足新需求
      維護成本飆升
      效能瓶頸
      法規合規風險

典型企業困境:

  1. 人員流失:開發 10+ 年的系統,原始開發者早已離職
  2. 技術債堆積:多年修修補補,程式碼結構混亂
  3. 資安壓力:舊版框架漏洞無法修補(如 Struts 1.x、Spring 2.x)
  4. 平台 EOS:Windows Server 2012、Java 8 等陸續停止支援
  5. 合規要求:金管會 / 資安法規要求系統安全性達標

1.3 GitHub Copilot 在逆向工程的角色

GitHub Copilot(2026 版)已從單純的「程式碼補全工具」演進為完整的 AI 代理(Agent)平台,在逆向工程中扮演多維度的角色:

flowchart TB
    subgraph "GitHub Copilot 2026 能力矩陣"
        A[程式碼理解] --> A1[解讀 Legacy Code]
        A --> A2[辨識設計模式]
        A --> A3[追蹤資料流]
        A --> A4[跨檔案全域分析]
        
        B[文件生成] --> B1[自動產出 API 文件]
        B --> B2[生成架構說明]
        B --> B3[產出 ERD]
        B --> B4[PR 摘要與 Code Review]
        
        C[程式碼轉換] --> C1[語言轉換 VB→Java]
        C --> C2[框架遷移 Servlet→Spring]
        C --> C3[API 現代化]
        C --> C4[多檔案批次重構]
        
        D[品質保證] --> D1[自動產生測試]
        D --> D2[辨識潛在缺陷]
        D --> D3[安全性建議]
        D --> D4[Agentic Code Review]
        
        E[自動化代理] --> E1[Agent Mode 自主開發]
        E --> E2[Cloud Agent 遠端執行]
        E --> E3[MCP Server 工具整合]
        E --> E4[Plan 代理規劃任務]
        E --> E5[Custom Agents 專用代理]

        F[團隊治理] --> F1[Custom Instructions 規範]
        F --> F2[Agent Skills 標準流程]
        F --> F3[Agent Plugins 統一配發]
        F --> F4[Agent Hooks 驗證閘門]
    end

Copilot 2026 核心功能對逆向工程的價值

功能說明逆向工程應用
Agent Mode(本地代理)在 VS Code 中自主執行多步驟任務,自動編輯檔案、執行終端命令、自我修正自動分析整個 Legacy 專案、批次轉換模組、自動修正編譯錯誤
Cloud Agent(雲端代理)在 GitHub 雲端獨立運行;2026 年起可先研究(Research)/規劃(Plan)、於分支上反覆迭代後才開 PR指派 Copilot 完成單一模組的遷移任務並提交 PR
Plan 代理VS Code 內建代理之一,分析程式碼庫後產出結構化實作計畫,確認後才動手改碼自動規劃逆向工程步驟與模組遷移優先順序(見 4.7 節)
Custom Agents(*.agent.md)自訂專屬代理人格,可限定工具、模型、子代理與交接(handoffs);已取代舊的 *.chatmode.md建立「Legacy 分析代理 → 轉換代理 → 測試代理」的逆向工程流水線(見 5.8 節)
Agents 視窗VS Code 1.135 改版,單一介面集中管理多個本機/雲端 Agent Session,並可接續其他應用程式的 session同時推進多個模組的分析與遷移,逐一檢視變更差異
Copilot Chat對話式分析與問答;支援多對話並排、/btw 側邊提問、對話全文搜尋深入分析特定函式、追蹤呼叫鏈、解讀商業邏輯
Copilot Edits多檔案同步編輯一次性重構多個相關類別
Custom Instructions專案級指令(.github/copilot-instructions.md、*.instructions.md、AGENTS.md)定義逆向工程分析規範、輸出格式、命名慣例(見 5.7 節)
Agent Skills(SKILL.md)以 Markdown 定義專業工作流程,相關時自動載入,跨 VS Code/CLI/Cloud Agent 通用封裝「Legacy 程式碼分析標準流程」,全團隊共用同一套分析規格
Agent Plugins 1.02026-08 發布的開放標準,把 Skills 與 MCP Server 打包成單一可安裝外掛將逆向工程的技能與 DB/SonarQube MCP 一次配發給全團隊(見 9.10 節)
Agent Hooks(Preview)在代理生命週期事件(PreToolUse/PostToolUse/Stop 等)掛入自訂命令代理每次改檔後自動 mvn compile/弱掃,把驗證變成硬性閘門
MCP Server擴充外部工具能力(Model Context Protocol)整合 DB 分析工具、SonarQube、Figma 設計稿等
Copilot Spaces組織相關內容為上下文空間將舊系統文件、程式碼、分析結果組織為統一上下文
跨對話記憶並非單一功能,依介面而異(CLI 跨 Session 記憶/Plan 代理當次記憶/指令檔)逆向工程專案的長期上下文延續策略,見 9.9 節 的機制對照表
Copilot Code ReviewAI 自動程式碼審查(Agentic 架構,可調 Effort Level、支援 Skills 與 MCP)自動審查轉換後的程式碼品質與安全性
Next Edit Suggestions(NES)預測下一個編輯位置並自動建議加速逐行轉換程式碼的效率
多模型支援涵蓋 OpenAI、Anthropic、Google、Microsoft(MAI 系列)等多家供應商模型,並支援 Auto 自動選模對不同語言或任務選擇最佳模型。陣容每月變動且會下架(2026-09-01 即有一批模型退場),現行清單見 附錄 C

Copilot 在逆向工程中的四大角色:

角色說明使用方式
分析師理解並解釋程式碼Copilot Chat:@workspace 分析這個模組的商業邏輯
翻譯官跨語言轉換Agent Mode:自動將整個模組從 VB 轉為 Spring Boot
文件撰寫者自動產出文件Copilot Chat:為此模組產出 OpenAPI 規格
自動化代理端到端自主執行任務Cloud Agent:指派 Issue 後自動完成遷移並提交 PR

⚠️ 重要提醒:Copilot 是「智慧助手」而非「替代者」。即使 Agent Mode 可以自主完成任務,所有 AI 產出的結果都必須經過資深工程師審查驗證,特別是商業邏輯與安全相關的部分。AI 可能產生「看似正確但實際有誤」的幻覺內容(Hallucination),在財務計算、權限控制等關鍵領域尤需謹慎。

1.4 適用情境

銀行/金融業

  • 核心系統現代化(Core Banking System → Microservices)
  • 報表系統遷移(COBOL/RPG → Java)
  • 交易系統重構(VB/Delphi → Spring Boot)

製造業

  • MES 系統升級(VB6 → Web)
  • ERP 客製模組遷移

政府機關

  • 老舊服務系統 Web 化
  • 資料開放平台建置

適用判斷矩陣

條件適合逆向工程不適合
程式碼可取得✅—
無任何設計文件✅—
系統仍在運行✅—
程式碼已無法編譯⚠️ 部分可行—
僅有執行檔⚠️ 黑箱可行白箱困難
有完整文件—❌ 不需逆向

💡 實務建議:在啟動逆向工程專案前,務必進行「可行性評估」。確認舊系統的程式碼品質、規模與複雜度,再決定策略。


第 2 章 三種逆向工程策略

flowchart LR
    subgraph "三種逆向工程策略"
        direction TB
        BB["🔲 黑箱逆向<br/>Black-box"]
        WB["📄 白箱逆向<br/>White-box"]
        GB["🔀 灰箱逆向<br/>Gray-box"]
    end
    
    BB --> |"無原始碼<br/>僅觀察行為"| R1[推測需求]
    WB --> |"有原始碼<br/>完整分析"| R2[精準還原]
    GB --> |"混合方式<br/>漸進替換"| R3[逐步遷移]

2.1 黑箱逆向(Black-box Reverse Engineering)

黑箱逆向的定義

在不接觸原始碼的前提下,透過觀察系統的「輸入 / 輸出行為」來推導系統功能與需求。

黑箱適用情境

  • 只有執行檔(.exe / .dll),無原始碼
  • 原始碼語言已無法讀取(如 COBOL、RPG 等極少數人懂的語言)
  • 第三方系統無法取得原始碼
  • 需先快速建立系統概觀

操作方式

sequenceDiagram
    actor 工程師
    participant 舊系統
    participant Copilot
    participant 新系統
    
    工程師->>舊系統: 1. 操作各項功能
    工程師->>工程師: 2. 記錄輸入/輸出
    工程師->>工程師: 3. 截圖畫面流程
    工程師->>工程師: 4. 擷取 DB Schema
    工程師->>工程師: 5. 攔截 API 呼叫
    工程師->>Copilot: 6. 提供觀察結果
    Copilot->>Copilot: 7. 分析並推導需求
    Copilot->>工程師: 8. 產出 SRS 草稿
    工程師->>新系統: 9. 依需求開發

具體步驟:

  1. 功能盤點:逐一操作舊系統每個畫面與功能
  2. 行為記錄:記錄每個操作的輸入、處理結果、錯誤訊息
  3. 畫面截圖:完整記錄 UI 流程
  4. 網路擷取:使用 Fiddler / Wireshark 擷取 API 呼叫
  5. DB 分析:匯出資料庫 Schema(Table / View / SP)
  6. Copilot 協助推導:將上述資訊輸入 Copilot 進行分析

Copilot 如何協助

# Prompt 範例:黑箱逆向分析

我有一個舊系統的功能觀察記錄如下:

## 畫面:客戶查詢
- 輸入:客戶編號(8位數字)、客戶姓名(模糊搜尋)
- 輸出:客戶基本資料列表(編號、姓名、電話、地址、開戶日期)
- 可進行:新增、修改、刪除、匯出 Excel
- 權限:僅主管可刪除

## 資料庫 Table
- CUSTOMER (CUST_ID, CUST_NAME, PHONE, ADDRESS, OPEN_DATE, STATUS)
- CUSTOMER_LOG (LOG_ID, CUST_ID, ACTION, ACTION_DATE, OPERATOR)

請幫我:
1. 推導出此功能的完整需求規格(Functional Requirements)
2. 識別可能的商業規則(Business Rules)
3. 產出 User Story 格式
4. 建議 Spring Boot 的 API 設計

黑箱優缺點

項目優點缺點
門檻不需原始碼可能遺漏隱藏邏輯
速度快速取得概觀細節精準度不足
風險低技術風險商業規則可能推導錯誤
適用任何系統複雜批次邏輯難以觀察

黑箱實務案例

某銀行信用卡系統黑箱逆向

該銀行有一套 20 年前以 PowerBuilder 開發的信用卡帳務系統,原始碼散落在多個不同版本。團隊先以黑箱方式:

  1. 操作所有畫面功能,記錄約 150 個 Use Case
  2. 使用 Copilot 解析 DB Schema(約 300 張表)自動產出 ERD
  3. 透過 Copilot 從 Use Case + ERD 推導出 80% 的功能需求
  4. 剩餘 20% 透過訪談長期使用者補充

結果:3 個月完成需求文件,較傳統方式節省 60% 時間。


2.2 白箱逆向(White-box Reverse Engineering)

白箱逆向的定義

直接分析原始碼,深入理解系統的實作邏輯、架構設計、資料流程,並據此重建完整的系統文件。

白箱適用情境

  • 擁有完整原始碼(即使語言過時)
  • 原始碼可編譯或至少可閱讀
  • 需要精準還原所有商業邏輯
  • 系統有大量隱藏的商業規則(寫在程式碼中而非文件)

Copilot 如何理解 Legacy Code

flowchart TB
    A[匯入 Legacy Code<br/>至 VS Code] --> B[Copilot 掃描<br/>程式碼結構]
    B --> C{程式碼類型}
    C -->|VB/Delphi| D[逐檔案分析]
    C -->|舊 Java| E[整體架構分析]
    C -->|C/C++| F[模組化分析]
    C -->|Stored Procedure| G[邏輯流程分析]
    
    D --> H[產出文件]
    E --> H
    F --> H
    G --> H
    
    H --> H1[架構圖]
    H --> H2[API 文件]
    H --> H3[資料模型]
    H --> H4[商業邏輯文件]

分析步驟:

Step 1:程式碼匯入與結構化

# 將舊系統程式碼整理至 VS Code 工作區
# 建立統一的資料夾結構
legacy-system/
├── src/                  # 原始碼
│   ├── forms/           # VB Form / Delphi Form
│   ├── modules/         # 共用模組
│   ├── classes/         # 類別檔案
│   └── database/        # Stored Procedure / SQL
├── docs/                # 分析產出文件
│   ├── architecture/    # 架構文件
│   ├── api/            # API 規格
│   ├── data-model/     # 資料模型
│   └── requirements/   # 需求文件
└── analysis/           # 分析筆記

Step 2:使用 Copilot 分析原始碼

# Prompt:分析 VB6 模組

@workspace 請分析以下 VB6 程式碼,並說明:
1. 此模組的主要功能
2. 呼叫了哪些外部 API 或 COM 元件
3. 商業邏輯流程(用 Mermaid flowchart 表示)
4. 存取了哪些資料庫 Table
5. 錯誤處理機制
6. 隱含的商業規則

隨 Prompt 一併貼上的原始碼:

' === modCustomerMgmt.bas ===
Public Function GetCustomerByID(ByVal custID As String) As ADODB.Recordset
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim sql As String
    
    conn.Open "Provider=SQLOLEDB;Data Source=PROD_DB;..."
    
    If Len(custID) <> 8 Then
        Err.Raise 9001, , "客戶編號必須為8碼"
    End If
    
    sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = '" & custID & "' AND STATUS = 'A'"
    rs.Open sql, conn, adOpenKeyset, adLockReadOnly
    
    If rs.EOF Then
        Set GetCustomerByID = Nothing
    Else
        Set GetCustomerByID = rs
    End If
End Function

Step 3:Copilot 產出分析結果

Copilot 會自動識別出:

  • SQL Injection 風險:字串直接拼接 SQL
  • 硬編碼連線字串:資料庫連線資訊寫死在程式碼中
  • 商業規則:客戶編號必須 8 碼、只查詢狀態為 ‘A’(有效)的客戶
  • 資料存取:CUSTOMER 表

如何產出架構圖

# Prompt:產出架構圖

請根據以下程式碼檔案清單,分析並產出系統架構圖(Mermaid 格式):

檔案清單:
- frmMain.frm(主畫面)
- frmCustomer.frm(客戶管理)
- frmTransaction.frm(交易管理)
- modCustomer.bas(客戶模組)
- modTransaction.bas(交易模組)
- modReport.bas(報表模組)
- clsDBHelper.cls(資料庫工具)
- clsLogger.cls(日誌工具)

請產出:
1. 系統模組關係圖
2. 呼叫依賴圖
3. 資料流向圖

如何產出 API 文件

# Prompt:產出 API 設計

根據以下 Legacy 程式碼的功能分析:
- GetCustomerByID:依 ID 查詢客戶
- SearchCustomer:模糊搜尋客戶
- CreateCustomer:新增客戶
- UpdateCustomer:修改客戶
- DeleteCustomer:停用客戶(邏輯刪除)

請產出對應的 RESTful API 設計(OpenAPI 3.0 格式),包含:
1. HTTP Method & Path
2. Request / Response Schema
3. 狀態碼定義
4. 驗證規則

如何產出資料模型

# Prompt:產出 ERD

以下是舊系統的資料庫 DDL:

CREATE TABLE CUSTOMER (
    CUST_ID     CHAR(8) NOT NULL,
    CUST_NAME   VARCHAR(50),
    PHONE       VARCHAR(20),
    ADDRESS     VARCHAR(200),
    OPEN_DATE   DATE,
    STATUS      CHAR(1) DEFAULT 'A',
    PRIMARY KEY (CUST_ID)
);

CREATE TABLE CUSTOMER_ACCOUNT (
    ACCT_NO     CHAR(14) NOT NULL,
    CUST_ID     CHAR(8) NOT NULL,
    ACCT_TYPE   CHAR(2),
    BALANCE     DECIMAL(15,2),
    OPEN_DATE   DATE,
    STATUS      CHAR(1),
    PRIMARY KEY (ACCT_NO),
    FOREIGN KEY (CUST_ID) REFERENCES CUSTOMER(CUST_ID)
);

請產出:
1. Mermaid ERD 圖
2. 欄位說明表
3. 建議的 JPA Entity 設計
4. 資料關係說明

白箱優缺點

項目優點缺點
精準度可完整還原所有邏輯需讀懂過時語言
深度包含隱藏商業規則耗時較長
可靠性不會遺漏功能程式碼品質差時分析困難
AI 輔助Copilot 可加速理解過大的程式碼 Copilot 需分段分析

白箱實務案例

某壽險公司保單管理系統白箱逆向

原系統以 Delphi 7 開發,約 50 萬行程式碼。團隊使用白箱逆向:

  1. 使用 Copilot 逐模組分析,共計 120 個 Form、80 個 Unit
  2. Copilot 自動識別出 300+ 條商業規則(如保費計算公式、理賠規則)
  3. 產出 Mermaid 架構圖 15 張、ERD 8 張
  4. 識別出 42 個 SQL Injection 風險點與 15 個硬編碼密碼

關鍵發現:約有 15% 的商業邏輯只存在於程式碼的註解或變數命名中,必須由資深人員確認。


2.3 灰箱逆向(Gray-box / Hybrid)

灰箱逆向的定義

結合黑箱與白箱的混合策略,先透過黑箱快速了解系統全貌,再以白箱深入分析關鍵模組,並採用 Strangler Fig Pattern 逐步替換舊系統。

灰箱適用情境

  • 大型系統(數十萬至百萬行程式碼)
  • 需要「邊運行舊系統、邊開發新系統」
  • 風險承受度低(如銀行核心系統、交易系統)
  • 有時間壓力,無法一次性全面分析

Strangler Fig Pattern

flowchart TB
    subgraph "Phase 1:並行運行"
        U1[使用者] --> LB[負載平衡器<br/>/ API Gateway]
        LB --> |"舊功能"| OLD1[舊系統]
        LB --> |"新功能A"| NEW1[新系統<br/>Module A]
    end
    
    subgraph "Phase 2:逐步替換"
        U2[使用者] --> LB2[負載平衡器<br/>/ API Gateway]
        LB2 --> |"少數舊功能"| OLD2[舊系統<br/>縮小中...]
        LB2 --> |"新功能A+B+C"| NEW2[新系統<br/>持續擴大]
    end
    
    subgraph "Phase 3:完全替換"
        U3[使用者] --> LB3[API Gateway]
        LB3 --> NEW3[新系統<br/>完整取代]
        OLD3[舊系統<br/>下線] -.-> |"資料遷移完成"| NEW3
    end

灰箱逆向操作流程

flowchart LR
    A[黑箱<br/>功能盤點] --> B[優先排序<br/>模組清單]
    B --> C[白箱<br/>深度分析<br/>第一批模組]
    C --> D[開發<br/>新系統模組]
    D --> E[並行測試<br/>雙軌驗證]
    E --> F[切換流量<br/>至新模組]
    F --> G{所有模組<br/>完成?}
    G --> |否| C
    G --> |是| H[舊系統下線]

詳細步驟:

  1. Phase 0 — 全域黑箱掃描(2-4 週)

    • 操作舊系統所有功能
    • 記錄功能清單與 Use Case
    • 匯出 DB Schema
    • 使用 Copilot 產出系統概觀文件
  2. Phase 1 — 模組優先排序(1 週)

    • 依「商業重要性 × 技術風險 × 依賴程度」排序
    • 決定遷移批次
  3. Phase 2 — 迭代式白箱分析 + 開發(每模組 2-6 週)

    • 白箱分析特定模組
    • 使用 Copilot 協助轉換
    • 開發新模組
    • 雙軌測試驗證
  4. Phase 3 — 漸進切換

    • 透過 API Gateway / Feature Flag 控制流量
    • 逐步將使用者導向新系統

Copilot 在灰箱逆向的角色

# Prompt:模組優先排序分析

我正在對一個大型 Legacy 系統進行灰箱逆向。以下是系統模組清單:

| 模組 | 程式碼行數 | 使用頻率 | 相依模組數 | 最後修改 |
|------|----------|---------|-----------|---------|
| 客戶管理 | 15,000 | 高 | 3 | 2024-01 |
| 交易處理 | 45,000 | 極高 | 8 | 2025-06 |
| 報表系統 | 25,000 | 中 | 5 | 2023-03 |
| 帳務結算 | 35,000 | 中 | 6 | 2024-08 |
| 系統管理 | 8,000 | 低 | 2 | 2022-11 |

請幫我:
1. 建議遷移優先順序
2. 分析模組間依賴關係(Mermaid dependency graph)
3. 識別高風險模組
4. 提出風險緩解策略

灰箱優缺點

項目優點缺點
風險最低風險(漸進式)需維護兩套系統
業務衝擊可不停機遷移開發成本較高
靈活性可隨時調整策略需有 API Gateway 支援
適用大型系統首選小型系統 overkill

灰箱實務案例

某商業銀行核心帳務系統灰箱遷移

原系統為 COBOL + DB2(約 200 萬行 COBOL),採灰箱策略:

  1. Phase 0:3 週黑箱盤點,識別出 500+ 個交易碼
  2. Phase 1:按業務重要性分為 5 個批次
  3. Phase 2:先遷移「查詢類」交易(風險最低),使用 Copilot 輔助 COBOL→Java 轉換
  4. Phase 3:透過 ESB + API Gateway 雙軌運行 18 個月

成果:零停機完成遷移,同時保障日均 500 萬筆交易不受影響。


2.4 三種策略比較總覽

比較項目黑箱逆向白箱逆向灰箱逆向
需要原始碼❌ 不需要✅ 必需⚠️ 部分需要
分析精準度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
執行速度⭐⭐⭐⭐⭐⭐⭐⭐⭐
風險等級中(可能遺漏)低(精準)最低(漸進)
適合規模小~中型系統中型系統大型系統
業務停機可能需要可能需要不需要
Copilot 效益⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
建議使用場景快速概觀 / 無原始碼完整重建企業關鍵系統
費用💰💰💰💰💰💰
時間1-3 月3-12 月6-24 月
quadrantChart
    title "逆向工程策略選擇矩陣"
    x-axis "低精準度" --> "高精準度"
    y-axis "低速度" --> "高速度"
    quadrant-1 "快速但精準"
    quadrant-2 "快速但粗略"
    quadrant-3 "慢但粗略"
    quadrant-4 "慢但精準"
    "黑箱逆向": [0.35, 0.8]
    "白箱逆向": [0.9, 0.3]
    "灰箱逆向": [0.7, 0.55]

💡 選擇建議:

  • 只有執行檔 → 黑箱
  • 中小型系統、有完整原始碼 → 白箱
  • 大型企業關鍵系統、不可停機 → 灰箱
  • 不確定時 → 先黑箱快速摸底,再決定後續策略

第 3 章 SDLC 對應逆向工程流程

逆向工程並非獨立作業,而是必須對應到標準的 SDLC 流程中。以下說明如何在每個 SDLC 階段運用 Copilot 進行逆向工程。

flowchart TB
    subgraph "SDLC × 逆向工程對應"
        A["1️⃣ 需求分析<br/>Requirement Analysis"] --> B["2️⃣ 系統設計<br/>System Design"]
        B --> C["3️⃣ 開發<br/>Implementation"]
        C --> D["4️⃣ 測試<br/>Testing"]
        D --> E["5️⃣ 部署<br/>Deployment"]
    end
    
    subgraph "Copilot 逆向工程對應"
        A1["程式碼 → SRS<br/>推導需求"] --> B1["架構重建<br/>Clean Architecture"]
        B1 --> C1["Spring Boot<br/>自動生成 Code"]
        C1 --> D1["JUnit / 自動化測試<br/>自動生成"]
        D1 --> E1["CI/CD<br/>容器化部署"]
    end
    
    A --- A1
    B --- B1
    C --- C1
    D --- D1
    E --- E1

3.1 需求分析(Requirement Analysis)

從程式碼推導需求的方法論

在缺乏需求文件的情況下,程式碼本身就是「唯一的真相來源(Single Source of Truth)」。

flowchart LR
    subgraph "程式碼 → 需求 推導流程"
        A[原始碼] --> B[功能識別]
        B --> C[商業規則抽取]
        C --> D[使用者情境重建]
        D --> E[需求規格書 SRS]
    end
    
    subgraph "Copilot 在各階段的輔助"
        B1["分析函式/方法功能"]
        C1["識別 if/else 商業邏輯"]
        D1["從 UI Form 推 User Story"]
        E1["自動格式化 SRS"]
    end
    
    B --- B1
    C --- C1
    D --- D1
    E --- E1

Copilot 推導需求的實作範例

從 Stored Procedure 推導需求:

-- 舊系統 Stored Procedure
CREATE PROCEDURE sp_CalcInterest
    @AccountNo CHAR(14),
    @CalcDate DATE
AS
BEGIN
    DECLARE @Balance DECIMAL(15,2)
    DECLARE @Rate DECIMAL(5,4)
    DECLARE @Interest DECIMAL(15,2)
    DECLARE @AcctType CHAR(2)
    
    SELECT @Balance = BALANCE, @AcctType = ACCT_TYPE 
    FROM ACCOUNT WHERE ACCT_NO = @AccountNo
    
    -- 依帳戶類別取利率
    IF @AcctType = '01'  -- 活期存款
        SET @Rate = 0.0125
    ELSE IF @AcctType = '02'  -- 定期存款
        SELECT @Rate = RATE FROM RATE_TABLE 
        WHERE ACCT_TYPE = '02' AND EFF_DATE <= @CalcDate
        ORDER BY EFF_DATE DESC
    ELSE IF @AcctType = '03'  -- 外幣存款
        SET @Rate = 0.0050
    
    -- 計息公式
    SET @Interest = @Balance * @Rate / 365
    
    -- 餘額低於 1000 不計息
    IF @Balance < 1000
        SET @Interest = 0
    
    INSERT INTO INTEREST_LOG (ACCT_NO, CALC_DATE, BALANCE, RATE, INTEREST)
    VALUES (@AccountNo, @CalcDate, @Balance, @Rate, @Interest)
    
    RETURN @Interest
END

Copilot Prompt:

請分析上述 Stored Procedure,推導出以下內容:

1. 功能需求(Functional Requirements)
2. 商業規則清單(Business Rules)
3. 資料需求(Data Requirements)
4. 例外處理需求
5. 以 User Story 格式撰寫需求

請使用企業級 SRS 格式輸出。

Copilot 產出結果:

### FR-001:利息計算功能

**功能描述**:系統應根據帳戶類型、餘額及適用利率,自動計算每日利息。

**商業規則**:
- BR-001:活期存款(帳戶類型 01)適用固定利率 1.25%
- BR-002:定期存款(帳戶類型 02)適用利率表中生效日最近的利率
- BR-003:外幣存款(帳戶類型 03)適用固定利率 0.50%
- BR-004:帳戶餘額低於 1,000 時不計息
- BR-005:計息公式 = 餘額 × 利率 ÷ 365

**使用者故事**:
作為 帳務系統管理員
我要 系統每日自動計算各帳戶利息
以便 正確記錄利息收入並產出對帳資料

**驗收條件**:
- [ ] 活期存款按固定利率 1.25% 計算
- [ ] 定期存款從利率表取最新利率
- [ ] 餘額 < 1000 的帳戶利息為 0
- [ ] 計算結果記錄至利息日誌表

從程式碼推 SRS 的標準流程

步驟動作Copilot 用法產出
1掃描所有入口點@workspace 列出所有 public 方法清單功能清單
2分析每個功能分析此方法的商業邏輯與流程功能說明
3抽取商業規則識別所有 if/switch 中的商業規則BR 清單
4重建資料模型從 SQL DDL 產出 ERD 與欄位說明資料字典
5組合成 SRS將以上分析整合為 IEEE 830 格式 SRSSRS 文件

⚠️ 注意:AI 推導的需求務必與業務單位與資深使用者確認。程式碼中的邏輯可能包含「已知的 Bug」或「歷史遺留的暫時方案」,不應視為正確需求。


3.2 系統設計(System Design)

架構重建(Architecture Reconstruction)

flowchart TB
    subgraph "舊系統架構分析"
        A[掃描程式碼結構] --> B[識別模組邊界]
        B --> C[分析相依關係]
        C --> D[繪製架構圖]
    end
    
    subgraph "新系統架構設計"
        E[選擇架構風格] --> F[定義分層]
        F --> G[設計 API 介面]
        G --> H[定義資料模型]
    end
    
    D --> E

使用 Copilot 進行架構重建:

# Prompt:架構重建

我有一個 Legacy VB6 系統,結構如下:

Forms(畫面):
- frmLogin.frm → 登入驗證
- frmMain.frm → 主選單
- frmCustomer.frm → 客戶管理(CRUD)
- frmAccount.frm → 帳戶管理
- frmTransaction.frm → 交易處理
- frmReport.frm → 報表查詢

Modules(底層模組):
- modDB.bas → 資料庫連線
- modAuth.bas → 權限驗證
- modCustomer.bas → 客戶邏輯
- modAccount.bas → 帳戶邏輯
- modTransaction.bas → 交易邏輯
- modReport.bas → 報表邏輯
- modUtil.bas → 共用工具

請幫我:
1. 分析目前的架構(識別架構風格)
2. 提出目標 Clean Architecture 設計
3. 產出 Spring Boot 專案的 Package 結構
4. 定義各層的職責與介面

Copilot 建議的新架構:

新系統 Spring Boot 專案結構(Clean Architecture):

com.company.newapp/
├── adapter/                    # Interface Adapter Layer
│   ├── web/                   # Controller(REST API)
│   │   ├── CustomerController.java
│   │   ├── AccountController.java
│   │   └── TransactionController.java
│   ├── persistence/           # Repository 實作
│   │   ├── CustomerRepositoryImpl.java
│   │   ├── entity/           # JPA Entity
│   │   └── mapper/           # Entity ↔ Domain 轉換
│   └── security/             # Spring Security 設定
│       └── JwtAuthFilter.java
├── application/               # Application Layer(Use Cases)
│   ├── service/
│   │   ├── CustomerService.java
│   │   ├── AccountService.java
│   │   └── TransactionService.java
│   ├── dto/                  # Request / Response DTO
│   └── port/                 # Port 介面定義
│       ├── in/              # Driven Port(Use Case)
│       └── out/             # Driving Port(Repository)
├── domain/                    # Domain Layer(Business Logic)
│   ├── model/
│   │   ├── Customer.java
│   │   ├── Account.java
│   │   └── Transaction.java
│   ├── valueobject/
│   │   ├── AccountNumber.java
│   │   └── Money.java
│   └── rule/                 # 商業規則
│       ├── InterestCalculator.java
│       └── TransactionValidator.java
└── infrastructure/            # Infrastructure Layer
    ├── config/
    │   ├── SecurityConfig.java
    │   └── DatabaseConfig.java
    └── external/
        ├── NotificationService.java
        └── ReportGenerator.java

Clean Architecture 映射圖

flowchart TB
    subgraph "Clean Architecture"
        direction TB
        subgraph "Infrastructure"
            I1[DB Config]
            I2[External Services]
        end
        subgraph "Adapter"
            A1[REST Controller]
            A2[JPA Repository]
            A3[Security Filter]
        end
        subgraph "Application"
            S1[Use Cases / Services]
            S2[DTO]
            S3[Ports]
        end
        subgraph "Domain"
            D1[Entity / Model]
            D2[Value Object]
            D3[Business Rules]
        end
    end
    
    A1 --> S1
    S1 --> D1
    S1 --> S3
    S3 --> A2
    A2 --> I1

💡 實務建議:架構重建時,建議先畫出「舊系統架構圖」與「目標架構圖」的對照,讓團隊清楚每個模組的遷移路徑。


3.3 開發(Implementation)

使用 Spring Boot 開發新系統

Step 1:建立專案骨架

# 使用 Spring Initializr 建立專案
# 透過 Copilot CLI 或 VS Code Spring Boot Extension

# 必要 Dependencies:
# - Spring Web
# - Spring Data JPA
# - Spring Security
# - Spring Validation
# - Lombok
# - MapStruct
# - SpringDoc OpenAPI (Swagger)

Step 2:使用 Copilot 將 Legacy Code 轉為 Spring Boot

舊系統 VB 的客戶查詢邏輯如下:

Public Function SearchCustomer(ByVal name As String, _
                                ByVal phone As String) As Collection
    Dim sql As String
    sql = "SELECT * FROM CUSTOMER WHERE 1=1"
    
    If Len(name) > 0 Then
        sql = sql & " AND CUST_NAME LIKE '%" & name & "%'"
    End If
    
    If Len(phone) > 0 Then
        sql = sql & " AND PHONE = '" & phone & "'"
    End If
    
    sql = sql & " AND STATUS = 'A' ORDER BY CUST_NAME"
    
    ' ... execute and return
End Function

搭配的 Prompt:

# Prompt:將 VB 函式轉為 Spring Boot Service

請將上述 VB6 的 SearchCustomer 函式轉換為 Spring Boot:
1. Repository(使用 Spring Data JPA + Specification)
2. Service(包含驗證邏輯)
3. Controller(RESTful API)
4. DTO(Request / Response)
5. 修正原始碼的 SQL Injection 問題

Copilot 產出:

// === CustomerRepository.java ===
@Repository
public interface CustomerRepository extends JpaRepository<Customer, String>,
                                            JpaSpecificationExecutor<Customer> {
}

// === CustomerSpecification.java ===
public class CustomerSpecification {
    
    public static Specification<Customer> withFilters(String name, String phone) {
        return (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 只查有效客戶
            predicates.add(cb.equal(root.get("status"), "A"));
            
            if (StringUtils.hasText(name)) {
                predicates.add(cb.like(root.get("custName"), "%" + name + "%"));
            }
            
            if (StringUtils.hasText(phone)) {
                predicates.add(cb.equal(root.get("phone"), phone));
            }
            
            query.orderBy(cb.asc(root.get("custName")));
            return cb.and(predicates.toArray(new Predicate[0]));
        };
    }
}

// === CustomerService.java ===
@Service
@RequiredArgsConstructor
public class CustomerService {
    
    private final CustomerRepository customerRepository;
    
    public Page<CustomerResponse> searchCustomer(CustomerSearchRequest request, 
                                                  Pageable pageable) {
        Specification<Customer> spec = CustomerSpecification.withFilters(
            request.getName(), request.getPhone()
        );
        
        return customerRepository.findAll(spec, pageable)
                .map(CustomerMapper.INSTANCE::toResponse);
    }
}

// === CustomerController.java ===
@RestController
@RequestMapping("/api/v1/customers")
@RequiredArgsConstructor
public class CustomerController {
    
    private final CustomerService customerService;
    
    @GetMapping
    public ResponseEntity<Page<CustomerResponse>> searchCustomer(
            @Valid CustomerSearchRequest request,
            @PageableDefault(size = 20, sort = "custName") Pageable pageable) {
        
        return ResponseEntity.ok(customerService.searchCustomer(request, pageable));
    }
}

⚠️ 注意:Copilot 轉換的程式碼已自動修正 SQL Injection 風險(改用 JPA Specification 參數化查詢),但仍需 Code Review 確認所有商業邏輯完整。


3.4 測試(Testing)

自動生成測試案例

# Prompt:產生單元測試

請為以下 CustomerService.searchCustomer 方法產生完整的 JUnit 5 測試:

1. 正常查詢(有結果)
2. 空結果
3. 只輸入姓名
4. 只輸入電話
5. 分頁測試
6. 邊界條件(空字串、null)

使用 @MockBean 替換 Repository,使用 AssertJ 斷言。

Copilot 產出:

@ExtendWith(MockitoExtension.class)
class CustomerServiceTest {

    @Mock
    private CustomerRepository customerRepository;

    @InjectMocks
    private CustomerService customerService;

    @Test
    @DisplayName("依姓名模糊查詢客戶 - 應返回匹配結果")
    void searchByName_shouldReturnMatchingCustomers() {
        // Given
        Customer customer = Customer.builder()
                .custId("00000001")
                .custName("王小明")
                .phone("0912345678")
                .status("A")
                .build();
        
        Page<Customer> page = new PageImpl<>(List.of(customer));
        when(customerRepository.findAll(any(Specification.class), any(Pageable.class)))
                .thenReturn(page);

        CustomerSearchRequest request = new CustomerSearchRequest();
        request.setName("王");

        // When
        Page<CustomerResponse> result = customerService.searchCustomer(
                request, PageRequest.of(0, 20));

        // Then
        assertThat(result.getContent()).hasSize(1);
        assertThat(result.getContent().get(0).getCustName()).isEqualTo("王小明");
        verify(customerRepository).findAll(any(Specification.class), any(Pageable.class));
    }

    @Test
    @DisplayName("查詢無結果 - 應返回空頁面")
    void searchWithNoResult_shouldReturnEmptyPage() {
        // Given
        when(customerRepository.findAll(any(Specification.class), any(Pageable.class)))
                .thenReturn(Page.empty());

        CustomerSearchRequest request = new CustomerSearchRequest();
        request.setName("不存在的名字");

        // When
        Page<CustomerResponse> result = customerService.searchCustomer(
                request, PageRequest.of(0, 20));

        // Then
        assertThat(result.getContent()).isEmpty();
        assertThat(result.getTotalElements()).isZero();
    }

    @Test
    @DisplayName("不帶任何條件查詢 - 應返回所有有效客戶")
    void searchWithNoFilter_shouldReturnAllActive() {
        // Given
        List<Customer> customers = List.of(
                Customer.builder().custId("00000001").custName("王小明").status("A").build(),
                Customer.builder().custId("00000002").custName("李大華").status("A").build()
        );
        when(customerRepository.findAll(any(Specification.class), any(Pageable.class)))
                .thenReturn(new PageImpl<>(customers));

        CustomerSearchRequest request = new CustomerSearchRequest();

        // When
        Page<CustomerResponse> result = customerService.searchCustomer(
                request, PageRequest.of(0, 20));

        // Then
        assertThat(result.getContent()).hasSize(2);
    }
}

逆向工程測試策略

flowchart TB
    A[舊系統行為] --> B[Characterization Test<br/>特徵測試]
    B --> C[記錄舊系統行為<br/>作為基準]
    C --> D[新系統開發]
    D --> E[新系統測試]
    E --> F{結果與舊系統一致?}
    F --> |是| G[✅ 通過]
    F --> |否| H[分析差異]
    H --> I{Bug or Feature?}
    I --> |Bug| J[新系統修正]
    I --> |Feature| K[確認需求後調整]

💡 Best Practice:在逆向工程中,建議先建立「Characterization Test(特徵測試)」— 記錄舊系統的實際行為,確保新系統能完全重現。


3.5 部署(Deployment)

CI/CD Pipeline 設計

flowchart LR
    A[Git Push] --> B[GitHub Actions]
    B --> C[Build<br/>Maven]
    C --> D[Test<br/>JUnit]
    D --> E[Scan<br/>SonarQube]
    E --> F{Quality Gate}
    F --> |Pass| G[Build Image<br/>Docker]
    G --> H[Push to<br/>Registry]
    H --> I[Deploy<br/>Staging]
    I --> J[雙軌驗證<br/>新舊比對]
    J --> K{通過?}
    K --> |是| L[Deploy<br/>Production]
    K --> |否| M[Rollback]
    F --> |Fail| N[通知開發者]

Docker 容器化

# === Dockerfile (Multi-Stage Build) ===
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar

# 安全性設定
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

GitHub Actions CI/CD 範例

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'

      - name: Build and Test
        run: mvn clean verify

      - name: SonarQube Scan
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: mvn sonar:sonar

      - name: Build Docker Image
        if: github.ref == 'refs/heads/main'
        run: |
          docker build -t myapp:${{ github.sha }} .
          docker tag myapp:${{ github.sha }} registry.company.com/myapp:latest

      - name: Push to Registry
        if: github.ref == 'refs/heads/main'
        run: docker push registry.company.com/myapp:latest

💡 實務建議:在逆向工程專案中,CI/CD 必須包含「新舊系統行為比對」的自動化測試步驟。可使用 Contract Test 或 Parallel Run 機制確保一致性。


第 4 章 GitHub Copilot 實戰流程

本章提供完整的 Step-by-Step 操作指引,適合團隊按步驟執行。

flowchart TB
    S1["Step 1<br/>分析舊系統"] --> S2["Step 2<br/>建立理解模型"]
    S2 --> S3["Step 3<br/>產出文件"]
    S3 --> S4["Step 4<br/>建立新專案"]
    S4 --> S5["Step 5<br/>逐步重構"]
    S5 --> S6["Step 6<br/>驗證與測試"]
    
    S1 -.-> |"Copilot Chat<br/>@workspace"| T1["分析程式碼結構<br/>識別模組與功能"]
    S2 -.-> |"Copilot Chat"| T2["產出 Domain Model<br/>ERD / Class Diagram"]
    S3 -.-> |"Copilot Chat"| T3["產出 SRS / SDS<br/>API 規格"]
    S4 -.-> |"Copilot Agent"| T4["自動建立專案<br/>Spring Initializr"]
    S5 -.-> |"Copilot Chat / Agent"| T5["逐模組轉換<br/>語言遷移"]
    S6 -.-> |"Copilot Chat"| T6["自動產生測試<br/>行為比對"]

4.1 Step 1:分析舊系統

Step 1 目標

建立舊系統的完整清冊(Inventory),包括:功能清單、技術棧、模組結構、資料庫結構。

Step 1 操作指引

1. 程式碼盤點

# Copilot Chat Prompt

@workspace 請幫我分析這個 Legacy 專案,產出以下報告:

1. 技術棧摘要(語言、框架、版本)
2. 檔案結構清單(按模組分類)
3. 各模組的程式碼行數統計
4. 外部依賴清單(第三方元件、COM 元件)
5. 資料庫連線設定
6. 識別所有入口點(Main Form / Entry Point)

2. 功能點盤點

# Copilot Chat Prompt

請分析這個模組(modCustomer.bas),列出:

1. 所有 Public Function / Sub 的名稱與功能說明
2. 每個功能的參數與回傳值
3. 功能間的呼叫關係(Call Graph)
4. 存取的資料庫 Table 清單
5. 錯誤處理方式

3. 產出系統清冊

模組功能數程式碼行數存取 Table複雜度備註
客戶管理123,500CUSTOMER, CUST_LOG中—
帳戶管理185,200ACCOUNT, ACCT_HIST高含利息計算
交易處理258,000TRANSACTION, TX_LOG極高核心模組
報表系統82,100(多表 JOIN)中Crystal Reports
系統管理61,200SYS_USER, SYS_AUTH低—

💡 實務建議:系統清冊是整個逆向工程的基礎,務必完整。建議由 2-3 人分工盤點,再整合交叉確認。


4.2 Step 2:建立理解模型(Domain Model)

Step 2 目標

從程式碼中抽取領域模型(Domain Model),建立系統的「概念理解」。

Step 2 操作指引

1. 識別核心實體(Entity)

# Copilot Chat Prompt

請分析此專案的資料庫 Schema,識別出:

1. 核心實體(Core Entity)及其關係
2. 值物件(Value Object)
3. 聚合根(Aggregate Root)— DDD 觀點
4. 產出 Mermaid Class Diagram
5. 產出 Mermaid ER Diagram

Copilot 產出範例:

erDiagram
    CUSTOMER ||--o{ ACCOUNT : "擁有"
    CUSTOMER {
        string custId PK "客戶編號"
        string custName "客戶姓名"
        string phone "電話"
        string address "地址"
        date openDate "開戶日期"
        char status "狀態"
    }
    ACCOUNT ||--o{ TRANSACTION : "產生"
    ACCOUNT {
        string acctNo PK "帳號"
        string custId FK "客戶編號"
        char acctType "帳戶類型"
        decimal balance "餘額"
        date openDate "開戶日"
        char status "狀態"
    }
    TRANSACTION {
        string txId PK "交易編號"
        string acctNo FK "帳號"
        char txType "交易類型"
        decimal amount "金額"
        datetime txDate "交易日期"
        string operator "經辦人"
    }

2. 識別 Bounded Context

# Copilot Chat Prompt

根據以上分析的領域模型,請識別可能的 Bounded Context:

1. 各 Context 包含哪些 Entity
2. Context 之間的關係(Context Map)
3. 建議的微服務拆分方式(若適用)

4.3 Step 3:產出文件(AI 自動生成)

Step 3 目標

使用 Copilot 自動產出完整的技術文件套件。

文件清單與 Copilot 指令

文件Copilot Prompt格式
SRS根據分析結果,產出 IEEE 830 格式的 SRSMarkdown
SDS產出系統設計規格書,含架構圖與模組說明Markdown + Mermaid
API 規格產出 OpenAPI 3.0 規格YAML
ERD產出 ER Diagram(Mermaid 格式)Mermaid
資料字典產出完整的資料字典(Table / Column 說明)Markdown Table
測試計畫產出測試計劃與測試案例Markdown

批次產出文件的 Prompt:

# Copilot Chat Prompt

請根據我們分析的舊系統資訊,自動產出以下文件包:

## 1. 需求規格書(SRS)
- 系統概述
- 功能需求清單(按模組分類)
- 非功能需求(效能、安全、可用性)
- 商業規則清單
- 使用者故事

## 2. 系統設計書(SDS)
- 系統架構圖(C4 Model - System Context + Container)
- 模組設計(Class Diagram)
- API 設計(RESTful)
- 資料庫設計(ERD + 資料字典)
- 安全設計

各文件請使用 Markdown 格式,圖表使用 Mermaid。

4.4 Step 4:建立新專案(Spring Boot)

Step 4 目標

基於分析文件,建立新的 Spring Boot 專案。

Step 4 操作指引

# Copilot Chat / Agent Prompt

請幫我建立一個 Spring Boot 4.x 專案,需求如下:

專案名稱:customer-management-system
Java 版本:21
Build Tool:Maven

Dependencies:
- Spring Web
- Spring Data JPA
- Spring Security
- Spring Validation
- Spring Boot Actuator
- Lombok
- MapStruct
- SpringDoc OpenAPI
- Log4j2

架構:Clean Architecture
分層:
- adapter.web(Controller)
- adapter.persistence(JPA Repository)
- application.service(Use Case)
- application.dto(DTO)
- application.port(Port Interface)
- domain.model(Entity)
- domain.rule(Business Rules)
- infrastructure(Config)

請產出完整的 pom.xml 與基礎程式碼骨架。

4.5 Step 5:逐步重構

Step 5 目標

按優先順序逐模組將舊系統功能遷移至新系統。

遷移順序建議

gantt
    title 模組遷移時程
    dateFormat  YYYY-MM-DD
    section Phase 1(低風險)
    系統管理     :a1, 2026-01-01, 30d
    客戶管理     :a2, after a1, 45d
    section Phase 2(中風險)
    帳戶管理     :b1, after a2, 45d
    報表系統     :b2, after a2, 30d
    section Phase 3(高風險)
    交易處理     :c1, after b1, 60d
    section 驗證
    整合測試     :d1, after c1, 30d
    UAT          :d2, after d1, 30d

每個模組的遷移步驟

  1. 白箱分析:使用 Copilot 深入分析模組程式碼
  2. 需求確認:將 AI 產出的需求與業務單位確認
  3. API 設計:設計 RESTful API
  4. 程式碼轉換:使用 Copilot 將 Legacy Code 轉為 Java
  5. 測試撰寫:使用 Copilot 產生單元測試
  6. 整合測試:與其他模組整合測試
  7. 行為比對:比對新舊系統輸出是否一致
  8. 切換流量:透過 API Gateway 將流量切至新系統

4.6 Step 6:驗證與測試

雙軌驗證(Parallel Run)

flowchart LR
    A[相同輸入] --> B[舊系統]
    A --> C[新系統]
    B --> D[舊系統輸出]
    C --> E[新系統輸出]
    D --> F{比對}
    E --> F
    F --> |一致| G[✅ 驗證通過]
    F --> |不一致| H[❌ 分析差異]
    H --> I[修正新系統<br/>或確認是 Bug Fix]

驗證清單

  • 所有 API 回傳結果與舊系統一致
  • 資料庫操作(CRUD)結果正確
  • 商業規則(計算公式等)正確
  • 錯誤處理行為一致
  • 效能不低於舊系統(Response Time / Throughput)
  • 安全性通過弱掃(SAST / DAST)
  • 使用者驗收測試(UAT)通過

⚠️ 重要提醒:雙軌驗證期間,建議至少運行 2-4 週,涵蓋月結、季結等特殊業務週期。


4.7 Agent Mode 加速逆向工程

使用 Agent Mode 自動化分析

Agent Mode 是 Copilot 2026 年最具革命性的功能——讓 AI 自主決定分析步驟、編輯檔案、執行終端命令並自我修正:

flowchart TB
    subgraph "Agent Mode 逆向工程自動化流程"
        A[使用者下達高階目標] --> B[Agent 分析程式碼庫]
        B --> C[Agent 制定分析計畫]
        C --> D[自動建立分析報告]
        D --> E[自動產出架構圖]
        E --> F[自動生成遷移骨架程式碼]
        F --> G[執行 mvn compile 驗證]
        G --> H{編譯通過?}
        H -->|否| I[Agent 自動修正錯誤]
        I --> G
        H -->|是| J[產出結果供人工審查]
    end

Agent Mode 操作範例:

在 VS Code Chat 中選擇 Agent Mode,輸入:

分析 legacy-cms/ 目錄中的所有 VB6 原始碼,完成以下任務:

1. 掃描所有 .bas 和 .frm 檔案,建立模組功能清單
2. 分析每個模組的 Public 方法與商業規則
3. 識別所有資料庫操作(Table、SP)
4. 將分析結果寫入 docs/reverse-engineering-report.md
5. 產出 Mermaid 架構圖與 ERD
6. 建議 Spring Boot 4.x 對應的專案結構

請使用企業級格式輸出,表格對齊,圖表使用 Mermaid。

Agent Mode 會自主:

  • 瀏覽並讀取所有 VB6 檔案
  • 辨識模組結構與呼叫關係
  • 建立並寫入報告檔案
  • 如果遇到無法辨識的語法,會嘗試其他分析策略

使用 Plan 代理規劃遷移

Plan 是 VS Code 內建的代理之一(與 Ask/Edit/Agent 並列於代理選單),可在開始改動任何程式碼之前,先產出結構化的實作計畫供人審閱:

# Plan 代理 Prompt

請為以下 Legacy 系統遷移規劃完整的實作計畫:

系統資訊:
- 程式碼:35,000 行 VB6
- 資料庫:SQL Server 2008(50 表、30 SP)
- 目標:Spring Boot 4.x + PostgreSQL 17

計畫需包含:
1. 遷移批次分組(按風險等級與依賴關係)
2. 每個批次的預估工時
3. 關鍵路徑識別
4. 風險項目與緩解方案
5. 里程碑定義

Plan 代理會產出結構化的逐步計畫,確認後可直接交由 Agent Mode 或 Cloud Agent 執行。

⚠️ 計畫不會自動保留:Plan 代理的計畫屬於「當次對話」的產物,對話結束即失效。逆向工程的遷移計畫是需要長期追蹤的資產,務必把確認後的計畫另存為 Repo 中的檔案(例如 docs/migration-plan.md)並納入版控,不要依賴代理「記得」。各種記憶機制的差異見 9.9 節。

使用 Cloud Agent 自動化遷移

Cloud Agent(原 Copilot Coding Agent)適合獨立模組的遷移任務:

flowchart LR
    A["開發者指派 Issue<br/>給 Copilot"] --> B["Cloud Agent<br/>分析倉庫"]
    B --> C["建立功能分支"]
    C --> D["實作程式碼變更"]
    D --> E["執行測試驗證"]
    E --> F["開啟 Pull Request"]
    F --> G["團隊 Code Review"]
    G --> H["合併至主分支"]

操作方式:

  1. 在 GitHub 建立 Issue:「遷移客戶管理模組:modCustomer.bas → CustomerService.java」
  2. 將 Issue 指派給 @copilot
  3. Cloud Agent 自動:
    • 分析 modCustomer.bas 的所有方法
    • 建立 feature branch
    • 生成 Spring Boot 相關類別(Entity、Repository、Service、Controller、DTO)
    • 執行 mvn compile 確認編譯通過
    • 開啟 PR 附上變更摘要
  4. 團隊審查 PR,確認商業邏輯正確後合併

💡 實務建議:Cloud Agent 最適合「邊界清晰、獨立性高」的模組遷移。對於高度耦合的核心模組,仍建議使用本地 Agent Mode + 人工協作方式。

以 Agents 視窗並行推進多模組

逆向工程專案的常態是「A 模組在分析、B 模組在轉換、C 模組的 PR 在等審查」。VS Code 1.135 改版後的 Agents 視窗正是為此設計,可在單一介面集中管理多個本機 Agent Session 與遠端 Cloud Agent Session,不必再於 Chat 視窗與 GitHub 網頁之間反覆切換。

能力說明逆向工程用法
多 Session 集中管理本機與雲端 session 並列,session 資訊以互動式標籤呈現(變更、PR、Issue、產出物)一眼看出各模組進度:哪個在分析、哪個已開 PR
跨應用程式接續可在 VS Code 中接續其他應用程式開啟的 Copilot/Claude agent session在 CLI 起頭的批次分析,回到編輯器繼續深入
多對話並排水平/垂直分割並保存版面左邊放 Legacy 分析對話、右邊放新系統實作對話,對照進行
/btw 側邊提問開啟共用上下文與 prompt cache 的側邊對話,不打斷代理當前工作代理正在批次轉換時,順手問「這個 IIf 在 VB 的 NULL 行為是什麼」
/rubber-duck(實驗性)由另一個互補模型提供第二意見,指出被忽略的細節與邊界條件商業規則抽取的二次確認——請它檢查是否漏掉隱藏分支
每輪 Token 用量明細滑鼠停在回應頁尾,顯示各模型的輸入/快取輸入/輸出 token 數量化「一個模組的分析成本」,回推整案 AI Credits 預算
Agent Host 多視窗實驗性功能,多個 VS Code 視窗連到同一個 session舊系統與新專案分屬兩個視窗,共用同一個分析代理

💡 實務建議:/rubber-duck 對逆向工程特別有價值。AI 抽取商業規則時最常見的失誤不是「寫錯」,而是「漏掉」——尤其是巢狀 if 深處那種多年前補上的特例(參見 7.1 節的 VIP 回饋金案例)。用互補模型做一次交叉檢查,成本遠低於上線後才發現規則遺漏。


第 5 章 Copilot Prompt Engineering

Prompt Engineering 是使用 Copilot 進行逆向工程的核心技能。好的 Prompt 能讓 Copilot 產出精準、可用的結果;差的 Prompt 會導致錯誤或無用的產出。

5.1 Prompt 設計原則

mindmap
  root((Prompt<br/>設計原則))
    明確性
      指定輸出格式
      指定程式語言
      限定範圍
    上下文
      提供原始碼
      說明背景
      給出約束條件
    結構化
      分步驟要求
      使用編號
      採用模板
    驗證性
      要求範例
      要求解釋
      要求邊界條件

高品質 Prompt 的 CRISP 原則

原則說明範例
Context(上下文)提供足夠背景資訊「這是一個 VB6 銀行帳務系統…」
Role(角色)指定 AI 扮演的角色「你是一位 Java 架構師…」
Instruction(指令)明確指出任務「請將此程式碼轉換為 Spring Boot…」
Specification(規格)限定輸出格式與品質「使用 Clean Architecture、包含 JavaDoc…」
Proof(驗證)要求 AI 提供驗證依據「請解釋每個轉換決策的原因…」

好 Prompt vs 壞 Prompt

❌ 壞 Prompt:

幫我把這個 VB 程式改成 Java

✅ 好 Prompt:

## 上下文
這是一個銀行帳務系統的 VB6 模組,負責客戶帳戶的利息計算。

## 任務
請將以下 VB6 函式轉換為 Spring Boot 4.x 的 Service 方法。

## 要求
1. 使用 Java 21 語法
2. 遵循 Clean Architecture 分層
3. 使用 JPA 取代 ADO 直接 SQL
4. 修正原始碼中的 SQL Injection 風險
5. 加入 JavaDoc 與 @Valid 驗證
6. 保留所有商業規則(標註在註解中)

## 原始碼
[貼上 VB 程式碼]

## 輸出格式
請分別產出:
- Entity
- Repository
- Service
- Controller
- DTO

5.2 程式碼分析類 Prompt

Prompt #1:模組功能分析

# 角色:資深系統分析師
# 任務:分析 Legacy 程式碼模組

請分析以下 [VB6/Delphi/C#] 程式碼模組:

[貼上程式碼]

請產出:
1. **功能摘要**:此模組的主要功能(一句話)
2. **詳細流程**:商業邏輯步驟(Mermaid flowchart)
3. **商業規則**:所有 if/else/switch 中隱含的規則(BR-001 ~ BR-xxx)
4. **資料存取**:存取的 Table / SP 清單
5. **外部依賴**:呼叫的外部元件或 API
6. **安全風險**:識別潛在安全漏洞
7. **可維護性評估**:程式碼品質評分(1-10)及改善建議

Prompt #2:呼叫鏈追蹤

# 任務:追蹤函式呼叫鏈

從入口點 [函式名稱] 開始,追蹤完整的呼叫鏈:

1. 列出所有被呼叫的函式(含檔案名稱)
2. 標示每個函式的層級深度
3. 標示資料庫操作點(CRUD)
4. 產出 Mermaid Sequence Diagram

格式:
入口函式 → 子函式A → 子函式B → DB操作

Prompt #3:資料流分析

# 任務:資料流分析

分析此「[交易/功能]」的完整資料流:

1. 資料輸入點(使用者輸入 / 外部系統)
2. 資料轉換步驟
3. 資料驗證規則
4. 資料存入/更新的 Table
5. 資料輸出(畫面 / 報表 / 外部系統)

請產出 Mermaid Data Flow Diagram(DFD)。

5.3 語言轉換類 Prompt

Prompt #4:VB → Java 完整轉換

# 角色:資深 Java 架構師
# 任務:VB6 → Spring Boot 轉換

## 原始 VB6 程式碼
[貼上 VB 程式碼]

## 轉換需求
1. **語言**:Java 21
2. **框架**:Spring Boot 4.1.x(3.x 系列已於 2026-06-30 EOL,不得採用)
3. **架構**:Clean Architecture
4. **ORM**:Spring Data JPA(取代 ADO)
5. **安全**:修正所有 SQL Injection、XSS 風險
6. **日誌**:使用 SLF4J + Log4j2
7. **驗證**:使用 Jakarta Validation
8. **例外**:使用自定義例外 + @ControllerAdvice

## 商業邏輯保留
- 請在 Java 程式碼中以 @BusinessRule 註解標示原始商業規則
- 如有不確定的邏輯,請加 @TODO 標記

## 輸出
請分層產出(附 JavaDoc):
1. Domain Model (Entity)
2. Repository Interface
3. Service (Use Case)
4. Controller (REST API)
5. DTO (Request/Response)

Prompt #5:Stored Procedure → Java Service 轉換

# 角色:資料庫和 Java 專家
# 任務:Stored Procedure → Spring Boot Service

## 原始 SP
[貼上 Stored Procedure]

## 轉換原則
1. SP 中的 SQL → JPA Repository 方法
2. SP 中的商業邏輯 → Service 方法
3. SP 中的資料驗證 → Jakarta Validation + 自定義 Validator
4. SP 中的錯誤處理 → 自定義 Exception
5. 暫存表邏輯 → Java Collection 處理
6. 游標邏輯 → Stream API

## 注意
- 保持交易完整性(@Transactional)
- 處理並發(樂觀鎖 / 悲觀鎖)
- 效能考量(N+1 問題、Batch 操作)

Prompt #6:C# → Java 轉換

# 角色:跨平台資深工程師
# 任務:C# .NET → Java Spring Boot 轉換

## 原始 C# 程式碼
[貼上 C# 程式碼]

## 對照轉換規則
| C# | Java |
|------|------|
| LINQ | Stream API |
| Entity Framework | Spring Data JPA |
| ASP.NET Controller | @RestController |
| Dependency Injection | Spring @Autowired / Constructor Injection |
| async/await | CompletableFuture / @Async |
| ILogger | SLF4J Logger |
| DataAnnotation | Jakarta Validation |

## 輸出
依 Spring Boot 最佳實務產出轉換後的 Java 程式碼,
附上轉換決策說明。

5.4 文件產出類 Prompt

Prompt #7:自動產出 API 文件

# 任務:產出 RESTful API 文件

根據以下 Legacy 函式清單,設計對應的 RESTful API:

Legacy 函式:
1. GetCustomerByID(custID) → 單一客戶查詢
2. SearchCustomer(name, phone, page) → 客戶搜尋
3. CreateCustomer(custData) → 新增客戶
4. UpdateCustomer(custID, custData) → 修改客戶
5. DeleteCustomer(custID) → 停用客戶
6. GetCustomerAccounts(custID) → 查詢客戶帳戶
7. ExportCustomerReport(criteria) → 匯出報表

請產出:
1. API 一覽表(Method / Path / 說明)
2. 每個 API 的 Request / Response Schema(JSON)
3. 錯誤碼定義
4. OpenAPI 3.0 YAML 片段

Prompt #8:產出架構設計文件

# 任務:產出系統架構設計文件(SDS)

根據逆向分析結果,產出以下架構文件:

## 系統概述
[簡述系統功能]

## 需要產出
1. C4 Model(Context / Container / Component 三層)— 使用 Mermaid
2. 部署架構圖
3. 資料庫架構(ERD)
4. 安全架構
5. 模組相依關係圖
6. 技術選型理由

## 格式
- 每個圖表使用 Mermaid
- 每個設計決策需附上理由
- 標示風險點與緩解方案

5.5 測試生成類 Prompt

Prompt #9:生成特徵測試(Characterization Test)

# 任務:生成 Characterization Test

為以下商業邏輯生成「特徵測試」,用於記錄舊系統的實際行為:

## 商業邏輯
[貼上 Service 方法或商業規則]

## 測試要求
1. 使用 JUnit 5 + AssertJ
2. 使用 @ParameterizedTest 覆蓋所有分支
3. 覆蓋正常路徑、邊界值、異常路徑
4. 每個測試附上 @DisplayName(中文說明)
5. 測試資料覆蓋所有商業規則

## 測試案例需包含
- 正常案例(Happy Path)
- 邊界值(Boundary)
- 異常案例(Error Path)
- 並發案例(如適用)

Prompt #10:生成整合測試

# 任務:生成 API 整合測試

為以下 REST API 產出完整整合測試:

## API
[貼上 Controller 程式碼]

## 測試要求
1. 使用 @SpringBootTest + @AutoConfigureMockMvc
2. 使用 @TestContainers 模擬資料庫
3. 測試完整的 HTTP 請求/回應
4. 驗證 HTTP Status Code
5. 驗證 Response Body(JSON Path)
6. 驗證資料庫狀態變化

## 測試案例
- 成功建立資源 → 201
- 查詢存在的資源 → 200
- 查詢不存在的資源 → 404
- 無效輸入 → 400
- 未授權 → 401
- 權限不足 → 403

5.6 Prompt 模板庫

以下提供可直接複製使用的 Prompt 模板:

通用分析模板

# === 逆向工程分析模板 ===

## 角色
你是資深 [語言] 工程師與 Java 架構師。

## 上下文
這是 [系統名稱] 的 [模組名稱],功能為 [一句話描述]。

## 原始碼
[貼上程式碼]

## 分析任務
請產出:
1. 功能摘要(50字以內)
2. 詳細流程(Mermaid flowchart)
3. 商業規則清單(BR-xxx)
4. 資料庫操作清單
5. 安全風險識別
6. 對應的 Spring Boot 設計建議

## 輸出格式
使用 Markdown,圖表使用 Mermaid。

批次轉換模板

# === 批次程式碼轉換模板 ===

## 轉換目標
源語言:[VB6 / C# / Delphi / COBOL]
目標語言:Java 21(或 25 LTS)+ Spring Boot 4.1.x

## 轉換規則
- [源語言特性] → [Java 對應]
- [源語言特性] → [Java 對應]
(根據語言調整)

## 品質要求
- [ ] 遵循 Clean Architecture
- [ ] 包含 JavaDoc
- [ ] 包含 Validation
- [ ] 修正安全漏洞
- [ ] 保留商業規則(標註)
- [ ] 產出對應的單元測試

## 原始碼
[貼上程式碼]

💡 實務建議:建議團隊建立「Prompt Library」,將常用且驗證過的 Prompt 模板集中管理(可放在 Git Repo 的 .github/prompts/ 目錄下),方便團隊成員重複使用。


5.7 Custom Instructions(專案級指令)

什麼是 Custom Instructions

Custom Instructions 讓你在 .github/copilot-instructions.md 中定義專案級的 AI 行為規範。Copilot 在回答問題或產生程式碼時,會自動參考這些指令,確保所有產出符合團隊的逆向工程標準。

目前支援的客製化檔案類型

Copilot 的客製化檔案已發展成一套完整體系,涵蓋「always-on 指令」「路徑限定指令」「可重用 Prompt」「專用代理」「技能」五類。逆向工程專案的新舊程式碼並存特性,正好需要用到其中大部分:

檔案類型適用範圍逆向工程用法
.github/copilot-instructions.mdAlways-on 指令整個 Repo全域性規範,本節主要範例即此類型
.github/instructions/**/*.instructions.md路徑限定指令以 glob 限定的路徑逆向工程最實用的一種:對 legacy/** 套用「唯讀、只分析不修改」規範,對 src/main/java/** 套用新系統編碼規範
AGENTS.md(含巢狀子資料夾)Always-on 指令,跨工具通用整個 Repo 或子目錄開放標準(agents.md);團隊同時使用 Claude Code、Codex CLI 等工具時,用同一份避免重複維護。VS Code 亦支援 CLAUDE.md
.github/prompts/*.prompt.md可重用 Prompt手動叫用把本章 5.6 節的模板庫落地成可直接執行的指令
.github/agents/*.agent.md自訂代理選單中挑選建立「Legacy 分析代理」「VB→Java 轉換代理」等專用人格(詳見 5.8 節)
.github/skills/<name>/SKILL.md技能相關時自動載入封裝標準分析流程,跨 VS Code/CLI/Cloud Agent/Code Review 通用

兩個容易踩雷的細節:

  • *.agent.md 已取代舊的 *.chatmode.md。若手上的專案還留著 .chatmode.md,需重新命名為 .agent.md 並移到 .github/agents/,否則不會被載入。
  • Monorepo/多層目錄:逆向工程專案常把舊系統與新專案放在同一個 Repo 的不同子目錄。若希望子資料夾也能沿用上層 Repo 的客製化設定,需啟用 chat.useCustomizationsInParentRepositories。

💡 選型建議:僅使用 GitHub Copilot 的團隊可專注於 copilot-instructions.md + 路徑限定的 .instructions.md;若團隊同時導入多種 AI 開發工具,改採開放的 AGENTS.md 標準能降低維護成本。使用者層級的個人設定則存放於 ~/.copilot(Copilot)或 ~/.claude(Claude),不要把專案規範寫在個人層級——否則其他團隊成員的 AI 產出不會遵守同一套標準。

逆向工程專用 Custom Instructions 範例

# .github/copilot-instructions.md — 逆向工程專案專用

## 專案背景
本專案正在將 VB6 客戶管理系統遷移至 Spring Boot 4.x。

## 程式碼規範
1. 目標框架:Spring Boot 4.x + Java 21
2. 架構風格:Clean Architecture(adapter / application / domain / infrastructure)
3. ORM:Spring Data JPA
4. 驗證:Jakarta Validation
5. 日誌:SLF4J + Log4j2
6. 安全:Spring Security + JWT

## 逆向工程規範
1. 分析 Legacy 程式碼時,必須識別並標註所有商業規則(使用 @BusinessRule 註解)
2. 所有 AI 產出必須包含「轉換決策說明」
3. 轉換後的程式碼必須修正原始碼中的安全漏洞
4. 使用 Mermaid 格式產出所有圖表
5. 目的碼必須包含 JavaDoc(繁體中文)

## 命名慣例
- Package:com.company.cms
- REST API 路徑:/api/v1/{resource}
- 資料庫表名:小寫底線(customers, customer_accounts)
- Entity 類名:PascalCase 單數(Customer, Account)

搭配 Agent Skills 使用

Agent Skills 讓你把「團隊認可的標準分析流程」寫成 Markdown,Copilot 判斷情境相關時會自動載入,不需每次重貼 Prompt。同一份技能可跨 VS Code、Copilot CLI、Cloud Agent 與 Copilot Code Review 使用——這代表分析階段與審查階段能套用同一套逆向工程標準。

⚠️ 路徑已變更:技能檔的正確位置是 .github/skills/<skill-name>/SKILL.md(每個技能一個子資料夾,檔名固定為大寫的 SKILL.md)。早期教材常見的 .github/copilot/skills/*.md 單檔寫法已不適用,照抄不會被載入。

<!-- .github/skills/analyze-legacy-code/SKILL.md -->
---
name: analyze-legacy-code
description: 分析 Legacy 程式碼並產出結構化報告。當使用者要求分析 VB6、Delphi、COBOL 或舊版 Java 程式碼時使用。
---

## 指令
當使用者要求分析 Legacy 程式碼時:
1. 先識別程式語言(VB6 / Delphi / C# / COBOL / 舊版 Java)
2. 掃描所有 Public 方法與全域變數
3. 識別商業規則(所有 if/switch 條件),逐條給 BR-xxx 編號
4. 列出資料庫操作(Table + CRUD 類型)
5. 識別安全風險(SQL Injection、硬編碼密碼等)
6. 產出 Mermaid 架構圖
7. 建議 Spring Boot 對應設計

## 限制
- 不得修改 legacy/ 目錄下的任何檔案,該目錄為唯讀參考
- 無法確定的邏輯必須標記為「待業務確認」,不得自行臆測

## 輸出格式
使用 Markdown,包含:模組摘要表、商業規則清單、安全風險清單、架構圖。

💡 撰寫要訣:description 是 Copilot 判斷「何時要載入這個技能」的唯一依據,務必寫清楚觸發情境(如上例的「當使用者要求分析 VB6、Delphi…」),而不是只寫技能名稱。技能還可以連同 MCP Server 一起打包成 Agent Plugin 配發給全團隊,見 9.10 節。


5.8 Agent Mode 專用 Prompt 設計

Agent Mode vs Chat Mode Prompt 的差異

面向Chat Mode PromptAgent Mode Prompt
粒度單一任務多步驟目標
指令風格具體步驟高階目標 + 約束條件
上下文手動提供Agent 自行探索
輸出方式在 Chat 視窗直接修改檔案
錯誤處理人工介入Agent 自動修正

Agent Mode Prompt 範例:全模組逆向分析

# Agent Mode — 全模組逆向分析

## 目標
對 legacy-cms/ 目錄中的 VB6 專案進行完整逆向分析,
所有結果寫入 docs/analysis/ 目錄。

## 約束條件
- 輸出格式:Markdown + Mermaid
- 語言:繁體中文
- 架構設計目標:Spring Boot 4.x + Clean Architecture
- 安全標準:OWASP Top 10 2025

## 預期產出
1. docs/analysis/module-inventory.md — 模組清冊
2. docs/analysis/business-rules.md — 商業規則清冊
3. docs/analysis/architecture.md — 系統架構圖
4. docs/analysis/erd.md — 資料庫 ERD
5. docs/analysis/security-audit.md — 安全風險報告
6. docs/analysis/migration-plan.md — 遷移計畫

請依序完成以上 6 個檔案。

Agent Mode Prompt 範例:自動化模組遷移

# Agent Mode — 模組自動遷移

## 目標
將 legacy-cms/Modules/modCustomer.bas 中的客戶管理功能,
遷移為 Spring Boot 4.x 的完整實作。

## 約束條件
- 遵循 Clean Architecture 四層架構
- 使用 Spring Data JPA(非原生 SQL)
- 所有商業規則標註 @BusinessRule
- 修正所有 SQL Injection 漏洞
- 包含 JavaDoc(繁體中文)
- 包含 JUnit 5 測試(覆蓋率目標 80%)

## 預期產出
在 src/main/java/com/company/cms/ 下建立:
1. domain/model/Customer.java
2. domain/rule/CustomerValidator.java
3. application/service/CustomerService.java
4. application/dto/CustomerRequest.java
5. application/dto/CustomerResponse.java
6. adapter/web/CustomerController.java
7. adapter/persistence/CustomerRepository.java
8. adapter/persistence/CustomerEntity.java

在 src/test/java/com/company/cms/ 下建立:
9. application/service/CustomerServiceTest.java
10. adapter/web/CustomerControllerTest.java

完成後執行 mvn compile 確認無編譯錯誤。

用 Custom Agents 建立逆向工程流水線

上述兩個 Prompt 有一個共同缺點:每次都要重寫一遍約束條件。當團隊有 5 個人、20 個模組要遷移時,Prompt 品質必然參差不齊。解法是把每個階段固化成一個 *.agent.md 專用代理,讓約束條件成為代理本身的一部分。

<!-- .github/agents/legacy-analyzer.agent.md -->
---
description: Legacy 程式碼分析代理。只讀不寫,負責抽取商業規則與安全風險。
tools: ['search', 'codebase', 'fetch']
model: Claude Opus 4.8
handoffs:
  - agent: vb-to-spring-converter
    prompt: 依據剛才產出的商業規則清冊,開始轉換此模組
---

你是資深 Legacy 系統分析師,專精 VB6 與 Delphi。

## 硬性規則
1. **絕對不得修改 legacy/ 目錄下的任何檔案**——該目錄是唯讀的事實來源
2. 每條商業規則都必須標註來源(檔名:行號),無來源者不得列入清冊
3. 無法確定的邏輯標記為「待業務確認」,嚴禁臆測補完
4. 所有產出寫入 docs/analysis/,使用繁體中文與 Mermaid 圖表

三個關鍵欄位對逆向工程的價值:

Frontmatter 欄位作用逆向工程價值
tools限定此代理可用的工具分析代理不給予編輯工具,從機制上杜絕「分析途中順手改壞舊系統」
model綁定特定模型分析階段用推理強的模型、轉換階段用程式碼模型,成本與品質同時最佳化
handoffs定義代理間的交接與預填 Prompt串起「分析 → 轉換 → 測試」流水線,每次交接都帶著標準化的指令

💡 實務建議:逆向工程流水線建議切成三個代理——分析代理(唯讀、抽規則)、轉換代理(可寫、產 Spring Boot 程式碼)、測試代理(產 Characterization Test 與比對腳本)。權責分離不只是流程講究,更是實質的防呆:分析代理沒有寫入權限,就不可能發生「AI 動到還在線上的舊系統」這種事故。


第 6 章 架構設計(企業級)

6.1 微服務 vs 單體架構決策

在逆向工程中,新系統的架構選擇是關鍵決策。以下提供決策框架:

flowchart TB
    A{系統規模} --> |"小型<br/>小於 10 萬行"| B[單體架構<br/>Monolith]
    A --> |"中型<br/>10-50 萬行"| C[模組化單體<br/>Modular Monolith]
    A --> |"大型<br/>大於 50 萬行"| D{團隊規模}
    D --> |"小於 5 人"| C
    D --> |"大於 5 人"| E[微服務<br/>Microservices]
    
    B --> F[Spring Boot<br/>單一部署]
    C --> G[Spring Boot<br/>模組化 + API Gateway]
    E --> H[Spring Cloud<br/>獨立服務]

架構選擇比較表

因素單體架構模組化單體微服務
複雜度⭐⭐⭐⭐⭐⭐⭐
部署簡單中等複雜
團隊協作易衝突模組分工獨立開發
效能高(同 Process)高網路開銷
擴展性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
維運成本低中等高
適合場景小型系統中型企業系統大型平台系統

💡 企業級建議:多數 Legacy 系統遷移建議先採「模組化單體」,穩定後再視需要拆分為微服務。避免一開始就微服務化導致複雜度過高。


6.2 分層架構設計

flowchart TB
    subgraph "分層架構(Clean Architecture)"
        direction TB
        
        subgraph "Adapter Layer(外部適配)"
            WEB["📱 Web Layer<br/>Controller / Filter"]
            PERSIST["💾 Persistence<br/>JPA Repository"]
            EXT["🔗 External<br/>REST Client / MQ"]
        end
        
        subgraph "Application Layer(應用邏輯)"
            UC["📋 Use Case<br/>Service / Command"]
            DTO["📦 DTO<br/>Request / Response"]
            PORT["🔌 Port<br/>Interface"]
        end
        
        subgraph "Domain Layer(領域核心)"
            ENT["🏛️ Entity<br/>Domain Model"]
            VO["💎 Value Object"]
            RULE["⚖️ Business Rule"]
        end
        
        subgraph "Infrastructure(基礎設施)"
            CFG["⚙️ Config"]
            SEC["🔒 Security"]
            LOG["📝 Logging"]
        end
    end
    
    WEB --> UC
    UC --> ENT
    UC --> PORT
    PORT --> PERSIST
    PORT --> EXT
    PERSIST --> CFG

各層職責定義

層職責包含元件允許依賴
Adapter處理外部通訊Controller, Repository Impl, ClientApplication
Application協調業務流程Service, DTO, Port InterfaceDomain
Domain核心商業邏輯Entity, VO, Business Rule無(最內圈)
Infrastructure技術實作Config, Security, DB ConfigApplication

實際範例:利息計算模組

// === Domain Layer: Business Rule ===
public class InterestCalculator {
    
    /**
     * 計算帳戶利息
     * @BusinessRule BR-001: 活期利率 1.25%
     * @BusinessRule BR-004: 餘額 < 1000 不計息
     */
    public Money calculateDailyInterest(Account account, InterestRate rate) {
        if (account.getBalance().isLessThan(Money.of(1000))) {
            return Money.ZERO;
        }
        
        BigDecimal dailyRate = rate.getAnnualRate()
                .divide(BigDecimal.valueOf(365), 10, RoundingMode.HALF_UP);
        
        return account.getBalance().multiply(dailyRate);
    }
}

// === Application Layer: Use Case ===
@Service
@RequiredArgsConstructor
@Transactional
public class CalculateInterestUseCase {
    
    private final AccountPort accountPort;
    private final InterestRatePort ratePort;
    private final InterestLogPort logPort;
    private final InterestCalculator calculator;
    
    public InterestResult execute(String accountNo, LocalDate calcDate) {
        Account account = accountPort.findByAccountNo(accountNo)
                .orElseThrow(() -> new AccountNotFoundException(accountNo));
        
        InterestRate rate = ratePort.findEffectiveRate(
                account.getAccountType(), calcDate);
        
        Money interest = calculator.calculateDailyInterest(account, rate);
        
        InterestLog log = InterestLog.create(account, calcDate, rate, interest);
        logPort.save(log);
        
        return InterestResult.of(account, interest);
    }
}

// === Adapter Layer: Controller ===
@RestController
@RequestMapping("/api/v1/interest")
@RequiredArgsConstructor
public class InterestController {
    
    private final CalculateInterestUseCase calculateInterest;
    
    @PostMapping("/calculate")
    public ResponseEntity<InterestResponse> calculate(
            @Valid @RequestBody InterestRequest request) {
        
        InterestResult result = calculateInterest.execute(
                request.getAccountNo(), request.getCalcDate());
        
        return ResponseEntity.ok(InterestMapper.INSTANCE.toResponse(result));
    }
}

6.3 資料庫遷移設計

遷移策略

flowchart LR
    subgraph "資料庫遷移策略"
        A["同構遷移<br/>(Same DB)"] --> A1["DB2 → DB2<br/>Oracle → Oracle"]
        B["異構遷移<br/>(Different DB)"] --> B1["DB2 → PostgreSQL<br/>Oracle → PostgreSQL"]
        C["漸進遷移<br/>(Parallel Run)"] --> C1["雙寫<br/>新舊 DB 同步"]
    end

DB Schema 遷移對照表

舊名稱(DB2/Oracle)新名稱(PostgreSQL)說明
CUSTOMERcustomers小寫 + 複數(JPA 慣例)
CUST_ID CHAR(8)id VARCHAR(8)主鍵命名簡化
CUST_NAME VARCHAR(50)name VARCHAR(50)欄位名簡化
STATUS CHAR(1)status VARCHAR(10)改用有意義的值

Flyway 資料遷移腳本範例

-- V001__create_customer_table.sql
CREATE TABLE customers (
    id          VARCHAR(8)   PRIMARY KEY,
    name        VARCHAR(50)  NOT NULL,
    phone       VARCHAR(20),
    address     VARCHAR(200),
    open_date   DATE         NOT NULL DEFAULT CURRENT_DATE,
    status      VARCHAR(10)  NOT NULL DEFAULT 'ACTIVE',
    created_at  TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at  TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_customers_name ON customers(name);
CREATE INDEX idx_customers_status ON customers(status);

COMMENT ON TABLE customers IS '客戶主檔';
COMMENT ON COLUMN customers.id IS '客戶編號(8位)';
COMMENT ON COLUMN customers.status IS '狀態:ACTIVE/INACTIVE/CLOSED';
-- V002__migrate_customer_data.sql
-- 從舊系統匯入資料
INSERT INTO customers (id, name, phone, address, open_date, status)
SELECT 
    CUST_ID,
    CUST_NAME,
    PHONE,
    ADDRESS,
    OPEN_DATE,
    CASE STATUS 
        WHEN 'A' THEN 'ACTIVE'
        WHEN 'I' THEN 'INACTIVE'
        WHEN 'C' THEN 'CLOSED'
        ELSE 'ACTIVE'
    END
FROM legacy_customer_import;

⚠️ 注意:資料遷移要特別注意:字元編碼(Big5 → UTF-8)、日期格式、數值精度、NULL 值處理。


6.4 中介軟體整合

企業級系統架構圖

flowchart TB
    subgraph "Frontend"
        UI[Web UI<br/>Vue / React]
    end
    
    subgraph "API Gateway"
        GW[Spring Cloud Gateway<br/>/ Kong]
    end
    
    subgraph "Backend Services"
        CS[Customer Service<br/>Spring Boot]
        AS[Account Service<br/>Spring Boot]
        TS[Transaction Service<br/>Spring Boot]
        RS[Report Service<br/>Spring Boot]
    end
    
    subgraph "Middleware"
        CACHE[Redis<br/>Cache]
        MQ[RabbitMQ<br/>/ Kafka]
        SEARCH[Elasticsearch<br/>全文搜尋]
    end
    
    subgraph "Database"
        DB1[(PostgreSQL<br/>主資料庫)]
        DB2[(Oracle<br/>舊系統 read-only)]
    end
    
    subgraph "Infrastructure"
        LOG[ELK Stack<br/>日誌]
        MON[Prometheus<br/>+ Grafana]
        SEC[Vault<br/>密鑰管理]
    end
    
    UI --> GW
    GW --> CS
    GW --> AS
    GW --> TS
    GW --> RS
    
    CS --> CACHE
    CS --> DB1
    TS --> MQ
    TS --> DB1
    RS --> SEARCH
    
    CS -.-> DB2
    AS -.-> DB2

中介軟體選型建議

元件推薦方案適用場景注意事項
API GatewaySpring Cloud Gateway統一入口、驗證、限流替代舊系統的直接 DB 連線
CacheRedisSession / 熱資料快取設定 TTL、避免 Cache Stampede
Message QueueRabbitMQ異步處理、事件通知交易類訊息需保證順序
SearchElasticsearch報表查詢加速取代舊系統的複雜 SQL JOIN
LoggingELK Stack集中式日誌取代舊系統的 File Log
MonitoringPrometheus + Grafana系統監控設定 Alert 閾值

💡 實務建議:不要在第一階段就引入所有中介軟體。建議按需導入:

  1. 第一階段:API Gateway + DB
  2. 第二階段:+ Cache + Logging
  3. 第三階段:+ MQ + Monitoring
  4. 第四階段:+ Search + 進階功能

第 7 章 風險與最佳實務

7.1 常見錯誤

在逆向工程專案中,以下是最常見的錯誤與對應預防措施:

flowchart TB
    subgraph "常見錯誤類型"
        E1["🔴 錯誤1<br/>過度信任 AI 產出"]
        E2["🔴 錯誤2<br/>跳過需求驗證"]
        E3["🔴 錯誤3<br/>一次性全面重寫"]
        E4["🔴 錯誤4<br/>忽略非功能需求"]
        E5["🔴 錯誤5<br/>低估資料遷移複雜度"]
    end
    
    subgraph "預防措施"
        P1["✅ 所有 AI 產出必須人工審查"]
        P2["✅ 每個需求必須與業務確認"]
        P3["✅ 採用漸進式遷移"]
        P4["✅ 同步定義 NFR"]
        P5["✅ 資料遷移獨立排程測試"]
    end
    
    E1 --> P1
    E2 --> P2
    E3 --> P3
    E4 --> P4
    E5 --> P5

錯誤一:過度信任 AI 產出

問題:盲目使用 Copilot 產出的程式碼,未經審查直接部署。

風險:

  • AI 可能「編造」不存在的 API 或方法
  • AI 可能忽略邊界條件
  • AI 可能產出有安全漏洞的程式碼
  • AI 可能誤解商業邏輯

預防:

✅ 建立 AI 產出審查流程:
1. AI 產出 → Code Review(至少 2 人)
2. 特別檢查:商業邏輯、安全性、效能
3. 執行自動化測試驗證
4. 與舊系統行為比對

錯誤二:Big Bang 全面重寫

問題:試圖一次性將整個舊系統重寫,而非漸進式遷移。

風險:

  • 專案時程失控
  • 新系統長期無法上線
  • 與舊系統行為不一致
  • 團隊士氣崩潰

預防:

  • 採用 Strangler Fig Pattern 漸進式替換
  • 每個 Sprint 交付一個可驗證的模組
  • 確保隨時可以 Rollback

錯誤三:忽略「隱藏功能」

問題:舊系統中存在未被文件記錄的功能(通常是多年來的 Hotfix 或特殊處理)。

案例:

## 真實案例:銀行帳務系統
舊系統中有一段「看似無用」的程式碼:

If custType = "VIP" And dayOfMonth = 25 Then
    balance = balance + (balance * 0.001)
End If

此段程式碼實際上是:每月 25 日為 VIP 客戶自動加計 0.1% 回饋金。
由於未記錄在任何文件中,逆向工程時差點被跳過。

教訓:所有看似無用的程式碼都需要調查確認。

7.2 逆向工程失敗案例分析

案例一:某銀行核心系統全面重寫失敗

timeline
    title 專案時程演變
    第1-3月 : 需求分析 : 順利進行
    第4-8月 : 開發階段 : 發現複雜度遠超預期
    第9-12月 : 測試階段 : 與舊系統行為大量不一致
    第13-18月 : 修修補補 : 無限迴圈
    第19月 : 專案重新評估 : 改為漸進式遷移

失敗原因分析:

原因詳細說明
低估複雜度舊系統 150 萬行 COBOL,商業規則超過 2000 條
人員不足僅 8 位 Java 工程師,無人懂 COBOL
未雙軌驗證直到測試才發現大量差異
未漸進交付18 個月才第一次與使用者見面

改善方案:

  1. 改採灰箱逆向 + Strangler Pattern
  2. 先遷移查詢類功能(風險低)
  3. 每 2 週交付一個可驗證的模組
  4. 建立自動化行為比對機制

案例二:忽略 Stored Procedure 遷移

問題:團隊只遷移了前端(VB→Java)和業務邏輯,但未處理大量 Stored Procedure。

後果:

  • 新系統仍依賴舊資料庫的 SP
  • 形成「技術債轉移」而非「技術債消除」
  • DB 升級受阻(SP 語法不相容)

教訓:

SP 遷移必須納入逆向工程範圍。使用 Copilot 可有效加速 SP→Java Service 的轉換。


7.3 資料遺失風險與對策

資料遷移風險矩陣

風險可能性影響對策
字元編碼錯誤高中遷移前統一確認 Big5 → UTF-8 轉換
數值精度遺失中高金額欄位使用 BigDecimal
日期格式不一致高中統一使用 ISO 8601
NULL 值處理差異中中定義 NULL 轉換規則
外鍵關係中斷低極高遷移前驗證 Referential Integrity
大量資料遷移超時中高分批遷移 + 增量同步

資料遷移安全方案

flowchart TB
    A[備份舊資料庫] --> B[建立遷移環境<br/>非 Production]
    B --> C[執行遷移腳本]
    C --> D[驗證資料筆數]
    D --> E{筆數一致?}
    E --> |否| F[排查遺失原因]
    E --> |是| G[驗證資料內容<br/>抽樣比對]
    G --> H{內容一致?}
    H --> |否| F
    H --> |是| I[驗證商業計算<br/>利息/餘額]
    I --> J{計算正確?}
    J --> |否| F
    J --> |是| K[✅ 遷移通過]
    F --> C

資料遷移 Checklist:

  • 遷移前完整備份舊資料庫
  • 確認字元編碼轉換規則
  • 確認數值精度(小數位數)
  • 確認日期格式轉換
  • 確認 NULL → Default Value 規則
  • 建立資料驗證腳本
  • 抽樣 1000 筆比對
  • 驗證彙總金額一致
  • 驗證 Referential Integrity
  • 測試環境演練至少 3 次

7.4 安全性考量

逆向工程中的安全重點

mindmap
  root((安全性<br/>考量))
    舊系統安全問題
      SQL Injection
      硬編碼密碼
      弱加密演算法
      無權限控管
    新系統安全要求
      OWASP Top 10 防護
      JWT Token Authentication
      輸入驗證
      資料加密
    遷移過程安全
      敏感資料保護
      連線資訊管理
      測試資料脫敏
      日誌不記錄敏感值

舊系統常見安全漏洞與修正

漏洞舊系統寫法(VB/C#)新系統修正(Java)
SQL Injectionsql = "..." & userInputJPA 參數化查詢
硬編碼密碼conn.Password = "P@ss123"Spring Vault / 環境變數
XSS直接輸出 HTMLSpring Security + CSP Header
CSRF無防護Spring Security CSRF Token
弱加密MD5 / SHA1BCrypt / Argon2
權限漏洞前端判斷權限Spring Security + RBAC

使用 Copilot 進行安全審查

# Prompt:安全性分析

請對以下程式碼進行安全性審查(參考 OWASP Top 10 2025):

[貼上程式碼]

請檢查並列出:
1. 所有 SQL Injection 風險點
2. XSS 風險點
3. 認證/授權漏洞
4. 敏感資料洩露風險
5. 加密方式是否安全
6. 輸入驗證是否完善
7. 嚴重程度評級(Critical / High / Medium / Low)
8. 修正建議(含程式碼)

⚠️ 重要:逆向工程是「修正舊系統安全債務」的最佳時機。不要將舊系統的安全漏洞「原封不動」搬到新系統。


7.5 AI 治理與企業合規

在企業級逆向工程中使用 AI 工具,必須建立完善的治理框架,確保合規性、可追溯性與品質控制。

AI 治理框架

flowchart TB
    subgraph "企業 AI 治理框架"
        A["📜 政策層<br/>AI 使用政策"] --> B["🔒 安全層<br/>資料保護與合規"]
        B --> C["⚙️ 流程層<br/>審查與品質控制"]
        C --> D["📊 監控層<br/>使用追蹤與稽核"]
    end
    
    A --> A1["定義 AI 可/不可處理的資料類型"]
    A --> A2["明確 AI 產出的審查流程"]
    B --> B1["敏感資料不得上傳至 AI 服務"]
    B --> B2["啟用 Copilot Content Exclusion"]
    C --> C1["AI 產出物必須經 Code Review"]
    C --> C2["關鍵商業邏輯需雙人確認"]
    D --> D1["追蹤 Copilot 使用率與接受率"]
    D --> D2["定期稽核 AI 產出品質"]

企業 AI 使用政策建議

政策項目說明範例
資料分級定義哪些資料可讓 AI 處理公開/內部資料可用;客戶個資、金鑰不可上傳
Content Exclusion設定 Copilot 排除特定敏感檔案.env、secrets/、**/credentials/**
審查層級AI 產出依風險分級審查低風險:1 人審查;高風險(金融計算):2+ 人
可追溯性記錄 AI 輔助的決策過程Git commit message 標註 AI 輔助、保留 Prompt 紀錄
授權管理Copilot 存取權限控制使用 GitHub Enterprise Policy 管理組織存取
智慧財產定義 AI 生成程式碼的 IP 歸屬依企業政策與 GitHub TOS 確認
模型選擇限定可使用的 AI 模型企業可透過政策管理限制特定模型;並須追蹤模型下架時程(見 附錄 C)
外掛來源管控限制 Agent Plugins 的可安裝來源以 managed-settings.json 的 strictKnownMarketplaces 鎖定僅允許企業內部市集
自動化閘門以 Agent Hooks 強制執行驗證代理每次改檔後自動編譯/弱掃,未過不得繼續(見 9.6 節)
對話資料保留確認 Chat 紀錄的保存期限與落地位置2026-09-28 起 Chat 資料保留由 28 天延長為帳號存續期間,金融業須重新評估

⚠️ 2026 年下半年的三項政策變更(金融業與受監理產業請特別留意):

  1. 席次預付:新的 Copilot Business/Enterprise 席次指派自 2026-09-01 起須先付款才能使用;既有客戶自 2026-10-01 起適用。方案單價不變,但採購與預算流程需提前調整。
  2. Copilot 體驗整併與資料保留期延長(不早於 2026-09-28):github.com、GitHub Mobile 與 Cloud Agent 的 Chat 整併為單一體驗,對話資料保留期由 28 天改為「帳號存續期間」,並改用單一政策。選擇退出(opt out)將失去這些平台上的 Copilot 存取權——換言之,「用但不留紀錄」不再是可選項,須改以 Content Exclusion 與資料分級從源頭控管。
  3. Code Review 預設審查強度調整(2026-09-28):預設由 Lite 改為 Balanced,成本隨之上升;若要維持 Lite,須在期限前於組織設定中手動選定。

對逆向工程專案的實質影響:舊系統的程式碼往往內嵌客戶個資樣本、正式環境連線字串與帳務公式。在資料保留期延長後,Content Exclusion 的設定必須在專案啟動時就完成,而不是等出事才補。

Copilot 企業管理功能

GitHub Copilot Enterprise / Business 提供以下管理能力:

# 企業級 Copilot 政策設定範例
copilot_policies:
  # 程式碼建議
  code_suggestions: enabled
  
  # 排除特定檔案(避免 AI 存取敏感資料)
  content_exclusion:
    - "**/.env*"
    - "**/secrets/**"
    - "**/config/credentials/**"
    - "**/sql/production/**"
  
  # Agent 功能控制
  agent_mode: enabled
  cloud_agent: enabled_with_approval  # 需管理者核准

  # 稽核日誌
  audit_logging: enabled

  # 使用量追蹤
  usage_metrics: enabled

Agent Plugins 的來源控管(企業實際設定於 managed-settings.json):

{
  "enabledPlugins": [
    "com.company.legacy-reverse-engineering"
  ],
  "extraKnownMarketplaces": [
    "https://plugins.internal.company.com"
  ],
  "strictKnownMarketplaces": true
}
設定作用為何逆向工程專案需要
enabledPlugins白名單,僅允許列出的外掛確保全團隊使用同一版分析技能,產出格式一致
extraKnownMarketplaces新增企業內部市集內含正式環境 DB 連線設定的 MCP,不應公開發布
strictKnownMarketplaces設為 true 時只允許已知市集阻擋工程師自行安裝未經審核的第三方外掛存取 Legacy 原始碼

⚠️ 供應鏈風險:Agent Plugin 會同時帶入「技能指令」與「MCP Server(可執行程式)」。一個未經審核的外掛等同於在開發機上執行未知程式碼,且該程式碼能存取你的 Legacy 原始碼與資料庫連線。這正是 OWASP Top 10:2025 新增分類 A03 Software Supply Chain Failures 所指的風險類型,應納入既有的第三方元件審核流程,而非視為「編輯器設定」。

AI 輔助開發的 Commit 規範

建議在 AI 輔助的程式碼提交中標註:

feat(customer): 新增客戶查詢 API — 從 VB6 modCustomer.bas 遷移

- 使用 Copilot Agent Mode 輔助轉換 SearchCustomer 函式
- 修正原始 SQL Injection 漏洞(SEC-001)
- 保留商業規則 BR-001~BR-005
- 新增 JUnit 5 測試(覆蓋率 85%)

AI-Assisted: GitHub Copilot (Agent Mode)
Reviewed-By: senior-dev@company.com
Legacy-Source: legacy-cms/Modules/modCustomer.bas

OWASP Top 10 2025 對照清單

OWASP Top 10:2025 已於 2026 年 1 月正式發布(2025 年 11 月 OWASP Global AppSec 大會公告),相較 2021 版新增 2 個分類、改名 2 個、SSRF 併入 Broken Access Control,且 Security Misconfiguration 由第 5 名躍升至第 2 名。在逆向工程中,應對照這份最新標準進行安全檢查:

OWASP 2025 風險逆向工程中的常見問題預防措施
A01: Broken Access Control舊系統缺乏 RBAC;SSRF(伺服器端請求偽造)已於 2025 版併入本類Spring Security + Method-level Security + 外部請求 URL 白名單
A02: Security Misconfiguration預設密碼、開放測試端口、除錯介面未關閉(2025 版排名由第 5 躍升第 2,需優先處理)Spring Security Auto-Configuration + 環境別設定檔隔離
A03: Software Supply Chain Failures舊系統相依套件來源不明、CI/CD 流程缺乏簽章驗證(2025 年新分類,擴展自舊版「易受攻擊與過時組件」)SBOM 產出 + Dependabot + 套件來源與簽章驗證(如 Sigstore)
A04: Cryptographic Failures舊系統使用 MD5/SHA1(2025 版排名由第 2 降至第 4)BCrypt / Argon2 + Spring Vault
A05: InjectionLegacy 字串拼接 SQL(2025 版排名由第 3 降至第 5)JPA 參數化查詢 + Input Validation
A06: Insecure Design缺乏威脅建模(2025 版排名由第 4 降至第 6)重建時進行 Threat Modeling
A07: Authentication Failures弱密碼策略、無 MFASpring Security + OAuth2/OIDC
A08: Software or Data Integrity Failures無簽章驗證、反序列化未過濾JWT + Digital Signature + 反序列化白名單
A09: Security Logging and Alerting Failures缺乏稽核日誌與異常告警機制(2025 版更名,強調告警能力)SLF4J + ELK + Audit Trail + 告警規則
A10: Mishandling of Exceptional Conditions舊系統例外處理不當、錯誤訊息外洩系統內部細節(2025 年新分類,聚焦例外處理與邏輯錯誤)統一例外處理(@ControllerAdvice)+ 錯誤訊息脫敏 + Fail-safe 預設值

資料來源:OWASP Top 10:2025。分類會隨官方版本持續調整,正式導入前請以官方頁面為準。


第 8 章 完整案例(實戰)

8.1 案例背景:VB6 客戶管理系統

系統概述

項目說明
系統名稱客戶資料管理系統(CMS)
開發語言VB6 + ADO + SQL Server 2008
開發年份2005 年
使用者銀行分行人員(約 500 人)
功能客戶 CRUD、帳戶管理、交易查詢、報表
程式碼行數約 35,000 行
資料庫50 張表、30 個 Stored Procedure
問題SQL Server 2008 EOS、VB6 Runtime 不安全、無法擴充

舊系統架構

flowchart TB
    subgraph "舊系統架構"
        UI["VB6 Form<br/>(胖客戶端)"]
        BL["VB6 Module<br/>(商業邏輯)"]
        DAL["ADO Connection<br/>(資料存取)"]
        DB["SQL Server 2008<br/>+ 30 SPs"]
    end
    
    UI --> BL
    BL --> DAL
    DAL --> DB

8.2 Copilot 分析過程

Step 1:匯入舊系統原始碼

專案結構:
legacy-cms/
├── Forms/
│   ├── frmMain.frm           # 主畫面
│   ├── frmLogin.frm          # 登入
│   ├── frmCustomer.frm       # 客戶管理
│   ├── frmCustSearch.frm     # 客戶查詢
│   ├── frmAccount.frm        # 帳戶管理
│   └── frmReport.frm         # 報表
├── Modules/
│   ├── modDB.bas             # 資料庫連線
│   ├── modCustomer.bas       # 客戶邏輯
│   ├── modAccount.bas        # 帳戶邏輯
│   ├── modAuth.bas           # 權限
│   └── modUtil.bas           # 工具
├── Classes/
│   └── clsLogger.cls         # 日誌
└── SQL/
    ├── sp_GetCustomer.sql
    ├── sp_SearchCustomer.sql
    ├── sp_CreateCustomer.sql
    └── sp_UpdateCustomer.sql

Step 2:使用 Copilot 分析關鍵模組

原始 VB6 程式碼:客戶查詢

' === frmCustSearch.frm ===
Private Sub cmdSearch_Click()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim sql As String
    
    ' 連線資料庫
    conn.Open "Provider=SQLOLEDB;Data Source=BANKDB01;" & _
              "Initial Catalog=CMS;User ID=sa;Password=Bank#2005;"
    
    ' 組合 SQL
    sql = "SELECT c.CUST_ID, c.CUST_NAME, c.PHONE, c.ID_NO, " & _
          "c.ADDRESS, c.OPEN_DATE, c.STATUS, " & _
          "(SELECT COUNT(*) FROM ACCOUNT WHERE CUST_ID = c.CUST_ID) AS ACCT_CNT " & _
          "FROM CUSTOMER c WHERE 1=1"
    
    If txtCustID.Text <> "" Then
        sql = sql & " AND c.CUST_ID = '" & txtCustID.Text & "'"
    End If
    
    If txtCustName.Text <> "" Then
        sql = sql & " AND c.CUST_NAME LIKE '%" & txtCustName.Text & "%'"
    End If
    
    If txtIDNo.Text <> "" Then
        sql = sql & " AND c.ID_NO = '" & txtIDNo.Text & "'"
    End If
    
    sql = sql & " AND c.STATUS <> 'D'"  ' 排除已刪除
    sql = sql & " ORDER BY c.CUST_NAME"
    
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' 填充列表
    lvResult.ListItems.Clear
    Do While Not rs.EOF
        Dim li As ListItem
        Set li = lvResult.ListItems.Add(, , rs("CUST_ID"))
        li.SubItems(1) = rs("CUST_NAME") & ""
        li.SubItems(2) = rs("PHONE") & ""
        li.SubItems(3) = rs("ID_NO") & ""
        li.SubItems(4) = rs("ACCT_CNT") & ""
        li.SubItems(5) = IIf(rs("STATUS") = "A", "有效", "停用")
        rs.MoveNext
    Loop
    
    rs.Close
    conn.Close
    
    lblCount.Caption = "共 " & lvResult.ListItems.Count & " 筆"
End Sub

Copilot Chat 分析:

@workspace 請分析以上 VB6 程式碼(frmCustSearch.frm 的 cmdSearch_Click),
並產出以下報告:

1. 功能描述
2. 商業規則
3. 安全漏洞
4. 效能問題
5. 建議的 Spring Boot API 設計

Copilot 分析結果:

## 分析報告:客戶查詢功能

### 1. 功能描述
多條件客戶搜尋功能,支援依客戶編號(精準)、姓名(模糊)、
身分證號(精準)查詢,排除已刪除客戶,並顯示各客戶帳戶數量。

### 2. 商業規則
- BR-001:查詢排除 STATUS = 'D'(已刪除)的客戶
- BR-002:客戶編號為精準查詢
- BR-003:姓名為模糊查詢(前後 LIKE)
- BR-004:身分證號為精準查詢
- BR-005:結果需顯示關聯帳戶數量

### 3. 安全漏洞 🔴
- SQL-001:嚴重 SQL Injection(字串直接拼接)
- SEC-001:資料庫密碼硬編碼(sa/Bank#2005)
- SEC-002:使用 sa 帳號連線(最高權限)
- SEC-003:身分證號等敏感資料未脫敏顯示

### 4. 效能問題
- PERF-001:子查詢 COUNT(*) 每次執行(N+1 問題)
- PERF-002:無分頁(大量資料時效能低落)
- PERF-003:每次查詢都建立新連線(無連線池)

### 5. 建議的 Spring Boot API 設計
GET /api/v1/customers?custId={}&name={}&idNo={}&page=0&size=20

Step 3:識別所有商業規則

使用 Copilot 掃描整個專案後,產出商業規則清單:

規則編號模組規則說明來源程式碼
BR-001客戶查詢排除 STATUS=‘D’ 的客戶frmCustSearch.frm:L28
BR-002客戶新增客戶編號必須 8 碼數字modCustomer.bas:L15
BR-003客戶新增身分證號不可重複sp_CreateCustomer.sql:L12
BR-004帳戶管理一個客戶最多 5 個帳戶modAccount.bas:L42
BR-005帳戶管理帳號格式:分行碼(3) + 科目(2) + 流水號(9)modAccount.bas:L58
BR-006利息計算活期利率每日更新sp_CalcInterest.sql:L20
BR-007利息計算餘額 < 1000 不計息sp_CalcInterest.sql:L35
BR-008權限刪除功能僅主管可用modAuth.bas:L22

8.3 新系統 Spring Boot 實作

轉換後的客戶查詢功能

Entity:

@Entity
@Table(name = "customers")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Customer {
    
    @Id
    @Column(name = "cust_id", length = 8)
    private String custId;
    
    @Column(name = "cust_name", length = 50, nullable = false)
    private String custName;
    
    @Column(length = 20)
    private String phone;
    
    @Column(name = "id_no", length = 10)
    private String idNo;
    
    @Column(length = 200)
    private String address;
    
    @Column(name = "open_date", nullable = false)
    private LocalDate openDate;
    
    @Enumerated(EnumType.STRING)
    @Column(length = 10, nullable = false)
    private CustomerStatus status = CustomerStatus.ACTIVE;
    
    @OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
    private List<Account> accounts = new ArrayList<>();
    
    // === 商業規則方法 ===
    
    /** @BusinessRule BR-002: 客戶編號必須8碼數字 */
    public static Customer create(String custId, String custName, String idNo) {
        if (!custId.matches("\\d{8}")) {
            throw new InvalidCustomerIdException(custId);
        }
        Customer customer = new Customer();
        customer.custId = custId;
        customer.custName = custName;
        customer.idNo = idNo;
        customer.openDate = LocalDate.now();
        return customer;
    }
    
    /** @BusinessRule BR-001: 不可查詢已刪除客戶 */
    public boolean isQueryable() {
        return this.status != CustomerStatus.DELETED;
    }
}

Repository:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, String>,
                                            JpaSpecificationExecutor<Customer> {
    
    /** @BusinessRule BR-003: 身分證號不可重複 */
    boolean existsByIdNo(String idNo);
    
    @Query("SELECT c FROM Customer c LEFT JOIN FETCH c.accounts " +
           "WHERE c.custId = :custId AND c.status <> 'DELETED'")
    Optional<Customer> findActiveById(@Param("custId") String custId);
}

Service:

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CustomerQueryService {
    
    private final CustomerRepository customerRepository;
    
    /**
     * 客戶多條件查詢
     * @BusinessRule BR-001: 排除已刪除客戶
     */
    public Page<CustomerSearchResponse> search(
            CustomerSearchRequest request, Pageable pageable) {
        
        Specification<Customer> spec = Specification.where(null);
        
        // BR-001:排除已刪除
        spec = spec.and((root, query, cb) -> 
            cb.notEqual(root.get("status"), CustomerStatus.DELETED));
        
        if (StringUtils.hasText(request.getCustId())) {
            spec = spec.and((root, query, cb) -> 
                cb.equal(root.get("custId"), request.getCustId()));
        }
        
        if (StringUtils.hasText(request.getName())) {
            spec = spec.and((root, query, cb) -> 
                cb.like(root.get("custName"), "%" + request.getName() + "%"));
        }
        
        if (StringUtils.hasText(request.getIdNo())) {
            spec = spec.and((root, query, cb) -> 
                cb.equal(root.get("idNo"), request.getIdNo()));
        }
        
        return customerRepository.findAll(spec, pageable)
                .map(this::toResponse);
    }
    
    private CustomerSearchResponse toResponse(Customer customer) {
        return CustomerSearchResponse.builder()
                .custId(customer.getCustId())
                .custName(customer.getCustName())
                .phone(customer.getPhone())
                .idNo(maskIdNo(customer.getIdNo()))  // 脫敏處理
                .accountCount(customer.getAccounts().size())
                .status(customer.getStatus().getDisplayName())
                .build();
    }
    
    /** 安全性:身分證號脫敏 */
    private String maskIdNo(String idNo) {
        if (idNo == null || idNo.length() < 4) return "****";
        return idNo.substring(0, 3) + "****" + idNo.substring(idNo.length() - 3);
    }
}

Controller:

@RestController
@RequestMapping("/api/v1/customers")
@RequiredArgsConstructor
@Tag(name = "客戶管理", description = "客戶資料查詢與管理 API")
public class CustomerController {
    
    private final CustomerQueryService customerQueryService;
    
    @GetMapping
    @Operation(summary = "客戶查詢", description = "支援多條件組合查詢")
    public ResponseEntity<Page<CustomerSearchResponse>> searchCustomers(
            @Valid CustomerSearchRequest request,
            @PageableDefault(size = 20, sort = "custName") Pageable pageable) {
        
        return ResponseEntity.ok(
            customerQueryService.search(request, pageable));
    }
}

DTO:

@Data
public class CustomerSearchRequest {
    
    @Size(max = 8, message = "客戶編號最多8碼")
    @Pattern(regexp = "^\\d*$", message = "客戶編號僅限數字")
    private String custId;
    
    @Size(max = 50, message = "姓名最多50字")
    private String name;
    
    @Size(max = 10, message = "身分證號最多10碼")
    private String idNo;
}

@Data
@Builder
public class CustomerSearchResponse {
    private String custId;
    private String custName;
    private String phone;
    private String idNo;     // 已脫敏
    private Integer accountCount;
    private String status;
}

新舊系統對照

項目舊系統(VB6)新系統(Spring Boot)
SQL Injection❌ 有風險✅ JPA 參數化
密碼管理❌ 硬編碼✅ 環境變數 / Vault
分頁❌ 無✅ Spring Data Pageable
敏感資料❌ 明文顯示✅ 脫敏處理
N+1 問題❌ 子查詢✅ JOIN FETCH
連線管理❌ 手動開關✅ HikariCP 連線池
API 標準❌ 無(直接 DB)✅ RESTful + OpenAPI

8.4 案例二:舊 Java Servlet 轉 Spring Boot

原始 Servlet 程式碼

// === CustomerServlet.java (Java 1.4 + Servlet 2.3) ===
public class CustomerServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        String action = req.getParameter("action");
        Connection conn = null;
        
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection(
                "jdbc:oracle:thin:@proddb:1521:ORCL", "app_user", "app_pass");
            
            if ("search".equals(action)) {
                String name = req.getParameter("name");
                String sql = "SELECT * FROM CUSTOMER WHERE CUST_NAME LIKE '%" 
                            + name + "%'";
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery(sql);
                
                ArrayList list = new ArrayList();
                while (rs.next()) {
                    HashMap map = new HashMap();
                    map.put("id", rs.getString("CUST_ID"));
                    map.put("name", rs.getString("CUST_NAME"));
                    map.put("phone", rs.getString("PHONE"));
                    list.add(map);
                }
                
                req.setAttribute("customers", list);
                req.getRequestDispatcher("/WEB-INF/customer.jsp").forward(req, resp);
                
            } else if ("delete".equals(action)) {
                String id = req.getParameter("id");
                String sql = "DELETE FROM CUSTOMER WHERE CUST_ID = '" + id + "'";
                Statement stmt = conn.createStatement();
                stmt.executeUpdate(sql);
                resp.sendRedirect("CustomerServlet?action=search");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServletException(e);
        } finally {
            try { if (conn != null) conn.close(); } catch (Exception e) {}
        }
    }
}

Copilot 分析與轉換

# Prompt

請將上述 Java Servlet 程式碼分析並轉換為 Spring Boot 4.x:

問題識別:
1. SQL Injection(字串拼接)
2. 硬編碼資料庫密碼
3. 物理刪除(應改邏輯刪除)
4. 無型別安全(Raw Type ArrayList/HashMap)
5. Exception 處理不當(直接 printStackTrace)
6. 無資源管理(Statement/ResultSet 未關閉)

轉換要求:
- 使用 Spring Data JPA
- 使用 @RestController(前後端分離)
- 使用 @Valid 驗證
- 刪除改為邏輯刪除
- 適當的例外處理(@ControllerAdvice)

轉換後的 Spring Boot 程式碼

// === CustomerController.java ===
@RestController
@RequestMapping("/api/v1/customers")
@RequiredArgsConstructor
public class CustomerController {
    
    private final CustomerService customerService;
    
    @GetMapping
    public ResponseEntity<Page<CustomerDto>> search(
            @RequestParam(required = false) String name,
            Pageable pageable) {
        return ResponseEntity.ok(customerService.search(name, pageable));
    }
    
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('MANAGER')")  // BR-008: 僅主管可刪除
    public ResponseEntity<Void> delete(@PathVariable String id) {
        customerService.softDelete(id);  // 邏輯刪除
        return ResponseEntity.noContent().build();
    }
}

// === CustomerService.java ===
@Service
@RequiredArgsConstructor
@Transactional
public class CustomerService {
    
    private static final Logger log = LoggerFactory.getLogger(CustomerService.class);
    private final CustomerRepository repository;
    
    @Transactional(readOnly = true)
    public Page<CustomerDto> search(String name, Pageable pageable) {
        if (StringUtils.hasText(name)) {
            return repository.findByNameContainingAndStatusNot(
                name, CustomerStatus.DELETED, pageable)
                .map(CustomerMapper.INSTANCE::toDto);
        }
        return repository.findByStatusNot(CustomerStatus.DELETED, pageable)
                .map(CustomerMapper.INSTANCE::toDto);
    }
    
    /** 邏輯刪除(取代物理刪除) */
    public void softDelete(String id) {
        Customer customer = repository.findById(id)
                .orElseThrow(() -> new CustomerNotFoundException(id));
        customer.markAsDeleted();
        repository.save(customer);
        log.info("客戶 {} 已被邏輯刪除", id);
    }
}

💡 實務建議:舊 JavaEE/Servlet 系統轉 Spring Boot 時,最常見的問題是:

  1. 直接 JDBC → 改用 JPA
  2. JSP 前端 → 改用 REST API(前後端分離)
  3. web.xml 設定 → 改用 Java Config
  4. 物理刪除 → 改用邏輯刪除
  5. 同步處理 → 大量作業考慮異步(@Async / MQ)

第 9 章 工具整合

9.1 VS Code 配置

必備 Extension

Extension用途說明
Java Extension PackJava 基礎開發語法、編譯、偵錯
Spring Boot Extension PackSpring Boot 開發專案建立、自動完成
GitHub CopilotAI 程式碼補全逆向工程核心工具
GitHub Copilot ChatAI 對話分析程式碼分析、文件生成
REST ClientAPI 測試替代 Postman
Mermaid Preview圖表預覽即時預覽架構圖
SonarLint程式碼品質即時安全掃描
GitLensGit 歷史追蹤程式碼變更歷史

💡 版本建議:VS Code 每月發布新版(撰稿時為 1.135,2026-08-26 發布),Copilot 的代理相關功能幾乎每個版本都有變動。逆向工程專案動輒數月至一年,建議團隊統一版本基準並每季檢視一次 官方更新日誌,避免手冊中的設定與實際介面脫節。

VS Code 設定建議

// .vscode/settings.json
{
    "java.configuration.runtimes": [
        {
            "name": "JavaSE-21",
            "path": "/path/to/jdk-21",
            "default": true
        }
    ],
    "java.compile.nullAnalysis.mode": "automatic",
    "editor.formatOnSave": true,
    "github.copilot.enable": {
        "*": true,
        "markdown": true,
        "plaintext": true,
        "sql": true
    },
    "github.copilot.chat.localeOverride": "zh-TW",
    "chat.useCustomizationsInParentRepositories": true,
    "chat.mcp.discovery.enabled": true
}
設定對逆向工程的作用
github.copilot.enable 開啟 markdown/sql/plaintext逆向工程的主要產出是文件與 SQL,預設關閉會少掉一半的輔助
github.copilot.chat.localeOverride: "zh-TW"讓分析報告與商業規則清冊直接輸出繁體中文,省去二次翻譯
chat.useCustomizationsInParentRepositories舊系統與新專案分屬子目錄時,仍能沿用上層 Repo 的客製化規範
chat.mcp.discovery.enabled自動探索其他應用程式(如 Claude Desktop)已設定的 MCP Server

⚠️ 注意:上表沒有列出任何「啟用 Agent Mode」的設定——因為現行版本不需要。既有專案的 settings.json 若殘留早期預覽階段的代理設定,可逕行移除,詳見 9.6 節。

逆向工程專案的成本可視化:VS Code 1.135 起,把滑鼠停在對話回應的頁尾,即可看到該輪的 輸入/快取輸入/輸出 token 明細(依模型分列)。建議在專案初期先跑 2–3 個代表性模組,記錄其 token 用量,再回推整案的 AI Credits 預算——這比事後看帳單準確得多,也是 附錄 D ROI 估算的實測依據。

工作區配置(多語言專案)

// .vscode/settings.json (Legacy + New 混合工作區)
{
    "files.associations": {
        "*.bas": "vb",
        "*.frm": "vb",
        "*.cls": "vb",
        "*.pas": "pascal",
        "*.dfm": "pascal"
    },
    "files.encoding": "utf8",
    "files.autoGuessEncoding": true
}

💡 實務建議:建議建立獨立的 VS Code 工作區(Workspace),分別放置舊系統程式碼與新系統專案,方便對照分析。


9.2 GitHub Copilot Chat

逆向工程專用命令

命令說明範例
@workspace分析整個工作區(傳統寫法,仍可用)@workspace 列出所有模組及其功能
#codebase搜尋並帶入工作區程式碼上下文(目前建議寫法)#codebase 列出所有模組及其功能
/explain解釋程式碼/explain 這段 SP 的商業邏輯是什麼
/fix修正問題/fix 修正此程式碼的 SQL Injection
/tests產生測試/tests 為此 Service 產生完整測試
/doc產生文件/doc 產生 JavaDoc
#file指定檔案#file:modCustomer.bas 分析此模組
#selection選取範圍#selection 將選取的程式碼轉為 Java
/btw開啟側邊對話,共用主對話的上下文與 prompt cache代理批次轉換時順手追問:/btw VB 的 IIf 對 NULL 的行為是什麼
/rubber-duck由互補模型提供第二意見(實驗性)/rubber-duck 檢查這份商業規則清冊是否有遺漏的分支

💡 @workspace vs #codebase:兩者目前都未被棄用,Copilot 也會在相關情境下自動索引工作區內容,不一定要顯式輸入。但官方建議日常使用逐步改用 #codebase——它更靈活、可與其他 # context variable(如 #file、#selection)併用,且能在 Agent Mode 等代理式工作流程中正常運作,而 @workspace 主要設計給傳統 Chat 模式。本手冊後續 Prompt 範例仍以 @workspace 為主(沿用既有寫法),實務上可依專案慣例替換為 #codebase。

Copilot Chat 最佳實務

1. 分段分析(Chunking)

大型 Legacy 程式碼不適合一次貼入 Copilot。建議:

Step 1:先讓 Copilot 分析檔案結構
> @workspace 列出此專案的所有檔案結構,按模組分類

Step 2:逐模組分析
> #file:modCustomer.bas 分析此模組的所有 Public 方法

Step 3:深入特定函式
> 分析 GetCustomerByID 函式的完整邏輯流程

Step 4:跨模組追蹤
> GetCustomerByID 呼叫了哪些其他模組的函式?

2. 上下文累積(Context Building)

第一輪:「分析 CUSTOMER 表的 Schema」
第二輪:「根據上述 Schema,分析 modCustomer.bas 如何操作此表」
第三輪:「根據以上分析,設計對應的 Spring Boot Entity + Repository」
第四輪:「根據以上設計,產出完整的 CRUD API」

3. 多對話並排與側邊提問

VS Code 1.135 支援把多個對話水平/垂直並排並保存版面,逆向工程可據此建立固定工作版面:

版面配置用途
左:Legacy 分析對話|右:新系統實作對話一邊查舊邏輯、一邊寫新程式碼,不必來回切換對話而丟失上下文
主對話:代理批次轉換|/btw 側邊:臨時提問不中斷代理當前工作的前提下釐清語法細節
對話全文搜尋(支援大小寫、全字、規則運算式)從數週前的長對話中找回「當初為什麼這樣轉換」的決策依據

💡 實務建議:逆向工程的對話動輒數百輪,重要結論不要只留在對話裡。對話搜尋是救急手段,正式做法仍是把確認過的商業規則寫入 docs/business-rules.md 並納入版控。


9.3 Copilot CLI

GitHub Copilot CLI 已於 2026-02-25 正式 GA(先前為 Preview),是獨立於 VS Code 的終端機原生 Agent,可在命令列中規劃任務、編輯檔案、執行測試並自我迭代,不同於舊版 gh copilot suggest(gh CLI 擴充套件的單次建議指令)。

安裝與啟動

# 需 Node.js 22 以上
npm install -g @github/copilot

# 啟動互動式 Session(首次需執行 /login 完成 GitHub 帳號驗證)
copilot

逆向工程情境下的實際用法

# 互動模式:啟動後直接以自然語言下達任務
copilot
> 分析 legacy-cms/ 目錄下所有 .bas 與 .frm 檔案,列出模組清單、
  Public 方法與存取的資料庫 Table,並將結果寫入 docs/cli-analysis.md

# 一次性腳本模式:適合寫進 CI/CD 或批次腳本,用 -p 傳入 Prompt
copilot -p "統計 legacy-cms/ 目錄下各語言的程式碼行數,並依模組分類輸出表格"

# Session 內常用斜線指令
/model              # 切換或查詢目前使用的模型
/context            # 檢視目前 Session 的 Token 用量與上下文組成
/plugin             # 瀏覽、安裝 Agent Plugins(市集、Repo 或本機路徑)

Copilot CLI 的關鍵能力(2026 現況)

CLI 自 2026-02-25 GA 後持續演進,2026-06-23 全新終端介面亦已 GA,定位從「終端助手」轉為完整的終端原生開發環境:

能力說明對逆向工程的價值
跨 Session 記憶可在新的 Session 中詢問先前分析過的檔案、PR、決策長期逆向工程專案的關鍵:可分次執行而不遺失上下文,是目前少數官方支援的跨對話延續機制(見 9.9 節)
分頁式介面Session 上方有分頁;在 GitHub Repo 內執行時另有 Issues 與 Pull requests 分頁分析、Issue 追蹤、PR 審查在同一個終端完成,不必切到瀏覽器
內建代理內建 Explore(快速掃描程式碼庫)與 Task(執行測試、建置等命令)等專用代理Explore 適合初期摸底盤點;Task 適合把 mvn verify 納入代理迭代迴圈
Agent Plugins以 /plugin 從市集、Repo 或本機路徑安裝,與 VS Code/Copilot App 共用同一套外掛同一份「逆向工程技能包」在編輯器與終端一致生效
MCP 支援支援 MCP 2026-07-28 規格直接在終端連上 DB/SonarQube MCP 做批次分析
原生 Rust runtime改以 Rust 實作,執行效能顯著提升大型 Legacy 專案的全域掃描等待時間縮短
100 萬 Token 上下文VS Code、CLI、Copilot App 皆已支援超長上下文一次性分析大型 Legacy 模組不必手動分段
跨平台macOS / Linux / Windows 皆可用,支援 npm / Homebrew / WinGet 安裝可整合進既有 CI/CD 或 Windows 開發機工作流程

💡 實務建議:Copilot CLI 適合搭配 Shell Script 做「批次、可重複執行」的分析工作(例如每個模組跑一次 copilot -p),VS Code 內的 Agent Mode(見 9.6 節)則更適合需要邊看程式碼邊互動調整的深度分析。指令與可用模型持續更新,請以 官方文件 為準。


9.4 SonarQube 整合

在逆向工程中使用 SonarQube

SonarQube 在逆向工程中有兩個關鍵用途:

  1. 分析舊系統程式碼品質:識別技術債與安全漏洞
  2. 確保新系統品質:設定 Quality Gate 確保產出品質

舊系統分析配置

# sonar-project.properties(舊系統 VB6 分析)
sonar.projectKey=legacy-cms
sonar.projectName=Legacy CMS Analysis
sonar.sources=.
sonar.language=vbnet
sonar.sourceEncoding=big5

新系統 Quality Gate

# SonarQube Quality Gate 設定
quality_gate:
  conditions:
    - metric: new_coverage
      operator: LT
      value: 80          # 新程式碼覆蓋率 >= 80%
    - metric: new_bugs
      operator: GT
      value: 0           # 不允許新 Bug
    - metric: new_vulnerabilities
      operator: GT
      value: 0           # 不允許新安全漏洞
    - metric: new_code_smells
      operator: GT
      value: 10          # 新 Code Smell <= 10
    - metric: new_duplicated_lines_density
      operator: GT
      value: 3           # 重複率 <= 3%

Maven 整合 SonarQube

<!-- pom.xml -->
<plugin>
    <groupId>org.sonarsource.scanner.maven</groupId>
    <artifactId>sonar-maven-plugin</artifactId>
    <version>4.0.0.4121</version>
</plugin>
# 執行掃描
mvn clean verify sonar:sonar \
  -Dsonar.host.url=http://sonarqube:9000 \
  -Dsonar.token=${SONAR_TOKEN}

9.5 Swagger / OpenAPI

自動產出 API 文件

使用 SpringDoc OpenAPI 為逆向工程後的新 API 自動產出文件:

<!-- pom.xml -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>
// OpenAPI 設定
@Configuration
public class OpenApiConfig {
    
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                .title("客戶管理系統 API")
                .description("由 Legacy VB6 系統逆向工程重建的 RESTful API")
                .version("1.0.0")
                .contact(new Contact()
                    .name("架構團隊")
                    .email("arch@company.com")))
            .addSecurityItem(new SecurityRequirement().addList("JWT"))
            .components(new Components()
                .addSecuritySchemes("JWT", new SecurityScheme()
                    .type(SecurityScheme.Type.HTTP)
                    .scheme("bearer")
                    .bearerFormat("JWT")));
    }
}

存取 Swagger UI:http://localhost:8080/swagger-ui.html

用途:

  • 作為新舊系統 API 對照文件
  • 供前端團隊開發使用
  • 供測試團隊驗證使用
  • 作為對外 API 合約

💡 實務建議:在逆向工程專案中,建議儘早產出 Swagger 文件,作為「新系統 API Contract」,讓前端、測試、業務團隊可同步進行。


9.6 Copilot Agent Mode 與 Cloud Agent

Agent Mode(本地代理)設定

在 VS Code 中使用 Agent Mode 進行逆向工程:

1. 選擇代理與基本設定

Agent 已是 VS Code 內建代理之一,不需要任何設定即可使用——在 Chat 的代理選單中選擇 Agent(或自訂的 *.agent.md 代理)即可。

⚠️ 已過時的設定:"chat.agent.enabled": true、"github.copilot.chat.agent.runInTerminal"、"github.copilot.chat.agent.fileEditing" 是早期預覽階段的設定,現行版本毋須設定;工具權限改由代理選單、*.agent.md 的 tools 欄位與終端命令的核准機制控制。

逆向工程專案真正該設定的是 9.1 節提到的那幾項(工作區客製化繼承、MCP 探索、輸出語系)。

2. 選擇適合的 AI 模型

Agent Mode 支援多供應商模型,建議按任務類型選擇:

任務類型建議模型(2026-09-01 現況)說明
程式碼分析 / 複雜推理Claude Opus 4.7/4.8/5、GPT-5.5抽取商業規則、追蹤跨模組呼叫鏈,深度優先,成本較高
程式碼生成 / 轉換GPT-5.4、GPT-5.3-Codex大量的 VB→Java 逐模組轉換,品質與成本平衡
快速問答 / 輕度任務GPT-5 mini、GPT-5.4 mini、Claude Haiku 4.5、MAI-Code-1-Flash語法查詢、格式整理,Credits 消耗低
大上下文 / 多模態Gemini 3.6 Flash長篇規格文件與截圖分析
自動選擇Auto(預設)系統依任務自動選擇,也是控制 AI Credits 成本的簡便做法

⚠️ 模型會下架,不要把模型名稱寫死在流程文件裡:2026-09-01 起 Gemini 3.1 Pro、Claude Opus 4.5/4.6、Claude Sonnet 4.5/4.6、Raptor Mini 已自 Copilot 移除(Sonnet 4.6 僅保留給年繳的個人方案訂閱者)。若團隊的 *.agent.md 或自動化腳本指定了這些型號,需改為上表的替代模型。完整淘汰/替代對照見 附錄 C。

💡 成本提醒:自 2026-06-01 起 Copilot 已全面改為 AI Credits(Token 用量計費),不同模型消耗的 Credits 差距可達 10-60 倍。日常問答建議優先使用輕量模型,複雜任務再切換高階模型;VS Code 1.135 起亦可在對話中逐輪切換模型,並檢視每輪 token 明細。詳見 附錄 D。

3. 搭配 Agent Hooks 自動化驗證(Preview)

Hooks 讓你在代理的生命週期事件上掛入自訂命令,把「驗證」從人工提醒變成機制上的硬性閘門——這對逆向工程尤其重要,因為 AI 轉換出來的程式碼看似正確但編譯不過、或悄悄改動了唯讀的 Legacy 目錄,都是常見狀況。

⚠️ 設定位置已變更:Hooks 不再寫在 settings.json(早期的 github.copilot.chat.agent.hooks 已不適用)。正確位置是 .github/hooks/*.json(工作區)、~/.copilot/hooks(使用者),或直接寫在 *.agent.md frontmatter 的 hooks 欄位;事件名稱為 PascalCase。此功能目前仍為 Preview,格式可能再調整。

// .github/hooks/reverse-engineering.json
{
  "hooks": {
    "PostToolUse": [
      {
        "type": "command",
        "command": "./scripts/verify-migration.sh",
        "timeout": 120
      }
    ],
    "Stop": [
      {
        "type": "command",
        "command": "mvn -q checkstyle:check",
        "timeout": 180
      }
    ]
  }
}

可用事件與逆向工程用法:

事件觸發時機逆向工程用法
SessionStart新 Session 的第一個 Prompt印出當前商業規則清冊摘要,讓代理帶著既有結論開工
UserPromptSubmit使用者送出 Prompt檢查 Prompt 是否夾帶正式環境連線字串等敏感字串
PreToolUse代理呼叫工具前守住唯讀邊界:偵測到寫入 legacy/ 的意圖即以非零結束碼阻擋
PostToolUse工具執行成功後每次改檔即 mvn compile -q,編譯失敗立刻回饋給代理自我修正
PreCompact上下文壓縮前把當前已抽取的商業規則落檔,避免壓縮時遺失
SubagentStart/SubagentStop子代理啟動/結束記錄流水線中各代理的接手時點,供稽核追溯
Stop代理 Session 結束跑完整驗證(Checkstyle、單元測試、弱掃)並輸出報告

💡 實務建議:Hooks 以 stdin/stdout 傳遞 JSON,並可用結束碼控制代理後續行為。逆向工程專案最值得優先導入的是 PreToolUse(保護舊系統原始碼唯讀)與 PostToolUse(編譯即時回饋)這兩個——前者防事故、後者省時間。

Cloud Agent(雲端代理)設定

Cloud Agent 在 GitHub 雲端環境獨立運行,適合分派單一遷移任務:

設定 Cloud Agent 的驗證工具:

# .github/copilot/config.yml
agent:
  validation:
    build_command: "mvn clean compile -q"
    test_command: "mvn test -q"
    lint_command: "mvn checkstyle:check -q"
  permissions:
    file_access: "src/**"
    terminal: true

使用情境:

  • 指派 GitHub Issue 給 @copilot,Agent 自動完成遷移並提交 PR
  • 適合「邊界清晰」的模組遷移任務
  • 2026 年起 Cloud Agent 已不再侷限於「PR 流程」:可先在分支上研究(Research)、規劃(Plan)、修改程式碼,反覆迭代後再開 PR,彈性更高(詳見 GitHub Changelog)

最新發展:統一的 Agents 體驗

VS Code 自 2025-11 起把原本的「Chat Modes」正式更名為「Agents」,內建代理為 Ask / Edit / Agent / Plan(部分版本另有 Research),自訂代理則以 *.agent.md 定義(見 5.8 節)。Agents 視窗於 2026-07 推出後持續改版,至 1.135 已調整為單一窗格側邊版面,session 資訊以互動式標籤(變更、PR、Issue、產出物)呈現於對話輸入區上方,並支援接續其他應用程式開啟的 agent session。

逆向工程專案常同時進行多模組分析與遷移,Agents 視窗的實際用法與版面配置建議見 4.7 節。


9.7 MCP Server 整合

什麼是 MCP(Model Context Protocol)

MCP 是一個開放標準協定,讓 Copilot Agent 能存取外部工具與資料來源,大幅擴充其在逆向工程中的能力。

flowchart LR
    subgraph "VS Code + Copilot"
        A[Agent Mode]
    end
    
    subgraph "MCP Servers"
        B["🗄️ Database MCP<br/>查詢 DB Schema"]
        C["🔍 SonarQube MCP<br/>程式碼品質分析"]
        D["🎨 Figma MCP<br/>UI 設計轉程式碼"]
        E["📁 File System MCP<br/>跨專案存取"]
        F["🌐 Web Fetch MCP<br/>技術文件查閱"]
    end
    
    A --> B
    A --> C
    A --> D
    A --> E
    A --> F

逆向工程常用 MCP Server 設定

⚠️ 設定檔位置已變更:MCP Server 不再設定於 settings.json 的 "mcp" 區段。現行做法是專用設定檔:工作區層級為 .vscode/mcp.json(應納入版控供團隊共用),使用者層級則以命令面板執行 MCP: Open User Configuration 開啟。設定檔具備 IntelliSense 自動完成。

// .vscode/mcp.json
{
  "inputs": [
    {
      "id": "legacy-db-url",
      "type": "promptString",
      "description": "Legacy 資料庫連線字串(唯讀帳號)",
      "password": true
    }
  ],
  "servers": {
    "database-analyzer": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@mcp/postgres-server"],
      "env": {
        "DATABASE_URL": "${input:legacy-db-url}"
      }
    },
    "sonarqube": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@mcp/sonarqube-server"],
      "env": {
        "SONAR_URL": "http://sonarqube:9000",
        "SONAR_TOKEN": "${env:SONAR_TOKEN}"
      }
    },
    "internal-api-catalog": {
      "type": "http",
      "url": "https://mcp.internal.company.com/catalog"
    }
  }
}

三個必須留意的重點:

重點說明
type 為必填本機程序用 stdio,遠端服務用 http
改用 inputs 而非硬編碼連線字串、Token 以 inputs 定義後用 ${input:id} 引用,VS Code 會在啟動時提示輸入。逆向工程專案的 mcp.json 必然要進版控,把正式環境連線字串直接寫進去等同於重蹈舊系統「硬編碼密碼」的覆轍(本手冊 7.4 節正在批評的那件事)
沙箱(macOS/Linux)可限制 MCP Server 的檔案系統與網路存取範圍,適合限制第三方 MCP 只能讀 legacy-cms/

安裝方式:除了手動編輯設定檔,也可在擴充功能檢視搜尋 @mcp 瀏覽 MCP 資源庫,選 Install 安裝到使用者設定檔,或右鍵選 Install in Workspace 只安裝到目前工作區。若要自動探索其他應用程式(如 Claude Desktop)已設定的 MCP Server,可啟用 chat.mcp.discovery.enabled。

MCP 在逆向工程中的實際應用

# Agent Mode + MCP Prompt

使用 database-analyzer MCP 連接舊系統資料庫,完成以下任務:

1. 列出所有 Table 與 View
2. 產出完整 ERD(Mermaid 格式)
3. 識別孤立表(無外鍵關聯)
4. 識別缺少索引的查詢欄位
5. 產出 Flyway 遷移腳本(DB2 → PostgreSQL)

同時使用 sonarqube MCP 掃描 Legacy 專案,產出安全風險報告。

9.8 Copilot Code Review

Agentic Code Review

2026 年 3 月起 Copilot Code Review 已升級為 Agentic 架構——AI 會主動用工具探索儲存庫、讀取關聯檔案、追蹤跨檔案相依關係,建立完整上下文後才產出審查意見,而非單純看 diff:

2026 年最新更新

更新項目內容上線時間
Effort Levels(審查深度)提供 Lite / Balanced 兩種審查強度,可依 PR 複雜度與風險調整審查深度與耗用成本2026-08-07 GA
嚴重度標籤每則評論標示 High / Medium / Low 嚴重度,方便排定處理優先順序2026 年中
Fix with Copilot原本的「Implement suggestion」按鈕已改名為 Fix with Copilot,可透過 Cloud Agent 一鍵套用審查建議2026-05
雙軌計費Code Review 同時消耗 AI Credits(Token 用量)與 GitHub Actions minutes2026-06-01 起
Agent Skills 與 MCP審查時可載入 Repo 的 SKILL.md 與 MCP Server,把團隊規範與外部系統上下文帶進審查2026-07-29 GA
解除 PR 大小上限原本 300 檔/20,000 行的限制取消,超大型 PR 亦可完整審查2026-08-27
Resolution Reasons結案時可標註 Addressed/Won’t fix/Incorrect2026-08-27
Bot/Cloud Agent PR 審查Cloud Agent 開出的 PR 可獲得完整 agentic 審查,不再降級2026-08-27
預設 Effort 改為 Balanced預設審查強度由 Lite 提升為 Balanced(欲維持 Lite 須於期限前手動設定)2026-09-28

⚠️ 計費提醒:導入 PR 自動 Code Review 前,建議在 GitHub Actions 用量指標中追蹤 copilot-pull-request-reviewer workflow 的耗用量,避免大量 PR 觸發時超出預期的 Actions 分鐘數與 AI Credits 額度。2026-09-28 起預設改為 Balanced 會直接推高成本,逆向工程專案 PR 數量龐大,請提前評估。

另須注意:Code Review 的 agentic 運作依賴 GitHub Actions runner。若 GitHub-hosted runner 不可用、自架 runner 又未正確設定,審查會降級為功能受限的模式——企業內網環境導入前務必確認 runner 供給。

這三項更新對逆向工程的具體意義:

更新為何逆向工程特別受益
解除 PR 大小上限模組遷移的 PR 天生就大(一次搬進 Entity/Repository/Service/Controller/DTO/測試共 10+ 檔)。過去超限只能硬拆 PR、破壞模組完整性,現在可整包送審
Agent Skills 與 MCP 進入審查可讓審查代理載入與分析階段同一份 SKILL.md,用同一套標準檢查商業規則是否保留;搭配 MCP 還能即時查詢 BR 清冊或 Issue 追蹤系統
Cloud Agent PR 完整審查由 Cloud Agent 自動遷移產出的 PR,現在能拿到完整 agentic 審查——形成「AI 遷移 → AI 審查 → 人工終審」的三段式把關

啟用自動審查:

⚠️ 常見誤解:坊間教材常見「用一個 github/copilot-code-review action 觸發審查」的 workflow 範例,實務上並非如此。自動審查是在 GitHub 平台設定中啟用的,不是靠自訂 action 呼叫。

正確做法有二:

  1. 儲存庫/組織設定:於儲存庫的 Settings → Code and automation → Rules → Rulesets 建立規則集啟用自動審查,可選擇在 PR 開啟時、草稿轉正式時,或每次推送時觸發。組織層級設定可一次套用到所有遷移專案的 Repo。
  2. .github/workflows/copilot-code-review.yml:此檔案的用途是設定審查代理的執行環境(預先安裝 JDK、Maven 等工具或指定作業系統),而非觸發審查本身。逆向工程專案若希望審查代理能實際執行 mvn verify 再給意見,就需要這個檔案。

逆向工程專用 Review 規則:

審查用的自訂指令沿用 5.7 節的客製化體系(copilot-instructions.md/*.instructions.md),並可搭配專用技能:

<!-- .github/instructions/migration-review.instructions.md -->
---
applyTo: "src/main/java/**"
---

## 逆向工程 Code Review 重點

請在審查遷移後的程式碼時,特別注意:
1. 所有商業規則是否完整保留(對照 docs/business-rules.md 的 BR-xxx 清冊)
2. SQL Injection 等安全漏洞是否已修正
3. 是否使用 JPA 參數化查詢(非字串拼接)
4. 是否包含適當的 Input Validation
5. 日誌是否避免記錄敏感資料(身分證號、帳號需脫敏)
6. 例外處理是否適當(不吞掉例外)
7. 是否有對應的單元測試與 Characterization Test
8. 遷移後的行為是否與舊系統一致;若刻意不同,PR 描述須說明原因

💡 實務建議:applyTo 讓這份審查規範只作用於新系統程式碼。逆向工程 Repo 通常同時放著唯讀的 legacy/ 目錄,用同一套規範去審舊程式碼只會產生大量無法處理的雜訊。


9.9 Copilot Spaces 與 Memory

Copilot Spaces — 組織逆向工程上下文

Copilot Spaces 讓你將分散的文件、程式碼、分析結果組織為統一的上下文空間,AI 在回答時會參考 Space 中的所有內容。Spaces 的 REST API 已於 2026-05-18 GA,可用程式化方式管理個人或組織的 Space。

建議的 Space 組織:

Space 名稱包含內容用途
Legacy-CMS-Analysis舊系統程式碼、DB Schema、分析報告分析階段參考
Migration-SpecsSRS、SDS、API 規格、ERD開發階段設計參考
Business-RulesBR 清冊、驗證條件、計算公式確保商業邏輯完整
Security-AuditOWASP 檢查結果、SonarQube 報告安全審查參考

在 VS Code 中存取 Space:透過 GitHub MCP Server(見 9.7 節)即可在 Agent Mode 對話中呼叫 list_copilot_spaces / get_copilot_space 工具,讀取指定 Space 內的內容作為上下文,不需離開編輯器切換到網頁版操作。

Copilot「記憶」機制 — 依介面而異,並非單一功能

重要澄清:目前官方並沒有一個統一、跨所有介面的「Copilot Memory」功能會自動記住整個 Repo 的分析歷史。實際上是依使用介面分散實作的幾種機制,範圍與持久性各不相同,使用前務必分清楚:

機制所在介面記住什麼是否跨 Session 保留
Plan 代理的當次計畫VS Code Plan 代理當次對話產出的實作計畫❌ 對話結束即清除,不會保留到下次開啟
Copilot CLI 跨 Session 記憶Copilot CLI先前處理過的檔案、PR、決策✅ 可在新 Session 中詢問過去的工作內容
對話全文搜尋VS Code Chat可搜尋歷史對話全文(支援規則運算式)⚠️ 對話仍在時可查,但屬「找得回來」而非「AI 記得」
Custom Instructions / AGENTS.md所有介面團隊編碼慣例、專案規範(非對話記憶,而是每次都重新載入的固定指令)✅ 以檔案形式存在 Repo 中,非「記憶」但效果類似
Copilot Spacesgithub.com、透過 GitHub MCP 於 IDE 存取人為整理的文件與程式碼集合✅ 以 Space 形式持久保存

💡 實務建議:逆向工程專案若需要「累積理解、跨多次對話延續」的效果,目前最務實的做法是:(1) 用 Copilot CLI 進行需要跨 Session 延續的長期分析工作;(2) 把已確認的商業規則、架構特徵寫入 Custom Instructions 或 Copilot Spaces,作為每次對話都會載入的固定上下文,而不是依賴「AI 自動記住」。這兩者是目前唯一有官方文件佐證、行為穩定的做法。

換句話說:在逆向工程中,「記憶」應該是你主動維護的檔案,不是你期待 AI 具備的能力。 一個 8 個月的遷移專案不可能靠對話上下文撐完;商業規則清冊、架構決策記錄(ADR)、遷移計畫都必須是版控中的檔案。

Copilot App 的 Customize 分頁

Copilot App 的 Customize 分頁已於 2026-08-25 GA,並帶入 MCP 支援,可直接在 App 中連結團隊既有工具。對逆向工程的意義是:專案的技能與 MCP 設定可在 VS Code、CLI、Copilot App 三處保持一致——搭配 9.10 節的 Agent Plugins,等於一次配發、三處生效。


9.10 Agent Plugins 1.0 打包逆向工程工具鏈

為什麼逆向工程需要 Agent Plugins

前面幾節分別介紹了 Agent Skills(標準分析流程)與 MCP Server(DB/SonarQube 存取)。實務上的痛點是:這兩者必須一起配發才有意義——只給技能卻沒有 DB MCP,代理就查不到 Schema;只給 MCP 卻沒有技能,每個人的分析格式又各行其是。過去要跨 VS Code、CLI、Copilot App 配發,還得為每個客戶端維護一份設定。

Agent Plugins 1.0(2026-08 發布)解決的正是這件事:它是由 AWS、Anysphere、Microsoft、OpenAI、Vercel、Google 共同維護的開放標準,獨立於任何單一供應商,把 Agent Skills 與 MCP Server 打包成單一可安裝的外掛,一次建置即可在所有相容的代理客戶端使用。

外掛結構

legacy-reverse-engineering/
├── plugin.json                          # 外掛資訊清單(含 $schema)
├── mcp.json                             # 隨外掛配發的 MCP Server 設定
├── skills/
│   ├── analyze-legacy-code/
│   │   └── SKILL.md                     # Legacy 分析標準流程
│   ├── extract-business-rules/
│   │   └── SKILL.md                     # 商業規則抽取與編號規範
│   └── vb-to-spring/
│       └── SKILL.md                     # VB6 → Spring Boot 轉換規則
└── com.github.copilot/                  # Copilot 專屬設定(選用)
// plugin.json
{
  "$schema": "https://agentplugins.org/schema/v1/plugin.json",
  "name": "legacy-reverse-engineering",
  "version": "1.0.0",
  "description": "VB6/Delphi Legacy 系統逆向工程分析與遷移工具組"
}

企業導入方式

步驟做法
1. 建置由架構團隊維護外掛 Repo,技能內容即團隊認可的分析規範
2. 發布發布至企業內部市集(見 7.5 節的 extraKnownMarketplaces)
3. 配發以 managed-settings.json 的 enabledPlugins 指定為必裝
4. 安裝開發者於 VS Code 安裝,或在 CLI 執行 /plugin;亦可從 Repo 或本機路徑安裝
5. 更新分析規範修訂時只需更新外掛版本,全團隊同步生效

💡 實務建議:逆向工程專案的分析品質差異,往往不在工程師的能力,而在每個人給 AI 的指令不一樣。把分析規範封裝成外掛統一配發,是目前最有效的一致性手段——這與過去用 Checkstyle 統一程式碼風格是同一個道理,只是對象換成了 AI 的行為。既有的 Copilot 外掛仍相容,不必強制遷移。


9.11 工具鏈時效性的自我查證

為什麼這一節有必要

本手冊在 2026-09-01 這個時點是正確的,但 Copilot 生態的變動速度是以週為單位:光是 2026 年 6 至 9 月就發生了計費模式改為 AI Credits、MCP 設定檔搬家、Agent Skills 路徑變更、Hooks 改為獨立檔案、Chat Modes 更名為 Agents、一批模型下架。逆向工程專案動輒 6–24 個月,專案中期時本手冊必然已有部分內容過時。

與其追求手冊永遠正確,不如讓讀者具備自我查證的能力。

官方查證來源與檢查頻率

來源內容建議頻率
VS Code 更新日誌每月版本的完整功能變更,Copilot 相關佔比極高每月
GitHub Changelog(copilot 標籤)功能上線、GA、預覽、下架公告每兩週
模型與定價頁現行模型清單與 Credits 費率每月,或收到下架公告時
VS Code Copilot 客製化文件指令檔、代理、技能、Hooks 的正確路徑與格式專案啟動時、每季
編輯器內的模型選單當下實際可用的模型(最權威)隨時

專案的季度複查清單

  • 對照官方文件確認 .vscode/mcp.json、.github/skills/、.github/hooks/、.github/agents/ 的路徑格式未變更
  • 檢查專案 *.agent.md 中指定的 model 是否仍在服務中(模型下架會使代理無法啟動)
  • 檢視 AI Credits 與 GitHub Actions 分鐘數的實際用量對比預算
  • 確認 Code Review 的 Effort Level 設定仍符合成本規劃
  • 檢查 Agent Plugins 與 MCP Server 是否有安全性更新
  • 更新專案內部文件中引用的功能名稱(例如 Chat Modes → Agents 這類更名)

⚠️ 給讀者的提醒:凡是本手冊中的具體路徑、設定鍵名、模型名稱與價格,都請以官方文件為準。 本手冊的價值在於方法論與逆向工程的判斷框架——那些不會過時;工具細節則是有保存期限的。本次改版的逐條佐證來源見 附錄 E。


第 10 章 結論

10.1 三種逆向策略比較表

比較維度🔲 黑箱逆向📄 白箱逆向🔀 灰箱逆向
原始碼需求不需要必需部分需要
分析精準度★★☆☆☆★★★★★★★★★☆
執行速度★★★★☆★★☆☆☆★★★☆☆
風險等級中低最低
業務衝擊可能停機可能停機不停機
適合規模小~中型中型大型
Copilot 效益★★★☆☆★★★★★★★★★☆
人力需求少(3-5 人)中(5-10 人)多(8-15 人)
典型工期1-3 個月3-12 個月6-24 個月
建議場景快速評估 / 無原始碼完整重建企業關鍵系統

10.2 推薦最佳實務

逆向工程成功關鍵

mindmap
  root((逆向工程<br/>成功關鍵))
    策略階段
      選擇正確的逆向策略
      與業務充分溝通
      建立可行性評估
    分析階段
      善用 Copilot AI 加速
      所有 AI 產出需人工審查
      建立完整的商業規則清冊
    開發階段
      漸進式遷移
      每個模組獨立驗證
      雙軌運行比對
    品質階段
      自動化測試覆蓋 80%+
      SonarQube Quality Gate
      安全弱掃通過
    團隊面
      跨職能團隊
      知識轉移
      持續學習

Top 10 最佳實務(Best Practices)

  1. 先評估再行動:啟動前完成可行性評估,選定正確策略
  2. AI 輔助但不取代:Copilot 是加速器,不是決策者
  3. 漸進式遷移:採用 Strangler Pattern,一次一個模組
  4. 雙軌驗證:新舊系統平行運行,確保行為一致
  5. 商業規則優先:先建立完整 BR 清冊,再開始開發
  6. 安全性提升:逆向工程是清除安全債務的最佳時機
  7. 自動化測試:Characterization Test → Unit Test → Integration Test
  8. 文件同步產出:不要等開發完才補文件,邊分析邊產出
  9. 版本控制:所有分析結果、文件、程式碼都要進 Git
  10. 知識轉移:建立 Wiki / 教學手冊,避免知識再次斷層

推薦的團隊組成

角色人數職責
架構師1技術決策、架構設計
Legacy 專家1-2舊系統分析、商業邏輯確認
Java 工程師3-5新系統開發
QA 工程師1-2測試、行為驗證
DBA1資料庫遷移、效能調校
BA / PM1需求確認、進度管理
DevOps1CI/CD、部署自動化

附錄 A:逆向工程檢查清單(Checklist)

📋 Phase 0:專案啟動

  • 確認專案範圍與目標
  • 取得舊系統程式碼 / 執行檔
  • 取得資料庫存取權限
  • 確認舊系統仍可運行
  • 組建專案團隊
  • 選定逆向工程策略(黑箱 / 白箱 / 灰箱)
  • 建立版本控制倉庫(Git)
  • 設定開發環境(VS Code + Copilot + JDK)

📋 Phase 1:分析

  • 完成系統功能盤點
  • 匯出資料庫 Schema(DDL)
  • 識別所有模組與入口點
  • 使用 Copilot 產出模組分析報告
  • 建立商業規則清冊(BR-xxx)
  • 產出系統架構圖
  • 產出 ERD
  • 識別安全漏洞清單
  • 與業務單位確認需求

📋 Phase 2:設計

  • 選定系統架構(單體 / 模組化 / 微服務)
  • 完成 Clean Architecture 分層設計
  • 設計 RESTful API(OpenAPI 規格)
  • 設計資料庫遷移方案
  • 定義 Quality Gate 標準
  • 建立 CI/CD Pipeline
  • 規劃模組遷移順序

📋 Phase 3:開發

  • 建立 Spring Boot 專案骨架
  • 使用 Copilot 逐模組轉換程式碼
  • 所有轉換程式碼經過 Code Review
  • 撰寫 Characterization Test
  • 撰寫單元測試(覆蓋率 >= 80%)
  • 撰寫整合測試
  • 通過 SonarQube Quality Gate
  • 通過安全弱掃

📋 Phase 4:驗證

  • 完成功能測試
  • 完成新舊系統行為比對
  • 完成效能測試
  • 完成安全測試(SAST / DAST)
  • 完成 UAT(使用者驗收測試)
  • 完成資料遷移測試(至少 3 次)
  • 制定 Rollback Plan

📋 Phase 5:上線

  • 完成 Production 環境準備
  • 完成資料遷移(Production)
  • 雙軌運行 2-4 週
  • 監控新系統效能與穩定性
  • 確認無異常後切換流量
  • 舊系統下線(保留 3-6 個月備查)
  • 知識轉移與文件歸檔

附錄 B:Prompt 快速參考卡

分析類

目的Prompt 開頭
模組分析分析此 [語言] 模組的功能、商業規則、資料存取…
架構分析根據以下檔案結構,分析並產出系統架構圖…
安全分析對此程式碼進行 OWASP Top 10 安全審查…
資料流分析追蹤此功能的完整資料流,從輸入到資料庫…
相依分析列出此模組的所有外部依賴與呼叫關係…

轉換類

目的Prompt 開頭
語言轉換將此 [源語言] 程式碼轉為 Java 21 + Spring Boot 4.x…
SP 轉 Java將此 Stored Procedure 轉為 Spring Data JPA + Service…
Form 轉 API分析此 UI Form 的功能,設計對應的 RESTful API…
批次轉換將此批次程式轉為 Spring Batch Job…

文件類

目的Prompt 開頭
產出 SRS根據分析結果,產出 IEEE 830 格式的需求規格書…
產出 ERD根據 DDL 產出 Mermaid ER Diagram 與資料字典…
產出 API 文件產出 OpenAPI 3.0 YAML 規格…
產出測試計畫為此模組產出完整測試計畫與測試案例…

測試類

目的Prompt 開頭
單元測試為此 Service 產出 JUnit 5 單元測試,覆蓋所有分支…
整合測試為此 Controller 產出整合測試,使用 MockMvc…
特徵測試產出 Characterization Test,記錄此功能的實際行為…
效能測試設計此 API 的 JMeter 效能測試腳本…

附錄 C:常用工具版本對照

工具建議版本說明
JDK21 LTS / 25 LTS21 為既有企業系統主流,25(2025-09 GA)為新專案建議 LTS
Spring Boot4.1.x(建議,最新 patch 4.1.1)/ 4.0.x(維護中)4.1.0 於 2026-06-10 發布;最低需求 Java 17,4.1 已支援至 Java 26。3.x 系列已於 2026-06-30 全面 EOL(最終 patch 3.5.16),既有 3.x 專案應規劃升級
Spring Framework7.0.x(對應 Spring Boot 4.x)/ 6.2.x(對應 Spring Boot 3.x,已進入維護期)新專案請直接採用 7.0.x(Spring Boot 4.1.0 對應 Spring Framework 7.0.8)
Maven3.9+ / 4.0+4.0 支援更好的模組化
Gradle8.x+替代 Maven 的選項
VS Code1.135(2026-08-26)或更新每月更新;代理相關功能變動頻繁,建議團隊統一版本基準
GitHub Copilot ExtensionLatest持續更新,含 Agent Mode、Agents 視窗、Agent Plugins
GitHub Copilot CLILatest終端原生代理;2026-02-25 GA、2026-06-23 新介面 GA
SonarQube10.x+ / 11.x企業版建議;Community Edition 免費
PostgreSQL16+ / 1717 為最新穩定版
Docker27+容器化
Docker Compose2.x多容器編排
Git2.47+版本控制
Node.js22 LTS 以上Copilot CLI 與多數 MCP Server 的執行環境
SpringDoc OpenAPI2.8+API 文件自動生成
Flyway10.x+資料庫遷移
MapStruct1.6+DTO 對應工具
Lombok1.18.x減少樣板程式碼
JUnit5.11+單元測試框架
Testcontainers1.20+整合測試容器化

AI 模型版本對照(2026 年 Q3 現況)

供應商代表模型(2026-09-01 現況)備註
OpenAIGPT-5 mini、GPT-5.3-Codex、GPT-5.4(+ mini)、GPT-5.5GPT-4.1、GPT-5.2 系列已下架
AnthropicClaude Haiku 4.5、Claude Sonnet 5、Claude Opus 4.7/4.8/5型號迭代速度快,建議以最新次版本為準
GoogleGemini 3.5/3.6 Flash2026-05 起已自 Copilot 網頁版 Chat 移除,IDE 端仍可用
MicrosoftMAI-Code-1-Flash輕量快速任務,取代已下架的 Raptor Mini
自動選擇Auto(預設)系統依任務自動選擇最佳模型,也是控管 AI Credits 成本的簡便做法

2026-09-01 模型下架與替代對照

以下模型自 2026-09-01 起已自 GitHub Copilot 移除。若團隊的 *.agent.md、自動化腳本或內部文件仍指定這些型號,必須改用替代模型,否則代理將無法啟動:

已下架模型建議替代
Gemini 3.1 ProGemini 3.6 Flash
Claude Opus 4.5Claude Opus 4.7/4.8/5
Claude Opus 4.6Claude Opus 4.7/4.8/5
Claude Sonnet 4.5Claude Sonnet 5
Claude Sonnet 4.6Claude Sonnet 5(例外:年繳制的個人訂閱者仍可繼續使用 Sonnet 4.6)
Raptor MiniMAI-Code-1-Flash

⚠️ 注意:AI 模型陣容每月變動、且會實際下架,自 2026-06-01 起所有模型互動皆以 AI Credits(Token 用量計費) 扣抵,各模型成本差距可達數十倍。導入前請查閱 GitHub Blog Changelog 與官方模型定價頁確認即時清單與費率。

給長期專案的建議:不要在流程文件與代理設定中寫死模型名稱。改以「任務類型 → 模型層級(推理型/程式碼型/輕量型)」的方式描述,實際型號集中維護在一處(例如本附錄或一份團隊設定檔),下架時只需改一個地方。查證方法見 9.11 節。


附錄 D:成本效益分析(ROI 評估)

逆向工程 ROI 計算框架

flowchart LR
    subgraph "成本 Cost"
        C1["人力成本<br/>工程師 × 工時"]
        C2["工具成本<br/>Copilot / SonarQube"]
        C3["培訓成本<br/>團隊技能提升"]
        C4["風險成本<br/>系統不穩定期間"]
    end
    
    subgraph "效益 Benefit"
        B1["維運成本降低<br/>年省 40-60%"]
        B2["開發效率提升<br/>新功能上線加速"]
        B3["安全合規<br/>避免罰鍰風險"]
        B4["技術債清除<br/>降低未來修改成本"]
    end

典型 ROI 估算

項目傳統方式(無 AI 輔助)AI 輔助(Copilot)節省比例
分析階段12 人月5 人月58%
文件產出6 人月2 人月67%
程式碼轉換24 人月14 人月42%
測試撰寫8 人月3 人月63%
總計50 人月24 人月52%

GitHub Copilot 授權成本

⚠️ 計費模式重大變更(2026-06-01 起生效):GitHub Copilot 已從「Premium Requests(固定次數)」全面改為「GitHub AI Credits(Token 用量計費)」。程式碼補全(Inline Suggestions)與 Next Edit Suggestions 不消耗 AI Credits、無限使用;Chat、Agent Mode、Code Review、Copilot CLI 才會依 Token 用量扣抵 AI Credits。以下月費為方案基本費,實際可用額度依模型選擇與用量而定,Business/Enterprise 採組織共池機制。詳細費率請查 官方定價頁。

方案月費/人適用包含功能
Copilot Free$0個人試用有限 AI Credits 額度 + 基礎補全
Copilot Pro$10個人開發者無限補全 + 基礎 AI Credits 額度
Copilot Pro+$39進階個人使用者更高 AI Credits 額度、可用進階模型與 Agent Mode
Copilot Max$100重度 AI 使用者(新增方案)最高個人 AI Credits 額度,適合大量 Agent Mode / Cloud Agent 任務
Copilot Business$19企業團隊組織級 AI Credits 共池、政策管理、稽核、Cloud Agent
Copilot Enterprise$39大型企業Business 全功能 + Copilot Spaces + 進階安全與治理

⚠️ 2026 年下半年的計費與政策異動(採購與預算規劃請留意):

  • 席次預付(Upfront Billing):新指派的 Copilot Business/Enterprise 席次自 2026-09-01 起須先完成付款,使用者才能取得存取權;既有客戶自 2026-10-01 起適用。每月依已指派席次數預先收費,用量超出內含額度時另計超額費用。方案單價不變,但採購流程需提前,臨時加人不再能立即開通。
  • Code Review 預設 Effort 改為 Balanced(2026-09-28):審查更深入,成本亦隨之提高。逆向工程專案 PR 數量大,若預算吃緊,須在期限前於組織設定手動維持 Lite。
  • Code Review 的雙軌成本:同時消耗 AI Credits 與 GitHub Actions 分鐘數,兩者都要納入預算,詳見 9.8 節。

成本估算的實務做法:與其套用通用估算,不如在專案初期實測——先以 2–3 個代表性模組跑完整流程(分析 → 轉換 → 測試 → 審查),利用 VS Code 1.135 的每輪 token 明細記錄實際用量,再依模組數量外推。逆向工程模組間的複雜度差異極大(查詢類模組與帳務結算模組可能差上一個數量級),實測基準遠比通用公式可靠。

💡 ROI 重點(簡化對比,非完整總體 ROI):以 10 人團隊、50 人月中型逆向工程專案為例,Copilot Enterprise 授權年費約 $4,680(10 人 × $39 × 12 月),相比節省的 26 人月人力成本(假設人月成本 $8,000,約 $208,000),單純「授權費 vs. 節省人力成本」比較下投資回報率超過 40 倍。請注意:此計算僅比較授權費與節省的人力成本,並未納入上方 ROI 框架圖列出的培訓成本、風險成本、AI Credits 超額費用與 Actions 分鐘數,也未計入完成 24 人月工作本身的人力薪資,因此不代表專案的完整總體 ROI,僅供快速評估授權投資的直觀參考。


附錄 E:參考資料與官方來源

本手冊 v3.0 的技術主張皆對照下列官方來源查證(查證時點:2026-09-01)。工具細節具時效性,引用前請先確認原文是否已更新,查證方法見 9.11 節。

VS Code 官方文件

主題連結
VS Code 更新日誌(每月版本)https://code.visualstudio.com/updates/
Copilot 客製化總覽(指令檔/代理/技能)https://code.visualstudio.com/docs/copilot/customization/overview
Custom Agents(*.agent.md)https://code.visualstudio.com/docs/copilot/customization/custom-agents
MCP Server 設定(.vscode/mcp.json)https://code.visualstudio.com/docs/copilot/customization/mcp-servers
Agent Hooks(Preview)https://code.visualstudio.com/docs/copilot/customization/hooks
VS Code 文件首頁https://code.visualstudio.com/docs

GitHub Copilot Changelog

日期主題連結
2026-08-31VS Code v1.132–1.135 的 Copilot 更新彙整https://github.blog/changelog/2026-08-31-github-copilot-in-vs-code-august-2026-releases/
2026-08-28Copilot 政策與計費異動(席次預付、體驗整併、Code Review 預設值)https://github.blog/changelog/2026-08-28-upcoming-changes-to-github-copilot-policies-and-billing/
2026-08-27Code Review:Resolution Reasons 與能力擴充https://github.blog/changelog/2026-08-27-copilot-code-review-resolution-reasons-and-expanded-capabilities/
2026-08-12Agent Plugins 1.0https://github.blog/changelog/2026-08-12-agent-plugins-1-0-in-vs-code-copilot-cli-and-the-copilot-app/
2026-07-312026 年 8 月模型淘汰預告(2026-09-01 生效)https://github.blog/changelog/2026-07-31-upcoming-august-2026-model-deprecations-in-github-copilot/
2026-07-29Code Review 的 Agent Skills 與 MCP 正式 GAhttps://github.blog/changelog/2026-07-29-copilot-code-review-agent-skills-and-mcp-now-generally-available/
2026-06-23Copilot CLI 新終端介面 GAhttps://github.blog/changelog/2026-06-23-copilot-cli-new-terminal-interface-is-generally-available/
2026-04-01Cloud Agent 支援 Research/Plan/Codehttps://github.blog/changelog/2026-04-01-research-plan-and-code-with-copilot-cloud-agent/
2026-02-25Copilot CLI 正式 GAhttps://github.blog/changelog/2026-02-25-github-copilot-cli-is-now-generally-available/
—Changelog(copilot 標籤總覽)https://github.blog/changelog/label/copilot/

GitHub Docs 與其他

主題連結
Copilot 模型與定價https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing
設定 Copilot 自動 Code Reviewhttps://docs.github.com/en/copilot/how-tos/copilot-on-github/set-up-copilot/configure-automatic-review
Copilot CLI 使用說明https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/overview
AGENTS.md 開放標準https://agents.md/
Spring Boot 4.1.0 發布公告(2026-06-10)https://spring.io/blog/2026/06/10/spring-boot-4/
OWASP Top 10:2025https://owasp.org/Top10/2025/

文件維護與版本紀錄

更新時機

📝 文件維護說明

本手冊應隨以下事件更新:

  • GitHub Copilot 重大版本更新(新模型、模型下架、Agent 功能變更、設定路徑變更)
  • VS Code 每月版本中影響代理工作流程的變更
  • GitHub Copilot 計費模式或企業政策異動
  • Spring Boot 新版發布與 EOL 時程
  • OWASP Top 10 更新版
  • 團隊實務經驗累積
  • 新的逆向工程工具、MCP Server 或 Agent Plugin 出現

建議每季度審視一次,具體查證方法與檢查清單見 9.11 節。最新版本請查看 Git 歷史紀錄。

版本紀錄

版本日期主要變更
3.02026-09-01目錄擴充至三層(H2/H3/H4)並全面可跳轉;修正 MCP、Agent Skills、Agent Hooks 三處已變更的設定路徑;移除不存在的 Code Review workflow 範例並改為官方啟用方式;更新 2026-09-01 生效的模型下架清單與 2026-09/10 計費政策;新增 9.10 Agent Plugins 1.0、9.11 工具鏈時效性查證、附錄 E 參考來源;補充 Custom Agents 流水線、Agents 視窗、Copilot CLI 最新能力
2.12026-08-26補充 Agent Mode/Cloud Agent、OWASP Top 10:2025 對照、AI 治理章節

© 2026 企業架構團隊 — GitHub Copilot 逆向工程教學手冊 v3.0