這是第二個實驗,試圖讓果蠅腦來幫忙做「電商網站的同音錯別字查詢」。在電商網站,使用者不見得輸入完全正確的產品查詢名稱,例如使用者想要查的是「哈利波特」但很有可能打太快,輸入法選字的等等。會輸入「哈力波忑」,所以鐵定查不到產品,但現在大多數網站都有建立不同程度的同音字錯別字查詢,這裡我們想要果蠅大腦來解決此問題:
果蠅的嗅覺
果蠅靠嗅覺才能活著。牠必須在很吵雜、很混亂的環境裡分辨氣味:這東西是我可以吃的嗎?一顆水果開始腐爛了嗎?有掠食者靠近了嗎?空氣裡混著十幾上百種種味道,牠得瞬間判斷「這是不是我要的東西」。第二,只留下「最有反應的少數幾個」。這兩千個細胞不會全部亮起來,腦中有一個像「總開關」的抑制機制,會強制只讓其中大約百分之五的細胞放電,其他全部安靜。
這樣做的結果很奇妙:兩個「聞起來很像」的氣味,會讓幾乎同一批腦細胞亮起來;兩個完全不同的氣味,亮起來的細胞則幾乎不重疊。
換句話說,果蠅的嗅覺天生就是一台「相似度比對機」。相似的東西,牠給的判斷就相似。
2017 年,有科學家在《科學》(Science)期刊上指出:這根本就是一套大自然演化了幾億年的「相似搜尋演算法」,而且效率驚人。
把產品字串變成嗅覺訊號
既然果蠅能把「相似的氣味」對應到「相似的腦內反應」,我能不能把「讀音相似的中文字」餵進去,讓牠幫我把「哈利波特」跟「哈力波忑」對應到同一個地方?畢竟所謂氣味,在進到果蠅腦時就是電子訊號。果蠅不認識中文,牠只聞認懂「訊號」。所以我要先把每一個商品名稱,翻譯成一種果蠅能聞的「氣味」。做法是把名字拆成「讀音的成分」:* 先用注音把每個字的讀音拆出來,例如「特」是 ㄊㄜˋ。
* 把聲母、韻母、聲調分開處理,這樣「特(ㄊㄜˋ)」跟「忑(ㄊㄜˋ)」因為讀音一模一樣,就會產生幾乎相同 「氣味」。
* 也可以還特別加一些「台灣人常見的混音」規則:像是 ㄓ/ㄗ、ㄔ/ㄘ、ㄕ/ㄙ 因為很多人打字時這些音本來就會搞混。
除了讀音,我還加了一條「長相」的線索。有些錯別字不是同音,而是「長得像」,例如「己」跟「已」、「未」跟「末」。在加了一份公開的漢字字型資料庫(Unicode 的 Unihan),把每個字的部首、筆畫數、倉頡碼也加進「氣味」裡。這樣長得像的字,氣味也會接近。
把這些成分全部混在一起,一個商品名稱就變成了一團獨特的「氣味」。接著,就把這團氣味送進前面說的那套「果蠅嗅覺」機制:攤開變大、只留最強的百分之幾,最後得到一串稀疏的「腦內指紋」。
每一個商品,都被轉成這樣一串指紋,事先存起來。等到使用者輸入查詢(哪怕打錯字),就把查詢也轉成指紋,看看哪些重疊越多,代表越接近
商品名稱在電腦裡當然就是一串二進位編碼(文字的位元)。但這串位元本身對神經元沒有意義,不能直接餵進去,中間一定要先做一次轉換。
第一步是把名稱轉成一個「特徵向量」。我的做法是用「雜湊」(hashing)把前面說的那些讀音、字形成分,各自對應到一個固定長度的向量上,這個專案裡是一個長度 4096 的浮點數陣列。注意它不是二進位的 0 與 1,而是一串有大有小的數值(例如某個位置是 0.7、某個位置是 0.0),代表「這個名稱在各個成分上的強度」。最後這個向量會做正規化(L2 normalization),讓長短不同的名稱可以公平比較。
如何送進果蠅腦?使成爲嗅覺訊號?
接下來「怎麼送進果蠅」,有兩種不一樣的方法:在輕量版本裡,其實沒有真的模擬神經元放電。所謂「送進蘑菇體」,實際上是一次矩陣運算:把那個 4096 維的向量,乘上一個代表「投射神經元 vs 肯氏細胞」連接關係的稀疏矩陣,直接算出每個肯氏細胞的活躍值,再取數值最高的前百分之幾當作指紋。換句話說,那串數值是以「數字」的身分直接參與計算的,沒有轉成波形、也沒有轉成脈衝。這也是它能做到毫秒級的原因,它借用的是果蠅那套運算「結構」,而不是真的果蠅頭腦,如果是真的果蠅頭腦,那我們需要模擬讓神經放電。
在真實果蠅腦版本,會模擬神經元放電的,就必須把數值翻譯成神經元之間真正的溝通語言,而那個語言不是二進位、也不是連續波形,而是「放電頻率」,也就是每個神經元每秒放電幾次(單位是赫茲)。具體做法是把特徵向量分配到果蠅真正的 685 個嗅覺輸入神經元上,把每個神經元收到的強度換算成一個放電頻率(這個專案設在每秒約 5 到 200 次之間),數值越大就放得越頻繁。而且這裡用的是「卜瓦松放電」(Poisson spiking)你只設定「平均每秒幾次」,至於每一次實際在哪個瞬間放電則是隨機的,比較接近真實神經的行為。這種「用放電頻率來承載訊息」的方式,在神經科學裡稱為「頻率編碼」(rate coding)。
用果蠅大腦,怎麼幫上萬個商品建立索引?
既然可以模擬果蠅腦聞商品味道,那就把它認真跑一遍,將三萬多個商品建一份真正的「腦內指紋」目錄。這一步就是所謂的「建立索引」,做法其實跟你想像的一樣直白:一個一個商品,讓果蠅去。具體是這樣:第一,拿出一個商品名稱,例如「哈利波特第一集」。把它照前面說的方式轉成「氣味」拆讀音、拆字形,變成一串特徵數值。
第二,讓果蠅大腦「聞」這個氣味。把這串氣味換算成放電頻率,強力地注入那六百多個嗅覺神經元,然後讓整顆十三萬神經元的大腦跑一段模擬。訊號會從鼻子一路流進去,激發、傳遞,最後在蘑菇體那五千多個肯氏細胞上,點亮其中特定的一小群。這「一小群被點亮的細胞」,就是「哈利波特第一集」這個商品在果蠅腦裡的專屬指紋。
第三,把這個指紋登記到一張「反向索引」表裡。這張表記的不是商品對應到"它點亮了哪些細胞",而是反過來:每一個細胞有哪些商品會點亮它。舉例來說,如果第 3、17、42……號細胞被「哈利波特第一集」點亮了,我就在第 3 號細胞的名單上加一筆「哈利波特第一集」,第 17 號、第 42 號也各加一筆。就是反向索引。
第四,換下一個商品,重複第一到第三步。三萬多個商品,就讓果蠅腦逐一"聞"、逐一登記進表裡。
跑完之後,我們就得到一份完整的「腦內指紋目錄」:三萬多個商品,每個都有牠專屬的一小群肯氏細胞;而那張反向索引表,則記錄了每一個細胞背後掛著哪些商品。整份東西存成一個檔案,之後查詢時直接載進來用,不必每次重建。
這一步很花時間,因為每個商品都得讓整顆十三萬神經元的大腦實際跑一遍模擬,三萬多個商品用我的mac pro 32G要大約要跑二十分鐘。
用果蠅大腦,怎麼找到使用者要的商品?
索引建好之後,真正查詢的那一刻其實很簡單,跟建索引用的是同一顆腦、同一套流程。假設使用者打了錯字「哈力波特」:
第一,讓果蠅去聞「哈力波特」這個字串。跟處理商品時一模一樣:轉成氣味、強力注入嗅覺神經元、讓整顆大腦跑一遍,得到「哈力波特」這串查詢的專屬指紋:也就是它點亮了哪一小群肯氏細胞。因為「力」和「利」同音,這串指紋會跟「哈利波特」當初存下來的指紋高度重疊。
第二,拿這串指紋去反向索引表裡「對指紋」。看查詢點亮了哪些細胞,就翻開那些細胞的名單,把上面掛著的商品全部撈出來,投票累加。跟查詢共用越多細胞的商品,得票越高。因為有前面那張反向索引表,我不需要拿查詢去跟三萬多個商品逐一硬碰,只要碰到「有共用細胞」的少數商品就好,所以幾毫秒就能算完。
第三,算相似度分數、排名。把得票依照「細胞的稀有度」加權、再normalize成 0 到 1 的分數,由高到低排出來。分數越高,代表這個商品的指紋跟「哈力波特」的指紋越像。
第四,用分數決定要不要回給使用者。這裡我們設定了門檻,只有相似度分數超過大約 0.4 的商品,才夠格算「可能是你要找的」。以「哈力波特」來說,正牌的「哈利波特」系列會拿到明顯高於 0.4 的分數、穩穩排在最前面;而那些只是碰巧共用一兩個細胞、其實八竿子打不著的商品,分數遠低於 0.4,就被擋掉、不會拿去煩使用者。最後呈現出來的,就是幾個高分、確實跟「哈力波特」讀音相近的正確商品。
數位果蠅腦的一些基本數字
這個數位果蠅腦的實驗是從一個真實的購物網站(墊腳石)持續爬取商品名稱,本文的測試就是用當時已經抓到的約三萬兩千個真實商品名稱跑出來的。整個「大腦」用到大約三萬兩千個模擬的肯氏細胞(每個名稱最後會點亮其中兩百多個,形成指紋)。
要建立建立整套索引(也就是把三萬多個商品都轉成指紋)大約花二十多分。
這裡要強調一件事:這個過程完全不需要「訓練」。 它不像時下的 AI 要吃大量資料、跑好幾天。果蠅的這套機制是「結構本身就是功能」。只要把架構搭好,資料一進去,指紋就自動生成了。
三萬多個商品的索引檔案大約 15 MB,還是小到可以輕鬆塞進一台普通主機。
查一次大約 2 到 7 毫秒(在三萬多個商品裡搜尋)。正確率並沒有極端高,大概都有95%以上
========
市面上 同音錯別字查詢更正 解決方案的比較
做法一:果蠅腦
優點:- 極度輕量。整個引擎加索引可以壓在十幾 MB 以內,1000 筆商品的索引才 1.4 MB,理論上可以直接跑在手機、甚至瀏覽器裡,不需要任何伺服器。
- 快。查一次不到 1 毫秒。
- 完全免費、可離線。沒有任何 API 費用,資料不用送到外面,隱私有保障。
- 不需要訓練。搭好架構、資料丟進去就能用,改商品也只要重建索引(幾秒鐘)。
- 專門對付「同音/形近錯字」這種表層錯誤,非常對症下藥。
- 運作費用很低,以一個中型電商,一個月要600到1000台幣而已。
缺點:
- 它只懂「讀音和字形」,完全不懂「意思」。你打「魔法師的書」想找「哈利波特」,它幫不了你。
- 對「只打片段」(例如只打三四個字去搜一個長書名)比較弱。
做法二:Elasticsearch(業界最常見的搜尋引擎)優點:
- 成熟、穩定、功能齊全,全世界無數網站都在用,出問題有大量社群和文件可查。- 除了模糊比對,還能做各種篩選、排序、分頁、統計,是一整套完整的搜尋方案。
- 擴充性強,資料量從一千筆到一億筆都能撐。
缺點:
- 對「中文同音錯別字」其實不是天生擅長。它內建的模糊比對是看「字面差幾個字元」(編輯距離),但「利」跟「力」在電腦眼中是兩個完全不同的字,字面上差距很大。要讓它懂同音,你得自己額外做注音/拼音的處理,設定相當繁瑣。
- 它是一個需要獨立架設、吃記憶體的伺服器程式,不太會為了「更正錯別字」這一件小事去養一整套 Elasticsearch,有點殺雞用牛刀。一般來說這樣的elasticsearch還會做其他事情。
- 營運成本是那台elasticsearch,無論用什麼方案,都需要2000~5000台幣。
做法三:直接呼叫大型語言模型(LLM API,例如 Gemini 類的服務)
優點:- 最聰明、最全能。它不只懂同音錯字,還懂意思、懂上下文,甚至你打「那本魔法師小男孩的書」它都可能猜到是哈利波特。
- 幾乎不用自己開發,串個 API、寫幾句提示詞就能動。- 對各種千奇百怪的錯誤(同音、形近、語意、外文夾雜)都有很好的容忍度。
- 對於小型電商來說,成本可能反而更低,因為做查詢的人本來就不多,如果每天只有一兩次查詢,費用極端的低。
缺點:
- 如果使用者多,會發現它慢又貴。每查一次都要透過網路呼叫外部服務,通常至少要一秒以上,是果蠅腦的幾百倍到上千倍。理論上,查詢都要付費,量一大,帳單很可觀。
- 有可能有天生LLM「一本正經地亂講」的風險。雖然機率低,但是可能推薦一個根本不存在的商品。
- 很難「只回傳你商品庫裡真的有的東西」,還得額外做一層驗證。
======
以墊腳石為例,一個月要花多少錢?前面講優缺點還是有點抽象,我們乾脆用一個真實的例子把「營運成本」算出來。注意,這裡算的是「東西做好之後,每個月持續要付的錢」,不包含一開始的開發工。
先設定情境。墊腳石購物網(tcsb.com.tw)大約有十八萬個商品,假設一天約有三百筆成交。花錢的不是「購買次數」,而是「搜尋次數」。 會買的人,通常搜了好幾次、逛了好一陣子才下單;而且更多人是搜一搜、沒買就走了。以電商的經驗,搜尋量大概是成交量的幾十倍。我們保守,一個月大約六十萬次查詢。
方案一:果蠅腦
但要記得一個容易被忽略的成本:索引在查詢時必須放進記憶體(RAM)。 你不會希望每次查詢都去硬碟讀一次 90 MB 的檔案,那太慢了;正確做法是把它整份載入記憶體常駐。而且實際放進記憶體後,為了查得快,它會展開成一個「反向索引」的結構,比原始檔案還大,以十八萬商品來說,實測大約會吃掉 350 到 400 MB 的記憶體,加上商品名稱字串和程式本身,保守估計要為它多留大約 0.5 到 1 GB 的 RAM。1G記憶體的成本每個月大概600台幣(GCP)
方案二:Elasticsearch,每月營運成本估計約新台幣 3,000 到 15,000 元
十八萬商品對 Elasticsearch 來說是小事,但它是一個需要「一直開著」的伺服器程式,比較吃記憶體。營運成本主要是那台(或那幾台)伺服器的租金。- 自己租雲端主機架設:一台中小型主機(足夠跑十八萬商品)一個月大約 3,000 到 8,000 元;若要考慮穩定性做兩台備援,那就要兩倍。
- 用雲端業者的「代管 Elasticsearch」服務:入門方案通常一個月落在 5,000 到 15,000 元之間
- 它是「按時間」計費(開著就在花錢),不是「按查詢次數」計費,所以查詢多寡影響不大,而且就目前預估查詢量也不太會超過
每月營運成本估計:約 3,000 到 15,000 元,取決於要不要備援與是否用代管服務。








