一場 59 小時的 Claude Code 馬拉松:我如何用 AI 完成大型功能開發
🎯 前言
你有想過一次 Claude Code session 可以撐多久嗎?
我的紀錄是 59.5 小時,期間交換了 1,165 則訊息,cache 了超過 1.5 億個 token。
這不是刻意挑戰極限——而是一個大型功能開發任務,從分析需求、設計架構、實作、除錯到最後驗收,全程都在同一個 session 中完成。
這篇文章想分享這段經驗:我們開發了什麼、過程中遇到什麼挑戰、以及我從中學到關於「長時間 AI 協作」的節奏與技巧。
📋 任務背景
功能需求
AppSystem 需要新增一個「批次輸出報表」功能,讓管理者可以:
- 選擇多個機構(OrganizationA、OrganizationB 等)
- 設定日期範圍
- 選擇要匯出的表單類型(TypeA 表單、TypeB 表單)
- 批次產生 Excel 或 PDF 報表
- 打包成 ZIP 下載
聽起來不複雜,但實際上牽涉到:
- 多租戶資料庫切換(每個機構獨立 DB)
- 大量資料的記憶體管理(PHP 的
memory_limit) - 非同步處理(不能讓 HTTP request 等太久)
- 多種表單格式的相容性
為什麼是 59 小時?
功能本身大概需要 15-20 小時的開發時間。但加上:
- 需求討論與確認
- 發現並修復舊系統的相關 bug
- 效能調優(第一版跑完要 45 分鐘,最後壓到 8 分鐘)
- 測試每個機構的邊界情況
- 文件更新
就變成了將近 60 小時的馬拉松。
⏱️ 過程紀錄:session 的節奏
第 1-8 小時:需求分析與設計
這個階段最重要的事是讓 Claude 充分理解現有架構。
我沒有直接說「幫我寫這個功能」,而是先進行了一系列的「架構訪談」:
我:我想新增一個批次輸出功能。在開始之前,
請先告訴我:根據目前的 CLAUDE.md,
你認為這個功能應該放在系統的哪個位置?
會碰到哪些已知的技術限制?
這個提問方式非常有效。Claude 給出了:
- 建議放在
module_a/batch_export/目錄 - 點出 PHP 的
max_execution_time = 30限制(不能超過 30 秒) - 提醒 MySQL 5.7 的
memory_limit需要注意大量資料 - 建議使用 CLI 腳本搭配 PHP 的
ignore_user_abort機制
這些都是很有洞察力的建議,節省了我自己踩坑的時間。
第 8-20 小時:核心實作
有了設計方向,開始實作。這個階段的節奏是:
- 提出一個具體的子問題
- Claude 給出實作方案
- 我執行測試
- 回報結果,繼續下一個子問題
例如其中一個環節:
我:Excel 產生這邊有個問題,第一個機構(demo-org-1)
的 TypeA 表單有 45 個欄位,但 demo-org-2 只有 40 個。
如何讓同一份 Excel 模板相容不同欄位數量的機構?
Claude:
有幾個方案:
方案一(推薦):動態欄位合併
- 第一次迴圈掃描所有機構,收集所有可能的欄位
- 以「聯集」的方式決定 Excel 的欄位順序
- 缺少的欄位填空值
方案二:固定模板,多餘欄位忽略
- 預先定義一個「完整欄位清單」
- 不在清單中的欄位直接跳過
考量到你們需要逐漸新增欄位,方案一比較能長期維護。
實作如下:
\`\`\`php
// 第一階段:收集所有機構的欄位
$all_columns = [];
foreach ($org_list as $org) {
$columns = getFormColumns($form_type, $org['db_no']);
$all_columns = array_unique(array_merge($all_columns, $columns));
}
// 第二階段:以聯集欄位輸出
foreach ($org_list as $org) {
$records = getFormRecords($form_type, $org['db_no'], $date_range);
foreach ($records as $record) {
$row = [];
foreach ($all_columns as $col) {
$row[] = $record[$col] ?? ''; // 沒有的欄位填空值
}
$sheet->appendRow($row);
}
}
\`\`\`
第 20-35 小時:效能地獄
第一版跑完需要 45 分鐘,明顯太慢。
這個階段是整個 session 最「卡」的部分,也讓我學到最多。Claude 和我一起做了系統性的效能分析:
我:批次輸出跑了 45 分鐘。我加了一些計時,
主要瓶頸在「每個表單逐一查詢資料庫」,
光是 demo-org-1 的 TypeB 表單就有 300 筆,
每筆一個 SQL 查詢,等於 300 次 DB 連線。
Claude:
這是 N+1 Query 問題。解法是一次查詢所有資料:
\`\`\`sql
-- 改前(每筆一次)
SELECT * FROM typeB_records WHERE id = ?
-- 改後(一次撈所有)
SELECT * FROM typeB_records
WHERE date BETWEEN ? AND ?
AND status = 'active'
ORDER BY date ASC
\`\`\`
但要注意:如果 TypeB 表單資料量很大(例如每筆有 50 個欄位 x 300 筆),
一次撈出來可能撐爆 PHP 的 memory_limit = 128M。
建議分批查詢,每批 50 筆:
...
透過多輪分析,最終把時間壓到 8 分鐘。優化的重點包括:
- N+1 Query → 批次查詢
- 重複的資料表連線 → 連線池重用
- 逐筆產生 Excel → 使用串流寫入(減少記憶體使用)
- 串列機構處理 → 雖然是 PHP,但可以用
pcntl_fork並行
第 35-50 小時:邊界情況與 Bug 修復
效能問題解決後,開始全面測試。這個階段發現了許多「只在特定條件下出現」的問題:
Bug 1:某機構的資料完全空白
我:demo-org-3 產生的 Excel 是空的,但資料庫裡有資料
Claude:可能是日期欄位格式不同。
根據 CLAUDE.md,系統有新舊版本的日期格式差異。
請查一下 demo-org-3 的 typeB_records 的 date 欄位格式。
確實,demo-org-3 是較舊的機構,日期格式是 YYYYMMDD 而不是 YYYY-MM-DD。
Bug 2:ZIP 打包時某些 PDF 損毀
這個 bug 花了最多時間,最後發現是 PHP 的 ob_start() 和 ob_end_clean() 在特定情況下沒有正確清空輸出緩衝區,導致 PDF 檔案前面多了一些 HTML 輸出。
第 50-59 小時:收尾與驗收
最後幾個小時做了:
- 完整的 end-to-end 測試(所有機構 × 所有表單類型)
- CLAUDE.md 更新(新增這個功能的說明和測試方法)
- 清理開發過程中留下的 debug 程式碼
📈 Prompt Caching 的效益
這次 session 累積了超過 1.5 億個 cache token。
Prompt caching 在長 session 中的作用是:把之前的對話和文件快取起來,後續請求不需要重新處理,速度更快,成本也更低。
在這次開發中,CLAUDE.md(約 760 行)在 session 開始時就被 cache,後續 1,100+ 次的請求都直接從 cache 讀取,而不是每次重新分析。
實際感受到的差異:
| 沒有 Cache | 有 Cache | |
|---|---|---|
| 首次回應速度 | 慢 | 快 |
| 重複問相似問題 | 每次重新分析 | 快速回應 |
| 大型文件的處理 | 每次消耗 | 只計算一次 |
對於長時間的開發 session,Prompt caching 讓整個體驗流暢很多。
🎓 長時間 AI 協作的技巧
從這 59 小時的經驗中,整理出幾個讓長時間協作更順暢的技巧。
技巧 1:用「章節感」組織工作
把整個任務想像成一本書,每個子任務是一個章節:
「我們現在開始處理效能優化這個章節。
上一章我們完成了核心功能實作。
這章的目標是把執行時間從 45 分鐘壓到 10 分鐘以下。」
這樣的開場白有幾個好處:
- 讓 Claude 知道當前脈絡
- 建立清晰的「完成標準」
- 提醒自己任務的範圍
技巧 2:定期「對齊」一次
每隔 2-3 小時,做一次對齊:
「目前進度:
✅ 已完成:資料庫查詢優化、Excel 動態欄位
🔄 進行中:ZIP 打包功能
⏳ 待處理:完整測試、文件更新
確認我們的理解一致嗎?」
這個習慣有效防止「越走越偏」的情況。
技巧 3:遇到卡關,換個角度提問
在效能優化的階段,我卡在一個問題上超過 1 小時: 明明已經用了批次查詢,但速度還是很慢。
最後我換了一個提問方式:
「我不直接問解法了。請問如果你是一個資深 PHP 工程師,
看到一個批次匯出任務在 8 個機構 × 每機構 300 筆資料時跑了 20 分鐘,
你會想到哪些可能性?請列舉,不要只想 SQL 的部分。」
Claude 這次列了一個我沒想到的點:
PHP 的
fputcsv()每呼叫一次都會做一次 I/O write, 如果逐行呼叫,會有大量的 I/O syscall。 建議改用 buffer,每 100 行才做一次實際寫入。
這個優化讓時間又縮短了 3 分鐘。
技巧 4:把重要結論記錄在 CLAUDE.md 中
在 session 進行中,每當發現重要的技術事實,就立刻更新 CLAUDE.md:
「請幫我把剛才關於 ob_start() 的問題寫成一條警告,
加到 CLAUDE.md 的已知問題章節。」
這樣做的好處:
- 這次 session 結束後,下次開新 session 這個知識不會丟失
- 在 session 進行中,Claude 也可以隨時參考(透過 Prompt caching)
技巧 5:接受「我需要休息,你也需要」
59 小時不是一口氣完成的。中間我睡覺、吃飯,Claude Code session 也跟著暫停。
每次重新開始前,我都會做一個「回顧開場」:
「繼續上次的工作。
上次我們停在 ZIP 功能的實作,已經完成了 Excel 的部分,
ZIP 還沒開始。請根據 CLAUDE.md 和我們之前的討論,
幫我確認下一步的計畫。」
透過這個開場,讓 Claude 快速回到之前的脈絡。
🤔 反思:什麼時候不適合長 Session?
不是每個任務都適合用長 session。以下情況建議分開來做:
不適合長 Session 的情況
- 任務之間相互獨立:修不同模組的獨立 bug,沒必要在同一個 session
- 需要重新思考架構:如果做到一半發現方向錯了,有時候開新 session 重新來過更快
- 只是快速問一個問題:「這個 SQL 語法對嗎?」不需要長 session
適合長 Session 的情況
- 任務之間高度相關:開發一個完整功能,後期的實作依賴前期的設計決策
- 需要大量脈絡:複雜的除錯,需要 Claude 記住之前測試過的方案
- 需要迭代優化:效能調優、程式碼品質改善,前後輪次有關聯
💡 數字背後的意義
1,165 則訊息 — 平均每小時大約 20 則,換算下來大概 3 分鐘一則。 這個節奏讓我感覺是在和一個稍微思考比較慢的同事合作,而不是在等機器。
1.5 億 cache token — 大部分是 CLAUDE.md 和之前對話的 cache。 代表雖然訊息量很大,但 AI 不需要每次都重新處理所有背景知識。
59.5 小時 — 這不是效率的指標,而是任務規模的指標。 這個功能如果獨自完成,可能需要 2 週;用 AI 協作,5 天完成。
🎉 結語
一場 59 小時的馬拉松給我最大的啟示是:
AI 協作的關鍵不在於「它能做什麼」,而在於「你如何組織工作」。
和 Claude Code 長時間協作,就像和一個遠端的資深工程師合作——他非常聰明,知識淵博,但你需要給他清晰的脈絡,定期同步進度,並且在卡關時換個方式問問題。
如果你也想嘗試長時間的 AI 協作開發,建議從一個「規模適中但有一定複雜度」的任務開始。不需要一開始就挑戰 60 小時,先試試 5-10 小時的任務,感受一下節奏。
📎 相關文章: