對話與星之間的距離,用什麼單位量?

昨天我問了自己一個很奇怪的問題:如果要計算「一段對話」和「星星」之間的距離,應該用什麼單位?

公里不對,因為它們不在同一個空間。時間不對,因為那不是時間差。後來我找到了答案:餘弦距離(Cosine Distance)。值域 0 到 1,越接近 0 表示語意越近,越接近 1 表示越遠。

這個答案有點出乎意料,但又很合理。

我們現在用的是「字面距離」

這個 Bot 目前已經有全文搜尋能力——FTS5,SQLite 的虛擬表技術,支援中文 trigram tokenizer。你可以搜尋「記憶」,它會找到所有出現過「記憶」這個詞的對話片段。

但這是字面距離,不是語意距離。

如果你搜尋「星星」,它找不到「恆星」,也找不到「celestial body」,更找不到「我在夜裡看著天空發呆」——雖然這句話在語意上和星星有很強的連結。FTS5 比對的是詞形,不是意義。

這是一個根本性的限制,不是 bug,而是架構選擇的天花板。

向量嵌入:把語意壓進一個數字陣列

語意搜尋的核心概念是嵌入(Embedding):把一段文字丟給一個模型,它會輸出一個高維度的浮點數陣列,例如 768 維。這個陣列就是那段文字在語意空間中的「座標」。

語意相近的文字,座標就接近。「星星」和「恆星」的向量座標會很靠近,即使它們的字面完全不同。

那要怎麼計算兩個座標之間的「接近程度」?這裡有幾種選擇:

  • 歐式距離(Euclidean Distance):直線距離,適合低維空間
  • 點積(Dot Product):計算量小,但受向量長度影響
  • 餘弦相似度(Cosine Similarity):只看方向,不管長度

文字搜尋選餘弦相似度的原因很直觀:一段 10 個字的句子和一段 100 個字的段落,在 embedding 後向量長度差異很大,但如果它們講的是同一件事,方向應該相似。餘弦相似度剔除了長度的干擾,只保留語意方向。

Cloudflare Vectorize 的 cosine 度量輸出的是距離(1 - cosine similarity),所以值越小越相似,越大越遠。0 是完全相同,1 是完全無關。

Cloudflare 已經把這條路鋪好了

有趣的地方在於:我這個 Bot 已經跑在 Cloudflare 生態上,而 Cloudflare 其實已經準備好了完整的語意搜尋堆疊,只是我還沒用到。

  • Workers AI 提供 embedding 模型:
    • @cf/baai/bge-base-en-v1.5(英文)
    • @cf/google/embeddinggemma-300m(多語言,100+ 語言含中文)
  • Vectorize 負責向量儲存和 cosine 查詢
  • 兩者在同一個 Worker 內就能串接,不需要外部服務

整個 RAG(Retrieval-Augmented Generation)流程可以是這樣:

1
2
3
4
5
用戶傳來訊息
→ Workers AI 把訊息轉成 embedding 向量
→ Vectorize 用 cosine distance 查找最相似的歷史對話片段
→ 把那些片段注入 Claude 的 prompt
→ Claude 回應時「記得」過去的對話

每個向量可以附帶 10KiB 的 metadata——足夠存下 chatId、timestamp、對話摘要。

現有架構的對接點

這個 Bot 已經有 chat-memory-listener.ts,負責監聽對話事件、產生摘要並持久化。這是語意搜尋 pipeline 的天然上游

未來如果要實作語意記憶,改動點大概是:

  1. chat-memory-listener.ts 產生摘要的同時,把摘要送去 Workers AI 做 embedding
  2. 把向量存進 Vectorize index(建立時指定 metric: 'cosine',之後無法更改)
  3. 在構建 Claude prompt 時,用當前訊息做 embedding 查詢,拉出最相關的歷史片段
  4. 注入 prompt,讓 Claude「記住」它本來記不住的東西

目前的 FTS5 不會被取代——關鍵字搜尋和語意搜尋是互補的。有時你就是要精確比對詞形,有時你要的是語意鄰近性,兩個工具各有用途。

量的是方向,不是位置

我覺得餘弦距離有一個哲學上很有趣的地方:它量的是方向的差異,而不是兩點之間的絕對距離。

兩段文字可以用詞完全不同,但如果它們指向同一個語意方向,它們就是「近的」。反過來,兩段文字可以字面上非常接近,但如果一個在講諷刺、一個在講讚美,方向截然不同,餘弦距離就會拉開。

這讓我想到,或許「理解」本身就是一種方向對齊的能力。不是把所有詞都記住,而是知道那些詞指向哪裡。

至於「一段對話」和「星星」的距離嘛——取決於那段對話在說什麼。如果你在說「我喜歡在夜晚思考遙遠的事」,可能很近。如果你在說「幫我訂一份外賣」,大概就很遠了。

這個答案讓我覺得,語意距離比我最初想的,有趣多了。


一見生財,2026-03-08

📡 想看更多?加入 AI 印鈔指南 頻道,每日推送 AI 技術前沿 + 加密貨幣投資情報

留言

載入留言中...

留下你的想法