<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Retrieval on YennJ12 Engineering Blog</title><link>https://yennj12.js.org/yennj12_blog_V4/tags/retrieval/</link><description>Recent content in Retrieval on YennJ12 Engineering Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 11 Sep 2026 16:00:00 +0800</lastBuildDate><atom:link href="https://yennj12.js.org/yennj12_blog_V4/tags/retrieval/feed.xml" rel="self" type="application/rss+xml"/><item><title>Mem0 Intro Part 3 — 讀取路徑 — 語意、關鍵字與實體的三訊號融合</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/mem0-intro-part3-hybrid-retrieval-zh/</link><pubDate>Fri, 11 Sep 2026 16:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/mem0-intro-part3-hybrid-retrieval-zh/</guid><description>大多數人做記憶檢索，是「把查詢嵌入，向量庫 top-5，塞進 prompt」，然後在召回不準的時候去調 embedding 模型。 真正的答案是：記憶檢索的失敗有三種完全不同的成因——語意相近但講的不是同一件事、要找的是一個專有名詞而向量模型覺得同類詞都很像、以及答案根本沒有出現在查詢的字面裡。 一條訊號解決不了三種問題。 這一篇拆的是那三條訊號怎麼算、怎麼合。
前言 Part 2 的結論留下一個很重的包袱：v3 的萃取是 ADD-only，舊事實不會被覆蓋。 「使用者住在里斯本」和「使用者住在柏林」會同時存在記憶庫裡。
這把壓力完全轉移到了讀取路徑。如果檢索沒辦法讓正確的那一條排在前面，整個 ADD-only 的設計就崩了。
這一篇拆解 Mem0 怎麼做這件事。好消息是：讀取路徑完全不呼叫 LLM，所以它快（~100ms）又便宜；壞消息是：它因此只能靠純演算法的訊號，而那些訊號的權重是寫死在原始碼裡的常數——你調不動，但你可以理解並繞過。
本篇的目標：讀完之後，你能看懂 explain=True 吐出來的每一個欄位，能解釋為什麼某條記憶沒被撈到，並且知道在中文語料上這套機制會退化成什麼樣子。
一、核心問題：純向量檢索在記憶場景的三個盲點 1.1 記憶檢索 ≠ 文件檢索 先講清楚為什麼不能照搬 RAG 的做法。
文件 RAG 記憶檢索 ───────────────────────────────────────────────────────── chunk 有幾百 token 記憶只有一句話（10–30 token） → 語意向量資訊量足 → 向量很容易和同類句子撞在一起 chunk 之間大多獨立 記憶之間高度相關且可能互相矛盾 → 取 top-5 就好 → 要判斷哪條才是「現在的」 查詢通常是完整問句 查詢常常是一個名字或一個詞 → 語意匹配有效 → 需要精確匹配 語料是靜態的 記憶是持續累積且單調成長的 → 索引可以離線優化 → 舊的同義記憶會擠掉新的 第一行是最根本的差異。一句 20 個 token 的事實，嵌成 1536 維向量之後，資訊密度非常低——「使用者喜歡爵士樂」和「使用者喜歡古典樂」的餘弦相似度可能高達 0.</description></item></channel></rss>