iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
Claude AI

從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄系列 第 22

Day 22 — 為什麼我在對話裡下的指令,下一輪就被覆蓋了?

  • 分享至 

  • xImage
  •  

系列:從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄


起因是一個顏色

Phase 2 做完 JSON Import 功能之後,我覺得那個「匯入」按鈕的顏色不夠明顯。

匯入是一個會覆蓋現有內容的操作。我希望它看起來就跟旁邊那個「匯出」不一樣,讓人按下去之前會停一秒。

所以我跟 GSD 說:把匯入按鈕的顏色改掉。

它改了。回報完成。

我打開來看,看不出任何差別。


這篇文章的重點是 Claude 錯了兩次

接下來的排查過程,我要完整寫出來,因為它比結論有意思。

我把畫面貼給 Claude,說按鈕顏色沒變。

Claude 的第一次診斷:指錯了元素

Claude 分析了 Data Export 頁籤,指出有三個元素的樣式不一致:

  1. 頁腳的提示文字
  2. 動作按鈕
  3. Modal 標題

它列了三個候選,分析得有條有理。

但沒有一個是我要問的東西。

我要的就是那個「匯入」按鈕,不是頁腳、不是標題。

這裡我學到一件事:我最初的描述不夠精確。 我說「按鈕顏色沒變」,但那個頁面上有好幾個按鈕。Claude 在資訊不足的情況下,選擇列出所有可能——這正好是我在 Day 02 和 Day 13 批評過的行為模式。

(回頭看很好笑:我花了三天論證「不要列舉所有可能性」,然後自己給了一個模糊的問題,換來一份三項清單。)

我澄清了:我說的是 Import 按鈕。

Claude 的第二次診斷:找對了元素,但這才發現問題更深

Claude 去看了 GSD 實際的改動,然後說:

GSD 把按鈕改成了 ghost / outline 樣式——透明背景加一圈 border。

而問題是:那個按鈕原本就長得差不多是那樣。所以「改了」和「沒改」在視覺上幾乎沒有差別。

GSD 沒有偷懶,它真的改了。改完的結果就是看不出來。

到這裡我們知道「改了什麼」,但還不知道「為什麼它會這樣改」。

而這一步,是我提供了關鍵素材才解開的。


我把 Phase 2 的完整規劃文件貼上去

因為 GSD 的設定裡,我把 commit planning docs 開成 Yes(Day 21 那張表的第三行)。

所以每一個 Phase 都有完整的規劃文件躺在 repo 裡。

我把 Phase 2 的規劃文件整份貼給 Claude。

然後真正的原因出現了。


真因:正典規格檔

02-CONTEXT.md 這份規格文件裡,有一條編號 D-03 的設計決策,內容明確寫著:

匯入按鈕使用 secondary / muted style(次要 / 低調樣式)

那是我自己在 Phase 2 規劃階段定下的。當時的想法大概是「匯入是次要功能,不要搶主要動作的視覺焦點」。

而關鍵在於 GSD 的運作方式:

GSD 在每一個執行週期開始前,都會重新讀取正典規格檔。

所以事情的順序是這樣:

規格檔 D-03:匯入按鈕 = 次要/低調樣式
        ↓
我在對話裡說:把匯入按鈕改明顯一點
        ↓
GSD 這一輪照做了(改成 outline,勉強算「改了」)
        ↓
下一個執行週期開始
        ↓
GSD 重讀規格檔,看到 D-03 說要低調
        ↓
我的對話指令被規格覆蓋

我在 chat 層下的指令,跟規格檔在打架。而規格檔永遠贏,因為它每一輪都會被重新讀取。


這是我對 AI agent 協作認知的分水嶺

我原本的心智模型是:跟 agent 說話,就像跟人說話。 你告訴它一件事,它就記住了。

錯了。

Agent 有兩種記憶,而它們的權重完全不同:

對話層 規格層
存在形式 這一輪的上下文 repo 裡的文件
生命週期 這一輪結束就沒了 一直存在
每輪執行時 不一定在上下文裡 必定被讀取
衝突時誰贏

所以那條教訓可以寫成一句話:

要改行為,就改規格檔。不要在對話裡下指令。

對話層適合的是「這一次幫我做什麼」。
規格層適合的是「以後都要怎樣」。

我把一個「以後都要怎樣」的需求,下在了「這一次做什麼」的層級。難怪它撐不過一輪。


Claude 還修正了自己更早的一個建議

事情還沒完。

在診斷過程中,Claude 早先建議過:加一個 .btn-import 的 CSS class 來控制樣式。

後來它自己主動撤回了這個建議,理由是:

這違反了本專案的 inline-styles-only 限制——不新增 CSS class。

而那條限制,正是 Day 21 提到的、GSD 寫進 CONVENTIONS.md 裡的那條專案慣例。

我覺得這件事值得記錄,因為它展示了一個很具體的現象:

同一個 AI,在讀過專案慣例文件之後,會推翻自己在沒讀之前給的建議。

不是「AI 前後不一致」,是「資訊量改變了,結論就該改變」。

而這也反向證明了規格文件的價值——它不只約束 agent,也約束你和 AI 之間的討論。


最終的修法:兩個部分

1. 先改規格

02-CONTEXT.md 的 D-03 改成:

匯入按鈕使用 amber (#d97706) 警示色,語義上標示這是一個破壞性 / 覆寫操作

注意這裡的用詞:不是「改成橘色因為比較顯眼」,而是**「警示色,語義上標示破壞性操作」**。

理由要寫進規格,不只寫結論。 因為下一次有人(或有 agent)想改這個顏色時,他會看到理由,而理由比結論更能防止錯誤的修改。

2. 再改程式碼

btn-import-json 上直接套 inline style,符合專案慣例。

這是現在跑在線上的實際程式碼:

<button id="btn-import-json" onclick="importJSON()"
  style="width:100%;margin-top:8px;padding:10px 0;
         background:#d97706;color:#fff;
         border:1px solid #b45309;border-radius:6px;
         cursor:pointer;font-size:14px"></button>

#d97706 是琥珀色,#b45309 是更深的琥珀當邊框。inline style,沒有新增 class。

順序很重要:先改規格,再改程式碼。 反過來做的話,下一個執行週期又會被打回去。


結構化地看這件事

核心 vs 外部
表面問題是「顏色不對」(外部)。核心問題是「我用錯了指令層級」。

如果只解決外部問題——手動把顏色改掉——那下一次同類問題還會發生,而且我不會知道為什麼。

可控 vs 不可控
我控制不了 GSD 每輪重讀規格的行為(那是它的設計)。我控制得了規格檔的內容。

把力氣花在可控的那一端,這是整件事的解法。

已成立 vs 假設
「跟 agent 說話它就會記住」是我的假設。
「規格檔每輪重讀,且優先於對話」是查證後成立的事實。

而讓假設變成事實的關鍵素材,是那份規劃文件。如果我當初 commit planning docs 選了 No,這個問題我大概到現在還在瞎猜。

一個設定選項,救了一次排查。


這條原則不只適用於 GSD

寫完之後我發現這個模式在別的地方也一樣:

  • Claude Code 有 CLAUDE.md
  • 各種 agent 有自己的規則檔或 memory 機制
  • 甚至一般的專案有 READMECONTRIBUTING.md、lint 設定

凡是「每次都會被讀取的檔案」,都是規格層。凡是「這次講的話」,都是對話層。

而幾乎所有 agent 系統都是規格層優先。因為那正是規格層存在的目的——它就是為了不被單次對話推翻而設計的。

我一開始把這個特性當成 bug,實際上它是 feature。


今天的反思

這件事的起點是一個顏色,終點是一個關於指令層級的認知。

而中間的過程包含:我的問題描述不精確、Claude 診斷了兩次才對、Claude 推翻自己的建議、我提供規劃文件才解開真因。

沒有任何一方是全對的,但迴路收斂了。

我覺得這才是人機協作的真實樣子。不是「AI 一次給出完美答案」,而是兩邊各自補上對方缺的資訊,直到問題被解開。

Claude 缺的是專案規格。我缺的是對 agent 記憶層級的理解。

各補一塊,就走出來了。


明天預告: 那個琥珀色不是隨便選的——它是一整組決策原則在 UI 上的一次落地。而那組原則的來源,是我在回答 GSD 一連串提問時被迫想清楚的東西。


作者:Rich Chang | IT 基礎建設工程師 | 越南・柬埔寨・台灣


上一篇
Day 21 — Claude Code + GSD agent:我的實際開發流程
系列文
從現場踩坑到 AI 工具 — IT Diagnostic Agent 開發實錄22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言