Firma wdrażająca asystenta AI do obsługi klientów B2B może mieć 300-800 aktywnych kontrahentów w jednej instancji systemu. Jeśli pamięć długoterminowa nie jest izolowana per-tenant, agent obsługujący klienta z branży medycznej może podciągać kontekst z rozmów prowadzonych z klientem z sektora finansowego. To nie jest scenariusz teoretyczny: błędna konfiguracja filtrowania w bazie wektorowej powoduje takie wycieki w praktyce, zanim ktokolwiek to zauważy.
Trzy warstwy pamięci agenta
#Każdy produkcyjny agent operuje na co najmniej trzech warstwach pamięci, które mają różne cykle życia i wymagania.
Pamięć sesyjna to kontekst okna bieżącej rozmowy (context window). Żyje od pierwszego komunikatu do zakończenia sesji. Nie jest persystowana, chyba że jawnie ją zapisujesz. Zawiera całą historię wymiany w bieżącej sesji, instrukcję systemową oraz pobrane fragmenty z RAG. Jej rozmiar jest ograniczony liczbą tokenów, którą model obsługuje w jednym oknie, zazwyczaj 8 000-128 000 tokenów w zależności od modelu.
Pamięć wektorowa (długoterminowa) to persystowane embeddingi fragmentów historii rozmów, dokumentów klienta i faktów, które agent ma zapamiętać między sesjami. Przechowujesz ją w bazie wektorowej (Qdrant, Weaviate, pgvector). Wyszukiwanie semantyczne przy każdym nowym zapytaniu podciąga reletwantne fragmenty z tej warstwy jako kontekst do odpowiedzi, wzorem wzorca RAG.
Profil użytkownika / tenanta to ustrukturyzowane dane: preferencje, role, historia spraw, udzielone zgody, daty retencji. Przechowujesz go w relacyjnej bazie danych (nie wektorowej), bo potrzebujesz precyzyjnych zapytań, aktualizacji i kaskadowego usuwania. To właśnie ten rekord jest dowodem zgody i źródłem prawdy dla prawa do bycia zapomnianym.
Izolacja kontekstów: jak nie mieszać danych klientów
#Najczęstszy błąd architektoniczny: baza wektorowa bez filtrowania po identyfikatorze tenanta. Wzorzec bezpieczny wygląda inaczej.
Każdy fragment zapisywany do bazy wektorowej dostaje metadane tenant_id (i opcjonalnie user_id). Przy każdym zapytaniu wyszukiwanie zawiera filtr where: { tenant_id: { eq: current_tenant } } jako obowiązkowy warunek, zanim zostanie obliczone podobieństwo cosinusowe. Bez tego filtru model embeddingów może zwrócić fragment z zupełnie innego kontekstu, jeśli jest semantycznie podobny.
Dodatkowe warstwy izolacji, które warto wdrożyć:
Namespace per-tenant w bazie wektorowej: Qdrant obsługuje kolekcje lub punkty z filtrami per-tenant. Przechowywanie danych różnych klientów w osobnych kolekcjach jest silniejszą izolacją niż samo filtrowanie metadanych, ale kosztuje więcej zasobów przy setkach tenantów.
Token sesji jako granica kontekstu: każda sesja otrzymuje unikalny identyfikator. Fragmenty historii zapisywane do pamięci wektorowej zawierają session_id jako metadaną. Dzięki temu możesz usunąć całą historię konkretnej sesji bez ruszania reszty danych tenanta.
Guardrails na wyjściu: zanim agent zwróci odpowiedź, warstwa guardrails sprawdza, czy odpowiedź nie zawiera danych osobowych (PII) innego klienta. To siatka bezpieczeństwa, nie główna linia obrony. Więcej o architekturze wieloetapowych agentów w artykule o agentach wielokrokowych.
Tabela: typ pamięci, zastosowanie i wymóg RODO
#| Typ pamięci | Zastosowanie | Gdzie przechowywać | Wymóg RODO |
|---|---|---|---|
| Sesyjna (in-memory) | Historia bieżącej rozmowy, kontekst zapytania | RAM / tymczasowy bufor | Nie persystować bez zgody; brak po zamknięciu sesji |
| Wektorowa (embeddingi historii) | Podciąganie kontekstu między sesjami | Baza wektorowa z filtrem tenant_id | Retencja ograniczona do celu, usuwanie na żądanie (kaskada po embedding ID) |
| Profil użytkownika | Preferencje, zgody, role, historia spraw | Relacyjna baza (SQL) | Podstawa prawna + TTL + prawo do bycia zapomnianym w 30 dni |
| Logi rozmów (audit) | Debugowanie, RODO art. 5 rozliczalność | Bezpieczne logi, osobne od wektorów | Retencja max 12-24 miesiące, pseudonimizacja PII |
| Cache semantyczny | Odpowiedzi na powtarzalne pytania | Baza wektorowa z TTL | Klucz per-tenant, nie cachować odpowiedzi z PII |
Retencja i prawo do bycia zapomnianym
#RODO art. 17 daje podmiotowi danych prawo żądania usunięcia jego danych. W kontekście pamięci agenta oznacza to kaskadową operację na co najmniej czterech zasobach.
Krok 1: Usuń profil z relacyjnej bazy danych. To zwykle prosta operacja DELETE WHERE user_id = X, ale wymaga wcześniejszego zebrania wszystkich identyfikatorów powiązanych z tym użytkownikiem.
Krok 2: Usuń embeddingi z bazy wektorowej. Qdrant pozwala usuwać punkty po filtrze metadanych: DELETE WHERE user_id = X AND tenant_id = Y. Zanim to zrobisz, musisz mieć listę point_id powiązanych z tym użytkownikiem, dlatego relacyjna baza profilu powinna przechowywać mapowanie user_id → [point_id_1, point_id_2, ...].
Krok 3: Usuń lub zanonimizuj logi. Logi przechowywane do celów audytowych mogą zawierać treść rozmów. Opcje to pseudonimizacja (zamień user_id na nieodwracalny hash) lub pełne usunięcie, jeśli cel przetwarzania nie uzasadnia dłuższego przechowywania.
Krok 4: Zinwaliduj cache. Jeśli cache semantyczny przechowuje odpowiedzi zawierające dane tego użytkownika (rzadko, ale możliwe przy spersonalizowanych odpowiedziach), usuń powiązane wpisy cache.
Termin realizacji: 30 dni kalendarzowych od żądania. Zautomatyzuj cały przepływ i prowadź log realizacji żądań jako dowód rozliczalności (RODO art. 5 ust. 2). Wzorce anonimizacji PII przed przetwarzaniem przez model opisujemy w artykule o anonimizacji PII.
Retencja jako polityka, nie tylko technikalia
#Retencja danych w pamięci agenta to nie tylko termin przechowywania. To decyzja o tym, jak długo agent „pamięta" kontekst i jak to wpływa na jakość odpowiedzi kontra ryzyko przechowywania nadmiarowych danych.
Praktyczne podejście: podziel pamięć wektorową na segmenty z różnymi TTL. Historia bieżącego projektu klienta: TTL 6-12 miesięcy lub do zamknięcia projektu. Ogólne preferencje komunikacyjne: TTL 24 miesiące. Dane wrażliwe (np. szczegóły finansowe): TTL 3-6 miesięcy lub po pierwszym użyciu.
Politykę retencji dokumentujesz w DPIA. Jeśli twój agent przetwarza dane w sposób systematyczny na dużą skalę (np. obsługuje tysiące klientów), DPIA jest obowiązkowa przed uruchomieniem. Zawiera opis celu przetwarzania, kategorii danych, czasu retencji i zastosowanych zabezpieczeń.
Wzorzec retencji, który dobrze się sprawdza w wdrożeniach firmowych: każdy fragment w bazie wektorowej ma pole expires_at (timestamp). Codzienny job bazodanowy usuwa wygasłe fragmenty i aktualizuje mapowanie point_id w profilu użytkownika. Dla bazy wiedzy firmowej (nie personalizowanej) retencja jest nieokreślona, ale każda aktualizacja dokumentu triggeruje reindeksację. Wzorce zarządzania wiedzą RAG opisujemy w artykule o firmowym GPT na bazie wiedzy.
Architektura self-hosted a zgodność z RODO
#Jeśli dane klientów są szczególnie wrażliwe (dane zdrowotne, finansowe, tajemnica przedsiębiorstwa), self-hosting całego stosu pamięci agenta eliminuje ryzyko transferu danych do kraju trzeciego. Model embeddingów (np. BGE-M3), baza wektorowa (Qdrant) i model LLM (Ollama) mogą działać na własnej infrastrukturze. Całość pozostaje pod data-residency wymaganym przez RODO. Szczegółowe wzorce self-hostingu LLM pod kątem RODO opisujemy w artykule o systemach multi-agentowych w firmie.
Zaprojektuj pamięć agenta na żywo
#FAQ
#Jak technicznie zrealizować prawo do bycia zapomnianym w bazie wektorowej?
#Bazy wektorowe jak Qdrant pozwalają usuwać punkty po filtrze metadanych. Przechowuj mapowanie user_id → [point_id] w relacyjnej bazie danych. Przy żądaniu usunięcia: pobierz listę point_id z profilu, wywołaj DELETE points WHERE id IN (...) w bazie wektorowej, usuń profil z SQL, zanonimizuj logi. Cały przepływ powinien być zautomatyzowany i logowany jako dowód rozliczalności.
Ile czasu i danych potrzeba, żeby pamięć wektorowa dawała realną wartość?
#Pierwsze efekty są widoczne po 20-50 zapisanych fragmentach na użytkownika, typowo po 3-5 sesjach roboczych. Przy 100+ fragmentach agent zaczyna trafnie podciągać kontekst z poprzednich projektów. Jakość zależy bardziej od trafności chunkingu i polityki zapisu (co zapisujesz) niż od ilości danych.
Czy mogę przechowywać podsumowania sesji zamiast pełnych transkryptów?
#Tak, to dobra praktyka z dwóch powodów. Po pierwsze, podsumowania zajmują mniej tokenów w oknie kontekstu, więc agent działa szybciej. Po drugie, możesz usunąć z podsumowania dane osobowe zanim je zapiszesz, co upraszcza retencję i zmniejsza zakres DPIA. Wada: utrata precyzji przy specyficznych faktach, które agent powinien zapamiętać dokładnie.
Jak unikać sytuacji, w której agent myli dane dwóch klientów o podobnym profilu?
#Filtr tenant_id w bazie wektorowej jest obowiązkowy i musi być pierwszym warunkiem zapytania, przed obliczeniem podobieństwa semantycznego. Samo podobieństwo embeddingów nie wystarczy jako izolacja. Dodatkowo warstwa guardrails na wyjściu może weryfikować, czy odpowiedź nie zawiera identyfikatorów innego tenanta (nazwy firm, numery umów).
Czy pamięć wektorowa wymaga osobnej bazy czy można użyć PostgreSQL z pgvector?
#Oba podejścia działają produkcyjnie. pgvector w PostgreSQL (rozszerzenie) to dobre rozwiązanie przy mniej niż 1-2 mln wektorów i ruchu poniżej kilkuset zapytań na minutę. Przy większych wolumenach dedykowane bazy (Qdrant, Weaviate) oferują lepsze zarządzanie metadanymi, filtrowanie wieloatrybutowe i optymalizacje ANN (approximate nearest neighbor). Zaletą pgvector jest jeden system baz danych do obsługi zarówno profilu użytkownika jak i embeddingów, co upraszcza kaskadowe usuwanie przy realizacji prawa do bycia zapomnianym.