從一到二
都說從零到一是最困難的,但這似乎已經是過去式了。在生成式AI的時代,從零到一變得容易許多,而從一到二卻容易被忽視。許許多多的零在一夜之間成爲了一,然而就永遠地停在了一這裏,成爲了幾千串無人在意的字節。
我在一年前開始動手寫一個app,起初是因爲想要有一個工具來幫助自己更好地記錄一些東西,一些關於人事物的容易忘記的細節。那個時候,初代的Vibe Coding工具才剛出現,並沒有那麼好用,基本上屬於從locale文件生成翻譯都會出錯漏行的那種。即便如此,效率的提升也是挺讓人沉迷的,一兩個小時就可以整一個PoC(Proof of Concept)出來,然後沾沾自喜五分鐘。
所以其實當這個app上綫的時候,充其量不過是一個PoC而已,粗糙得很(現在可能仍是)。而從那個時候起,我也有更多的一些時間,思考下在這個時代背景下,如何構建一個成熟的數字產品。
關於大模型
當設計產品的時候,如果先入為主地認為這些那些大模型都能做,不如丟進去讓大模型完成。結果就陷入一種困境,可以說像是戴著鐐銬跳舞,或者說就是在寫八股文一樣,有一個無形的框框在那裡限制著你的想像力。
我試過寫格律詩,裏面平仄有定式,但當你的火候還不夠的時候,就是那些定式還沒有成爲你的一種條件反射的時候,要把你的想象力塞進那個框框裏,其實挺難受的。
並不是說框架下就不能有好作品,就好像杜甫的詩向來都嚴格按照格律,仍有許多傳世佳作,這個需要一定的天賦和沉澱。不過對於年輕人來說,誰不喜歡李白多一點呢?
所以我在設計2.0的時候,做了一个方向上的轉變——最小化,甚至說刻意地边缘化大模型的角色。產品的核心邏輯需要能夠脫離大模型存在,這個是一個關鍵的轉變,當我踏出這一步的時候,我發現我可以更多地去關注許多應該注意的細節,比如說在交互和在工程性上,而不是花許多的時間在優化prompt以及解析大模型response上。
有許多產品是建立在大模型上的,其性能高度依賴於大模型提供商的供貨,而現在的確不乏有許多實惠的模型可供選擇。但其實對於用戶來說,他們不得不在便利性和隱私之間有所取捨,這個見仁見智。另外也有端側大模型的選擇,比如Apple原生的Foundation Model,或者通過Apple-MLX來運行定製化的本地模型,算是顧及到隱私的另一個方向,只不過這個對於設備的要求也更高了。
但我在這一次的重新構思裏,發現許多的功能,其實也是可以用非大模型的方法來實現的,這個就是我想要講的第二個點,就是工程性的重要。
關於工程性
有的人在大模型編程逐漸普及的時候,就提出一個觀點,說是在軟件開發行業,編程能力不再重要了,更重要的是產品思維。這個觀點忽略了一個成熟度高的軟件中功能的工程複雜性,高估了大模型對於軟件宏觀架構和細節把控的平衡。在一個工程中,關於實現某一個功能模塊,其實是有許多不同的選擇的,比如一個簡單的“Carousel組件”,你可以選擇調用第三方的庫,也可以選擇自己重頭開發,也可以選擇改寫第三方的庫,在做這個選擇的時候,需要做一個權衡,這個權衡需要經驗來做出判斷。一個工程由許多這樣的權衡組成,錯誤的累積會導致後期的難以維護。
在這個項目裏,其中的一部分是要在筆記中抓取一些人事物。在1.0的版本中,這個是直接交給大模型做的,其實結果十分可靠,千問的模型基本上可以很穩定地給出滿意的結果。但是,這個是犧牲了隱私性的,我對這個解決方案並不喜歡,因此還是添加了Foundation Model作後備選項,但直接用Foundation Model處理大量的input效果並不好。
所以在改版的過程中,我決定對這個模塊進行功能拆分,最終拆成了以下幾個部分:
- 分詞:就是對文本進行一個基本的分詞,將其中的關鍵詞找出來。
- 匹配:將分詞後得到的詞組與現有的印象進行比對,找到匹配的。
- 關聯分析:分析筆記作者(我)和抓取結果之間的關係。
以上只是簡述,每一步裏面有更細節的實現,比如優化分詞,語義相似度計算等等。
其中在分詞的階段,我碰到一個案例覺得挺有意思,也記錄一下。
當我在用一個分詞庫進行測試的時候,對於以下的句子:
當我走出門的時候,天都黑了。
分詞器給出了“天都”這個詞,因爲在它的詞典裏,的確存在這個詞,是一個地名,所以它給出了很高的confidence score。這個是基於詞典的分詞器的一個致命傷,過於依賴詞典。一些基於深度學習的分詞器可以輕鬆地在這個句子中分出“天”來。然而,如果我手上只有這個基於詞典的分詞器,能不能解決這個問題呢?我當時試了一個方法去驗證分詞是否正確,就是調用了iOS自帶的翻譯API,把原句子和分詞結果分別翻譯成英文,再對結果進行語義相似度(Semantic Similarity)計算。對於以上的例子:
When I walked out of the door, the sky was completely dark
分詞如果是天都這個地名的話,就會被翻譯成
Tiandu
當計算語義相似度的時候,會得到一個相當低的分數,因此可以判斷分詞是不正確的。
這個方法如果對於大量的分詞需求,並不是一個可行的方案,因爲翻譯API的調用效率是瓶頸,然而在這一個特定的情況下,如果沒有更好的分詞方法可以用,卻的確是可以在比較普遍的用例中都能夠去掉許多不想要的結果。
雖然最後我還是選擇了一個更成熟的基於深度學習的分詞器,不過這個小案例讓我看到對於一些技術問題,我和AI給出的解決方案之間,存在一種難以描述的差異,有點像直覺,就是那種不知道哪裏來的想法。
臨了,想到一個關於工程的聖經經節:
各人的工程必然顯露,因為那日子要將牠指明出來;牠要在火中被揭露,這火要試驗各人的工程是那一種的。(哥林多前書3:13)
是個提醒,不要忽略了內在的東西。
總結
以幾個成語來結束,第一個是“過猶不及”,第二個是“矯枉過正”,我覺得1.0版本應該是前者,現在的2.0可能是後者,希望到3.0的時候,能夠達到“執兩用中”。
放個app store鏈接,給大家下載來玩,因爲不再有第三方服務商,所以就開放免費了,歡迎提建議。
Member discussion