實戰背景
在進行大規模專案重構(如將大型專案中的過時 API 進行版本遷移)時,開發流程通常會拉長到數天。這意味著開發者必須開啟多個不同的 AI 對話會話(Chat Sessions)。
痛點與問題描述: 開發者在昨天的 Session A 中,已經帶領 AI 將整個專案的資料庫存取層從 Dapper 重構為 Entity Framework Core,且在背景處理了複雜的命名映射。然而,今天開發者開啟全新的 Session B 時,AI 因為「失憶」,完全不記得昨天的重構決策。當開發者要求 AI 修復某個資料庫連線錯誤時,AI 給出的建議依然使用了舊的 Dapper 語法,甚至試圖去修改已經被刪除的檔案,這讓開發過程變得極為混亂。
本範例將展示如何利用 Claude-Mem 的持久化記憶功能,在重啟會話後,自動為 AI 注入昨天的記憶,引導其實施正確的 bug 修復。
規格定義
本次變更計畫的 ID 為 fix-long-session-bug。我們在 OpenSpec 增量規格中定義了以下驗收標準:
# 實戰範例 002:openspec/changes/fix-long-session-bug/specs/context-memory/spec.md
## ADDED Requirements
### Requirement: Cross-session database interface integrity
在跨會話的重構過程中,系統必須(SHALL)保持 Entity Framework Core 介面的一致性,嚴禁在任何修改中使用已被廢棄的 Dapper 舊方法。
#### Scenario: Fix connection timeout in new session
- **WHEN** 開啟全新對話並要求 AI 修復資料庫超時錯誤
- **THEN** AI 必須(SHALL)直接讀取 Claude-Mem 的歷史觀察,並使用 `DbContext` 實作而非 Dapper 進行修復。
端到端 8 輪 AI 協作紀錄
以下是 You (開發者) 與 AI 助手在重啟會話後進行 Debug 的完整對話:
── 第 1 輪:重啟會話與記憶自動注入 ──
- You:
/opsx:explore "今天開啟新會話。昨天我們重構了資料庫,但現在出現了 'Connection Timeout' 錯誤。請幫我查詢昨天的記憶,看看我們改了什麼。" - AI:
好的,已進入探索模式。在全新會話中,我會首先調用
claude-mem的記憶檢索工具,拉取與資料庫重構相關的持久化記憶節點。CM 呼叫:
get_observations(query: "database refactor")
CM 回傳:MemoryEntryID:mem_9821aSummary: “昨日將專案從 Dapper 遷移至 EF Core。建立了AppDbContext.cs,廢棄了原有的SqlConnectionHelper。所有資料庫操作現在必須透過 DbContext 進行。”
分析:
感謝claude-mem提供的持久化上下文!我已經知道專案昨日已完全停用 Dapper,改用 EF Core。目前出現的連線超時,我們應該檢視AppDbContext.cs中的連線配置,而不是去尋找舊的 Helper。
── 第 2 輪:定位新版資料庫配置 ──
- You:
很好,你記起來了。請幫我搜尋並讀取 AppDbContext.cs 的連線與超時配置。 - AI:
我現在在專案中尋找
AppDbContext.cs並讀取其原始碼。CM 呼叫:
search_graph(query: "AppDbContext")(結合 codebase-memory)
CM 回傳: 檔案位於Data/AppDbContext.cs。接下來讀取其代碼。 CM 呼叫:
get_code_snippet(file_path: "Data/AppDbContext.cs", start_line: 1, end_line: 45)
CM 回傳:public class AppDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 警告:連線字串中沒有設定 CommandTimeout,且連線池大小為預設 optionsBuilder.UseSqlServer("Server=tcp:sqlserver.local;Database=PhysioDb;"); } }診斷:
在 EF Core 的配置中,沒有顯示聲明 Timeout。當資料庫負載過高時,預設的 30 秒超時可能不夠用,或者連線字串需要優化。
── 第 3 輪:檢索昨天的連線字串設定 ──
- You:
昨天我們在 Session A 中,是不是已經在環境變數或記憶中記錄了正確的連線字串與超時參數?請幫我搜尋記憶中的 connection string。 - AI:
好的,我將呼叫
claude-mem搜尋歷史對話中關於「connection string」或「SQL Server」的記錄。CM 呼叫:
get_observations(query: "connection string")
CM 回傳:MemoryEntry: “在 Session A 中,確認生產環境連線字串應附加Connect Timeout=60;以應對尖峰網路延遲。且必須從環境變數SQL_CONN_STR讀取,不可硬編碼。”
再次感謝持久化記憶!這避免了我硬編碼或設定錯誤的連線參數。
── 第 4 輪:建立變更提案 ──
- You:
/opsx:propose "修復 EF Core 連線超時錯誤,將 AppDbContext 改為從環境變數讀取連線字串,並設定 CommandTimeout 為 60 秒" - AI:
好的,變更提案
fix-ef-timeout-bug已建立:- proposal.md: 說明重構 EF Core 超時與安全讀取環境變數的必要性。
- specs/context-memory/spec.md: 定義超時 60 秒的驗收 Scenario。
- tasks.md: 任務拆解如下:
- 1.1 修改
AppDbContext.cs從環境變數讀取SQL_CONN_STR。 - 1.2 設定 EF Core 命令超時時間為 60 秒。
- 1.3 執行驗證。
- 1.1 修改
計畫已就緒!請執行
/opsx:apply。
── 第 5 輪:實作連線字串讀取 (Task 1.1) ──
- You:
/opsx:apply - AI:
Implementing: fix-ef-timeout-bug (schema: spec-driven)
正在處理任務 1.1:修改連線字串來源。
我已更新了
Data/AppDbContext.cs,改為使用環境變數讀取:protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var connStr = Environment.GetEnvironmentVariable("SQL_CONN_STR"); if (string.IsNullOrEmpty(connStr)) { throw new InvalidOperationException("環境變數 SQL_CONN_STR 未設定"); } optionsBuilder.UseSqlServer(connStr); }✓ 任務 1.1 完成。已將狀態寫入
tasks.md。
── 第 6 輪:實作超時配置 (Task 1.2) ──
- You:
繼續實作任務 1.2,設定 60 秒超時限制。 - AI:
Implementing: fix-ef-timeout-bug
正在處理任務 1.2:設定 EF Core CommandTimeout。
我修改了
AppDbContext.cs,在 SqlServerOptions 內設定了超時:optionsBuilder.UseSqlServer(connStr, opts => { opts.CommandTimeout(60); // 設定為 60 秒 });✓ 任務 1.2 實作完成。
── 第 7 輪:執行驗證與歸檔 ──
- You:
執行 verify 進行驗證,如果沒問題就歸檔。 - AI:
Implementing: fix-ef-timeout-bug
正在處理任務 1.3:執行驗證。
- 建置測試:執行
pnpm run build成功。 - 單元測試:在模擬環境下注入帶有
Connect Timeout=60的環境變數,AppDbContext 成功連線,且 CommandTimeout 確認為 60 秒,符合 Spec 驗收標準。
變更歸檔:
- 同步 spec 至主線。
- 移動計畫資料夾至
archive/。
Archive Complete
變更計畫已順利歸檔!
- 建置測試:執行
── 第 8 輪:將本次修改寫入長期記憶 ──
- You:
非常好!請把今天的除錯決策與變更背景,記錄到 claude-mem 的長期記憶中,好讓明天的會話能隨時拉取。 - AI:
好的,我將今天的重要決策以記憶項目的格式寫入
claude-mem本地資料庫。CM 呼叫:
save_observation(key: "database_config", value: "已於 2026-07-16 將 DbContext 改為從環境變數 SQL_CONN_STR 讀取連線字串,並強制設定 CommandTimeout 為 60 秒。")
CM 回傳:Success記憶寫入成功!現在該項記錄已被持久化保存。即使您隨後關閉對話或清除快取,未來的 AI 會話依然能在第一時間拉取此項架構限制。
產生的檔案結構
openspec/
├── specs/
│ └── context-memory/
│ └── spec.md # 已同步:最新跨會話資料庫存取規格
└── changes/
└── archive/
└── 2026-07-16-fix-ef-timeout-bug/
├── proposal.md
├── design.md
└── tasks.md
程式碼與設計亮點
- 記憶持久化關聯:利用外部儲存的 MCP 記憶伺服器,將 AI 對專案特有規則(如「禁止硬編碼連線字串」)的理解,沉澱為本機資料庫的一部分。
- 無雜訊 Context 注入:僅在需要時,透過關鍵字(如
database)將特定記憶段注入 Context,避免了每次對話都貼入幾十頁開發文檔的累贅。
學到了什麼
- 跨會話連續性 (Session Continuity):AI 助手的短期上下文是有極限的。使用
claude-mem這類觀察工具,能將過往 Session 的「軟記憶」轉化為「硬資料」,免去了頻繁的上下文重建。 - 規格的累積效應:隨手將變更決策寫入長期記憶,能在團隊協作(或多代理協作)中扮演「虛擬架構師」的角色,為後續代碼審查提供依據。
常見陷阱
- 陷阱 1:硬編碼環境變數名稱
在不同的部署環境下,環境變數名稱可能不一致(如SQL_CONN_STRvsDATABASE_URL)。應在claude-mem記憶中明確寫死專案所採用的特定變數名稱。 - 陷阱 2:忘記清空臨時觀察
若將密碼或憑證等敏感字串意外記錄到claude-mem的長期日誌中,可能會帶來資安隱患。必須配置排除過濾器(例如排除含有password、key的行)。