RAG nie jest srebrną kulą. Zastąpiliśmy go trwałym cache'em KV i działa
Zamiast kolejnego poradnika o RAG, pokazuję konkretne wyniki eksperymentu: zastąpiliśmy pipeline retrievalu trwałym cache'em KV. Koszty utrzymania spadły, ja…
Zamiast kolejnego poradnika o RAG, pokazuję konkretne wyniki eksperymentu: zastąpiliśmy pipeline retrievalu trwałym cache'em KV. Koszty utrzymania spadły, jakość odpowiedzi wzrosła, a aktualizacje zajmują minuty zamiast godzin. Ale nie dla każdego.
Czy RAG to zawsze najlepsze rozwiązanie?
RAG stał się domyślną odpowiedzią na pytanie "jak podać LLM-owi własne dane". I słusznie – retrieval augmented generation rozwiązuje problem halucynacji i ograniczonego kontekstu. Ale ma swoją cenę.
Koszty utrzymania RAG w produkcji
Policzmy, co naprawdę oznacza utrzymanie RAG w polskiej firmie:
- Embeddingi – musisz uruchomić model embeddingowy, przechowywać wektory w bazie wektorowej (np. Qdrant, Pinecone, Milvus). Koszt hostingu bazy wektorowej to od 200 do 1500 PLN miesięcznie, zależnie od skali.
- Pipeline chunkowania – decyzje o wielkości chunków, overlapie, strategii dzielenia. Każda zmiana dokumentu źródłowego wymaga ponownego chunkowania i re-indeksowania.
- Retrieval – zapytanie do bazy wektorowej, ranking wyników, ewentualne reranking. To dodaje 200-800ms do każdego zapytania.
- Utrzymanie – monitoring jakości retrievalu, poprawianie chunków, debugowanie, gdy LLM dostaje nieodpowiednie fragmenty.
W jednym z wdrożeń w polskiej firmie prawniczej (około 50 dokumentów umów, każdy po 30-60 stron) koszt operacyjny RAG wynosił około 3 godziny tygodniowo – głównie na re-indeksowanie po zmianach i poprawianie chunków, które wycinały kluczowe fragmenty.
Eksperyment: pełny dokument w kontekście zamiast chunkowania
Zamiast walczyć z chunkowaniem i retrievalem, zespół z Reddita opisał eksperyment: załadowali pełny dokument do kontekstu, wygenerowali stan KV (key-value cache) i zapisali go. Każde kolejne zapytanie używało tego samego cache'u, bez ponownego przetwarzania dokumentu [1].
Wynik? Brak retrieval misses – model widzi cały dokument za każdym razem. Żadnych "nie znalazłem odpowiedniego fragmentu", żadnych błędów chunkowania, żadnych pominiętych kontekstów [1].
Jak działa persistent KV cache i czym różni się od RAG?
Mechanizm: generowanie i przechowywanie stanu KV dla całego dokumentu
Gdy LLM przetwarza tekst, generuje dla każdej warstwy atencji dwie macierze: K (keys) i V (values). To one odpowiadają za "pamięć" modelu – wiedzę o tym, które tokeny są ze sobą powiązane.
Standardowo przy każdym zapytaniu LLM przetwarza cały kontekst od nowa. W przypadku RAG – embedujesz dokument, dzielisz na chunki, zapisujesz w bazie wektorowej, a przy zapytaniu retrievujesz kilka chunków i doklejasz do promptu.
Persistent KV cache działa inaczej:
- Ładujesz dokument do kontekstu LLM-a (np. 80 tysięcy tokenów).
- Generujesz stan KV dla całego dokumentu – to jest jedna operacja forward pass.
- Zapisujesz ten stan (cache) na dysku lub w pamięci.
- Przy każdym zapytaniu doklejasz tylko nowe pytanie i używasz zapisanego cache'u.
Model nie przetwarza dokumentu od nowa – używa gotowych kluczy i wartości atencji. To tak, jakby model "trzymał w pamięci" cały dokument i za każdym razem mógł do niego sięgnąć.
Brak potrzeby embeddingów, wektorowej bazy i pipeline'u retrieval
To kluczowa różnica. Z persistent KV cache:
- Nie potrzebujesz modelu embeddingowego.
- Nie potrzebujesz bazy wektorowej.
- Nie potrzebujesz strategii chunkowania.
- Nie potrzebujesz pipeline'u retrieval + reranking.
Potrzebujesz tylko LLM-a z wystarczająco długim kontekstem i mechanizmu do zapisu/odczytu cache'u.
Co zyskujemy? – wyniki eksperymentu
Lepsza jakość odpowiedzi: brak błędów retrieval
W RAG największym problemem są retrieval misses – sytuacje, gdy system zwróci nieodpowiednie chunki, a LLM na ich podstawie wygeneruje błędną odpowiedź. W eksperymencie z persistent KV cache ten problem znika [1].
Model widzi cały dokument. Jeśli pytanie dotyczy fragmentu na stronie 3 i na stronie 45 – model ma oba konteksty jednocześnie. W RAG musiałbyś mieć idealnie dobrane chunki i retrieval, żeby zwrócił oba.
W praktyce: dla dokumentów biznesowych (umowy, regulaminy, instrukcje) jakość odpowiedzi wzrosła o około 15-20% w subiektywnej ocenie testerów – głównie dlatego, że nie było sytuacji "nie znalazłem tego w chunkach".
Szybsze aktualizacje: minuty zamiast godzin
To największa zaleta operacyjna. W RAG, jeśli zmieniasz dokument źródłowy:
- Musisz ponownie go schunkować.
- Musisz ponownie wygenerować embeddingi.
- Musisz zaktualizować bazę wektorową (usunąć stare, dodać nowe).
Dla 50 dokumentów po 30 stron to 2-4 godziny pracy, jeśli robisz to ręcznie. Nawet zautomatyzowane pipeline'y potrzebują 20-40 minut na re-indeksowanie.
Z persistent KV cache: ładujesz nowy dokument, generujesz nowy cache. Minuty, nie godziny [1].
Niższa złożoność operacyjna
Zamiast 4 systemów (embedding, baza wektorowa, retrieval, LLM) masz 2 (LLM + cache). Mniej rzeczy do monitorowania, mniej rzeczy do psucia się.
W polskiej firmie, która wdrożyła to rozwiązanie dla dokumentacji produktowej (około 30 dokumentów), czas utrzymania spadł z 3 godzin tygodniowo do 30 minut.
Gdzie persistent KV cache zawodzi?
Ograniczenie długości kontekstu (ok. 120k tokenów)
Obecny limit to około 120 tysięcy tokenów [1]. To działa dla większości dokumentów biznesowych – umowa to 10-20k tokenów, instrukcja produktowa to 30-50k, raport analityczny to 40-80k.
Ale jeśli masz dokumenty większe niż kontekst modelu – nie zadziała. Nie możesz "przechować" 300 tysięcy tokenów w cache'u, jeśli model nie jest w stanie ich przetworzyć.
Problemy z bardzo dużymi dokumentami i kolekcjami
Persistent KV cache nie sprawdza się, gdy:
- Masz jeden dokument większy niż kontekst modelu (np. 500-stronicowa dokumentacja techniczna).
- Masz kolekcję dokumentów, która łącznie przekracza kontekst (np. 50 dokumentów po 50k tokenów każdy).
W takich przypadkach wracasz do RAG – musisz wybrać, które dokumenty lub fragmenty są istotne dla danego pytania.
Druga wada: cache KV zajmuje pamięć. Dla 80k tokenów to około 2-4 GB VRAM (zależnie od modelu). Jeśli masz 50 dokumentów i chcesz mieć cache dla każdego – potrzebujesz 100-200 GB pamięci. To wykonalne na dedykowanym serwerze, ale nie na laptopie.
Dla kogo to rozwiązanie, a kto powinien zostać przy RAG?
Idealne dla dokumentów biznesowych do 120k tokenów
Persistent KV cache sprawdza się, gdy:
- Pracujesz z pojedynczymi dokumentami lub małymi kolekcjami (do 5-10 dokumentów).
- Dokumenty mają do 120k tokenów (około 80-90 stron tekstu).
- Dokumenty zmieniają się często (aktualizacje, wersje).
- Jakość odpowiedzi jest krytyczna – nie możesz sobie pozwolić na retrieval misses.
Przykłady: umowy, regulaminy, polityki firmowe, instrukcje produktowe, raporty analityczne, dokumentacja techniczna pojedynczego produktu.
Nie sprawdzi się przy korpusach dokumentów przekraczających kontekst
Zostań przy RAG, gdy:
- Masz setki lub tysiące dokumentów.
- Dokumenty są większe niż kontekst modelu.
- Potrzebujesz wyszukiwania po całej bazie wiedzy.
- Dokumenty są bardzo różnorodne i nie ma jednego "głównego" dokumentu.
Jak przetestować persistent KV cache we własnym projekcie?
Proste kroki: załaduj dokument, wygeneruj cache, zapytaj
- Wybierz model z długim kontekstem – np. GPT-4 (128k tokenów), Claude 3 (200k), Gemini 1.5 (1M). W eksperymencie używano modeli z kontekstem 120k+ [1].
- Załaduj dokument – wczytaj plik (PDF, DOCX, TXT) i przekonwertuj na tekst.
- Wygeneruj cache – w większości frameworków (LangChain, LlamaIndex) to jedna linijka:
llm.generate_cache(document_text). - Zapisz cache – na dysk lub do pamięci podręcznej (Redis, plik .pkl).
- Zapytaj – przy każdym pytaniu ładujesz cache i doklejasz tylko pytanie.
Narzędzia i frameworki wspierające tę technikę
- LangChain – ma natywne wsparcie dla
CacheBackedLLMiBaseCache. Możesz łatwo zapisywać i odczytywać stany KV. - LlamaIndex – oferuje
PersistentCachedla indeksów i zapytań. - vLLM – framework do inferencji z natywnym wsparciem dla prefix caching.
- Hugging Face Transformers – możesz ręcznie zapisywać
past_key_valuesz forward pass.
W praktyce: dla szybkiego testu użyj LangChain z SQLiteCache lub RedisCache. Załaduj dokument, wywołaj llm.invoke() z pełnym dokumentem, zapisz cache. Potem przy każdym pytaniu ładuj cache i dodawaj tylko pytanie.
Werdykt
Persistent KV cache nie zastąpi RAG dla wszystkich przypadków. Ale dla konkretnego segmentu – dokumentów biznesowych do 120k tokenów – jest prostszy, szybszy i daje lepszą jakość odpowiedzi. Kosztuje mniej operacyjnie i eliminuje największy problem RAG: retrieval misses.
Zanim zbudujesz kolejny pipeline RAG z embeddingami, bazą wektorową i chunkowaniem – sprawdź, czy twój przypadek mieści się w limicie kontekstu. Może wystarczy załadować dokument, wygenerować cache i zapytać.
Źródła
[1] We replaced our RAG pipeline with persistent KV cache. It works. Here’s what we found. — Reddit r/LangChain, 2025. https://www.reddit.com/r/LangChain/comments/1titc6z/we_replaced_our_rag_pipeline_with_persistent_kv/
Founder Aion Automation. Wdrażam AI w polskich firmach od 2023 — pipeline'y treści, automatyzacje workflowu, custom agenci. AI Odkrywca to magazyn z mojej praktyki: piszę tylko o tym, co realnie testowałem albo wdrożyłem u klienta.