一個需求從 Prompt 到 Production 的完整旅程
這是「Agentic Engineering 實戰手冊」系列的第七篇。上一篇:Agent 產出品質保證
這篇沒有理論,只有一個完整的實戰紀錄
前幾篇我們聊了 Context Engineering、Spec-Driven Development、品質保證。每篇都有它的理論框架。
但理論歸理論,你可能最想看的是實際操作起來到底長什麼樣。
這篇就是答案。一個真實的 feature request——在 Astro 部落格裡加上「文章閱讀進度條」和「預估閱讀時間」功能。從收到需求到 deploy 上 production,我會把每一個步驟、每一段 prompt、每一次 agent 回應、每一次我介入的時刻都記錄下來。
任務背景
需求來源:我自己在分析部落格的 analytics 時發現,長文的跳出率偏高。假設之一是讀者不知道文章有多長、讀到哪裡了,缺乏「進度感」。
功能描述:
- 頁面頂部顯示閱讀進度條(scroll-based progress bar)
- 文章開頭顯示預估閱讀時間(estimated reading time)
- 只在 blog post 頁面顯示,其他頁面不要
複雜度評估:中等。涉及一個新 component、一段 client-side JS、一個 build-time 計算。不是 trivial,但也不需要架構重構。
為什麼選這個任務示範:它有代表性——有 UI component、有邏輯計算、有跨 layer 的整合(build-time + client-side)。而且它有明確的決策點和至少一次 iteration。
Step 1: Spec 撰寫(8 分鐘)
根據 Post 5 的 template,我花 8 分鐘寫了這份 spec:
## Task: Blog Reading Progress & Estimated Read Time
### Goal
在 blog 文章頁面加兩個功能:
1. 頁面頂部固定的閱讀進度條(隨滾動更新)
2. 文章 metadata 區塊顯示預估閱讀時間
### Context
- Astro 5 + MDX + Tailwind CSS 4 + TypeScript
- Blog layout: src/layouts/BlogLayout.astro
- 現有 design tokens: --color-primary, --color-bg-primary
- Dark mode 透過 .dark class 切換
- 已有 View Transitions,注意 script 在導航後要重新綁定
### Constraints
- 不引入任何 npm dependency
- 進度條用 CSS custom properties + Tailwind
- 閱讀時間在 build time 計算,不在 client side
- 中文內容以每分鐘 400 字計算(非英文的 200 wpm)
- 進度條只在 blog post 頁面出現
- 進度條不能蓋住 navigation bar
### Files to modify
- src/layouts/BlogLayout.astro(加入 component)
- 可新增 src/components/blog/ReadingProgress.astro
- 可新增 src/components/blog/ReadingTime.astro
### Verification Criteria
1. 滾動頁面時,頂部進度條從 0% 填充到 100%
2. 進度條在到達文章底部時是 100%,在頂部是 0%
3. 顯示格式:「約 N 分鐘閱讀」
4. 2000 字文章 → 顯示「約 5 分鐘閱讀」
5. Dark mode 下進度條顏色正確
6. 在非 blog 頁面(如 /about)不顯示進度條
7. npm run build 通過,無 TypeScript 錯誤
### Out of Scope
- 不做 reading analytics(不追蹤用戶實際閱讀行為)
- 不做 bookmark / save progress 功能
- 不做 table of contents(之後另外做)
關鍵決策標注:
- 中文 400 字/分鐘而非英文 200 wpm——這個如果不寫,agent 一定會用英文標準算
- 「不引入 npm dependency」——防止 agent 引入 reading-time 之類的 library
- 「進度條不能蓋住 navigation bar」——這是一個很容易被忽略的 UI 細節
- View Transitions 相關的提醒——Astro 的 View Transitions 會在頁面導航後讓 client-side script 失效,agent 需要知道這個 gotcha
Step 2: Context 準備(3 分鐘)
CLAUDE.md 已經有了大部分必要的 context(tech stack、project structure、conventions)。額外需要的只有兩件事:
- 讓 agent 看一下
BlogLayout.astro的現有結構,知道 component 要插在哪裡 - 確認 design tokens 的變數名
這些不需要我手動貼——agent 會自己 Read 相關檔案。但在 spec 裡提到「design tokens: —color-primary」是有幫助的,讓 agent 知道去找什麼。
Step 3: Agent 執行(Hands-off, 25 分鐘)
我把 spec 貼給 Claude Code,然後做了一件很重要的事——離開電腦去倒咖啡。
不是因為我不在乎,是因為 agent 沒人干預的時候通常做得更好。你如果一直盯著它、中途插嘴「等等那個不對」,反而會打斷它的 execution flow。
以下是 agent 的工作 log(摘要):
Agent 行動記錄
00:00-02:00 — 探索 codebase
Agent: 讀取 BlogLayout.astro... 了解現有結構
Agent: 讀取 global.css... 找到 design tokens
Agent: 讀取 BaseLayout.astro... 了解 nav 的 position
Agent: 讀取已有的 blog component... 理解命名慣例
02:00-08:00 — 建立 ReadingProgress.astro
Agent: 建立 src/components/blog/ReadingProgress.astro
- Fixed position bar at top of page
- Uses --color-primary for fill color
- z-index lower than nav bar
- Client-side script for scroll tracking
- Handles View Transitions with astro:after-swap
08:00-14:00 — 建立 ReadingTime.astro
Agent: 建立 src/components/blog/ReadingTime.astro
- Receives body content as prop
- Strips HTML/MDX tags, counts Chinese characters
- Calculates: Math.ceil(charCount / 400)
- Displays "約 N 分鐘閱讀"
14:00-20:00 — 整合到 BlogLayout.astro
Agent: 修改 BlogLayout.astro
- Import ReadingProgress + ReadingTime
- ReadingProgress placed after nav, before main content
- ReadingTime placed in article header metadata section
- Passes compiled content body to ReadingTime for word count
20:00-25:00 — 自我驗證
Agent: npm run build... ✅ 通過
Agent: 檢查 TypeScript... ✅ 無錯誤
Agent: 在 dev server 確認 progress bar 行為...
整個過程 25 分鐘。Agent 做了我預期的所有事情,加上一個我沒想到但很好的細節:它在 progress bar 上加了 transition: width 100ms ease 讓滾動更平滑。
Step 4: Review & 迭代(12 分鐘)
咖啡泡好了,回來看 agent 的產出。
第一輪 Review:發現兩個問題
問題 1:ReadingTime 的字數計算有 bug
Agent 的做法是先 strip HTML tags 再計算中文字數。邏輯上對,但它用的 regex 沒有處理 MDX component tags(像 <CodeBlock>...</CodeBlock>)。這些 tag 的內容會被計入字數,導致閱讀時間偏長。
問題 2:Progress bar 在手機上太粗
Agent 設了 4px 高度,在桌面上剛好,在手機上佔了太多視覺空間。
Feedback Prompt
兩個修正:
1. ReadingTime 的字數計算:MDX component tags 的內容也被計入了。
strip HTML 的 regex 需要同時處理 <ComponentName>...</ComponentName>
這種 self-closing 和 pair 的 MDX tags。或者更簡單的做法:
用 Astro 的 compiledContent 而不是 rawContent。
2. Progress bar 高度:桌面 4px OK,手機改成 3px。
用 Tailwind 的 responsive: h-[3px] md:h-[4px]
注意我的 feedback 方式:
- 具體描述問題,不是說「這個不對」
- 給出可能的修正方向,但不規定具體做法
- 第一個問題提了兩個可能的方向(改 regex 或換 API),讓 agent 選更適合的
第二輪:Agent 修正
Agent 選了「用 compiledContent 而不是 rawContent」的方案(更簡潔),修改了 progress bar 的 responsive height。
3 分鐘完成。重新跑 npm run build,通過。
Step 5: CI/CD & Deploy
代碼完成,進入自動化流程:
# Commit
git add src/components/blog/ReadingProgress.astro \
src/components/blog/ReadingTime.astro \
src/layouts/BlogLayout.astro
git commit -m "feat(blog): add reading progress bar and estimated reading time
- Fixed progress bar at page top, scroll-synced 0-100%
- Reading time calculated at build time (400 chars/min for zh-TW)
- Responsive height: 3px mobile, 4px desktop
- Handles Astro View Transitions correctly"
Push → GitHub Actions → Cloudflare Workers deploy。
CI 跑了 2 分鐘:
- TypeScript check ✅
- ESLint ✅
- Build ✅
- Deploy to staging ✅
在 staging 快速驗證:
- 長文(3000 字)→ 顯示「約 8 分鐘閱讀」 ✅
- 滾動 → progress bar 正確填充 ✅
- Dark mode → 顏色正確 ✅
- /about 頁面 → 沒有 progress bar ✅
- 手機寬度 → 3px 高度 ✅
Deploy to production。完成。
時間對比:60 分鐘 vs 以前的半天
這次的 Agentic Workflow
| 步驟 | 時間 | 誰做的 |
|---|---|---|
| 寫 Spec | 8 分鐘 | 我 |
| Context 準備 | 3 分鐘 | 我 |
| Agent 執行 | 25 分鐘 | Agent(我去倒咖啡) |
| Review | 7 分鐘 | 我 |
| Feedback + 修正 | 5 分鐘 | 我 + Agent |
| CI/CD + 驗證 | 12 分鐘 | 自動化 |
| 總計 | ~60 分鐘 |
如果用傳統方式
| 步驟 | 時間 |
|---|---|
| 理解需求 + 研究做法 | 30 分鐘 |
| 寫 ReadingProgress component | 45 分鐘 |
| 寫 ReadingTime component | 30 分鐘 |
| 整合到 BlogLayout | 20 分鐘 |
| 處理 View Transitions | 30 分鐘 |
| 寫 CSS / responsive | 20 分鐘 |
| 測試 + debug | 45 分鐘 |
| CI/CD + 驗證 | 12 分鐘 |
| 總計 | ~4 小時 |
4x 的時間差。而且注意,在 agentic workflow 裡,我的「工作時間」只有 ~23 分鐘(寫 spec + review + feedback),其他時間都是 agent 和 CI 在工作。
但不是每個任務都這麼理想
公平地說,這是一個「適合 agentic workflow」的任務——需求明確、scope 有限、技術棧 agent 很熟。
以下是 agentic workflow 不太適合的情況:
| 場景 | 原因 | 建議 |
|---|---|---|
| 全新的架構設計 | Agent 不知道你的業務 constraint | 你先設計,agent 來實作 |
| 跨多個 repo 的變更 | Context 太分散 | 拆成每個 repo 一個 task |
| Debug 未知的 production issue | 需要即時互動和直覺 | 你帶頭,agent 輔助 |
| 涉及敏感權限的操作 | 安全風險 | 你自己做,agent 不碰 |
| 第三方 API 整合(文件不完整) | Agent 可能 hallucinate API | 你先確認 API,agent 來寫整合 |
每個決策點的標注
回顧整個流程,有幾個關鍵的決策點值得標記:
決策 1:寫 Spec 還是直接叫 Agent 做?
選擇:寫 Spec。
原因:這個功能涉及 UI + 計算 + 整合,如果不寫 spec,agent 很可能做出我不想要的東西(比如用 npm library、用英文 wpm、progress bar 蓋住 nav)。8 分鐘的 spec 投資,預防了至少 1 小時的拆除工作。
決策 2:離開電腦 vs 盯著 Agent 做
選擇:離開。
原因:過去的經驗告訴我,中途干預通常讓事情變慢而不是變快。讓 agent 完整跑一輪,然後統一 review 和 feedback,比每幾分鐘插嘴一次快很多。
決策 3:怎麼給 Feedback
選擇:描述問題 + 給方向,不規定做法。
原因:「用 compiledContent 而不是 rawContent」是一個 hint,不是指令。Agent 有能力判斷哪種做法更適合——事實上它選了更乾淨的方案。如果我硬是叫它改 regex,它也會照做,但那可能不是最好的解法。
決策 4:這個 PR 是合成一個還是拆兩個?
選擇:合成一個。
原因:ReadingProgress 和 ReadingTime 雖然是兩個 component,但它們服務同一個 feature,而且修改的文件有重疊(都要改 BlogLayout.astro)。拆成兩個 PR 反而增加 overhead。
流程的核心公式
把整個流程提煉成一個公式:
Agentic Workflow =
高品質 Spec(10 分鐘)
+ 充足 Context(CLAUDE.md + codebase)
+ Hands-off 執行(讓 agent 完整跑一輪)
+ 精準 Review(focus 在 agent 特有的錯誤模式)
+ 快速 Feedback Loop(描述問題 + 給方向)
每一步都不難。難的是紀律——在你想偷懶直接打「幫我加一個功能」的時候,花 10 分鐘寫一份好的 spec。在你想中途插嘴的時候,忍住去倒杯咖啡。在你覺得「agent 的 code 看起來很專業不用看了」的時候,還是打開 diff 仔細 review 一遍。
這個紀律,就是 Agentic Engineering 和 Vibe Coding 的分界線。
Takeaway
-
Agentic workflow 的核心是「前置投資」——Spec 和 Context 的品質決定後續效率。8 分鐘的 spec + 3 分鐘的 context 準備,讓 25 分鐘的 agent 執行幾乎零障礙。
-
60 分鐘完成以前半天的工作,靠的不是魔法,是方法論——但前提是任務適合 agentic workflow、你的 spec 夠好、你的 CI 夠完善。不是所有任務都適合。
-
最重要的技能不是寫 prompt,是知道什麼時候介入、什麼時候放手——讓 agent 完整跑一輪再統一 review,比每隔幾分鐘干預一次更有效率。你的角色是 reviewer 和 direction-setter,不是 co-pilot seat 的指揮官。