How I Tricked Myself into Shipping Too Late

Michael Lynch

我是如何自欺欺人,導致產品太晚才上線

許多軟體創辦人失敗的原因很簡單:產品太晚才上線。他們花了數年時間在與世隔絕的狀態下開發產品,結果第一次交到真實客戶手上就土崩瓦解。

Indie Hackers podcast 有許多這類故事。該節目的宗旨是幫助聽眾從新創創辦人的錯誤中學習,但主持人 Courtland Allen(寇特蘭·艾倫)卻經常對此是否真的可行感到存在性的焦慮:

……有些事情你就算苦口婆心、一說再說,他們還是聽不進去,也無法真正理解你在說什麼,直到他們親自出門、犯下自己的錯誤,才會用慘痛的方式明白你的意思。

— 寇特蘭·艾倫,Indie Hackers Podcast

我總是心想:「才不呢,寇特蘭。這聽起來效率太差了。免費的教訓我收下了,才不需要去犯那些代價高昂的錯誤,謝謝。」

從這篇文章的標題,你大概已經猜到我的如意算盤並沒有成功。

產品構想

這個點子是在我盯著自己寫過最醜的一段程式碼時冒出來的。那是在我去年做的一個食譜搜尋工具裡。那款應用程式始終沒有起色,但偶爾做做還算有趣。程式碼庫中有個角落一直困擾著我:ingredient parsing(食材解析)。

舉例來說,給定像 "2 cups finely chopped red onions" 這樣的字串,應用程式必須判斷出 2 是數量,cups 是計量單位,以此類推:

食材解析結果的視覺化

將一項食材拆解成各個組成部分

一開始解析很簡單,但隨著新的邊界案例不斷出現,邏輯變得越來越脆弱、複雜。久而久之,邏輯崩壞成一座令人抓狂的 regular expressions(正規表示式) 迷宮——那是一種處理文字的指令,既強大又出了名的難讀。

regular expressions 實作截圖

我的 regular expressions 程式碼節錄

本想把一切打掉重練,改用 machine learning(機器學習) 方案,但那將是一項浩大的工程。我不可能為了一個不賺錢的網站上的小功能,投入好幾個月的開發時間。

然後,我靈光一現:如果 ingredient parsing 本身就是一門生意呢?如果這對我是個問題,那肯定也有其他開發者為此苦惱。或許,其中有些人已經在賺錢了,如果我能解決他們的問題,他們也願意分我一點。於是,我的 ingredient parsing 服務 Zestful 的構想就此誕生。

Zestful 標誌

Zestful,一款食譜食材解析服務

那個未能實現的 MVP

在 lean startup(精實創業) 的世界裡,人們經常談論「MVP(最小可行性產品)」,也就是 minimum viable product。MVP 是某個構想最簡單的版本。按照這個理念,你應該盡快把它做出來,交到潛在客戶手中,並從他們的反應來判斷它是否解決了真正的問題。

最常見的失敗故事之一,就是創辦人對自己的點子過度自信,因而忽略打造 MVP。相反地,他們投入數月甚至數年,去打造一個沒人想要的完整產品。

在 Zestful 這個案子上,我確實打造了 MVP。我甚至事先定義好了驗收標準,以免自己掉進無止盡微調與改進的兔子洞裡。

驗收標準文件

食材解析器驗收標準

大約投入 120 小時的開發工作後,我的可運作原型已經滿足了驗收標準。

然而,我又過了兩個月才正式上線。相反地,我把那段時間都花在寫更多程式碼上。

沒關係,因為這是銷售用的程式碼

你可能會好奇,為什麼我的 MVP 已經「完成」了,我卻還在原地空轉這麼久。以下是我在那兩個月期間的心路歷程摘要:

第 1 天:已達成驗收標準

服務能動了!但客戶只能透過在命令列中輸入複雜的表達式來使用。

我怎麼能讓客戶在 Web 3.1 的時代還得忍受撰寫 curl 指令的屈辱?加一個簡單的 HTML 前端,就能讓客戶直接在瀏覽器中測試服務。

5 天後

基本的 HTML 前端能動了,但一個孤零零的 HTML 表單擺在那裡,卻沒有任何說明,感覺很奇怪。

我需要在表單之外再建一個網站。不過這會是個超簡單的網站——只要一天就能搞定。

4 天後

太好了!服務已經有網站了。

……但網站還沒有說明每個欄位的說明文件頁面。這個下午就能搞定。

2 天後

現在頁面太多了,導覽列在行動裝置上會溢出螢幕。

我來把導覽列做成響應式的。以我的網頁框架 Angular 來說,這肯定只要一個小時就能搞定。

8 天後……

這就像九頭蛇。每次我完成「再加一個簡單的功能」,就會冒出兩個因而變得必要的新任務。最後,自從宣告程式碼完成以來,已經過了兩個月,而我對於自己竟然還沒上線任何東西感到百思不解。

這很重要,但可以等等再做

需要上線了。然而,我的關鍵任務清單仍未完成。我估計還需要五天才能做完。

然後,一件有趣的事發生了。在下定決心要盡快上線後,我意識到「最好要有」和「上線前非有不可」是兩回事。

一個例子就是我的 Terms of Use。如果我在沒有它的情況下上線,過幾天再補上會怎樣?最糟的情況是,若發生法律糾紛,我的立場會比較薄弱,但有人在上線後幾天內就告我的機率有多大?

閉嘴,上線就對了

對於任務清單上的每一項,我都問自己:「如果少了這個就上線,會怎樣?」在以同樣毫不留情的懷疑態度審視每一項任務後——就像我對待 Terms of Use 那樣——我真正的上線檢查清單才浮現出來。不到 24 小時後,我就把 Zestful 發布到了 API 市集 RapidAPI 上。我的服務上線了!

RapidAPI 上架頁面截圖

Zestful 在 RapidAPI 市集上的上架頁面

現在是見真章的時刻。我的服務已經準備好向真實客戶收款。我只需要說服他們購買。

我是為了逃避被拒絕才拖延上線嗎?

在「完成」與「上線」之間那兩個月的懸而未決期間,有個朋友問我,是否害怕把產品拿給客戶看。這些拖延上線的任務,是否只是一種逃避被拒絕的方式?

這個念頭我也曾想過,但很快就否定了。我以前做過業務,每天打陌生開發電話,被拒絕 40 次。被拒絕才嚇不倒我。

上線當天,我坐下來撰寫第一封陌生開發信:一封寫給不認識我的食譜應用程式開發者的電子郵件。我必須說明他們為什麼該把我的食材服務整合進他們的應用程式。

我盯著空白螢幕半小時,什麼也寫不出來。我已經向朋友解釋過我的服務數十次,但這次不一樣。每當我想到一個可能的賣點,就會想像客戶毫不留情的反駁:

那為什麼值得你開的這個價錢?

那如何增加我的獲利?

我為什麼需要你?

糟了。我確實害怕被拒絕。

另一種被拒絕

這和做業務完全不一樣。那份工作要我向企業銷售光纖網路,但光纖不是我鋪的,網路也不是我設計的。那種被拒絕,很容易就能坦然接受。

現在,我賣的是自己創造的東西。更何況,那是我寫的軟體。寫軟體是我自我認同中極為核心的一部分。沒有其他事是我更擅長、更引以為傲的。如果我把產品拿給客戶看,他們可能會想:「這東西不怎麼樣。你還拿來賣,表示你覺得它很好。所以,這個人也不怎麼樣。」

對被拒絕恐懼的漫畫

殘酷的現實

在數十次推銷、幾次對談、卻零成交之後,我才恍然大悟,自己已經成了那種花了數月投入在客戶根本不想要的產品上的開發者。

有些企業確實用得上像我這樣的服務,但最需要它的那些,早就自己打造了一套。其餘的人雖然認同這是個不錯的服務,卻無法證明這筆開銷是合理的,即使這項服務一個月只要 $20/month。

而就在那時,我發現了策略中的致命缺陷。對我的客戶而言,最大的成本不是我的月費,而是為了整合我的服務而修改他們應用程式的成本。

除此之外,他們還得權衡增加一個外部依賴的成本。如果我的服務發生中斷會怎樣?他們的應用程式會跟著停擺嗎?還是,他們得為我的服務故障時,建構整套備援的運作模式?

我把順序搞反了

回顧起來,我的流程完全顛倒了。向客戶進行陌生開發是我最後一步,但我本該在寫下一行程式碼之前就先這麼做。

一開始,我為自己先打造產品的決定找了個合理的藉口。客戶可能會對點子說好,卻永遠不會真的購買產品。我想要的「好」是真正的成交,也就是客戶透過購買服務來表示同意。

雖然那個邏輯現在想來依然有道理,但我忽略了「不好」的價值。如果客戶在概念階段就拒絕產品,他們在看到我做完之後也不會改變心意。如果每個人都說不,那大概就是死路一條。


Samantha Mason(莎曼珊·梅森) 編輯。插圖由 Loraine Yow(蘿蘭·尤)繪製。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯