about 2 years ago

還沒進新公司之前,對於要不要要求團隊估時與 CEO 曾有一些討論,當時討論的結論忘了 (路人:怎麼覺得這兩位是好隨便的 CEO 和 CTO,笑),不過,最後決定先照目前的流程跑,然後用 kanban 進行持續的觀察與優化,不過,對於 Scrum 團隊估時倒是有些個人想法可以分享。

為什麼要估時 (或估點)?

剛開始導入 Scrum 時,團隊大概最不能適應的事情之一,就是預估這件工作從 PM 移交給團隊了,過去由 PM 負責切 WBS,然後根據 WBS 規劃時程,有經驗的 PM 也許還好 ,沒經驗的 PM 則是用 dead line 天馬行空地認為團隊能在某個時間點全部開發完畢、然後進行測試等等,反正,一般來說,開發人員在水深火熱之中對於預估是無感的,甚至是排斥的,畢竟要花多少時間,開始開發才知道,說那麼多都沒用,即便 PM 規劃的時程多麼不合理都隨它去了。

在 Agile 方法中,預估的目的首要還是提供進度的可預測性度量,這是不可避免的,即便是粗略的估算,也是要有個大概的時程讓 stackholder 有個譜 (但是這譜有時會變成爭執的焦點又是另外的故事了),但在進行預估的會議中,像是 refinement meeting 或是 planning meeting,預估還有另一層意義:透過預估的方式,確定團隊對於工作內容都有一致的共識,個人認為,這才是將預估這件事交由團隊負責最有價值的地方。

至於可預測性量度,如果我們計劃得夠詳細了 (稍後會提到),是不是就能估算的很精確呢?答案是否定的,因為變異性是難以預測,在 Scrum 中的則是當團隊有穩定的預估穩定的開發能力後,相對來說就比較具有可預測量度。感覺很玄吧!難就難在穩定不是嗎?基本上,答案就是信賴團隊全體的智慧

以點數為例,當大小或複雜度差不多的 stories (或任何要進行預估的工作單位),團隊都能給予相近的點數,此時團隊的預估是彼此有共識的且穩定的;在有穩定的估預估前提下,當團隊能在一定的衝擊範圍 (有人突然重病無法上班、有人離職、新人加入或是遇上原先不預期的困難) 內,團隊能夠互相支援,依然能交付承諾的工作,此時團隊就有穩定的開發能力了。但這上述二點,不是瞬間就能擁有,是要團隊一定時間的磨合後才會穩定下來的。

預估的單位種類

穩定的開發能力需要多種 practice 組合和團隊組合的優化 (cross-functional team),不在這次討論的範圍,即便是有穩定的開發能力,但預估的大小變動範圍很大,也很難有一個穩定的數值可以參考,因此前面才會提到穩定的預估是很重要的前提,大多數 Scrum 書籍都會建議 user story 用點數當作單位,以小時當作 task 的估算單位,但這不是絕對,單位可以分成幾種:

時數

這是最直覺的單位,大家都習慣以『我要花多少時間』完成這個 story 或 task 的想法來估算,但也是最難估的準的單位,特別是用時數估算 story 時,除非 story 夠小,不然動不動就出現 20 或 40 以上的數字,意義就不太大了。如果團隊估時是用 planning poker 方法的話,有時也會容易造成 senior 與 junior 對於時數僵持不下的情況 (稍後再提),不過對剛開始使用 scrum 的團隊來說,用時數當成 task 的單位,在還沒有 velocity 參考數字之前,多一個數字作為一個 sprint 可以選多少 story 的參考。

通常是把每個團隊成員的實際可工作時數 (工作天數 * 5 - 休假時數 - 已知開會時數) 加總,作為一個 sprint 可選進 stories 的上限,從最優先的 story 開始挑,挑到時數已滿時,就不再加 story 了。

點數

和時數這種量測的單位相較,點數就有點抽象,但其實相對大小是比較容易比較的,點數代表複雜度的相對程度,也就是 2 點的 story 其複雜度會比 1 點的 story 要多複雜一倍,這也是為什麼撲克牌會是 1、2、3、5、8 的數列。那單看一個故事的點數有意義嗎?本身沒有,相對來看才有意義,在沒有 velocity 的情境下,也無法得知這個 story 要做多久。一般來說,點數可以用在 story 和 task 上,要使用點數作為單位估算,團隊必須先從過去開發的經驗中,找出一個不大不小的工作項目,訂下一個基礎點數 (3 點或 5 點),接下來所有的估算都是依照新工作比這個基礎複雜幾倍或簡單幾倍來估算。

有一種方法是找到一個最小的工作,當作是 1 點或 0.5 點,但『最小』有時候不容易找到,且也難保未來不會有更簡單的工作項目出現。

工作數

這個單位,我個人是比較建議團隊較成熟後,團隊的 task 切割有一定的慣性,例如切割方式都很類似,大小接近,此時可以簡化成 story 點數估完後,拆解完 task ,團隊對於 task 的內容有共識後,就可以開工了,PO 與 SM 看有多少 task 就大概知道時數的分布會在哪個區間,加快 planning meeting 的進行。由於缺少時數的 burn down chart,若真的想觀察更細微的團隊進度,可以用 task burn down chart 搭配 story burn down chart 來觀察。

個人的想法是,剛開始使用 Scrum 的團隊,還是用點數估算 user story,然後以時數估算 task,至少在一開始決定要納入多少個 stories 到一個 sprint 時,有比較好的參考點,當漸漸成熟時,是可以省去 task 時數的估算,但 story 的點數還是要有,因為團隊是會持續進步的 (當然也可能是退步),或是有人員異動,story 的消耗情況雖然是落後指標,但依舊可以觀察團隊的情況,即使有浮動或劇烈震盪,也應該要慢慢趨向一個穩定值才是夠成熟的團隊。

預防性措施

要讓團隊有較高品質的估算,agile coach 或 scrum master 可以觀察一些徵兆,若有發現盡早排除,免得讓團隊成員有壞習慣或是對估算這件事有陰影。

避免團隊成為橡皮章

首先,不論點數和時數都應該是由實際執行的團隊評估,PO 與 SM 都不要有建議,像是對團隊的數字說:『會不會估太少或估太多?』 (雖然,很多人都說遇到的 PO 大多是後者,但不管哪一種都不好)。最重要的是,不到非用不可的地步,PO 不要說:『不管怎樣,這些 stories 在這個 sprint 一定要做完。』這句話的殺傷力很大,因為就算團隊估算完後做不完也無法把 story 吐出來,會讓團隊之後更加不願意估算。而且為了趕上,犧牲掉的通常就是品質 (刪除某些細節的規格或是省略掉一些例外的處理),或堆積更多的技術債。但切記,對團隊信任度的傷害卻已經造成了。

就過去的經驗和參加其他活動聽到的經驗,很多的 dead line,都不是真的 dead line,通常是壓著說一定要做完,等到 sprint 最後一天,PO 看著牆面然後就冒出新的 dead line,或是當團隊勉強完成了,卻發現遲遲沒有真的上線,團隊才知道客戶根本沒這麼急著要。但 dead line 是一定會有的,像是奧運一定是在某一天開幕,作為支援的系統,勢必要在那一天之前上線,但如果真走到這一步,加班是避免不掉的,只是這應該是所有 agile 方法都在極力避免的 (透過減少未完成品的數量)。

避免換算

若同時使用點數與時數,要注意一點:點數與時數之間不一定有必然的關係,有可能某個 1 點的 story 切完 task 後估算結果是 8 小時,另一個 1 點的 story 估算後是 6 小時,這都是可以的。像剛剛我提到不大不小的 story,到底怎樣的 story 算是不大不小呢?我刻意避開像這樣的形容詞:『一人能在一天內完成的』story,原因就是避免讓團隊又落入以時間換算點數的情況,這樣就失去相對大小比較的好處了。

當排入 spring backlog,且 task 已經切好,也估完時數後,story 的點數雖然還是有一些統計上的意義,但沒那麼重要,因此不用拘泥於點數與實際的時數對不起來的問題,還特地回去修改點數或是調整時數,因為本來就沒有對應關係。當每個 spring 消化的點數趨於穩定,代表團隊的開發速度穩定,product owner是 是可以參考 velocity 大略估算時程,但這也不是絕對的時程。

即使事後統計發現有關係,也不需要拿出來跟團隊說,以後 1 點就是 5 小時,這會讓團隊在估算時礙手礙腳,一直在計算彼此之間的換算,或是讓團隊先估時數再回去推算點數。

避免僵局

若方法正確的話 (除了 planning poker 外,也可以參考 團隊估算遊戲),點數在估算上比較少會出現僵局,但 task 的時數就比較容易出現僵局,本來估點與估時的重點是釐清問題和尋找共識,但因為是以『如果是自己做這個 task 要花多少時間』就容易出現 senior 和 junior 就經驗上和能力上的不同有不同的數字,通常 junior 會比較擔心若在預估的時間內做不完,會不會讓自己的考績變差,因此會堅持較大的時數。此時也許可以考慮連 task 都用點數估算,所有的東西都是看相對的,這樣就可以排除不同人做同一件事時間不同,造成估算上的爭執。當全都以點數估算時,daily stand up meeting 就很重要了,因為那是團隊能知道實際還要多少時數的機會,這時就以真正做事情的人進行估算還需要多少時間,因為已經開始做了,這時候通常比較有把握,因此比較沒有爭議

一般來說,我說的是一般,但還是有些人本身很在意數字。團隊的氛圍通常是避免僵局最容易的方法,若對於多估 (實際執行時數比預估時數少) 或是少估 (實際執行時數比預估時數多),團隊能有開放性的檢討與改進,而不是批評或是做為考績的參考時,團隊也就比較不會對於數字斤斤計較,讓估時陷入僵局。

避免懼怕承諾

剛開始導入 Scrum 進行估時,通常都是估不準的,要不是過於樂觀就是過於悲觀,這都是正常現象,通常,團隊大概需要幾次的估算後才會趨於穩定,有點像下圖 (只是舉例,可能像任何數值),一開始沒經驗,因此承諾較多的點數 (40),但最後沒有完成, 於是下個 sprint 就曾諾較少的點數 (10),後來可能提前做完,因此又在下個 sprint 承諾較多的點數 (33),這震盪現象會持續一陣子,最後趨於一個穩定值 (大約20)。

所以在自省時 (稍後會說如何看過度悲觀或過度樂觀) 也不需要過度反應,非要團隊想出一個辦法或是要團隊在下次一定要估的很準,特別是承諾的 stories 沒有做完時 (這裡排除做錯被退的情況,單看因估計錯誤造成的沒做完),過度的反應有時會有反效果,像是花更多時間預估 (造成會議時間拉長)、數字灌水 (讓統計失真)、在估算時討論過多細節 (請參考後面的 mini-waterfall) 或是懼於給承諾。

在 TCP 網路協定中有個 Reno (Slow Start) 規則,當出現速度等異常時,傳送方會將傳送速度降到一半,然後慢慢再往上增加速度,當出現預估過度樂觀時,也許可以建議團隊先降低一個 sprint 能納入的 story 點數,當在 sprint 中提前做完,可以再添入 story 或是處理技術債,並在下次的評估中增加點數的上限,反覆幾次也能找到一個穩定值。

時時梳理

先前有提到,預估有一個重點是:團隊透過估點的方式釐清問題,看是否有不清楚的部分,因此若真要說一個 user story 本身點數有什麼意義的話,當點數很大時,例如:13、20,通常代表的是團隊根本不知道這個 story 要做什麼?或是太過複雜,應該再更進一步切小。一般來說 product backlog 中,高優先度的 story 點數應該都比低優先度的 story 要小,不然就應該安排 refinement meeting 將高優先度但點數仍然很大的 story 進行 refine,refinement 的重點也不是在切割,切割只是釐清問題後的結果,不是必然的過程。若團隊將一個不大不小的 story 點數是以5點來計算時,當進入 planning meeting 的 stories 點數都介在 1 ~ 8之間,時數估算的結果通常也會比較穩定。

切小還有一個好處是讓 PO 或 stackholder 有機會挑選真正最重要的功能來開發,agile 的 12 個原則中的一個是『將未完成的工作量最大化』,這一點看起來很矛盾,但這是因為一個軟體中,通常大部分的功能是使用者沒在用的,就算開發完成也只是浪費,同樣,一個需求,當初可能規畫得很完整,但切成小 story 後,可以根據時程與各項條件,把某些較不重要的 story 優先度調降,專注在更重要的 story 上,若擔心只有一個 product backlog 無法看到需求的全貌 (那些 stories 完成了,那些還沒),可以考慮 user story mappping 協助追蹤整個全貌

自省 & burn down chart 的解讀

其實從每天的 daily scrum meeting 就能觀察出預估與實際執行的落差,但即使出現落差,先別急討論預估的問題,這比較適合在每次 sprint 結尾的的自省會議中討論,自省會議 PO 可以參加,但如果要討論對預估的調整,我個人比較建議 PO 不參加自省,通常 PO (特別是兼主管職時) 參加會讓團隊不說話或是口頭上應付。討論時,scrum master 可以將該 sprint 的 story 與 task 的 burn down chart 作為會議討論的參考素材,也比較不會失焦。通常兩張圖擺在一起看可以看到三種類型:

Type 1 - 火力分散

在頭幾次的執行上,我個人的觀察是比較容易出現像下圖,團隊拼命地做自己擅長的事情,當一個 story 自己擅長的事做完後,就趕緊將下個 story 拉到進行中的狀態 (如果有累積圖的話更能印證),繼續做自己擅長的事情。因此,時數的消化很正常 (紅色折線),也貼近目標線 (黑色虛線),但真正完成的 story 很少 (藍色折線),此時檢討的重點恐怕不是預估的品質好不好,因為火力過度分散,導致團隊真正的效率還沒出現,所以,要先讓團隊能集中火力 (Stop starting, start finishing) 將已經開始的 story 盡量完成,讓 story 的 burn down 能持續下降。

Type 2 - 過度承諾

當線圖已經有比較順的下降,但到 sprint 結束時,總是有些 story 無法完成甚至還沒開始,如下圖一樣,這時候團隊就可能是過度承諾的狀態,這只是可能,story 無法完成的原因很多,像是中途改變了些需求,為了因應這些變動,團隊花了較多的時間導致無法處理別的 stories,或是遇到當初沒預期到的技術困難,這就是軟體專案上的變異性,光是技術困難這一件事就很難預期,例如:當初覺得 A 這個第三套件能完成 B 工作,但沒想到會影響系統,光是解決因第三套件引起的問題,就花了很多時間 survey,這通常是無法預期的。

因此,遇到下圖的情況,恐怕要 case by case 請團隊找出原因,而不是一開始就討論下次是否要少安排一點 stories,像是剛剛所說的第三方套件引起問題,那改進方向可能可以是下次在 refinement 後若有要使用不確定的技術,可以跟 PO 協調安插 prior study 的 story,在受控制的環境中實驗新技術;或是,太晚與 PO 確認完成的 story 導致 review 前一天才發現某個地方做錯了,那可能的改進方向就更不一樣了。

當其他原因都排除了,就可以重新檢視這次排入的 stories 數量與點數,未完成的 stories 點數,然後訂出下個 sprint 的 stories 點數上限,並在下次的 planning meeting 嚴格執行,否則團隊會覺得自省是玩假的:明明都做不完了,還是要我們吃下去。

Type 3 - 過度保守

可能有人覺得怎麼可能出現下圖?在 sprint 的一半時間就做完所有預估的事情?但事實上我擔任 scrum master 期間遇到過,而且不只一次,當出現下圖時,偶而出現是還好,畢竟團隊如果沒有一些盈餘時間,是無法學習新技術與改善團隊的。此時,scrum master 可以讓開發團隊與 PO 討論是否要再拉新的 stories 進來,或是用剩餘的時間處理技術債,又或是研究接下來可能用到的新技術,不論是哪種,都要與 PO 討論,確保真正重要的事被優先執行

但如果這現象是頻繁地出現,可能就是一個團隊過度保守的信號,在估點與估時的時候,數字帶有過多的 buffer,雖然說 PO 依舊可以在 sprint 期間加入新的 stories,但會讓本來穩定的 velocity 貶值,表面上 velocity 數字好像變大了,但其實整體來看完成的功能並沒有變多,此時,可能要決定是讓 velocity 續貶 (讓每個 sprint 能納入的 story 點數繼續增加),或是修正基礎點維持 velocity 的相對穩定 (從已完成的 story 中挑選一個作為新的比較基準),也可以跟團隊檢討,如何能有比較不虛胖的點數出現。當然,這也可能是團隊開發速度提升的信號,所以 scrum master 要小心應對,不然會讓本來開始進步的火苗又被澆熄了。

小心 mini-waterfall

Scrum 框架其實很簡單,卻是易學難精,若沒有理解藏在背後的 agile 精神,就容易變成只是依樣畫葫蘆卻沒有得到好處,例如,為了有『精確的』預估,為了有『漂亮的』的 burn down chart,一個 refinement meeting 開整整一天 (若是兩周為一個 sprint,一般是建議 refinement 不要超過 4 小時),把所有的設計細節全部寫下來,卻忘記當初使用 user story 的初衷是一個 placeholder 讓大家看到時,能用說故事的方式讓別人了解為什麼需要這功能,以及要完成什麼功能,怎麼完成是到 planning 及施工時,讓團隊發揮的,一次 planning meeting 要一天甚至兩天 (一樣,若是兩周為一個 sprint,planning meeting 也不建議超過 4 小時),task 切到小到不行,但卻又互相依賴,變成一次要領好幾個 task,這時恐怕是走火入魔,忘記當初這兩個會議的本意了。

從上面看下來,怎麼覺得開發團隊好像小朋友似的,都要 scrum master 像保母一樣照顧,但如果 scrum master 或 PO 真的像保母一樣帶團隊,那團隊就真的永遠是小朋友了,要讓一個團隊成長,要像對待成年人一樣,放手讓團隊走自己的路,上述很多觀察或是方法,能讓團隊發自內心提出來是最好的,甚至讓團隊想出更好的辦法,這時靠的是引導而不是教導,更不是指示,scrum master 要能從團隊的表現與現象觀察出問題,但切記別揠苗助長,適當地授權,團隊慢慢就能自我組織,自己解決問題。

← 《激發員工潛力的薩提爾教練模式:學會了,你的部屬就會自己找答案!》書摘 看板課後心得 →