行為的藝術: 52個非受迫性行為偏誤

延續上一本「思考的藝術」,本書一樣是作者觀察日常生活中人們常出現的一些不符合邏輯、或乍看之下理性的錯誤行為,也一樣是從演化角度來解釋我們會發生這些錯誤的原因。仍然是專欄的集結成冊,因此很適合在片段時間把它逐漸讀完。略舉令我印象深刻的篇章:

  • 決策疲勞:不管決策再小,都會消耗意志力,而意志力是有限的,所以要縮減你的選擇,把精力放在對你而言重要的決策上;同樣的概念也可以延伸到「想要保有所有選項而耗費太多精力,以至於最終一事無成」或是「『最後的機會』總讓人失去理智」的現象。破釜沉舟才能專心致遠。
  • 我們總是順從直覺或錯誤地類比(可以說是演化的結果,也可以說是因為現代社會太過複雜,大腦機制還來不及演化)。例如混淆了風險(確知其機率,如醫學上的預測)與模糊性(因統計母體過少,機率幾乎不具意義,如經濟學上的預測);或者相信平均值給我們的印象(在80/20法則下,平均值只會誤導,例如我與全國首富財產的平均值)
  • 能力的錯覺,包含「手中有錘子時,每個問題看來都像釘子」、「領域知識無法複製」、「運氣比能力更重要」,將軍之所以常勝,很可能是因為善於選擇戰場
  • 不該看新聞的原因:一、為吸引閱聽率而刻意簡化、單向歸因、下標聳動;二、新聞其實不重要,不影響你生活及事業的決策;三、披沙揀金,浪費時間。

看完這兩本書之後,當然要學點批判性思考,不能照單全收,例如:對於3C專欄作家或財經工作者,每天的相關新聞當然會影響自己的決策;最引人注目的不一定是最重要的或事件成因(顯著性效果),但也有可能是,除了注意隱而不顯及不受期待的地方外,也別忘了隨機性。


思考的藝術: 52個非受迫性思考錯誤

這是一本可以讓我們了解並自省自己思考錯誤的書。當我們提及思考錯誤時,一般總認為是與直覺、情緒化、非理性相關(這又是一個思考錯誤),但令人驚訝的是並非如此,就算我們在冷靜與自以為理性的狀況下,一樣會犯錯,常見的例子有:服膺權威、盲從集體決策、錯誤的因果關聯等。追根究柢,是人類在演化的過程中,我們的思考是幫助繁衍,而非追求真理。試想在採集狩獵時代,有一個人突然看到他的同伴拔腿就跑,他會跟著跑,還是停在原地思考他的同伴為什麼跑?是不是看到了獅子?事實是我們幾乎是這些跟著跑的人的後代,停在原地想的人可能早已從基因庫消失了。因此,我們的思想其實會系統性的犯錯,且與智力無關。

這本書是將作者的報紙專欄集結成冊,每一篇文章都不長,因此很適合在通勤或等待時閱讀。此處略舉令我印象深刻的思考錯誤:

  • 總是高估自己(及專家)的預測能力,事實上我們的能力並沒有比隨機預測好多少
  • 依據存活者偏差進行錯誤的歸納
  • 後見之明地相信故事的存在,以及採取行動或不行動的效果,而忽略了結果發生的必然性及隨機性
  • 只要風險不為零,我們對於風險的高低或機率通常沒有直觀的感受,且會花太多成本去達到零風險
  • 選擇越多,反而越難選,越難做決定
  • 月暈效應及框架效應(對於一件事因陳述方式不同而有不同的感覺)

在閱讀過程中我常常想到GRE考試的邏輯題:是否倒因為果?另有他因(有其他或更上層的原因,你認為的原因其實是結果)?有其他原因使結果不會發生?說白了就是批判性思考的練習。我也常想到人工智慧課堂上學到的:人類的大腦其實很會偷懶,我們常把觀察到的事物自行歸類,忽略細節;如果有兩個假設都滿足觀察到的現象,我們總是偏好比較簡單的那一個。日常的小事可以順應天性,但在做重要決定時,應該要好好確認是否有思考錯誤。


(Convert os.path.join() to Unix style under Windows)​

os.path.join()是組合檔案路徑好用的函式,會自動依照當前的OS組合出適合的檔案路徑。例如在Windows下

>>> print os.path.join('path', 'to', 'directory') 
path\to\directory

如果要在Window下強迫把路徑轉為Unix style輸出,其實也不難,只要改用posixpath.join()就可以了,例如

>>> print posixpath.join('path', 'to', 'directory') 
path/to/directory

但我遇到的問題是:在Windows下承接os.path.join()的結果,並join其他路徑後,轉換為Unix style輸出到JSON。找了一陣子沒有看到現成的解法,因此我的作法如下:

  1. os.path.join()的內容解構為list (用os.sep取得split用字元)
  2. 把解構後的list作為參數傳入posixpath.join() (用* operator (sequence unpacking)),其結果可以繼續posixpath.join()下去

範例如下

>>> win_path = os.path.join('path', 'to', 'data')
>>> print win_path
path\to\data
>>> posixpath.join(posixpath.join(*win_path.split(os.sep)), 'my_file.txt')
'path/to/data/my_file.txt'

前言:美國政府數位服務教戰手冊(U.S. Digital Service Playbook)(上)

帶入有經驗的團隊成員(Bring in experienced teams)

此處所謂的經驗包含了專案管理、軟體工程跟設計的經驗,例如團隊裡面應該有這些成員:

  • 打造過受歡迎且高流量的數位服務
  • 處理過數位服務的資安議題
  • 評估過不同第三方技術選項或管理過委外專案
  • 開發過行動與網頁應用程式
  • 使用過自動測試框架,有系統部署(DevOps)經驗(例如知道什麼是 Continuous Integration)
  • 另外也必須有外部夥伴支援預算處理及法律議題

如果不把乙方算進我們的團隊,且將第一點的「打造」跟第二點的「處理」解釋成「委外處理」,我想甲方團隊勉強能滿足前三項,而最後一項通常有其他部門(總務、法規會)支援;如果連乙方團隊都算進去,我想還是沒辦法滿足倒數第二項,可能是我看得太少,至少我之前接觸過跟聽過的廠商,沒人在做自動化測試(有手動迴歸測試就要偷笑了),更不用說 Continuous Integration 或較新的 DevOps 觀念了(當然,甲方也不懂)。

選擇現代化的解決方案架構(Choose a modern technology stack)

我們數位服務的技術架構必須與時俱進,才能讓專案有效率及省成本地進行,並且容易擴充。不管是在選擇基礎架構、資料庫、開發框架、程式語言或其它技術選項時,都應該選擇符合潮流、避免被單一廠商綁定、且現今大多數企業用來打造類似服務時所採取的方案。

  • 考慮以雲端服務為基礎,且一般企業廣為採用的解決方案。
  • 在技術架構的所有層級都考慮開源解決方案。
  • 軟體必須要能佈署在不同的常見硬體架構上。

一個很好的檢查方式是新成員需要多久時間才能把本地開發環境建起來(我們政府的甲方不做開發工作,所以這個問題…可以用來問乙方)。如果我們的架構是常見且開源的,則建立本地開發環境的時間就很快,這也有利於專案管理及成員交接。

將服務佈署在能應付不同流量的環境(Deploy in a flexible hosting environment)

這一點是談雲端服務的其中一個基本概念:隨需(On demand)。把服務佈署在所謂雲端主機,但卻必須手動管理環境中的資源,就是假雲端,徒耗人力跟經濟成本,也削弱了災害復原的能量。

  • 你的服務必須能應付尖峰流量;除了真實使用者外,若你的服務也能透過 API 提供,或預期會有國外使用者,這些流量都必須考慮進去,在尖峰流量時能自動增加資源;沒有這麼多流量時自動關閉資源(對照組:前陣子的戶役政系統、實價登錄查詢系統…)。
  • 我們只為目前使用的資源付錢。就算不使用外部雲端服務,你還是要知道你的服務如何針對流量隨需調配資源,而非過猶不及。
  • 你的服務有沒有 Data redundancy,例如其中一台掛掉了,可否能自動由其他台接手?若不行你的災害復原計畫為何。
  • 靜態資源考慮經由 CDN(Content Delivery Network,可想成離你最近的Cache)提供。
  • 服務建立在常見的硬體配置上。

自動化測試跟佈署(Automatic testing and deployments)

這一點在講 CI(Continuous Integration),如同之前提過的,依據我粗淺的經驗,我們政府的甲乙方都不知道這是什麼…

  • 現今的軟體佈署已經能作到讓自動化測試的腳本(scripts)在幾分鐘內驗證數以千計的情境(scenarios),接著在一天之內多次自動更新程式到正式環境中。工程師們也能將壓力測試自動化、模擬真實流量以找出效能瓶頸。雖然手動測試仍是不可替代的,但上述的自動化測試能提供一定程度的保證,讓開發者不會因增加新功能而損壞舊功能,或無意間重新導入已修正的 bug,進而增加修改軟體的信心跟速度。
  • 撰寫各種層級的測試個案(單元、元件、整合),每一次 build 時都自動執行。瞭解你的 test coverage。
  • 當然,build 跟 deploy 也要自動化,採用 CI 工具,或至少要用script。瞭解 build 跟 deploy 所需的時間。
  • 定期對模擬環境執行壓力測試,依據真實流量跟預估的最大流量調整你的壓力

用可重複的流程處理安全及隱私議題(Manage security and privacy through reusable process)

專案開始時就要請隱私權、資安及法律支援專家確認資料如何收集、保護、使用及保留,通知使用者相關資訊的方式(包含資料收集時與萬一資料外洩後),使用者要求資料更正的管道,以技術面來說,確保服務安全的一個方式是廣泛地測試解決方案架構的各個層級,或採用已驗證過的元件,然後在打造不同服務時重複使用經過測試跟驗證過的元件。服務的佈署最好也腳本化,確保正式環境在資安及設定上的一致性。

這方面我沒什麼經驗,但我認為目前政府的數位服務在資安技術面沒有什麼大問題(雖然我親身經歷過廠商管理的主機中毒,並散播到全國各機關,但我們的反應還算即時),如果有問題的話是出在管理者與承辦人的資安素養。

讓資料說話(Use data to drive decisions)

我們提供的服務到底有沒有用?好不好用?讓客觀資料說話。在系統面要有即時監測的量化指標,在服務面也要提供使用者回饋的機制。

  • 即時監測系統的使用情況,系統面的監測項目,例如軟硬體效能,回應時間,資料產出量(throughput),系統錯誤率等,確保我們能經由自動監測,量化目前系統的忙碌程度(ex. 50%, 95%, 98 %),並自動發出適當的警告;服務面的監測項目,例如同時在線人數,或使用者行為等,幫助我們了解服務是否滿足使用者需要。並對內及對外公佈我們採用的評量指標。

必須回答的關鍵問題例如:

  • 你知道系統的預期及實際回應時間嗎?有多少 requests 的回應時間超過 1秒/2秒/4秒/8秒?
  • 你知道系統前十名的交易(transaction)是什麼嗎?其平均回應時間為何?
  • 系統每月正常服務的時間是多久?
  • 系統掛點後你們的標準處理程序是什麼(當然不只是重開機)?

開放為原則,封閉為例外(Default to open)

政府資料的開放是近年常見的議題。政府蒐集的資料,本身很可能就與人民有關,且蒐集資料所需的成本也是來自人民的納稅,因此將資料開放是很合理的事。除了資料外,更可以考慮工具或流程的開放,讓公眾、非營利組織或任何有興趣的機構更容易取得、參與、回饋及重製,發揮開放的最大綜效。

  • 提供機制讓使用者可以回報錯誤或議題,並迅速回應。
  • 分類並維護資料清單,以批次下載或 API 的方式提供公眾完整的資料集(dataset)。如果可以的話,也開放政府服務的專案或工具原始碼、分享所使用的流程。
  • 解決版權問題,包含資料集本身,及第三方介接資料後產製的衍生資料或軟體工具,都要能讓公眾無償使用。

這方面我沒什麼經驗,但我認為目前政府的數位服務在資安技術面沒有什麼大問題(雖然我親身經歷過廠商管理的主機中毒,並散播到全國各機關,但我們的反應還算即時),如果有問題的話是出在管理者與承辦人的資安素養。

讓資料說話(Use data to drive decisions)

我們提供的服務到底有沒有用?好不好用?讓客觀資料說話。在系統面要有即時監測的量化指標,在服務面也要提供使用者回饋的機制。

  • 即時監測系統的使用情況,系統面的監測項目,例如軟硬體效能,回應時間,資料產出量(throughput),系統錯誤率等,確保我們能經由自動監測,量化目前系統的忙碌程度(ex. 50%, 95%, 98 %),並自動發出適當的警告;服務面的監測項目,例如同時在線人數,或使用者行為等,幫助我們了解服務是否滿足使用者需要。並對內及對外公佈我們採用的評量指標。

必須回答的關鍵問題例如:

  • 你知道系統的預期及實際回應時間嗎?有多少 requests 的回應時間超過 1秒/2秒/4秒/8秒?
  • 你知道系統前十名的交易(transaction)是什麼嗎?其平均回應時間為何?
  • 系統每月正常服務的時間是多久?
  • 系統掛點後你們的標準處理程序是什麼(當然不只是重開機)?

開放為原則,封閉為例外(Default to open)

政府資料的開放是近年常見的議題。政府蒐集的資料,本身很可能就與人民有關,且蒐集資料所需的成本也是來自人民的納稅,因此將資料開放是很合理的事。除了資料外,更可以考慮工具或流程的開放,讓公眾、非營利組織或任何有興趣的機構更容易取得、參與、回饋及重製,發揮開放的最大綜效。

  • 提供機制讓使用者可以回報錯誤或議題,並迅速回應。
  • 分類並維護資料清單,以批次下載或 API 的方式提供公眾完整的資料集(dataset)。如果可以的話,也開放政府服務的專案或工具原始碼、分享所使用的流程。
  • 解決版權問題,包含資料集本身,及第三方介接資料後產製的衍生資料或軟體工具,都要能讓公眾無償使用。

20150925 更新: 美國政府最近更發布了官方網站設計指南相關中文報導

2013年10月,美國政府的HealthCare.gov網站上線,目的是讓沒有自行營運網站的各州,其居民能夠輸入資料、搜尋配對適合自己的醫療保險公司以及相關補助,也是俗稱Obamacare健保政策的一部分。結果這個花了五百萬美金打造的網站,竟無法應付龐大的流量,上線後的一週內只有1%的人能夠完成他們的查詢及送件,且就算資料送到了後端,很多醫療保險公司反應收到的資料並不齊全,更不用說網路上數百個假健保網站橫行,媒體還報導網站本身會將民眾個資分享給廣告公司,總之這個網站是個大災難,最後請了一位在google工作八年的可靠度工程師Mikey Dickerson來解決,而事後評估整個網站的成本高達17億美金,此事件詳情可參照維基百科

有了這個慘痛的教訓後,2014年8月,美國政府啟動了國家數位服務小組(U. S. Digital Service),由Mikey Dickerson領導,讓其他政府部門在數位服務設計的初期就能要求諮詢,以免HealthCare.gov的災難重演。同時白宮也釋出了一本「數位服務最佳實務(U.S. Digital Service Playbook)」,內容包含了打造數位服務的13個最佳實務,每一項都附有觀念說明、檢核項目(checklist)與關鍵問題(key questions),可說是內外功兼備,非常值得我們政府及資訊人員參考。

「數位服務就是以數位渠道(digital channel)與民眾互動,例如透過網站、Email、App提供的服務。…今日,我們有太多的數位服務差強人意、時程延遲或超出預算。…透過遵循以下13個來自業界與政府的最佳實踐(Best Practice),將幫助政府創建更有效的數位服務。」

了解使用者需求(Understand what people need)

專案必須永遠緊跟使用者需求 – 使用者真正需要的是什麼,服務要以什麼方式融入使用者的生活。無論使用者是民眾或是政府雇員,他們必須在專案初期就加入,且在開發過程中持續測試你的產品,以確保我們知道專案真正的重點是什麼。記住,永遠讓使用者需求 – 而非組織架構或閉門造車 – 決定專案的技術與設計

  • 在專案初期就花時間了解目前跟未來的使用者
  • 使用一系列的量化跟質化方法了解使用者的目標、需要跟行為
  • 讓使用者試用各種解決方案的雛形,可能的話盡可能貼近其使用情境
  • 把挖掘到的使用者目標、需要跟行為記錄下來,並與團隊及大老闆分享(以後的團隊要去哪裡找這些文件)
  • 建立具有優先順序的使用者情境腳本清單,以簡短描述使用者目標
  • 專案開發過程中,定期讓使用者試用以確保符合其需要

聚焦使用者的整體經驗(Address the whole experience, from start to finish)

雖然我們做的是數位服務,但必須了解:民眾取得服務的方式不僅有一種,甚至不是數位的。不管是上網、透過App、打電話,甚至親自跑一趟,都必須確保民眾每一次不論透過什麼方式,都能一步步接近他需要的結果。

  • 了解民眾會在什麼流程點透過什麼方式取得服務 - 無論是不是線上(數位)的
  • 辨認民眾在使用目前的服務時最痛苦的地方是什麼,優先改進這個地方
  • 設計數位服務時,必須與實體服務流程整合,使服務一體化
  • 在服務的各個步驟設計評估指標,評量該步驟是否符合使用者需要

簡單直覺(Make it simple and intuitive)

政府服務不應該讓人有壓力、困惑或懼怕,我們的工作是讓服務夠簡單及直覺到使用者第一次使用且沒有人幫助的情況下就能上手。

  • 使用已知、簡單且彈性的設計樣式;相關服務的樣式要一致(甚至要考慮與其他政府服務在視覺上的關聯)
  • 清楚地告訴使用者:他們目前進行到服務的哪個階段或流程;當使用者需要時如何取得協助;要怎麼中離,中離後怎麼繼續未完的流程
  • 遵循可用性的最佳實踐(Accessibility best practices)以確保所有人都能使用服務
  • 用淺顯易懂的語言,並在所有地方(不論是數位或實體)保持語言跟設計的一致性(淺顯易懂的語言可參考美國直白書寫法案)

敏捷與迭代的開發方式(Build the service using agile and iterative practices)

敏捷跟迭代是打造數位服務的最佳開發方法。要讓專案成功跟符合使用者需求最好的方式就是快速產出雛形,盡快讓使用者試用,並據以調整專案。能夠做到這件事的關鍵能力就是自動化測試跟部署,才能讓新功能可以很輕易地更新。

  • 專案開始後三個月內就要產出會動的產品(可以掛上beta字樣,直到真正完成為止),目標是先解決使用者最核心的需求。經常進行易用性測試(Usability test),並取得使用者回饋以改進專案。
  • 每個月有多次的版本更新跟 bug 修正
  • 用 issue tracker 管理跟排序你的需求跟 bugs,導入版本控制跟 code review
  • 保持小規模且專注的開發團隊,並限制團隊的組織層級,團隊成員可使用戰情室、每日立會(站著開會)、群聊工具等頻繁且緊密的溝通。

適當的合約書與預算結構(Structure budgets and contracts to support delivery)

大多數專案都是外包,外包必須依照合約執行,且使用政府預算付款,因此有經驗的承辦人、好的合約範本以及有彈性的預算執行方式,都是打造數位服務不可或缺的助力。例如使用者需求探索、雛型產出、其他開源專案評估、需求修改、專案里程碑、雲端運算資源採購等項目,都是合約書內要考量的內容。美國政府有另外一本指南(The TechFAR Handbook)專文探討。

  • 專案預算必須包含需求或技術研究及雛型產出(註:凹廠商作白工嚐到苦果的總是機關自己)

合約書要注意的內容有:

  • 要求廠商負責頻繁的產出成品(或雛型),而非好幾個月才檢查一次的里程碑
  • 成品演進過程中,甲方有調整需求順序的權利
  • 考量技術選項時要把開源解決方案納入評估
  • 產出的軟體及資料必須要在甲方控制之下,能夠依照適當的法律規定重複使用及釋出給公眾
  • 若採用廠商的服務或工具,確保有不同的計價方式,如固定計價或依需求計價
  • 效能指標,如系統反應時間、系統正常服務時間、不同優先權的需求/錯誤處理時間等
  • 註明保固期,保固期內發現的bug應免費修正
  • 合約包含系統或服務的日出及日落條款(服務轉移期)

以我接觸過的國內政府現況來說,以上這些內容大部分都有,但合約範本還是偏向傳統waterfall模型,因此在專案彈性上,例如需求順序調整、雛型產出週期、開源方案的評估方面都不足。另外系統開發前的使用者需求探索及使用者的參與也不夠,這會導致專案需求一改再改,廠商被一凹再凹,弄得甲乙雙方都很累…

一人當責(Assign one leader and hold that person accountable)

每個專案都要有一個人負責產品的成敗,並賦予其相應的權力(而非只講義務),專案的各項行政及技術決定由他說了算,他的終極責任就是確保產品符合使用者需求,並且以此來評估負責人的績效。

  • 所有利害關係人都同意專案負責人有專案項目功能及工作分派的最終決定權。
  • 專案負責人要有專案管理跟技術背景,才能評估各技術選項及工作難度以便工作分派。
  • 專案負責人要會估預算,知道錢能從哪來,且與乙方保持良好關係。

這大概是目前政府專案欠缺的部分。首先擁有專案生殺大權的一定是最高的官,但高官往往沒有專案管理跟技術背景,或早已生疏,對預算細節及乙方底細也不是很清楚;符合後面兩點的可能是中階主管如科長級,但科長級又往往只被要求盡義務不被賦予權力,所以專案成敗=層層負責=沒人負責,你懂的…

(待續)