不只是樂觀:從單點(diǎn)數(shù)字到可校準(zhǔn)的估算系統(tǒng))
很多人在討論研發(fā)效率時(shí)都會(huì)把估算不準(zhǔn)歸因于樂觀或沒有經(jīng)驗(yàn)。我接觸過不少團(tuán)隊(duì)后有一個(gè)很直接的感受這兩個(gè)理由往往站不住腳。一個(gè)項(xiàng)目延期背后通常不是某個(gè)人太樂觀也不是某個(gè)人經(jīng)驗(yàn)太少而是整個(gè)估算過程把不確定性處理得太粗糙。我們拿著一個(gè)本來應(yīng)該是概率分布的問題最后卻只變成某個(gè)同事嘴里那句“就3天吧”。這篇文章想聊的就是怎么把估算從一個(gè)拍腦袋的數(shù)字變成一套可校準(zhǔn)、可討論、可修正的系統(tǒng)。1. 為什么“樂觀”和“沒有經(jīng)驗(yàn)”不是估算不準(zhǔn)的真正原因1.1 樂觀偏差被夸大了我們經(jīng)常聽到“規(guī)劃謬誤”這類心理學(xué)概念說人總是低估任務(wù)耗時(shí)因?yàn)檫^度樂觀。但實(shí)際工作里估長(zhǎng)的情況一點(diǎn)也不少見。有人擔(dān)心風(fēng)險(xiǎn)會(huì)在估算里主動(dòng)加緩沖結(jié)果任務(wù)提前完成反而被說成“故意藏工”。有的任務(wù)看著復(fù)雜實(shí)際上之前已經(jīng)做過類似的東西估了5天最后2天就做完了。這說明偏差并不是單一方向的。如果你只盯著樂觀偏差很容易把所有延期都?xì)w結(jié)為“心態(tài)問題”然后要求大家“更悲觀一點(diǎn)”。這種改變沒有意義因?yàn)樗鼪]有觸及估算系統(tǒng)的結(jié)構(gòu)性問題。一個(gè)任務(wù)從估3天變成估5天如果你的需求還是模糊的依賴還是不確定的你在5天之后同樣會(huì)翻車。真正的問題不是樂觀而是我們根本不知道自己知道多少。1.2 有經(jīng)驗(yàn)的人也會(huì)估算錯(cuò)誤經(jīng)驗(yàn)確實(shí)重要但它并不能消除不確定性。新人可能不清楚系統(tǒng)里有多少隱藏復(fù)雜度老手可能知道這里容易出問題但如果需求文檔沒有寫清楚第三方依賴又沒有驗(yàn)證過老手也只能給一個(gè)“希望不要出問題”的估算。比如一個(gè)工程師有五年服務(wù)端經(jīng)驗(yàn)但對(duì)新的消息隊(duì)列不熟悉。他估了一個(gè)接口改造需要兩天結(jié)果光是在測(cè)試環(huán)境驗(yàn)證消息順序就花了一整天。他不是不樂觀也不是沒有經(jīng)驗(yàn)而是他面對(duì)的信息不足。真正的經(jīng)驗(yàn)是知道自己什么時(shí)候信息不足而不是假裝什么都能估準(zhǔn)。經(jīng)驗(yàn)還有一個(gè)副作用你會(huì)對(duì)重復(fù)過很多次的任務(wù)產(chǎn)生慣性估計(jì)。但這次的數(shù)據(jù)量可能不一樣權(quán)限規(guī)則可能不一樣上下游團(tuán)隊(duì)可能換了人。經(jīng)驗(yàn)幫你建立了參考基線但如果不同時(shí)核對(duì)當(dāng)前前提基線本身就會(huì)變成誤導(dǎo)。1.3 真正的問題我們?cè)谟命c(diǎn)值預(yù)測(cè)分布估算的本質(zhì)是預(yù)測(cè)。任何預(yù)測(cè)都應(yīng)該包含不確定度就像天氣預(yù)報(bào)會(huì)告訴你降雨概率和氣溫范圍而不是直接說“明天一定下5毫米雨”。但很多公司的估算流程只允許填一個(gè)數(shù)字。這個(gè)數(shù)字看起來精確實(shí)際上一旦寫出來大家就會(huì)把它當(dāng)作承諾。你說3天管理層就按3天排計(jì)劃測(cè)試按3天準(zhǔn)備環(huán)境產(chǎn)品按3天和客戶溝通。一個(gè)點(diǎn)值背后的不確定性就在這個(gè)過程中被反復(fù)放大。所以估算不準(zhǔn)很多時(shí)候不是因?yàn)槟悴慌Χ且驗(yàn)槟阌靡粋€(gè)單點(diǎn)答案回答了一個(gè)本質(zhì)上是概率分布的問題。你被迫在一個(gè)區(qū)間里挑了一個(gè)數(shù)哪怕你心里想的是“大概率4天小概率3天也有可能6天”最終寫出來的只能是一個(gè)“4”。2. 估算不準(zhǔn)的結(jié)構(gòu)性原因需求、依賴、假設(shè)和反饋2.1 需求歧義你估算的很可能不是同一個(gè)任務(wù)很多估算失準(zhǔn)第一步就錯(cuò)了。不是你不會(huì)估而是需求還沒有收斂到可估的狀態(tài)。比如“做一個(gè)導(dǎo)出功能”到底導(dǎo)出的數(shù)據(jù)是哪張表最多多少行用什么格式大文件怎么處理有沒有權(quán)限限制這些都沒說清楚任何估算都只是猜。樂觀的猜是3天謹(jǐn)慎的猜是7天兩邊都有道理但都沒意義。我一般建議在估算之前先寫一份兩行的“需求邊界”這個(gè)任務(wù)必須做什么以及明確不做什么。至少讓參與估算的人對(duì)齊一下驗(yàn)收標(biāo)準(zhǔn)。很多時(shí)候爭(zhēng)議不是“估幾天”而是大家理解的是兩個(gè)完全不同的功能。等你花了一天討論需求才發(fā)現(xiàn)原本估的4個(gè)任務(wù)已經(jīng)變成了8個(gè)這時(shí)候再回頭看當(dāng)初的估算當(dāng)然對(duì)不上。2.2 外部依賴和等待個(gè)人效率高不等于任務(wù)周期短工期和“人寫代碼時(shí)間”是兩回事。一個(gè)任務(wù)從開始到完成通常包含等待設(shè)計(jì)評(píng)審、等待后端接口、等待前端聯(lián)調(diào)、等待測(cè)試環(huán)境、等待產(chǎn)品確認(rèn)。這些等待時(shí)間大多不由做估算的人控制。如果團(tuán)隊(duì)里同時(shí)有多個(gè)項(xiàng)目在互相搶資源那你個(gè)人估再準(zhǔn)也沒有用。這里的結(jié)構(gòu)性問題是我們習(xí)慣把注意力放在自己可控的開發(fā)時(shí)間上卻忽略了整體流程的排隊(duì)效應(yīng)。換個(gè)經(jīng)驗(yàn)更豐富的人來做也只能減少他自己的操作時(shí)間不能減少外部排隊(duì)時(shí)間。所以我經(jīng)??吹焦こ處煱讶蝿?wù)估得很精準(zhǔn)但最后實(shí)際周期還是超過一倍因?yàn)榇蠖鄶?shù)時(shí)間不是他在寫代碼而是他在等別人。2.3 假設(shè)沒有被記錄風(fēng)險(xiǎn)在事后聽上去全是借口估算時(shí)每個(gè)人心里都有一組默認(rèn)假設(shè)?!斑@個(gè)接口能按文檔返回”“這個(gè)Python庫的版本沒有坑”“測(cè)試環(huán)境可以隨時(shí)部署”“線上數(shù)據(jù)都是規(guī)范的”。這些假設(shè)如果不寫下來一旦被打破團(tuán)隊(duì)不會(huì)把它當(dāng)作“預(yù)期風(fēng)險(xiǎn)發(fā)生”而會(huì)當(dāng)作“你做事不靠譜”。我后來養(yǎng)成了一個(gè)習(xí)慣每次給估算時(shí)必須附帶三到五條前提條件。例如“按周三拿到接口文檔估算”“假設(shè)生產(chǎn)環(huán)境需要遷移兩類數(shù)據(jù)”“如果在聯(lián)調(diào)階段發(fā)現(xiàn)字段不一致需要重新評(píng)估”。這不是為了免責(zé)而是為了讓團(tuán)隊(duì)看清估算建立在哪里。假設(shè)寫得越清楚后續(xù)討論就越容易。假設(shè)沒有被寫下來風(fēng)險(xiǎn)發(fā)生時(shí)你只能說“我沒想到”非常被動(dòng)。2.4 沒有校準(zhǔn)機(jī)制同樣的錯(cuò)誤可以重復(fù)無數(shù)次估算不準(zhǔn)不可怕可怕的是從不回看。很多團(tuán)隊(duì)在每個(gè)迭代結(jié)束時(shí)會(huì)做復(fù)盤但復(fù)盤的重點(diǎn)是“功能上線了嗎”“客戶問了嗎”很少人會(huì)把當(dāng)初估算的小時(shí)數(shù)、故事點(diǎn)和實(shí)際對(duì)比。沒有反饋就沒有校準(zhǔn)。人的判斷力不能靠憑空提高必須靠大量“預(yù)測(cè)→結(jié)果”的對(duì)照。你如果連續(xù)十次都估少了30%下一次自然會(huì)考慮把余量放大一些。但前提是你真的知道自己一直估少了。很多團(tuán)隊(duì)把復(fù)盤開成了匯報(bào)會(huì)大家不好意思把“我上次估少了”放到臺(tái)面上于是同樣的偏差下個(gè)迭代繼續(xù)復(fù)現(xiàn)。3. 改進(jìn)估算的第一步從“給一個(gè)數(shù)字”變成“給一個(gè)區(qū)間”3.1 用三個(gè)數(shù)字描述你的真實(shí)判斷建議不要直接寫“5天”而是寫三個(gè)數(shù)樂觀、悲觀、最可能。比如任務(wù)復(fù)雜度中等既有熟悉的模塊也可能有第三方接口的不確定你可以估樂觀2天悲觀6天最可能4天。把這三個(gè)數(shù)寫到估算里別人就能看到一個(gè)范圍。這個(gè)范圍不是不專業(yè)反而是更準(zhǔn)確地描述了你現(xiàn)在掌握的信息量。如果你對(duì)任務(wù)完全陌生范圍會(huì)更大如果非常熟悉范圍會(huì)收斂。這個(gè)變化本身就是判斷力在起作用。你不需要每次都把三個(gè)數(shù)寫給所有人看但你至少要自己?jiǎn)栆槐槲业淖詈们闆r、最差情況、最可能情況分別是什么。3.2 用歷史數(shù)據(jù)校準(zhǔn)區(qū)間寬度區(qū)間從哪里來最好不靠感覺而是靠歷史記錄。比如你過去做了10個(gè)類似任務(wù)其中有5個(gè)實(shí)際耗時(shí)在估點(diǎn)的1.2倍到1.8倍之間那么估算區(qū)間就應(yīng)該覆蓋這個(gè)范圍。如果你的歷史數(shù)據(jù)里沒有這個(gè)信息就先記錄不要急著追求精確。區(qū)間寬度不是越大越好也不是越小越好而是要和不確定度匹配。給一個(gè)從1天到30天的區(qū)間沒有價(jià)值因?yàn)闆Q策者無法使用。更好的做法是“最可能是4到6天其中6天對(duì)應(yīng)的是接口文檔可能晚兩天?!?這個(gè)信息比一個(gè)干巴巴的數(shù)字有用得多。管理層聽到之后至少知道如果希望降低風(fēng)險(xiǎn)應(yīng)該優(yōu)先推動(dòng)哪個(gè)前置條件。3.3 把區(qū)間翻譯成排期管理層通常不要區(qū)間要日期。你要做的是把區(qū)間翻譯成帶條件的排期。比如“按今天的信息4到6天我建議排6天。如果接口文檔周四仍然沒有到那要從周四開始順延?!被蛘邠Q個(gè)說法“如果需求不再變更按5天排期一旦需求變更需要重新評(píng)估不能在這個(gè)基礎(chǔ)上只追加1天?!?這樣看起來是在給日期但實(shí)際上你把不確定性的責(zé)任放回了系統(tǒng)里需求變化、外部依賴這些因素不會(huì)被一筆帶過。我見過很多“高效”的團(tuán)隊(duì)其實(shí)是靠犧牲估算真實(shí)性換來了表面上的確定排期最后在下一個(gè)節(jié)點(diǎn)爆發(fā)。與其這樣不如一開始就允許估算里帶條件。帶條件的排期比假裝確定的排期對(duì)組織更負(fù)責(zé)。4. 建立校準(zhǔn)閉環(huán)記錄估算、實(shí)際和誤差4.1 先記錄10個(gè)任務(wù)不要急著調(diào)整建立估算習(xí)慣的第一個(gè)動(dòng)作不是改公式而是記賬。每完成一個(gè)任務(wù)就記錄剛開始估了多少最后實(shí)際用了多少中間發(fā)生了什么導(dǎo)致偏差。堅(jiān)持記錄10個(gè)左右的任務(wù)就可以做一次簡(jiǎn)單統(tǒng)計(jì)。你不用記錄得太精確重點(diǎn)在于字段穩(wěn)定。比如“估算天數(shù)”“實(shí)際天數(shù)”“偏差原因”。原因可以記“需求變更”“外部接口晚到”“個(gè)人不熟悉”“環(huán)境問題”“其他”。這能幫你把主要偏差因素拆出來。很多團(tuán)隊(duì)的問題不是沒有數(shù)據(jù)而是數(shù)據(jù)散落在每個(gè)人腦子里沒有形成結(jié)構(gòu)化記錄。拿不出來復(fù)盤就無法改進(jìn)。4.2 用一張簡(jiǎn)單的表格做個(gè)人校準(zhǔn)下面是一個(gè)示例表格你可以復(fù)制到文檔或表格工具里字段可以按你自己的情況調(diào)整任務(wù)估算天實(shí)際天差值主要偏差原因用戶列表導(dǎo)出34.51.5導(dǎo)出超時(shí)需要分頁接口日志查詢21.5-0.5已有通用組件權(quán)限重構(gòu)583歷史臟數(shù)據(jù)兼容邏輯這張表最重要的是三列估算、實(shí)際、原因。如果只記前兩列你只能看到一個(gè)“你很樂觀”的結(jié)論加上原因你才能知道下次該關(guān)注什么。記錄表只用于自我校準(zhǔn)和團(tuán)隊(duì)改進(jìn)不要用來追責(zé)。一旦變成績(jī)效工具所有人都會(huì)想方設(shè)法把估算寫高最后整個(gè)數(shù)據(jù)失去意義。4.3 計(jì)算調(diào)整系數(shù)但不要機(jī)械套用有了至少10個(gè)樣本后你可以算一個(gè)粗口徑實(shí)際總時(shí)長(zhǎng)除以估算總時(shí)長(zhǎng)。如果結(jié)果是1.3說明你系統(tǒng)性地低估了30%。下次估3天可以先按3.9天考慮。但接下來要問這30%里有多少是需求變更有多少是個(gè)人能力不足有多少是外部等待如果大部分是外部等待那你的任務(wù)應(yīng)該帶上更明確的前置條件再乘系數(shù)才有意義。如果大部分是需求變更那就不是估算問題而是范圍管理問題。把這兩者分清楚校準(zhǔn)才有效。如果不管三七二十一直接給所有估算乘一個(gè)系數(shù)你只是在掩蓋問題并沒有真正理解偏差從哪里來。5. 不同場(chǎng)景下的估算策略個(gè)人、團(tuán)隊(duì)、管理層5.1 個(gè)人任務(wù)把拆解、緩沖和風(fēng)險(xiǎn)寫出來即使沒有別人考核你也建議個(gè)人事務(wù)采用區(qū)間估算。比如“寫周報(bào)”可能半小時(shí)但“準(zhǔn)備技術(shù)方案評(píng)審”可能是一周到兩周。個(gè)人任務(wù)有一個(gè)陷阱我們往往只估算“有效工作時(shí)間”忘了溝通、等待、被打斷、返工。一個(gè)非常實(shí)用的辦法是把任務(wù)拆成“理解需求、編碼、驗(yàn)證、收尾”四段先分別給出區(qū)間再合并。合并之后在總時(shí)長(zhǎng)上額外增加10%到20%的緩沖專門應(yīng)對(duì)那些“說不清但一定會(huì)出現(xiàn)”的事情。別小看這個(gè)習(xí)慣它能讓你對(duì)時(shí)間的感知更真實(shí)。個(gè)人校準(zhǔn)做一段時(shí)間之后你再去看團(tuán)隊(duì)的復(fù)雜任務(wù)會(huì)更容易識(shí)別出哪部分被壓縮得過分了。5.2 團(tuán)隊(duì)迭代用相對(duì)估算而不是每個(gè)人的小時(shí)數(shù)團(tuán)隊(duì)排迭代時(shí)最好不要讓每個(gè)人報(bào)“我大概需要幾天”。這樣的數(shù)字會(huì)被個(gè)人信心、默默加班、怕被批評(píng)等因素污染。更穩(wěn)妥的方式是給任務(wù)打相對(duì)大小S、M、L、XL或者故事點(diǎn)。為什么相對(duì)估算更準(zhǔn)因?yàn)槿说南鄬?duì)判斷比絕對(duì)判斷穩(wěn)定很多。你說“這個(gè)任務(wù)比那個(gè)任務(wù)大一倍”往往比說“這個(gè)任務(wù)要3天”更接近事實(shí)。之后團(tuán)隊(duì)用過去幾個(gè)迭代的實(shí)際完成點(diǎn)數(shù)來推算容量。比如過去三個(gè)迭代平均完成20點(diǎn)新迭代塞30點(diǎn)大概率完不成。這不是樂觀是容量與需求的簡(jiǎn)單比較。相對(duì)估算還能把“誰是新人”這個(gè)因素暫時(shí)放一邊。新人同樣可以判斷任務(wù)大小只是他完成的速度可能更慢。接下來團(tuán)隊(duì)用每個(gè)人的歷史速率去換算排期而不是在估算階段就爭(zhēng)論誰快誰慢。5.3 向管理層匯報(bào)把假設(shè)和風(fēng)險(xiǎn)一起呈現(xiàn)面對(duì)管理層恐懼感會(huì)讓估算變形。很多人在“我真實(shí)的估算”和“管理層想聽的數(shù)字”之間取了一個(gè)中間值結(jié)果兩邊都不舒服。我的經(jīng)驗(yàn)是不要試圖把不確定性包裝成確定性。你可以在排期里明確寫出三個(gè)前提比如“需求不再增加”“第三方接口按文檔返回”“測(cè)試環(huán)境可用”。如果前提成立排期是5天如果前提不成立日期要順延。這樣做表面上是把風(fēng)險(xiǎn)推給管理層實(shí)際上是在逼管理層做決策是保范圍還是保時(shí)間還是保資源。把不可能三角擺到桌面上遠(yuǎn)比表演一個(gè)“很有信心的數(shù)字”更有價(jià)值。如果管理層堅(jiān)持要一個(gè)確定日期你可以給出帶置信度的日期“按目前掌握的信息90%的把握是6天內(nèi)完成80%的把握是5天內(nèi)完成?!?這既回應(yīng)了需求又保留了對(duì)不確定性的誠實(shí)。6. 改進(jìn)估算時(shí)最容易踩的坑和排查順序6.1 四個(gè)常見誤區(qū)第一個(gè)誤區(qū)一不準(zhǔn)就整體翻倍。翻倍的估算很快就會(huì)失去信用因?yàn)樗睦碛刹煌该?。你?天改成6天到底是哪里變了大家不知道所以下一次你就會(huì)被要求給出“真實(shí)值”。第二個(gè)誤區(qū)只依賴某一種公式。PERT公式E(O4MP)/6可以幫你算期望值但它假設(shè)你的三個(gè)數(shù)都有意義。如果O、M、P都是隨手填的算出來的數(shù)也不會(huì)靠譜。公式是輔助工具不是估算質(zhì)量的來源。第三個(gè)誤區(qū)把估算記錄表當(dāng)成績(jī)效工具。一旦記錄變成考核大家就會(huì)故意把估算寫得很高最后整個(gè)系統(tǒng)失真。記錄表的意義是校準(zhǔn)不是評(píng)價(jià)。第四個(gè)誤區(qū)只盯著數(shù)字不盯范圍。同一個(gè)任務(wù)名需求變了實(shí)際當(dāng)然對(duì)不上。這時(shí)候要直接重估而不是硬套舊估算。范圍變了還拿舊數(shù)字說事討論永遠(yuǎn)無法收斂。6.2 排查順序從現(xiàn)象往下追如果你發(fā)現(xiàn)團(tuán)隊(duì)最近連續(xù)延期我建議按這個(gè)順序排查先看需求是否清晰有沒有驗(yàn)收標(biāo)準(zhǔn)有沒有邊界說明。再看假設(shè)是否寫下來了依賴條件、環(huán)境條件、數(shù)據(jù)條件是否明確。然后看依賴是否可控有沒有等待外部接口、等待審批、等待其他團(tuán)隊(duì)。接著看是否有歷史數(shù)據(jù)過去的估算誤差是不是已經(jīng)在某個(gè)區(qū)間內(nèi)穩(wěn)定出現(xiàn)。最后再看個(gè)人態(tài)度和經(jīng)驗(yàn)這里才輪得到“樂觀”和“經(jīng)驗(yàn)”之類的話題。很多人一開始就質(zhì)問“你是不是太樂觀了”這是最低效的歸因。我見過很多次團(tuán)隊(duì)成員其實(shí)給了偏保守的估算但管理層為了項(xiàng)目目標(biāo)強(qiáng)行壓縮最后延期了。這種情況跟樂觀毫無關(guān)系。按順序排查你會(huì)發(fā)現(xiàn)真正的卡點(diǎn)往往在流程和輸入條件上而不是某個(gè)人的性格。6.3 從最小的實(shí)驗(yàn)開始改進(jìn)估算不需要一次到位。建議選一個(gè)迭代或者一個(gè)自然月做一個(gè)小實(shí)驗(yàn)每個(gè)任務(wù)必須給出區(qū)間記錄實(shí)際并且在執(zhí)行中定期更新一次“當(dāng)前預(yù)期是否變化”。不要急著引入復(fù)雜的估算工具也不要急著改變所有流程。先讓團(tuán)隊(duì)熟悉“給區(qū)間記偏差”這個(gè)動(dòng)作。幾輪之后再把誤差分布和調(diào)整系數(shù)引進(jìn)來。你會(huì)發(fā)現(xiàn)團(tuán)隊(duì)的討論會(huì)從“你憑什么估3天”變成“如果我們假設(shè)接口晚到兩天是不是應(yīng)該按5天排”。這個(gè)變化才是真正的進(jìn)步。我個(gè)人更建議把估算從“數(shù)字游戲”改成“預(yù)測(cè)系統(tǒng)”。不要再問“估幾天”而是問“什么情況下能按這個(gè)日期完成什么情況下不能”。把邊界劃出來把假設(shè)寫下來把誤差記下來。這樣即使估算依然不準(zhǔn)你也能知道不準(zhǔn)在哪里。踩過幾次之后就會(huì)發(fā)現(xiàn)很多問題不是能力問題而是反饋缺失。真正靠譜的估算不是每次都準(zhǔn)的估算而是每一次不準(zhǔn)都知道為什么不準(zhǔn)的估算。