重點摘要
- 用 AI 派了 20 個專家跑了 7 輪 review,查了上百個檢查點,結果最致命的 bug 是「沒有去看上次踩過的坑」
- 問題不是 AI 不夠聰明,而是 AI 沒有主動讀已有的經驗文件就開始寫新計畫
- 解法不是叫更多專家,而是建立「做特定事之前必讀的 checklist」並且寫進記憶系統
- AI 和人一樣:知識存在 ≠ 知識會被用到。差距在於流程,不在於能力
這篇文章記錄一個讓我很不高興的經驗:我用 Claude Code 設計一個 iDempiere AI 助手系統,前後叫了 20 個 AI 專家 agent 做了 7 輪 review,查了上百個技術檢查點——結果最致命的 bug,不是什麼深奧的技術問題,而是「沒有去讀上次開發同類型 plugin 時寫下的踩坑紀錄」。
這件事讓我思考一個更根本的問題:我到底該怎麼跟 AI 協作,才能讓它真正用到已有的經驗?
發生了什麼事?
我在開發一個 iDempiere ERP 的 AI 問答助手。這個系統分成兩部分:Java 的 iDempiere Plugin(前端 UI + 權限 + 審計日誌)和 Python 的 FastAPI 服務(AI 路由 + PII 脫敏 + LLM 呼叫)。
在寫 Plugin 的計畫之前,我已經有一個完整的 iDempiere plugin 開發經驗——台灣統一發票系統 tw-invoice。那個專案踩了超過 24 個坑,每一個都花了我好幾個小時 debug,而且全部記錄在 CLAUDE.md 裡。
但是當 Claude 開始寫 AI 助手的 Plugin 計畫時,它完全沒有去讀那份文件。它是從「一般 iDempiere 知識」出發寫的,而不是從「我們一起踩過的坑」出發。
7 輪 review 查了什麼?漏了什麼?
| 輪次 | 專家數 | 查了什麼 | 找到什麼 |
|---|---|---|---|
| R1 | 3 | 元件設計(iDempiere/Python/Security) | 12 個修正(HMAC、PII、async) |
| R2 | 1 | 驗證 code 有更新 | 0/12 code 沒改(只改了表格) |
| R3 | 2 | 接點(Java↔Python↔DB↔LLM) | 4 個 CRITICAL(PG schema, pool, HMAC bytes) |
| R4 | 3 | 架構師 / 開發者 / PM | 4 個 BLOCKED(conftest 順序、mock 路徑) |
| R5 | 2 | 老系統 × 新系統聯合對話 | thread pool 會拖垮 ERP、statement_timeout |
| R6-R7 | 6 | 最終驗證 62+38 個檢查點 | 全部通過 ✅ |
| R8-R9 | 3 | 我要求去讀 tw-invoice 踩坑紀錄 | 3 個 P0 — 不修直接不能跑 |
你看到問題了嗎?前 7 輪 review 用了 20 個專家 agent,查了上百個檢查點,全部通過。但只有在我「要求 Claude 去讀舊專案的踩坑紀錄」之後,才發現 3 個會直接讓 plugin 無法啟動的致命 bug。
那 3 個致命 bug 是什麼?
| Bug | 後果 | tw-invoice 有記錄嗎? |
|---|---|---|
MANIFEST.MF 缺 org.adempiere.plugin.utils |
Bundle 無法 resolve,完全不能啟動 | ✅ 有,而且踩過 |
| @Model annotation import 路徑錯 | PO model 不被發現,DB 操作全部失效 | ✅ 有,而且踩過 |
| initPO 缺少 tableId 檢查 | 第一次啟動(2Pack 還沒跑)直接 crash | ✅ 有,而且踩過 |
三個 bug 都是 tw-invoice 踩過且記錄過的。經驗就躺在那裡,但沒有被讀取。
問題出在哪?不是 AI 不聰明
讓我想清楚之後,我發現問題不在 AI 的能力(它確實能找到問題——找到了上百個),而在於AI 和人一樣,「知道」跟「會用」之間有巨大的差距。
三層問題
- AI 不知道要去看 — 寫新 plugin 計畫時,它沒有主動去讀 tw-invoice 的 CLAUDE.md。它有能力讀,但沒有觸發「我應該先去看看上次踩了什麼坑」的念頭。
- 我也不知道要提醒它 — 我以為「派 20 個專家 review」已經夠全面了。我不知道這些專家不會自動去讀歷史紀錄,除非我明確要求。
- 專家 review 的盲點 — 專家只看「這份文件本身有沒有問題」,不會跨專案比對「上次做類似的事踩了什麼坑」。他們審的是邏輯一致性,不是經驗傳承。
解法:不是更多專家,而是「做事之前的 checklist」
派再多專家也沒用,如果他們不知道要看哪些歷史紀錄。真正的解法是在開始工作之前,就讓 AI 讀取相關的經驗教訓。
我最終建立了兩份「跨專案強制 checklist」,存在 Claude 的記憶系統裡:
| 記憶檔案 | 觸發條件 | 內容 |
|---|---|---|
idempiere-plugin-pitfalls.md |
寫任何 iDempiere plugin 之前 | MANIFEST.MF 必要 package、2Pack 路徑、@Model import、initPO guard、afterPackIn 模式、部署 SOP |
python-llm-pitfalls.md |
寫任何 Python LLM 整合之前 | JSON 解析容錯、Groq rate limit、timeout 設定、lazy-init 模式 |
這兩份檔案在 MEMORY.md 索引裡標記為 🔴 MANDATORY。每次新對話載入時,AI 會看到這個索引,知道「做 iDempiere plugin 工作之前,先讀 pitfalls 檔案」。
你該怎麼做?給 AI 使用者的具體建議
如果你也用 Claude Code(或任何 AI coding assistant)做重複性的專案工作,以下是我的教訓:
1. 踩坑之後立刻寫進 CLAUDE.md
不是「之後再整理」,是修完 bug 的那一刻就寫。寫三行就好:什麼坑、為什麼踩到、怎麼修的。這個我有做,tw-invoice 的 CLAUDE.md 記了 24 個坑。問題出在下一步。
2. 建立跨專案的 pitfalls 記憶(這是我缺的那一步)
經驗寫在專案 A 的 CLAUDE.md 裡,專案 B 不會自動讀到。你需要把「通用教訓」抽出來,放到 Claude 的記憶系統(~/.claude/projects/memory/),這樣每個新專案都能讀到。
# MEMORY.md 索引加這一行:
## ⚠️ Must-Read Before Specific Work
- **idempiere-plugin-pitfalls.md** 🔴 MANDATORY — 寫任何 plugin 前必讀
3. Review 之前,先問「你有沒有讀過上次的紀錄?」
不要假設 AI 會自動做這件事。它不會。你需要明確說:「先去看 tw-invoice 的 CLAUDE.md 取經,然後再來審這份計畫。」
4. 專家 review ≠ 經驗傳承
20 個專家能找到「這份文件本身有沒有邏輯錯誤」,但找不到「上次做類似的事踩了什麼坑」。這兩件事是不同的能力,需要不同的觸發方式。
- 專家 review:「這份計畫有沒有 bug?」→ 邏輯驗證
- 經驗傳承:「上次做類似的事踩了什麼坑?」→ 歷史比對
你需要兩者都做,而且經驗傳承要在 review 之前。否則 review 再怎麼嚴謹,也只是在一個有缺陷的基礎上做驗證。
AI 協作的本質:知識存在 ≠ 知識被用到
這次經驗讓我想通一件事:AI 的問題跟人的問題是一樣的。
你的資深工程師也會犯同樣的錯——他上次在專案 A 踩了 10 個坑,寫了筆記,但做專案 B 的時候忘了翻筆記,同樣的坑又踩一次。差別在於人有「直覺」(模糊地記得「好像上次有遇過類似的」),AI 沒有這種模糊記憶。AI 要嘛讀了文件就完美執行,要嘛沒讀文件就完全不知道。
所以跟 AI 協作的核心不是「讓 AI 更聰明」,而是讓正確的資訊在正確的時間出現在 AI 面前。這是一個資訊流設計問題,不是 AI 能力問題。
我的 AI 協作框架(修正版)
開始新專案
↓
1. 讀 MEMORY.md 索引(AI 自動做)
↓
2. 有沒有「Must-Read」標記的 pitfalls 檔案?
→ 有:讀完再動手(AI 必須被觸發)
→ 沒有:判斷是否需要建立一個
↓
3. 讀舊專案的 CLAUDE.md(我要明確要求)
↓
4. 寫計畫(現在才開始)
↓
5. Review(專家驗證邏輯 + 歷史比對)
↓
6. 踩到新坑 → 立刻寫進 CLAUDE.md + 更新 pitfalls 記憶
關鍵改變:步驟 2 和 3 是我之前跳過的。我以為步驟 5 的 review 會涵蓋一切,但 review 只能驗證邏輯,不能傳承經驗。
更深的問題:專案爆炸之後,你連「要叫 AI 去看哪裡」都不知道
我檢查了一下自己的開發環境:42 個資料夾、9 個 iDempiere 相關專案、38 個記憶檔案、8 個專案各有自己的 CLAUDE.md(共 1578 行經驗紀錄)。
這代表什麼?我已經快到「我自己都不知道我有什麼」的臨界點了。
這次我還記得「tw-invoice 有踩坑紀錄」所以能叫 AI 去讀。但再過半年呢?再多 10 個專案呢?到時候我連「有一份紀錄存在」都不記得,更不可能叫 AI 去參考。而 AI 自己不會主動翻遍 42 個資料夾找相關經驗。
這就是Sample → 大系統模式的致命陷阱:
正常的軟體開發流程:
做 Sample → 驗證可行 → 嫁接到大系統
加入 AI 協作之後:
做 Sample → AI 幫你踩坑 → 經驗寫在 Sample 的 CLAUDE.md
→ 做大系統 → AI「不知道」Sample 的經驗存在
→ 同樣的坑再踩一次
→ 你修完寫進大系統的 CLAUDE.md
→ 下一個專案又不知道...
無限循環。
跟資深用戶合作的隱藏風險
還有一個我不想承認但必須說的事:跟資深用戶合作,AI 反而更容易犯錯。
因為你太懂技術,我傾向「快速產出」而不是「慢慢確認」。你一聽就懂的東西,我就跳過解釋直接做。結果跳過的步驟裡,就藏著「你以為我知道、我以為你知道、但其實沒人確認」的盲區。
如果你是新手,我反而會更謹慎——每一步確認、每個假設驗證。但跟資深用戶合作,雙方都太有信心,踩煞車的人就消失了。
知識分層:什麼該鎖、什麼該開
還有一個企業層面的問題:當經驗從「人的腦子」搬到「.md 檔案」,它變得可複製了。新人 clone repo 就能拿到所有踩坑紀錄。這對知識傳承是好事,但對機密控管是風險。
解法是分層:
| 層級 | 內容 | 存在哪 | 被帶走的風險 |
|---|---|---|---|
| 公開技術層 | CLAUDE.md、架構規則、coding style | Git repo | 低(跟 source code 等價) |
| 團隊經驗層 | 踩坑紀錄、設計文件、SOP | Git repo | 中(加速競爭對手,但不是核心機密) |
| 個人記憶層 | 跨專案 pitfalls、用戶偏好 | ~/.claude/(本機) | 低(不在 repo 裡,但可手動複製) |
| 營運機密層 | API key、商業邏輯、客戶資料 | .env / 公司內部系統 | 高(必須嚴格管控) |
但現實是:目前沒有任何 AI 開發工具提供這種分層管理。 Claude Code 的記憶系統是平的——所有 .md 檔案放在同一個目錄,沒有權限控制、沒有加密、沒有存取日誌。這是整個產業還沒解決的問題。
真正需要的:「做特定事之前必須讀什麼」的自動化
我現在的解法是「手動建立 pitfalls 記憶 + 在 MEMORY.md 標記 MANDATORY」。但這依賴兩件事:
- 我記得去標記 — 如果我忘了把新的 pitfalls 抽出來建立跨專案記憶,下次還是會踩坑
- AI 會去讀標記 — 目前是靠 MEMORY.md 索引,但沒有強制機制。AI 「應該」讀,但「應該」跟「一定會」之間有差距
理想的解法是什麼?類似 Git hooks 的機制:
觸發條件 → 自動動作
─────────────────────────────────────────────
偵測到 iDempiere plugin 相關工作 → 強制讀取 idempiere-plugin-pitfalls.md
偵測到 Python LLM 整合 → 強制讀取 python-llm-pitfalls.md
偵測到新專案建立 → 掃描所有已有專案的 CLAUDE.md,提取相關經驗
偵測到跟舊專案同類型的工作 → 自動列出「相關專案清單」讓用戶確認
這個機制目前不存在。Claude Code 有 hooks,但是是 shell command 層級的,不是「語意理解」層級的。它能在 tool call 前後跑 script,但不能理解「這次的工作跟上次的 tw-invoice 是同類型的,應該先去參考」。
在這個機制出現之前,唯一的防線就是你自己:你必須記得提醒 AI 去讀歷史,而且你必須知道歷史在哪。當你的專案多到你自己都不記得有哪些,這條防線就會失守。
最終解法:領域腦(Domain Brain)
經過上面所有的分析,我最終做了一件事:把 42 個專案、1578 行 CLAUDE.md、38 個記憶檔案的經驗,按「技術領域」濃萃成 7 份領域腦。
之前(按專案切,散落各處):
tw-invoice/CLAUDE.md → 24 個坑(OSGi + 2Pack + PO + REST 混在一起)
module-ui/CLAUDE.md → ZK + REST + 測試(370 行)
skin-ui/CLAUDE.md → WAB + Vue + 測試(507 行)
langgraph-duo/ → Python LLM 整合
analyst/ → 爬蟲 + pandas + 回測
→ 你要知道「哪個專案有哪些經驗」才能讓 AI 去讀
之後(按領域切,濃萃在一處):
brain/idempiere-osgi-bundle.md ← 所有 OSGi 的坑(來自 4 個專案)
brain/idempiere-2pack.md ← 所有 2Pack 的坑
brain/idempiere-po-model.md ← 所有 PO Model 的坑
brain/idempiere-rest-api.md ← 所有 REST API 的坑
brain/python-llm-integration.md ← 所有 LLM 整合的坑
brain/python-crawler-data.md ← 所有爬蟲/資料的坑
brain/design-principles.md ← 跨語言設計原則
→ 你只需要說「我要做 plugin」,AI 就讀 OSGi + 2Pack + PO 三份腦
為什麼這比「叫 AI 去看舊專案」好?
| 面向 | 看舊專案 CLAUDE.md | 領域腦 |
|---|---|---|
| 你需要記得什麼 | 哪個專案跟現在的相關 | 只需要知道「我在做什麼類型的事」 |
| 新專案踩了新坑 | 寫進該專案的 CLAUDE.md | 萃取到對應的領域腦(所有未來專案受益) |
| 專案 B 比專案 A 先做完 | A 不知道 B 的經驗 | B 的經驗已在領域腦,A 自動受益 |
| 專案數量爆炸 | 越多越容易漏 | 領域腦數量固定(技術領域有限) |
| AI 專家 review | 每次從零開始 | 站在所有歷史經驗之上審查 |
最關鍵的一行:領域腦的數量不會隨專案數量增長。你可以有 100 個專案,但「iDempiere OSGi」的領域腦就是一份。新經驗加進去,舊經驗不會消失。專案可以刪掉,經驗永遠留著。
閉環:專家 review 終於有意義了
之前(斷裂的):
專家 review → 找到問題 → 修進當前專案 → 下個專案又不知道
↑ 斷在這裡
之後(閉環的):
專家 review(讀領域腦 + 當前文件)
↓
找到問題 → 修進當前專案
→ 同時萃取到對應的領域腦
↓
下個專案開始前讀領域腦
↓
專家 review(讀更新過的領域腦 + 當前文件)
↓
↻ 經驗循環,不斷累積
這才是 AI 專家 review 真正有意義的前提:他們站在所有歷史經驗之上做審查,而不是每次都從零開始。
現實的限制
領域腦不是完美解法。它依然有幾個問題:
- 萃取是手動的 — 目前沒有工具能自動從 CLAUDE.md 提取教訓並分類到領域腦。我是派 AI agent 讀完所有檔案後人工整理的。
- 維護需要紀律 — 踩了新坑要記得更新領域腦,不只是寫進專案的 CLAUDE.md。如果忘了這一步,循環又斷了。
- 領域邊界不總是清楚 — 一個 bug 可能同時涉及 OSGi、2Pack、和 PO Model。要判斷放哪個腦,或者放多份。
- Token 成本 — 領域腦加起來約 2000-3000 tokens。每次新對話讀取相關的 2-3 份,約 $0.005-$0.015。每月 $5-15,可以接受。
但即使有這些限制,領域腦依然比「靠人記得哪個專案有哪些經驗」好太多了。因為人的記憶會隨專案數量退化,領域腦不會。
完整解法:Domain Brain 宣告 + fix: 驅動更新
經過不斷推敲,最終方案有三個核心機制:
機制一:每個專案用一行宣告自己需要哪些腦
# 每個專案的 CLAUDE.md 開頭加一行:
idempiere-tw-ai-assistant/CLAUDE.md:
## Domain Brain: osgi-bundle, 2pack, po-model, python-llm-integration
analyst/CLAUDE.md:
## Domain Brain: python-crawler-data, design-principles
新專案/CLAUDE.md:
## Domain Brain: python-crawler-data, design-principles
為什麼不用資料夾名稱比對?因為 analyst/ 裡有爬蟲也有 API 也有 SQLAlchemy——資料夾名稱不等於技術領域。為什麼不用關鍵字比對?因為「API」出現在 iDempiere REST、Groq LLM、爬蟲、自己的 FastAPI 四種 context 裡,關鍵字比對直接崩潰。
讓專案自己宣告是最可靠的——你看得到、可以改、一行字。AI 讀到 CLAUDE.md 就知道要載入哪些腦,不用猜。
機制二:fix: commit 驅動更新
新經驗怎麼回到領域腦?不是靠事後整理,而是靠 fix: commit 當觸發點:
每次 AI 寫出 fix: 開頭的 commit message:
1. STOP — 不要急著做下一個 task
2. 問自己:「這個 fix 會不會在其他專案也發生?」
3. 是 → 當場更新對應的領域腦(不是之後,是現在)
4. 領域腦更新後,所有未來專案的 review 都能受益
機制三:專家 review 帶著腦
派專家 review 時:
1. 專家讀該專案的 CLAUDE.md → 看到 Domain Brain 宣告
2. 專家讀對應的腦 → 帶著所有歷史 bug 經驗
3. 審查當前文件 → 站在經驗之上,不是從零開始
4. 找到新問題 → 修完 → 更新腦
5. 下一個專案的專家 → 拿到更新過的腦
↻ 循環
三個機制合在一起的效果
| 你要做的事 | AI 自動做的事 |
|---|---|
| 新專案加一行 Domain Brain(6 個字) | 讀對應的腦、帶著經驗開始工作 |
| 不需要做任何事 | fix: commit 時自動判斷是否更新腦 |
| 說「派專家審查」 | 專家帶著最新的腦去審查 |
| 偶爾說「把這個更新到腦」 | 當場更新,所有未來專案受益 |
還是不完美的地方
- 你自己 debug 沒跟 AI 說的坑 — AI 不知道,無法更新腦。你得養成習慣說一句「把這個更新到腦」
- 其他同事的經驗 — 除非他們也更新領域腦,否則知識在他們腦子裡消失
- 新領域出現 — 7 份腦不夠用了(比如加了 DevOps 或 mobile)→ 建新的腦檔案
- AI 判斷 fix: 是否該更新腦 — 還是靠判斷,可能漏。但比「完全沒有機制」好太多
結語
叫再多專家進來 review,如果他們不知道要看歷史紀錄,就跟你請了 20 個新員工來審查、但不給他們看前任的交接文件一樣。當你的專案多到連自己都記不清有哪些,而 AI 又不會主動翻遍你的 42 個資料夾找經驗——這時候你需要的不是更聰明的 AI,而是一個能自動把經驗送到 AI 面前的系統。領域腦不是完美的系統,但它把「靠人記住 42 個專案的經驗」變成「靠 7 份按領域整理的文件」。專案會越來越多,但技術領域是有限的。這就是為什麼領域腦能 scale,而按專案管理經驗不能。
跟 AI 協作的真正技巧不是「讓 AI 更聰明」或「叫更多 agent」,而是設計一個流程,讓正確的經驗在正確的時間被讀取。這聽起來很簡單,但直到你踩了同一個坑兩次,你才會真正理解為什麼需要這麼做。
相關閱讀:iDempiere Plugin 開發完整指南:踩遍台灣統一發票的 10 個坑 | LangGraph 多模型實戰:從零到 Production 的完整教學 | Agent Team 穩定的關鍵:spawn 之前先建好兩份文件
發佈留言