Branch8

外包越南開發團隊驗收標準:如何寫清楚 Acceptance Criteria

Matt Li
September 6, 2026
12 mins read
外包越南開發團隊驗收標準:如何寫清楚 Acceptance Criteria

Key Takeaways

  • 用 Given/When/Then 寫 AC,強迫寫出前置條件、動作與可觀察結果
  • 通用條件提到 Definition of Done,AC 只描述業務行為
  • 非功能需求必須量化:P95 延遲、LCP 秒數、掃描等級
  • 把 AC 掛進 CI 成為 merge gate,驗收由機器裁決
  • SOW 明訂 UAT 回合上限與缺陷分級,防止驗收無限延期

驗收標準(Acceptance Criteria)要寫得清楚,關鍵是把「做完」定義成可自動驗證的條件:每條標準用 Given/When/Then 格式、綁定測試腳本、寫入合約附件 SOW,並在 CI 管線中作為 merge gate 執行。香港公司與越南團隊之間的爭議,九成源於驗收語意含糊,而非技術能力。

為什麼跨境外判最常在驗收環節翻車?

香港、新加坡公司把工程交付放在越南、菲律賓或馬來西亞,通常是為了取得工程深度與時區覆蓋,而不是單純壓成本。根據 World Bank 的越南國家概覽,越南過去十年維持高於區域平均的實質 GDP 增長,軟件與 IT 服務業是其中主要出口類別之一——人才供給不是問題。

問題出在需求傳遞的損耗。Standish Group 的 CHAOS 研究長期指出,需求不完整與需求變動是專案失敗的前列成因。當這個損耗再疊加一層語言(粵語/英文/越南語)、一層合約(HK 公司法下的 SOW 對越南 LLC)、一層時區,模糊的一句「支援多幣別結帳」就會變成三次返工。

實務上我們看到的分歧模式很固定:

  • 功能範圍分歧:香港方認為「多幣別」包含匯率快取與退款原幣別回沖;越南方只實作了顯示層轉換。
  • 非功能分歧:沒有寫明 P95 回應時間,交付一個在 500 筆資料下順暢、在 50 萬筆下逾時的清單頁。
  • 完成度分歧:「做完了」等於本機跑得動,還是等於已通過 staging 的自動化回歸測試?

每一項都可以用一句寫得夠死的 Acceptance Criteria 提前消除。

開始之前需要準備什麼?

在寫第一條 AC 之前,先把這些前置條件備妥,否則 AC 會變成無法執行的一紙願望。

  1. 一份具法律效力的 SOW,並將 AC 列為附件:AC 不應只存在於 Jira。合約條款寫「交付物須通過附件 A 之驗收標準」,附件 A 由 Jira 匯出並版本化。
  2. 共用的追蹤系統與單一事實來源:Jira Cloud 或 Linear,越南團隊擁有寫入權限,不是每週交 Excel。
  3. 可重現的環境:至少 dev / staging / prod 三層,staging 資料量要接近正式環境的量級。
  4. CI 管線已就緒:GitHub Actions 或 GitLab CI,能跑 lint、單元測試、E2E。
  5. 明確的 Definition of Done(DoD):AC 是「這張票要滿足什麼」,DoD 是「所有票都要滿足什麼」。兩者不可混為一談。
  6. 時區重疊窗口:香港(UTC+8)與越南(UTC+7)只差一小時,這是相對倫敦或紐約發包越南的結構性優勢——每天有完整重疊工作日可做驗收回合。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

步驟一:把 Definition of Done 從 AC 中抽離

最常見的錯誤是把「有寫單元測試」重複貼在 40 張票的 AC 裡。應該把通用條件提到 DoD,讓 AC 專注於業務語意。

建議把 DoD 寫成倉庫內的檔案,例如 docs/definition-of-done.md,並在 PR template 中引用:

1## Definition of Done(適用所有交付項)
2- [ ] 程式碼已通過 code review(至少 1 位 reviewer)
3- [ ] 單元測試覆蓋新增邏輯,整體覆蓋率不低於 70%
4- [ ] 已部署至 staging 並通過完整 E2E 回歸套件
5- [ ] 無新增 ESLint error、無新增 TypeScript error
6- [ ] npm audit 無 high / critical 等級新增漏洞
7- [ ] API 變更已更新 OpenAPI schema
8- [ ] 中英文 UI 文案已交付並經 PM 確認

把這份檔案作為合約附件的一部分。之後每張票的 AC 就只需描述行為。

步驟二:用 Given / When / Then 寫每一條驗收標準

Gherkin 語法之所以適合跨境團隊,是因為它強迫你寫出前置狀態、觸發動作與可觀察結果三者,語意歧義空間小,而且可以直接轉成自動化測試。

反面示範

AC:使用者可以用信用卡付款,要支援多幣別。

這句話至少留下六個未定義項:哪些卡別?哪些幣別?匯率來源?失敗如何處理?3DS 是否必要?退款幣別?

正面示範

1Feature: 多幣別信用卡結帳
2
3 Background:
4 Given 商店基準幣別為 HKD
5 And 匯率來源為 ExchangeRate API,快取 TTL 為 3600 秒
6
7 Scenario: 以 SGD 完成結帳
8 Given 訪客的 IP 地理位置解析為 SG
9 And 購物車小計為 HKD 1,000.00
10 When 訪客進入結帳頁
11 Then 顯示幣別應為 SGD
12 And 顯示金額應為 1,000.00 × 當日 HKD→SGD 匯率,四捨五入至 2 位小數
13 And 頁面應顯示文案「以 SGD 計價,實際扣款幣別為 HKD」
14
15 Scenario: 3DS 驗證失敗
16 Given 訪客使用需 3DS 驗證的卡片
17 When 3DS 驗證回傳失敗
18 Then 訂單狀態應維持 pending_payment
19 And 不應建立任何 Shopify Order
20 And 使用者應看到錯誤代碼 PAY_3DS_FAILED 與重試按鈕
21
22 Scenario: 匯率服務逾時
23 Given ExchangeRate API 在 2000ms 內未回應
24 When 訪客進入結帳頁
25 Then 系統應使用最近一次快取匯率
26 And 應記錄 WARN 等級日誌,含 correlation_id

第三個 scenario 是關鍵。大部分驗收爭議發生在例外路徑,不是快樂路徑。 每個 feature 至少寫一條失敗情境與一條邊界情境。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

步驟三:把非功能需求量化成數字

「要快」、「要安全」、「要好用」無法驗收。改寫成有量測方法的門檻:

效能

  • 商品列表 API 在 staging(資料量 ≥ 200,000 筆商品、並發 50 rps)下,P95 回應時間 ≤ 400ms,量測工具為 k6,腳本置於 perf/product-list.js
  • 首頁 Largest Contentful Paint 在 Lighthouse mobile(4G throttling、Moto G Power preset)下 ≤ 2.5 秒。這個門檻對齊 Google Web Vitals 官方文件所定義的 LCP「Good」區間。

可執行的 k6 腳本片段:

1import http from 'k6/http';
2import { check } from 'k6';
3
4export const options = {
5 scenarios: {
6 steady: { executor: 'constant-arrival-rate', rate: 50, timeUnit: '1s',
7 duration: '3m', preAllocatedVUs: 100 },
8 },
9 thresholds: {
10 'http_req_duration{endpoint:list}': ['p(95)<400'],
11 http_req_failed: ['rate<0.01'],
12 },
13};
14
15export default function () {
16 const res = http.get(`${__ENV.BASE_URL}/api/products?page=1&limit=48`,
17 { tags: { endpoint: 'list' } });
18 check(res, { 'status 200': (r) => r.status === 200 });
19}

k6 在 threshold 未達標時會以非零 exit code 結束,可直接掛進 CI。驗收就不再是「我覺得慢」,而是 pipeline 紅或綠。

安全

  • OWASP ZAP baseline scan 無 High 等級告警。
  • 所有 API endpoint 皆有 authz 測試案例,覆蓋「未登入」「登入但非擁有者」「管理員」三種角色。
  • 個資欄位於資料庫加密靜態儲存。若處理香港客戶資料,須符合《個人資料(私隱)條例》下的資料保安原則;若涉及歐盟客戶,須另行標註 GDPR 資料處理者責任。跨境傳輸條款應在 SOW 內獨立成節,不要塞在 AC 裡。

可維護性

  • 新增 API 必須同步更新 openapi.yaml,CI 以 redocly lint 驗證。
  • 資料庫遷移必須可逆(提供 down migration)。

步驟四:讓 AC 在 CI 管線中自動裁決

寫得再好的 AC,如果只靠人眼檢查,跨時區就會退化成信任問題。把驗收條件變成 merge gate:

1# .github/workflows/acceptance.yml
2name: Acceptance Gate
3on:
4 pull_request:
5 branches: [main, release/**]
6
7jobs:
8 acceptance:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12 - uses: actions/setup-node@v4
13 with:
14 node-version: '20'
15 cache: 'npm'
16 - run: npm ci
17 - name: Lint & types
18 run: npm run lint && npm run typecheck
19 - name: Unit tests with coverage gate
20 run: npm run test -- --coverage --coverageThreshold='{"global":{"lines":70}}'
21 - name: BDD acceptance scenarios
22 run: npx cucumber-js --tags 'not @wip' --format summary
23 - name: E2E against preview
24 run: npx playwright test --reporter=line
25 env:
26 BASE_URL: ${{ steps.deploy.outputs.preview_url }}
27 - name: Performance thresholds
28 run: k6 run perf/product-list.js
29 env:
30 BASE_URL: ${{ steps.deploy.outputs.preview_url }}
31 - name: Security baseline
32 uses: zaproxy/action-[email protected]
33 with:
34 target: ${{ steps.deploy.outputs.preview_url }}

關鍵設定:在 GitHub repository settings 中,把上述 job 設為 required status check,並開啟 branch protection。這樣「未通過驗收標準的程式碼無法進入 main」不是流程共識,而是系統強制。

對於發包方(香港或新加坡的 product owner),這帶來一個具體好處:你不需要在越南團隊的工作時間內在線監督。當你早上打開 PR 列表,綠燈代表 AC 已機器驗證,你只需審查機器無法判斷的部分——業務邏輯是否符合意圖、UX 是否合理。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

步驟五:定義 UAT 回合與缺陷分級

自動化擋不住的部分,用結構化的 UAT(User Acceptance Testing)流程處理。SOW 內應明訂:

  1. UAT 窗口長度:例如交付後 5 個工作天。逾期未回報視為驗收通過(deemed acceptance)。這條保護的是承包方,能大幅提升合作意願。
  2. 回合次數:每個交付里程碑包含 2 個 UAT 回合,第 3 回合起若缺陷源自新增需求,走 change request。
  3. 缺陷分級與修復時限
  • P1 阻斷:核心流程無法完成(無法下單、無法登入)。24 小時內修復,阻擋驗收。
  • P2 嚴重:功能可用但結果錯誤(金額計算偏差、報表數字錯)。3 個工作天,阻擋驗收。
  • P3 次要:UI 錯位、文案錯字。可帶入下個 sprint,不阻擋驗收。
  • P4 建議:改善想法。一律轉為 backlog,不列入本次驗收。

把 P4 明確排除,是防止「驗收無限延期」最有效的一條。沒有這條,UAT 會變成需求收集會議。

  1. 缺陷回報格式:強制使用 Jira issue template,必填欄位包含環境、瀏覽器與版本、重現步驟、預期結果、實際結果、截圖或錄影、correlation_id。缺欄位的票直接退回,不計入 SLA 時鐘。

用 LLM 加速 AC 撰寫(同時避開它的陷阱)

2026 年這一環已經很實用:把粗略需求丟給 LLM,產出 Gherkin 草稿,人類負責審查與補例外路徑。一個可重複使用的提示模板:

1你是資深 QA 分析師。將以下需求轉為 Gherkin scenarios(繁體中文)。
2規則:
31. 每個 feature 至少產出 1 個快樂路徑、2 個例外路徑、1 個邊界值情境。
42. 所有金額、時間、數量必須是具體數值,不得使用「適當」「合理」等模糊詞。
53. 若需求中缺少判斷所需資訊,於檔案末端以 OPEN QUESTIONS 區塊列出,不要自行假設。
64. 不得產出無法由自動化測試驗證的斷言。
7
8需求:
9"""
10{貼上原始需求}
11"""

第 3 條規則是重點。LLM 的預設行為是填補空白,而填補出來的假設一旦進入合約附件,就是未來的爭議來源。要求它明確列出「不知道的事」,把這份 OPEN QUESTIONS 清單當成與越南團隊的第一次會議議程。

根據 GitHub 對 Copilot 使用者的研究報告,開發者在使用 AI 輔助時普遍回報流程加速,但這類工具的產出仍需人工審核——AC 撰寫同理:LLM 負責產量,人類負責判斷。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

實務案例:多品牌零售集團的驗收改造

Branch8 曾為一家在大中華與東南亞營運的多品牌零售集團重整跨境開發流程。當時的狀況是:香港總部負責產品定義,工程交付分散在越南與台灣,驗收依賴每兩週一次的視訊 demo。

改造的三個動作是:

  1. 把 demo 驗收改為 PR 級驗收——每個 PR 附帶 preview URL 與自動化報告,product owner 在自己的時區審查。
  2. 將原本散落在會議紀錄的需求,全數轉寫為 features/ 目錄下的 .feature 檔案,與程式碼同倉庫版本控制。需求變更走 PR,有 diff、有 reviewer。
  3. 缺陷分級表寫入 SOW 附件,並在 Jira 建立對應的 priority scheme 與 SLA 自動化規則。

這裡的機制價值在於:需求變更變成可追溯的 commit。當發包方與承包方對「這條是不是原始範圍」有分歧時,git log features/checkout.feature 就是答案,不需要翻六個月前的 WhatsApp 對話。

常見問題排查

越南團隊說 AC 通過了,但 PM 認為功能不對

八成是 AC 描述了實作而非意圖。檢查你的 Then 子句:如果寫的是「呼叫 /api/v2/checkout」,那是實作細節;應該寫「訂單狀態變為 confirmed 且庫存扣減 1」。修法:把 AC 的 Then 全部改寫為使用者或系統的可觀察結果。

E2E 測試在 CI 隨機失敗(flaky)

flaky test 會侵蝕驗收機制的信任度,一旦團隊習慣「重跑一次就好」,gate 就失效了。先在 Playwright 開啟 trace:

1// playwright.config.ts
2use: { trace: 'retain-on-failure', video: 'retain-on-failure' },
3retries: process.env.CI ? 2 : 0,

把重試次數限制在 2 次,並建立 flaky test 看板。連續一週 flaky 的測試必須修復或隔離,不能長期掛著。

staging 通過但 production 出錯

通常是資料量或設定漂移。把「staging 資料集規模須達 production 的 X%」寫進 AC 的 Background 區塊,並用 Terraform 或同等 IaC 管理兩邊環境設定,讓差異可 diff。

驗收清單愈滾愈長,交付永遠無法結案

檢查是否缺少 P4 排除條款與 UAT 回合上限。同時檢查 AC 是否在交付後被追加——AC 一旦凍結(例如 sprint 開始時),任何新增都應走 change request 而非直接改票。在 Jira 中可用 workflow condition 限制 In Progress 狀態下的 AC 欄位編輯權限。

語言歧義導致誤解

若團隊混用中英文,指定 AC 的權威語言(通常英文),中文為參考譯本,並在 SOW 註明衝突時以權威語言為準。技術術語建立共用 glossary,例如「訂單」對應 Order(已付款)而非 Cart(未結帳)。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

可直接複製的驗收標準檢查表

每寫完一條 AC,用這七個問題檢查:

  1. 這條標準能不能由一個從未參與討論的人獨立判斷通過與否?
  2. 所有數值是否具體(金額、時間、筆數、百分比)?
  3. 有沒有至少一條失敗路徑?
  4. 驗證方法是否指名工具與腳本路徑?
  5. 這條是描述「意圖」還是「實作」?
  6. 需要哪些測試資料?資料從哪來?
  7. 這條屬於 AC 還是應該提到 DoD?

七題全過,這條 AC 才可以進 sprint。

跨境交付的成敗,不取決於團隊在哪個城市,而取決於「完成」這兩個字是否被寫成機器可判讀的條件。越南與香港的一小時時差、東南亞成熟的工程人才池、以及可在 CI 中自動裁決的驗收管線,三者結合起來的效果,遠勝過每週一次的進度會議。

如果你正在建立跨境開發團隊,或現有的外判交付卡在驗收環節,Branch8 在香港、新加坡、台灣、越南與澳洲設有交付據點,可協助你設計 SOW 附件、驗收管線與缺陷分級制度——歡迎與我們的團隊談談你的交付流程現況。

Sources

FAQ

Acceptance Criteria 是針對單一需求票的業務條件,例如「以 SGD 結帳時顯示金額須四捨五入至 2 位小數」;Definition of Done 是所有交付項共用的品質門檻,例如覆蓋率、code review、部署至 staging。把 DoD 抽出來能避免在每張票重複貼相同條件,也讓 AC 專注於業務語意。

About the Author

Matt Li

Co-Founder & CEO, Branch8 & Second Talent

Matt Li is Co-Founder and CEO of Branch8, a Y Combinator-backed (S15) Adobe Solution Partner and e-commerce consultancy headquartered in Hong Kong, and Co-Founder of Second Talent, a global tech hiring platform ranked #1 in Global Hiring on G2. With 12 years of experience in e-commerce strategy, platform implementation, and digital operations, he has led delivery of Adobe Commerce Cloud projects for enterprise clients including Chow Sang Sang, HomePlus (HKBN), Maxim's, Hong Kong International Airport, Hotai/Toyota, and Evisu. Prior to founding Branch8, Matt served as Vice President of Mid-Market Enterprises at HSBC. He serves as Vice Chairman of the Hong Kong E-Commerce Business Association (HKEBA). A self-taught software engineer, Matt graduated from the University of Toronto with a Bachelor of Commerce in Finance and Economics.