前幾天,我們開始從「把 RAG 做出來」進一步走向 Production
但當流量增加後,一個問題也越來越明顯:
每一次 Request,都一定要從頭執行完整的 RAG Pipeline 嗎
三個問題雖然文字不同,但可能都需要查詢非常接近的文件
因此今天要加入一個非常重要的 Production 技術:
Caching:把可以重複使用的結果暫存起來,避免每次都重新計算
Cache 可以簡單理解成:
把已經算過的結果先存起來,下次需要時直接拿
最核心的概念就是 Cache Hit/Cache Miss
因此:
Cache 最直接的價值,就是降低 Response Latency
有些資料非常適合重複利用
因此可以建立不同層級的 Cache
如果相同 Query 再次出現
其實不需要每次重新計算 Embedding
這是一個非常簡單的 Cache
但它有一個問題:
程式重新啟動後,Cache 就消失了
每一台都有自己的 Dictionary
因此 Production 通常會使用:
Redis 作為集中式 Cache
Redis 是非常常見的 In-Memory Data Store
Cache 有一個非常重要的概念:
TTL
意思是:
Cache 最多保存多久
為什麼需要 TTL?
因為資料可能會改變
除了 Embedding,也可以 Cache Retrieval 結果
如果相同 Query 重複出現,可以直接使用之前的結果
如果同一個問題再次出現:
就不需要重新呼叫 LLM
因此可以直接降低 Token Usage、Cost
現實使用者文字不同,但語意可能非常接近
如果希望處理語意相似問題
就可以進一步使用:
Semantic Cache
只要語意足夠接近,也可以 Hit
Semantic Cache 很方便,但有一個非常重要的問題:
語意相似,不代表答案一定可以共用
Cache 最重要的問題之一:
到底要用什麼當 Key
但 Production 通常不夠
因為回答可能受到影響
Cache 系統最經典的一句話:Cache 不是「存起來」就結束
真正困難的是:
什麼時候應該刪掉
Cache 最重要的 KPI 之一:
Cache Hit Rate
理論上 LLM 成本可以大幅降低。
當然,實際成本還需要考慮:
所以不能只用單一公式判斷
但這裡也要注意:
Cache Hit Rate 高,不代表所有 Request 都會變快
如果 Cache Hit 的 Request 很少,或者真正耗時的是 Retrieval 或 Reranking,那麼整體改善可能有限
這樣就可以知道:
這一次 Request 是因為 Cache Hit 很快,還是真的跑完整 RAG
這裡還有一個不能忽略的問題:
Cache 不能只看速度與成本,也要看回答品質
因此 Cache 也應該加入 Evaluation
今天透過 Cache 降低:
但當系統開始有大量使用者與大量資料後,還有一個問題:
如果 Cache、Vector DB、LLM API、Application 都需要一起運作,整個系統的資料與服務應該如何部署
這時候就會開始碰到:
因此下一篇將從「單一 RAG Application」進一步走向:
開始思考:
當 RAG 不再只跑在一台機器上,要如何讓多台服務共同承擔流量