SaaS 選型訪談方法論 - 從使用者操作推導到技術選型
專案初始化的選型決策,常見的起手式是直接列工具名單:選哪個資料庫、要上 k8s 嗎、queue 用哪家。這個順序跳過了選型真正的依據——產品要提供使用者哪些操作、領域邊界怎麼切、哪種失敗的代價最高。SaaS 選型訪談方法論把順序反過來:從使用者操作推導功能、從功能推導領域結構、最後才到技術選型,並把整段推導包裝成一份可重複執行的結構化訪談協議。
方法論要解的問題
這套方法論的核心命題是成本不對稱:設計問題拖到開發中途才浮現,修正的代價遠高於在訪談階段多問十題。沒想清楚的操作、沒切清楚的領域邊界、沒被告知的防護缺口,最後都會在開發中途以重工的形式收費。訪談協議的責任是逼這些設計問題在寫第一行程式之前、於已知需求的範圍內浮現——因此訪談問題的數量刻意不設上限,問漏才是成本;節奏上每輪三到五題讓受訪者好消化,輪數跟著覆蓋率走。
協議同時內建「產品名攔截」:受訪者開口指定產品(「我要用 MongoDB」「直接上 k8s」)時,先回到需求確認背後動機(schema 變動頻繁?團隊熟悉度?),需求成立後產品可以直接採納。產品名是選型的輸出,由需求與領域模型推導出來,而非訪談的輸入。
推導鏈:從定錨到決策記錄
整條推導鏈的設計邏輯是:每一站的產出都是下一站的輸入,技術問題永遠錨在前面站點的具體產物上,避免「對空氣選型」。
1定錨 → 交付形態 gate → 操作盤點(BDD)→ domain / event 切分(DDD)
2 → 核心問題與維度展開(每個維度就地過防護底線)→ 決策記錄 + scaffold定錨。訪談從建立規模假設開始,定錨問題覆蓋七個面向:
- 產品形態(B2B / B2C / 內部工具)——決定合規壓力與流量不確定性的預設方向
- 動機(營收、學習、解決自己的營運問題)——決策記錄理由欄的錨點,「自建換學習」「託管換速度」的權重都從這裡來
- 租戶模型——多租戶把租戶隔離升級成儲存與安全維度的第一級問題
- 預期規模(首年用戶與資料量級)——決定容量維度是否展開
- 團隊能力(人數、production on-call 經驗)——維運經驗低時預設 managed 服務,每個自管元件都要回答「誰半夜處理它」
- 每週可投入時數——一週十小時跟全職的選型分母不同
- 上線時程與迭代節奏——時程緊時選型偏保守,團隊熟悉度的權重高於技術新穎度
定錨答案是後續每個推薦的合法依據——「因為團隊兩人且無維運經驗,推薦 managed 資料庫」這類理由都要能回指到定錨。
交付形態 gate。定錨之後、進入任何技術討論之前,先誠實回答「這個產品現在值得自建嗎」。需求落在現成平台的標準域時,訪談走縮減流程:完整推導跳過,但仍產出託管縮減記錄——平台選擇與理由、可遷出保險狀態、升級自建的 tripwire、防護底線總表的適用項,託管結論同樣留下可追溯的決策記錄。這一站的判讀邏輯單獨成節,見「交付形態 gate」。
操作盤點(BDD)。自建成立後,枚舉所有操作主體(含管理者、客服、訪客、機器角色)與其全部操作,每個操作寫行為情境——Given / When / Then 至少一條主情境加一條失敗情境。誤操作風險成對設計:前端引導(確認對話框、預設值、防呆)與後端防護(驗證、權限、idempotency)一一對應,從介面一路串到伺服器側。行為情境寫不出來,代表那個操作的需求還沒成形——在盤點階段攔下,比開發中途才發現便宜得多。
Domain / event 切分(DDD)。操作清單沿固定方向轉成領域骨架:operation → command → 唯一歸屬 domain → event。推導從操作出發而非資料表出發——從資料表出發會切出 CRUD 式的偽領域(UserManager、OrderManager),從操作出發才會浮現真正的業務領域與領域間需要交換的事實。切分只用兩個原則:
- SRP:一個 domain 一個變更理由、一個 event 一個事實。判讀問題包括「這兩個概念會因為同一個業務原因一起改嗎」「這個規則改變時誰說了算」——組織的決策邊界是領域邊界最誠實的線索。
- OCP:每個 domain 區分公開面(別的 domain 需要知道的:event schema、查詢介面)與內部面(表結構、狀態機、內部規則)。公開面是 contract、變更要盤點訂閱者;內部面可自由改。判讀問題是「Order domain 的表加一個欄位,要通知誰」——理想答案是「不用通知任何人」。
LSP / ISP / DIP(里氏替換、介面隔離、依賴反轉)三個原則刻意留給實作階段:初始化階段還沒有 class 階層、沒有 interface 簇、沒有依賴注入結構,提前套用會把訪談拖進實作細節,模糊掉「邊界在哪」這個此階段的核心問題。
核心問題與維度展開。領域骨架立好後,依序確認需求類型、流量形狀、資料生命週期、失敗代價、成本模型、定位與備援、安全邊界。每題附答案路由:訊號決定哪些技術維度要展開(快取、非同步佇列、容量),哪些維度任何 production 服務都逃不掉(儲存、部署、安全、觀測、可靠性)。
展開時問題錨在領域骨架上——「Order domain 的不可丟 event 用什麼機制送」,而非抽象的「要不要 queue」。每站也帶反向問,因為受訪者描述的是想要的功能,沒想到的東西藏在失敗面:「使用者做完馬上後悔怎麼辦」「凌晨三點服務掛了誰會知道」。
防護底線。每個維度附一份防護底線清單——底線的定義是「缺了它、第一次事故的代價會遠超過 day one 建立它的成本」的項目,例如 secret 管理、備份加至少一次還原驗證、物件層級授權、部署可回滾。底線跟選型的差別在答案空間:選型問題容許多個合理答案並存,底線項目只有「已納入」「已告知後延後」「不適用」三種合法狀態,每一項的狀態都要寫進決策記錄。延後必須轉成記錄:告知代價、記下延後理由、附具體的重評條件(「上線前」「第一個付費客戶前」),「之後再說」這種無期限的口頭妥協會被協議擋下。目的是讓六個月後接手的人能回答「當初為什麼沒做」,把口頭妥協變成可追溯的決策。底線在訪談中經過兩次——維度展開時就地逐項過,決策記錄的總表再核對一次;雙重核對是刻意設計,防止任何一條在長流程中被沉默跳過。
決策記錄。訪談收斂成一份決策記錄:操作風險表、domain map、event catalog、每項技術選型的理由 / 防護狀態 / tripwire 三欄齊備、防護底線總表、規模成長 tripwire 總表。被淘汰的次選項留名字——淘汰原因消失(例如團隊長出維運能力)就是重評入口。scaffold 建議是決策記錄的下游:先確認決策、再產生檔案,決策改了 scaffold 跟著重生。
交付形態 gate:先勸退不必要的自建
一套為自建選型而生的訪談協議,第一個正式任務是勸退不必要的自建。自建的前提是差異化在軟體本身;差異化在商品、內容或服務品質的業務,託管平台、BaaS、垂直 SaaS 可能是成本上更誠實的起點。跳過這個判斷,等於用整套自建流程回答一個本來就該用現成平台解的需求。交付形態光譜的完整論述(各形態的能力邊界、遷出代價、可遷出保險)見 交付形態選型:託管平台、BaaS 與自建的邊界,訪談協議把它操作化成 gate。
gate 的第一個澄清問是身分問題:這個軟體是要賣的產品,還是經營業務的工具?「給健身教練用的課表系統」有兩種身分——要賣給眾多教練的產品(市場上的垂直 SaaS 是競爭對手,走自建),或教練管理自己學員的工具(同一批垂直 SaaS 正是該優先評估的託管候選)。同一句需求描述,兩種身分的結論相反。
回答「先自用、之後想賣」的雙重身分,用時間判準裁決:付費外部用戶離現在多遠。協議把裁決寫成兩條規則:外部買家已有承諾或近期有交付時程的,按「要賣的產品」走完整訪談,自家使用記為首租戶(dogfooding);外部用戶還停在想像、目前唯一用戶是自己的,託管先行,平台野心轉成升級自建的 tripwire——協議給的觸發例是第一個付費外部用戶出現,或客製需求超出託管平台 API 的承載範圍。
gate 的收尾原則是尊重知情決定:受訪者聽完託管對照後仍選自建時,訪談照常繼續,勸退只做一次;選自建的動機(練手、控制權、長期成本)原樣記進決策記錄,讓未來重評者能還原當時的權重。
用合成 dry-run 驗證協議
方法論本身也需要驗證。這套協議以一組結構化文件存在——訪談流程、各站的判讀表、決策記錄模板都是 agent 可直接執行的文件,驗證因此可以採用合成 dry-run:讓 agent 同時扮演訪談者與 persona 受訪者,從定錨到決策記錄完整走一遍協議,過程中記錄機械性斷點。斷點分五類:
- 路由斷裂:協議指向的段落不存在,或前後站接不上
- gate 矛盾:兩條判讀規則同時命中且結論相反,協議沒給裁決方式
- 重複提問:同一風險在不同階段被當成新問題重新開放問
- 資訊斷流:前站的產出(操作清單、event catalog)沒被後站引用
- 判準缺席:協議要求做判讀,但沒給可操作的判讀條件
dry-run 收尾時實際試填決策記錄模板,量測每個欄位填得出來的比例——填不出來的欄位就是協議在某一站漏問了。
第一輪驗證跑了兩個 persona:一個雙重身分的健身房管理 SaaS(自用兼想賣),一個 solo 開發者的付費電子報(最該被勸退自建的案例)。合計記錄 13 個斷點,在兩個 persona 覆蓋的路徑上路由斷裂為零——協議的檔案結構與觸發路由都接得起來;決策記錄試填率約 85-90%,缺口集中在交付形態相關欄位:gate 判讀依據寫不出來、混合形態的記錄格式沒有規格、自建動機沒有欄位可放。影響最大的斷點是兩個 persona 從不同方向撞上同一個 gate 矛盾:判讀表兩列規則同時命中且方向相反——健身房的「都是」讓垂直 SaaS 列與自建列並立,付費電子報既符合「託管平台標準域」也符合「產品本身是軟體」——協議當時沒有 tie-breaker,在最該被勸退的案例上這個斷點被評為阻斷級;前文的時間判準正是這次修復補上的。矛盾發生在協議最核心的判斷上,且在真實使用者撞到之前被攔下。兩場 dry-run 最終收斂出 8 項修復回寫協議,包括雙重身分的時間判準、混合形態的決策記錄規格、訪談問句去重、跨 domain 寫入的一致性判讀條件。
合成 dry-run 的邊界也要誠實:它抓得到機械性斷點,抓不到真實受訪者的不耐與理解斷層。agent 扮演的 persona 永遠有耐心答完所有問題、永遠聽得懂術語;真實使用者在第四輪提問時的疲乏、對「event catalog」一詞的困惑,要等真人訪談才會浮現。另一層盲點是同源:persona 由產生協議的同一個模型扮演,回答分布偏向協議作者想像得到的案例,超出這個想像的需求形態,結構上不會出現在合成驗證裡。合成驗證的定位是上線前的結構檢查,取代不了真實使用回饋。
適用邊界與下一步
完整協議的固定成本是數輪訪談加一份決策記錄,值得跑的情境有明確輪廓:
- 產品會進 production,有真實使用者與失敗代價——失敗代價是核心問題階段的主要輸入,沒有它整條推導鏈失去分水嶺
- 團隊規模或交接需求讓「當初為什麼這樣選」值得被記錄——決策記錄的三種讀者(確認結論的現在使用者、回溯理由的未來維護者、等訊號的重評者)至少存在兩種
- 領域邊界有切分價值——操作主體超過一種、跨領域協作存在,domain / event 切分的產出才有承載對象
反過來,快速原型與純內部腳本跑完整協議是過度設計——原型的目的是丟棄式驗證假設,設計決策活不過原型本身;這類情境取協議的最小子集就夠:定錨(確認規模假設)加防護底線裡的 secret 管理一條。另一類邊界是需求不可知:產品會進 production、但要提供哪些操作得靠市場驗證才知道的探索型產品,協議能整理的只有已知部分——它解「已知需求沒想清楚」的成本,解不了「需求本身未知」;這類情境先走薄切片迭代,需求穩定後再回來補完整訪談。
判讀方式可以收成一個問題:這個專案的設計決策,六個月後有人需要回答「當初為什麼這樣選」嗎?需要,完整協議的固定成本就划算;無此需求,取子集。
下一步路由:
- 交付形態光譜與各形態的遷出代價:交付形態選型
- 判定自建後的服務選型順序:後端需求分類地圖
- 不可丟 event 的執行層機制:idempotency 與 outbox pattern 知識卡