# 從需求定義者到程式碼實作者:一個 PM 轉職工程師的 TDD 與 EDD 領悟

三年前的我,坐在 Sprint Planning 會議上,看著工程師 Kevin 說他需要兩天時間來「重構購物車邏輯並補完測試案例」。
我當時心裡 OS:「這功能不是上個月才做好嗎?為什麼要重構?而且補測試要兩天?直接改程式碼不就好了?」
Kevin 看出我的疑惑,解釋說:「沒有測試的程式碼就像沒有地基的房子,改一個地方可能整棟垮掉。」
我點點頭,但心裡還是覺得工程師太龜毛。
直到那個專案出包的那天。
## 那個讓我決定轉職的 Bug
那是一個看似簡單的需求:把折扣計算邏輯從「滿千折百」改成「滿五百折五十」。
我寫了清楚的需求文件,開了 Jira ticket,設定優先級為 P1。工程師說「這很簡單,一個下午就好」。
結果上線當天,客服電話被打爆。
不是因為新的折扣邏輯有問題,而是修改折扣計算的時候,不小心動到了會員等級判斷的部分。結果所有 VIP 會員都無法享受專屬折扣,系統把他們當成一般會員處理。
我看著工程師 debug 到凌晨三點,突然想起 Kevin 說的那句話:「沒有測試的程式碼就像沒有地基的房子。」
那個晚上,我做了一個決定:我要學寫程式。
不是要轉職當工程師,只是想理解「為什麼改一個邏輯會影響到其他功能」、「為什麼測試這麼重要」。
結果越學越深,半年後,我真的遞出了轉職申請。
## 從 PRD 到 Test Case:我的第一次頓悟
轉職後的第一個月,技術主管丟給我一本書:《Test Driven Development: By Example》。
「先從 TDD 開始學,」他說,「這會幫你建立正確的思維模式。」
我翻開書,看到第一個範例是寫一個計算器。作者說要「先寫測試,再寫程式碼」。
我心想:這不就是我以前寫需求文件的邏輯嗎?
**以前當 PM 寫的 User Story**:
```
As a 使用者
I want to 輸入兩個數字並選擇加法
So that 系統能顯示正確的計算結果
Acceptance Criteria:
- Given 使用者輸入 2 和 3
- When 選擇加法
- Then 系統顯示 5
```
**現在當工程師寫的 Test Case**:
```python
def test_addition():
calculator = Calculator()
result = calculator.add(2, 3)
assert result == 5
```
欸,這根本是同一件事啊!
只是 PM 用自然語言寫,工程師用程式碼寫而已。
那個瞬間我突然理解了 TDD 的精髓:**先定義「完成」的標準,再去實作功能**。這不就是我做了三年的產品管理嗎?
我開始瘋狂練習 TDD。每次寫功能前,我都會先想:「如果我是 PM,我會怎麼寫這個驗收標準?」然後把它轉成測試案例。
**Red(紅燈)** = 需求還沒實現
**Green(綠燈)** = 功能符合驗收標準
**Refactor(重構)** = 在不改變需求的前提下優化實作
這個循環跟敏捷開發的節奏完美契合。
我甚至開始覺得,PM 轉工程師搞不好是優勢。因為我太習慣「先定義完成標準」這件事了,TDD 對我來說根本是直覺反應。
直到我接到第一個 AI 相關的需求。
## 無法定義的「驗收標準」
公司決定在客服系統加入 AI 問答功能。技術主管知道我以前是 PM,就把需求分析的工作也交給我。
我打開熟悉的 Notion,開始寫需求文件:
```markdown
## User Story
As a 客戶
I want to 向 AI 客服詢問退貨流程
So that 我能快速了解如何退貨
## Acceptance Criteria
- Given 使用者輸入「如何退貨?」
- When 系統呼叫 AI 模型
- Then 系統回答「請在收到商品 7 天內...」
```
寫到這裡,我卡住了。
AI 的回答每次都不一樣。有時候它會說「收貨後七日內」,有時候說「7 天內」,有時候還會加上「記得保持商品完整喔」這種額外資訊。
我該怎麼寫 Acceptance Criteria?
以前當 PM 的時候,如果規格不明確,我會跟設計師或工程師討論,直到我們對「完成」有共識為止。但現在,我面對的是一個 LLM,它的輸出本質上就是不確定的。
我試著寫測試:
```python
def test_ai_customer_service():
bot = AICustomerService()
response = bot.answer("如何退貨?")
assert response == "請在收到商品 7 天內,保持商品完整,透過官網申請退貨。"
```
執行測試。紅燈。
我調整提示詞,再執行。還是紅燈。
但 AI 的回答明明是對的啊!只是用字不同而已。
我突然理解為什麼有些工程師會說「AI 應用很難測試」了。這不是技術問題,是**我們無法用傳統的『二元判斷』來評估 AI 的輸出**。
作為 PM,我最怕的就是「需求不明確」。但現在,我遇到的是「無法明確定義驗收標準」的情況。
這比需求不明確還要慘。
## PM 思維的反擊:從 KPI 到評估指標
那天晚上,我翻出以前當 PM 時做的 OKR 文件。
我記得當時公司要衡量「客服品質」,我設計了一套評估指標:
- 首次回應時間 < 30 秒
- 問題解決率 > 85%
- 客戶滿意度 > 4.0/5.0
- 平均對話輪數 < 5
等等,這不就是多維度評估嗎?
我沒有說「客服必須說『您好,我是客服專員 Alice,很高興為您服務』這句話」,而是定義了**好的客服應該符合的標準**。
這跟 AI 的情況很像啊!
我不需要規定 AI 一定要回答什麼,我只需要定義「好的回答應該符合哪些標準」。
我開始重新設計測試策略:
```python
class AIResponseEvaluator:
"""用 PM 思維設計的 AI 評估器"""
def evaluate(self, question, answer, reference_answer):
"""
多維度評估 AI 回答品質
就像評估 KPI 一樣
"""
scores = {}
# KPI 1: 資訊準確性(類似業務指標)
scores['accuracy'] = self._check_key_points(
answer,
required_keywords=["7 天", "完整", "申請"]
)
# KPI 2: 資訊完整性(類似覆蓋率指標)
scores['completeness'] = self._compare_with_reference(
answer,
reference_answer
)
# KPI 3: 用戶體驗(類似滿意度指標)
scores['user_experience'] = self._evaluate_tone(
answer,
expected_tone="friendly_and_professional"
)
# KPI 4: 效率指標(類似回應時間)
scores['conciseness'] = self._check_word_count(
answer,
max_words=80
)
# 加權計算(就像 OKR 的權重設計)
total_score = (
scores['accuracy'] * 0.4 +
scores['completeness'] * 0.3 +
scores['user_experience'] * 0.2 +
scores['conciseness'] * 0.1
)
return {
'total_score': total_score,
'breakdown': scores,
'passed': total_score >= 0.8 # 80 分門檻
}
```
這個設計讓我想起以前在 Google Analytics 設定轉換目標的邏輯。
你不會說「使用者一定要點擊這個按鈕」,而是定義「成功的使用者旅程應該包含哪些關鍵步驟」。
我開始用這套邏輯設計測試:
```python
def test_ai_response_quality():
"""不測試確切內容,而是測試品質指標"""
bot = AICustomerService()
evaluator = AIResponseEvaluator()
# 測試案例 1:退貨政策
response = bot.answer("如何退貨?")
result = evaluator.evaluate(
question="如何退貨?",
answer=response,
reference_answer="請在收到商品 7 天內,保持商品完整,透過官網申請退貨。"
)
assert result['passed'], f"品質評分 {result['total_score']:.2f} 低於門檻"
assert result['breakdown']['accuracy'] > 0.7, "關鍵資訊缺失"
# 測試案例 2:運費計算
response = bot.answer("運費怎麼算?")
result = evaluator.evaluate(
question="運費怎麼算?",
answer=response,
reference_answer="單筆訂單滿 1000 元免運,未滿收取 80 元運費。"
)
assert result['passed'], f"品質評分 {result['total_score']:.2f} 低於門檻"
```
第一次執行,平均分數 72 分。不及格。
我分析了低分案例,發現 AI 常常:
1. 回答太冗長(沒有遵守簡潔性原則)
2. 缺少具體數字(準確性不足)
3. 語氣太正式或太口語化(用戶體驗不穩定)
這就跟我以前做 PM 時分析產品指標一樣。找出問題,優化,再測試。
我調整了提示詞:
```python
system_prompt_v2 = """你是電商客服 AI,請遵循以下規範:
【資訊要求】
- 必須包含具體數字(天數、金額、百分比)
- 必須包含操作步驟
【語氣要求】
- 友善但專業
- 使用「您」而非「你」
- 適度使用表情符號增加親和力
【格式要求】
- 控制在 50 字以內
- 重點使用條列式
- 先講結論再講細節
"""
```
重新評估,平均分數跳到 89 分。
那個瞬間,我突然意識到:**我不是在寫測試,我是在設計產品的品質標準**。這跟我以前制定 PRD 裡的 Success Metrics 根本是同一件事。
後來我才知道,這套方法有個名字:**Evaluation-Driven Development(評估驅動開發)**,簡稱 EDD。

## 兩個世界的融合
現在回想起來,我的 PM 背景反而成了優勢。
**傳統工程師學 TDD** → 要改變「先寫程式碼再測試」的習慣
**PM 轉職工程師學 TDD** → 只是把「寫驗收標準」換成「寫測試案例」
**傳統工程師遇到 AI** → 困惑於無法寫確定性測試
**PM 轉職工程師遇到 AI** → 直覺套用「多維度評估指標」的思維
我開始理解為什麼 IBM 和 Microsoft 的研究顯示,採用 TDD 的專案缺陷率能降低 40-90%。因為 TDD 的本質就是**強迫你在寫程式前先想清楚「完成」的定義**。
這不就是 PM 每天在做的事嗎?
而 EDD 則是**把評估標準從二元判斷擴展到多維度量化**。這也是 PM 在設計 OKR 和 KPI 時的日常。
現在我的專案裡,TDD 和 EDD 和平共存:
**TDD 部分**(確定性邏輯):
```python
def test_calculate_shipping_fee():
"""測試運費計算邏輯(確定性)"""
order = Order(total=800)
assert order.calculate_shipping() == 80
order = Order(total=1200)
assert order.calculate_shipping() == 0
```
**EDD 部分**(AI 生成內容):
```python
def test_ai_recommendation_quality():
"""測試 AI 推薦品質(多維度評估)"""
recommender = AIRecommender()
evaluator = RecommendationEvaluator()
products = recommender.suggest_for_user(user_id=123)
score = evaluator.evaluate(
recommendations=products,
metrics=['relevance', 'diversity', 'novelty']
)
assert score['overall'] >= 0.85
assert score['relevance'] >= 0.9 # 相關性要特別高
```
這兩種方法不是對立的,而是互補的。就像 PM 和工程師不是對立的,而是互補的一樣。
## PM 轉 Coder 的獨特優勢
這一年多的轉職經驗,讓我發現 PM 背景帶來的幾個優勢:
### 1. 對「為什麼」的執著
工程師容易陷入「怎麼做」的細節,但 PM 訓練讓我總是先問「為什麼要做」。
寫測試時,我不會機械性地覆蓋所有分支,而是先問:
- 這個功能的核心價值是什麼?
- 用戶最在意的是哪個部分?
- 什麼情況下的失敗會造成最大損失?
這讓我的測試更聚焦在關鍵路徑上。
### 2. 對用戶體驗的敏感度
設計 AI 評估指標時,很多工程師會糾結於技術指標(如 BLEU score、ROUGE score)。
但我會問:「用戶真的在乎這個嗎?」
所以我設計的評估指標通常包含:
- 回答是否解決了用戶的問題(任務完成率)
- 用戶是否需要追問(對話效率)
- 用戶是否感到被尊重(情感體驗)
這些都是從產品角度出發的指標。
### 3. 對 Trade-off 的理解
PM 最常做的就是優先級排序和取捨。
這讓我在設計評估指標時,不會追求「完美」,而是追求「適合當前階段的好」。
例如,MVP 階段我可能只測試核心功能的準確性;產品成熟後才加入語氣、簡潔度等細緻指標。
### 4. 文檔化的習慣
PM 出身的我,註解和 README 寫得特別詳細。
這在團隊協作時特別有用,新人看我的測試案例,就能理解這個功能要達成什麼目的。
```python
def test_refund_eligibility():
"""
測試退款資格判斷邏輯
Business Context:
- 根據 2024 Q1 客訴分析,退款糾紛主要來自「收貨時間」認定
- 此測試確保系統正確計算 7 天鑑賞期
Edge Cases:
- 假日不計入鑑賞期
- 預購商品從實際收貨日起算
Related:
- Jira: PROD-1234
- Policy Doc: https://...
"""
# 測試程式碼...
```
## 給其他想轉職的 PM 的建議
如果你也在考慮從 PM 轉工程師,我想分享幾個心得:
### 你的 PM 經驗不會白費
很多人轉職時會擔心「過去的經驗都用不上」。其實不是。
你學過的需求分析、用戶研究、指標設計,都能在工程實踐中派上用場。特別是在設計測試策略和評估指標時,PM 思維是巨大優勢。
### 從 TDD 開始學比較容易
因為 TDD 的思維模式跟寫 User Story 很像,PM 轉職者通常能很快上手。
這會給你信心,讓你覺得「我可以做好工程師的工作」。
### 不要丟掉產品思維
有些轉職者會矯枉過正,刻意壓抑產品思維,只想「當個純粹的工程師」。
但其實,懂產品的工程師在團隊裡非常稀缺。保留你的產品敏感度,這會讓你成為「能獨立思考的工程師」而不只是「執行需求的碼農」。
### AI 時代對 PM 背景更友善
隨著 AI 應用越來越多,「如何評估 AI 的品質」成為新的挑戰。
這正是 PM 最擅長的:**定義成功標準、設計評估指標、量化產品價值**。
所以如果你正在猶豫,這可能是最好的轉職時機。
## 工具推薦(實戰驗證過的)
### TDD 工具
**Python 生態**:
```bash
pip install pytest pytest-cov pytest-mock faker
```
- `pytest`:測試框架,語法簡潔
- `pytest-cov`:程式碼覆蓋率報告
- `pytest-mock`:Mock 外部依賴
- `faker`:生成測試資料(省得自己想)
**學習資源**:
- 《Test Driven Development: By Example》- Kent Beck(TDD 之父)
- 線上課程:Test-Driven Development 101 (Udemy)
### EDD 工具
**Promptfoo**(我目前主力):
```bash
npm install -g promptfoo
```
簡單的配置檔案就能跑批次評估:
```yaml
prompts:
- file://prompts/customer_service_v1.txt
- file://prompts/customer_service_v2.txt
providers:
- openai:gpt-4
tests:
- vars:
question: "如何退貨?"
assert:
- type: contains
value: "7 天"
- type: javascript
value: output.length < 200 # 簡潔性
- type: llm-rubric
value: "回答是否友善且專業"
```
執行評估:
```bash
promptfoo eval
```
**其他值得關注的工具**:
- **LangSmith**:適合 LangChain 生態系統
- **DeepEval**:輕量級,適合快速驗證
- **Weights & Biases**:如果你需要追蹤模型訓練過程
## 寫在最後:從定義需求到定義品質
轉職這一年多,我最大的收穫不是學會了 Python 或 JavaScript,而是理解了**開發方法論的本質**。
TDD 教我:**在動手之前先想清楚目標**。
EDD 教我:**用多維度的標準取代二元的判斷**。
但其實,這些都是我當 PM 時就在做的事。
當 PM 時,我定義「什麼是成功的產品」。
當工程師時,我定義「什麼是合格的程式碼」。
形式不同,本質相同。
所以如果你也是 PM,正在考慮轉職,不用太擔心。你已經具備了很多工程思維,只是用不同的語言表達而已。
而如果你是工程師,我建議你花點時間理解 PM 的思維方式。特別是在 AI 時代,「如何定義品質」這件事,產品經理的經驗可能比傳統工程師更有幫助。
兩個世界的融合,或許能創造出更好的開發方法。
就像 TDD 和 EDD 的融合一樣。
---
## 延伸資源
**關於 TDD**:
- IBM/Microsoft 研究:TDD 降低 40-90% 缺陷率
- Martin Fowler 的 TDD 實踐文章
- Uncle Bob 的 Clean Code 系列
**關於 EDD**:
- arXiv 論文:《Challenges in Testing Large Language Model Based Applications》
- Medium 系列:《Evaluation-Driven Development for Agentic Applications》
- Promptfoo 官方文件:https://promptfoo.dev/
**關於 PM 轉職**:
- 《The Pragmatic Programmer》(實用主義程式設計師)
- 《Refactoring》(重構:改善既有程式的設計)
- Coding Interview University (GitHub)
**社群資源**:
- r/cscareerquestions(Reddit)
- Blind(匿名職場社群)
- TDD Practitioners(LinkedIn Group)
---
**關於作者**
一個從產品經理轉職工程師的學習者。曾經以為寫程式和寫需求文件是兩回事,後來發現它們都在回答同一個問題:「什麼是好的?」
現在的我,白天用 Python 寫程式,晚上用 Notion 整理筆記,周末會懷念開 Sprint Planning 的日子。
如果你也在轉職路上,歡迎留言交流。我們都是路上的同伴。
---
**留言討論**
你是 PM 轉職工程師嗎?或是工程師想轉 PM?
你覺得兩種角色最大的差異是什麼?
在 AI 開發上,你遇到了哪些挑戰?
歡迎在下方留言分享你的經驗。
---
**標籤**:#PM轉職 #工程師 #TDD #EDD #測試驅動開發 #評估驅動開發 #AI開發 #職涯轉換 #產品經理