iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
ChatGPT & Codex

AI 救得了祖傳系統嗎?30 天實戰企業 Legacy System × AI 協作開發系列 第 5

Day 5|畫面有值不代表資料正確:讓 AI 幫我們追出祖傳系統的資料流

  • 分享至 

  • xImage
  •  

前言/情境導入

前一篇,我們從按鈕開始追查事件流程。但找到事件之後,還有另一個問題更容易讓人誤判:

畫面明明有值,資料就真的正確嗎?

前幾天整理這套祖傳系統時,我們先學會把需求與程式片段整理成 AI 看得懂的 Context,接著又從按鈕一路追到背後的事件。這次,維護旅程繼續往資料層深入。

使用者勾選畫面上的選項,DBGrid 立刻顯示新狀態,按下儲存也出現「儲存完成」。可是重新進入畫面後,勾選卻消失了。

如果直接問 AI:

DBCheckBox 明明有勾選,
為什麼資料沒有存進資料庫?

它通常會很快叫我們檢查 DataFieldPostApplyUpdates。這些答案都合理,問題是:合理不等於適用於眼前這套系統。

Legacy System 的儲存動作可能藏在共用父類別、AP、Provider 或另一個 Dataset 裡。看到 Post 就直接補 ApplyUpdates,可能不是修好問題,而是多送一次更新。

所以這次我不讓 AI 直接猜答案。我要它先幫我把散落在 .pas.dfm 的線索接起來,畫出資料從畫面到後端的路徑。

Delphi 只是今天的案例。真正要練習的,是工程師如何限制 AI 的推論範圍,讓它成為 Legacy Code 的閱讀助手,而不是自信滿滿的改碼機器。


核心技術解析

一、第一輪:只給現象,不預設原因

過去我常把程式碼丟給 AI,再說「幫我找出問題並修改」。這等於要求它同時猜原始設計、判斷根因並提出修改。只要第一步猜錯,後面寫得再完整也沒有用。

第一輪,我只提供可重現的事實:

這是 Delphi 2009 的資料感知表單。

重現步驟:
1. 在 DBGrid 選取資料。
2. 勾選 DBCheckBox。
3. 按下儲存,畫面顯示成功。
4. 重新進入後,勾選恢復原值。

目前已知:
- 畫面會立即改變。
- 儲存時沒有例外。
- 重新查詢後資料恢復原值。

請先不要修改程式。
請列出還需要哪些 Context,才能判斷資料停在哪一層。

這裡刻意不說「一定漏了 ApplyUpdates」,也不把「畫面有勾選」寫成「資料已存入」。我要 AI 先承認資訊缺口,而不是用通用知識補滿空白。

二、第二輪:交叉比對 .pas.dfm

AI 回覆需要元件繫結與儲存事件後,我才提供最小片段。

// .dfm:畫面綁定
object ActiveCheckBox: TDBCheckBox
  DataSource = AccountSource
  DataField = 'IS_ACTIVE'
end

object AccountSource: TDataSource
  DataSet = AccountData
end
// .pas:儲存事件
procedure TAccountForm.SaveButtonClick(Sender: TObject);
begin
  if AccountData.State in [dsEdit, dsInsert] then
    AccountData.Post;

  ShowMessage('儲存完成!');
end;

如果沒有接觸過 Delphi,可以先把這兩個檔案理解成不同的證人:

  • .dfm 告訴我們「畫面上的元件綁到哪個資料來源」。
  • .pas 告訴我們「使用者操作後,程式實際執行哪些事件」。

在這個片段裡,.dfm 證明勾選框會把值交給 AccountData.pas 則只證明按下儲存後執行了 Post。它們都沒有單獨證明資料已經送到遠端 AP 或寫進資料庫。

這正是 AI 容易太快下結論的地方:看到 Post 就以為大功告成,卻還沒確認 ClientDataSet 後面是否存在 ApplyUpdates、共用儲存函式或其他遠端更新流程。

以前我可能在數千行 .dfm 裡反覆搜尋,再切回上萬行 .pas 對名稱。這種機械式比對正適合交給 AI,但任務必須縮小:

請交叉比對兩段內容:

1. 列出 DBCheckBox → DataSource → Dataset → 欄位。
2. 列出儲存事件中的資料操作順序。
3. 只根據已提供內容分析,不假設未提供的函式。
4. 分成「已確認」與「仍需人工驗證」。
5. 不要產生修正版程式碼。

如果沒有後面三項,AI 很容易從「看見 Post」直接跳到「缺少 ApplyUpdates」。但目前只能證明這個事件有 Post,不能證明整套系統沒有共用更新流程。

三、讓 AI 輸出資料流,而不是答案

我期待 AI 回傳的是:

已確認

  • ActiveCheckBox 綁定 AccountSource
  • AccountSource 指向 AccountData
  • 勾選值對應 IS_ACTIVE
  • 儲存事件會執行 Post
  • 成功訊息在 Post 後顯示。

仍需驗證

  • AccountData 是否為 ClientDataSet
  • 後端查詢是否包含 IS_ACTIVE
  • Post 後是否另有共用更新流程。
  • AP 或 Provider 是否收到更新。
  • 顯示成功時,後端是否真的完成儲存。

AI 還沒有找出唯一答案,卻已把兩個檔案的線索整理成待查清單。

AI 負責縮小範圍
工程師負責證明結論

這比直接產生修正版更有價值。因為 Legacy System 最麻煩的通常不是語法,而是眼前十行程式和其他 Unit、Dataset、AP 之間到底有什麼關係。

四、第三輪:把執行證據回餵 AI

接著才由工程師實際觀察 StateChangeCount、共用函式與後端結果。

假設得到:

- 勾選後 State = dsEdit
- Post 後 State = dsBrowse
- Post 後 ChangeCount = 1
- 目前呼叫鏈找不到 ApplyUpdates
- 重新查詢後 IS_ACTIVE 仍為 N

我會把結果回餵 AI:

請根據新的執行證據更新判斷:

1. 哪些假設可以排除?
2. 最可能中斷在哪一層?
3. 修改前還要確認哪些共用流程?
4. 只提出最小修改位置,不要重寫表單。

這時 AI 才有足夠證據逐步收斂,而不是看到 DBCheckBox 就背誦 Delphi 標準答案。

五、找不到,不等於不存在

AI 不會因為檔案很長而眼睛疲勞,但仍可能漏掉動態指定的 DataSource、父類別事件、其他 Unit、AP 端 SQL,以及 Trigger、Transaction 或 Lock。

因此,我會補上一條限制:

如果目前檔案無法證明,請標示為「尚未找到」,
不要改寫成「系統不存在」。

在 Legacy System 裡,沒有看到通常只代表還沒挖到那一層。老系統最不缺的,就是地下室。


程式碼實作:建立可重複使用的 AI 問題包

這篇的實作不是寫修正版,而是整理一份可重複使用的協作格式:

【實際現象】
- 使用者做了什麼?
- 畫面立即出現什麼?
- 重新查詢後變成什麼?

【已知事實】
- 哪些結果已重現?
- 哪些狀態已用除錯器確認?
- 後端是否真的收到請求?

【相關 Context】
- .dfm 的元件片段
- .pas 的事件與直接呼叫函式
- Dataset、DataSource 與欄位用途
- 共用儲存、Transaction、Lock 的範圍

【限制 AI】
- 先建立資料流,不要直接改程式
- 區分已確認事實與待驗證假設
- 找不到時寫「尚未找到」
- 只列出下一步需要的證據

【第二輪回餵】
- Breakpoint 觀察結果
- Dataset State/ChangeCount
- 後端或 SQL 查詢結果
- 實際呼叫到的共用函式

整個協作流程可以濃縮為:

flowchart TD
    A[描述現象] --> B[提供最小 Context]
    B --> C[要求 AI 建立資料流]
    C --> D[區分事實與假設]
    D --> E[人工執行驗證]
    E --> F[回餵新證據]
    F --> G[最後才討論修改]

這張圖最重要的不是箭頭有多漂亮,而是「人工驗證」位在 AI 建立資料流之後、討論修改之前。少了這一步,AI 的合理推測很容易被誤當成已經證實的根因。


今日小結

今天雖然用到 DBGridDBCheckBoxClientDataSet,重點卻不是教 Delphi 元件。

真正重要的是:面對畫面、程式與資料庫結果不一致時,不要直接把問題交給 AI 猜,也不要因為它很快產生一段合理的程式,就以為根因已經找到。

這次採用的協作方式是:

  1. 提供可重現的現象,不替問題預設答案。
  2. 分批提供 .pas.dfm,讓 AI 跨檔案對照。
  3. 要求 AI 輸出資料流,不急著輸出修正版。
  4. 強制區分「已確認」與「仍需驗證」。
  5. 由工程師取得執行證據,再回餵 AI 收斂範圍。

AI 最適合做的,不是替我們一槍打中 Legacy System 的答案,而是把散落、混亂又難讀的線索,整理成一條可以逐步驗證的路。

如果沒有 Context,也沒有約束推論方式,AI 只能拿通用知識補空白。最後就可能得到一份「每一句都合理,合起來卻不是這套系統」的答案。

所以,與 AI 協作維護 Legacy System 的關鍵,是讓它知道:

哪些是事實、哪些只是推測、下一步要用什麼證據證明。

至於案例最後是否真的缺少 ApplyUpdates,反而不是今天最重要的答案。只要資料流還沒被證明,就不應該急著把一行看似正確的程式塞進舊系統。

下一篇,我們會把今天的流程直接帶進下一個維護現場:從畫面上一個「內部預算」選項開始,不先相信元件名稱,也不先猜資料表,而是把畫面設定、事件、Dataset 與 AP 交給 AI 建立第一版資料流。

接著再用實際查詢結果逐層驗證,看看這個看似普通的選項,最後究竟把資料帶往哪裡。今天學的是如何追一個「沒有存進去的值」;下一篇,則要追一個「到底從哪裡來的值」。


上一篇
Day 4|從按鈕開始追:如何還原 Delphi 表單的事件流程
系列文
AI 救得了祖傳系統嗎?30 天實戰企業 Legacy System × AI 協作開發5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言