運作原理

每個客戶的記憶體

對話如何成為關於客戶的持久事實 — 推導、去重、重要性,以及哪些內容會被召回。

從您的文件中取得答案。記憶是另一半:代理程式對這位特定客戶的了解,跨越會話、頻道和月份持續存在。

記憶是衍生出來的,而非記錄下來的

1. 回合結束

對話回合結束。此時尚未儲存任何內容——在此系統中,轉錄稿並非記憶的單位。

2. 提取

模型從客戶所說的話中提取標準化的條目——而非來自代理程式自己的回覆:包含事實(「擁有四輛車的車隊」)和主題,每個條目都帶有重要性評分,以便讓隨口一提的話與嚴格限制條件不會被同等權重看待。

3. 批次嵌入

該回合的條目被作為一個批次嵌入,而不是一次一個。由於嵌入端點的併發數為一,因此一系列單次呼叫會阻塞其他使用者的查詢嵌入在其後。

4. 去重

每個條目都會與現有內容進行比對——主題按名稱比對,事實則在閾值內按向量相似度比對。若無此步驟,同一個事實若在五個對話中被提及,就會變成五筆記憶,從而擠壓掉其他所有內容。

5. 儲存

若找到匹配項,則更新現有資料列而非新增一筆:內容與嵌入向量會刷新,重要性會提升至兩者中較高者,並重新指向最近的會話,以便讓時效性追蹤活躍的關係。若無匹配項,則作為新條目儲存,加密並限定於該空間範圍內。

6. 召回

在下一個回合中,記憶會透過相似度進行召回,其閾值比文件使用的閾值更嚴格——因為與文件段落僅有輕微相關只是無用,而與某人的「事實」僅有輕微相關則是完全錯誤的。

在回合結束後執行。去重步驟是防止關係變長時召回品質下降的關鍵。

儲存整個轉錄稿並搜尋回傳是最直觀的做法,卻是個糟糕的做法。轉錄稿大部分是廢話,同一個事實會以二十種不同的措辭出現,且隨著關係變長,召回品質會下降——這完全背道而馳。

相反地,在回合結束後,平台會要求模型從客戶所說的話中提取標準化條目,分為兩類:

  • 事實——關於客戶的持久性陳述。「擁有四輛車的車隊。」「續約在五月。」「偏好使用 WhatsApp。」
  • 主題——關係中反覆出現的主題,每個主題都有主題名稱。

每個條目都帶有重要性評分,以便在空間有限時,讓隨口一提的話與嚴格限制條件不被視為同等重要。

僅限客戶的那一半對話

提取過程僅讀取客戶所說的話。代理程式自己的回覆不符合成為關於客戶的事實的資格,這比聽起來更重要。

如果代理程式猜測了一次——在回覆中提出一句關於該客戶公司可能生產什麼的猜測——否則該猜測會被提取為持久性事實,並在後續每個回合中作為前提條件讀取。從那時起,它就不再是猜測了;而是代理程式所知道的事實。客戶會看到後果,卻從未看到原因:答案始終圍繞著錯誤的業務,且螢幕上沒有任何內容解釋原因。

有兩道防線,因為第一道是請求,第二道是檢查。提取過程僅顯示客戶的那一半內容。然後,在寫入任何內容之前,軟體會驗證「事實」的措辭是否在客戶實際所說的話中有依據——這是一項在模型之外、針對每個條目和每個回合執行的檢查。

去重是整個遊戲的關鍵

客戶在五個對話中提及相同的事情。若無去重,您會累積五筆幾乎相同的記憶,它們會在召回時擠壓掉其他所有內容,導致代理程式開始重複自己。

在寫入條目之前,平台會尋找應將其合併的現有條目:

  • 主題按主題名稱匹配——精確匹配,因為主題已經是標準化標籤。
  • 事實按向量相似度匹配:同一類型中最近的現有記憶,僅當其餘弦距離在配置的閾值內時才被視為重複。

若找到匹配項,現有資料列會更新而非複製——內容與嵌入向量刷新,重要性提升至兩者中較高者,以便讓後來顯得更重要的事實得到提升,而非以不同權重儲存兩次。該條目也會重新指向觸發它的最近會話和訊息,以便讓其時效性反映活躍的關係。

批次嵌入

單一回合通常會產生多個條目。一次一個地嵌入它們意味著多次順序往返嵌入端點——而由於該端點的併發數為一,這一系列呼叫會阻塞其他使用者的查詢嵌入在其後。

因此,一個回合的條目會作為一個批次嵌入,並將向量傳遞至寫入路徑。在三個條目的回合上測量:順序執行為 117 毫秒,批次執行為 46 毫秒——在介於客戶與答案之間的路徑上,有 2.4 倍的差異。

召回

在回合開始時,會根據其自身的距離閾值,透過向量相似度為該客戶召回記憶——這比文件召回使用的閾值更嚴格,因為與文件段落僅有輕微相關只是無用,而與某人的「事實」僅有輕微相關則是完全錯誤的。

召回的記憶會與任何召回的文件區塊一起加入提示中。代理程式從您的文件中取得答案,並針對它已經認識的人進行回覆。

遺忘

上述所有內容都會累積。條目合併,重要性上升,沒有任何內容離開——這對記憶來說是正確的預設值,但對錯誤的記憶來說則是錯誤的。

錯誤的記憶從客戶的角度來看幾乎是隱形的。他們無法看到儲存庫,因此無法看到錯誤的事實在其中;他們看到的是代理程式不斷將某事視為理所當然。對話中唯一能識別錯誤條目的人是被誤記的人,而唯一能這樣做的方式就是說出來。

所以說出來是有效的。「我們不做那個。」「那不是我的公司。」「忘記你對 X 的了解。」代理程式會將這些話與儲存內容進行匹配,並刪除找到的條目,使用任何語言,無需任何人開啟設定頁面。

判斷一句話是否在否定某個記憶確實是一個語言問題——「我們不做那個」可以是更正,也可以只是關於業務的陳述——因此由模型來做出判斷。模型無法決定它能造成多少損害,這些限制在程式碼中:

  • 每次請求最多刪除少數幾個條目,以便讓一次誤讀保持在可控範圍內。
  • 僅刪除足夠接近以實際匹配的條目。 相似度搜尋總是返回其最近的結果,即使是在沒有任何相關內容的帳戶上也是如此;若無距離下限,在無關帳戶上說「忘記你對 X 的了解」會刪除恰好排名第一的任何內容。
  • 刪除的內容會讀回給客戶。 靜默刪除與錯誤記憶一樣糟糕,而這次,唯一能告訴我們刪除是否正確的人已經在對話中。

刪除是永久性的——沒有存檔保存客戶要求被遺忘的內容的副本,這是對該請求唯一有意義的解讀。

範圍限定與加密

記憶限定於最終使用者的空間範圍,在資料庫層面強制執行,如同其他由租戶擁有的記錄,並按空間加密儲存。一個客戶的歷史記錄不會出現在另一個客戶的對話中,且僅從資料庫中無法讀取儲存的文字。

為什麼這很難在事後附加

按客戶劃分的記憶改變了資料模型的形狀:每個最終使用者的身份、用於限定範圍的空間、按該範圍加密的密鑰,以及回合循環中的衍生步驟。以單一共享助理為起點的系統往往最終會在某處擁有一個 CRM 欄位並稱之為記憶——這就是為什麼差異體現在對話中,而非功能列表中。

此做法的商業論證(而非機制)位於 按客戶劃分的記憶