RAG w praktyce: jak podpiąć dane firmowe do LLM

0
36
Rate this post

Nawigacja:

Co to jest RAG i kiedy ma sens w firmie

RAG jako sposób dopinania własnych danych do LLM

RAG (retrieval augmented generation) to wzorzec, w którym model językowy (LLM) nie „wymyśla” wszystkiego z głowy, tylko przed wygenerowaniem odpowiedzi dostaje świeży kontekst wyszukany z Twoich danych firmowych. Najpierw system wyszukuje relewantne fragmenty dokumentów, a dopiero potem dokleja je do promptu, który trafia do modelu.

W praktyce wygląda to tak:

  • użytkownik zadaje pytanie (np. „Jak zgłosić incydent bezpieczeństwa w naszej firmie?”),
  • system zamienia pytanie na wektor (embedding) i szuka podobnych fragmentów w bazie wiedzy,
  • kilka najlepszych fragmentów (chunków) jest wstrzykiwanych do promptu,
  • LLM generuje odpowiedź, opierając się głównie na tym kontekście, a nie wyłącznie na własnym „ogólnym” treningu.

Kluczowa zaleta: nie trenujesz modelu od zera, nie robisz kosztownego fine-tuningu na każdym drobnym update’cie procedury, tylko aktualizujesz dane w bazie wektorowej. Aktualizacja polityki czy regulaminu to zwykle:

  • nowa wersja dokumentu,
  • ponowne pocięcie na fragmenty,
  • ponowna wektoryzacja i podmiana rekordów w bazie.

Fine-tuning, RAG i proste promptowanie – praktyczne porównanie

Do „podpięcia” wiedzy firmowej pod LLM są trzy główne strategie:

PodejścieOpisKiedy sensowneWady
Proste promptowanieRęczne przeklejanie fragmentów dokumentów do promptu lub krótkie instrukcje w system promptPojedyncze zadania, mało danych, prototypy typu „one off”Brak skalowalności, brak aktualizacji wiedzy, ryzyko halucynacji
Fine-tuningTrenowanie modelu na przykładach Q&A lub tekście firmowymSpecyficzny język, styl, modele on‑premise, powtarzalne zadaniaDrogi, czasochłonny, trudny w częstej aktualizacji danych
RAGDynamiczne dokładanie fragmentów dokumentów do promptu dzięki wyszukiwaniu wektorowemuDuże zbiory dokumentów, aktualizowana wiedza, potrzeba śledzenia źródełWymaga architektury: ekstrakcja, baza wektorowa, filtry uprawnień

W wielu organizacjach rozsądny jest kompromis: RAG jako fundament, a fine-tuning tylko tam, gdzie naprawdę potrzebny jest firmowy styl, dokładna kontrola tonu wypowiedzi lub działasz w środowisku bez dostępu do zewnętrznych API.

Typowe use case’y RAG w firmie

Najczęściej RAG w firmie pojawia się w kilku powtarzalnych scenariuszach:

  • Wyszukiwarka po dokumentach – „Google wewnętrzny”, ale z rozumieniem treści, a nie tylko słów kluczowych.
  • Asystent wiedzy o produktach – dla działu sprzedaży, customer success, partnerów; odpowiedzi z aktualnych cenników, kart produktów, FAQ.
  • Wsparcie helpdesku i IT – RAG zasilany ticketami, procedurami, artykułami w bazie wiedzy, aby odpowiadać na pytania pracowników i klientów.
  • Onboarding pracowników – Q&A z polityk HR, regulaminów, instrukcji sprzętowych.
  • Asystent prawny / compliance – wyszukiwanie i streszczanie klauzul z umów, polityk, regulacji wewnętrznych.

Realistyczny przykład z PDF-ami procedur

Korporacja ma tysiące PDF‑ów z procedurami: bezpieczeństwo, HR, finanse, IT, BHP. Pracownicy, zamiast wertować SharePointa, chcą zadać pytanie w stylu: „Jak zgłosić utratę służbowego laptopa?”. Manualne szukanie w intranecie trwa długo, a i tak często kończy się pytaniem na Slacku.

RAG pozwala:

  • zindeksować treść wszystkich PDF‑ów w bazie wektorowej,
  • zachować metadane (dział, wersja, data),
  • w odpowiedzi LLM cytować konkretne paragrafy z odpowiednich dokumentów,
  • dodać filtr uprawnień, żeby pracownik z działu A nie widział poufnych procedur działu B.

Efekt: realne skrócenie czasu szukania informacji i mniejsza liczba powtarzających się pytań do działów wsparcia wewnętrznego.

Podstawowa architektura RAG – z czego to się składa

Kluczowe komponenty w architekturze RAG

Przy wdrażaniu RAG pomaga myślenie o systemie jak o kilku modułach, które można rozwijać niezależnie. Klasyczna architektura obejmuje:

  • Źródła danych – SharePoint, dyski sieciowe, wiki (Confluence, Notion), bazy SQL, CRM, narzędzia ticketowe, Slack/Teams, e‑maile.
  • Moduł ekstrakcji – parsowanie PDF‑ów, DOCX, HTML, treści z API; czyszczenie, normalizacja, wykrywanie duplikatów.
  • Chunking – dzielenie dokumentów na fragmenty (chunki), które będą wektoryzowane.
  • Embeddingi – moduł generujący wektory numeryczne dla każdego fragmentu.
  • Baza wektorowa – przechowuje wektory + metadane, pozwala na szybkie wyszukiwanie podobieństwa.
  • Warstwa zapytań (retrieval + biznesowa logika) – przyjmuje pytanie użytkownika, stosuje filtry, odpytuje bazę, kontroluje uprawnienia.
  • LLM – model generujący odpowiedź na bazie promptu i dostarczonego kontekstu.

Owocny projekt zwykle wymaga klarownego zdefiniowania interfejsów między modułami – np. jak wygląda obiekt DocumentChunk, co dokładnie zapisujesz w metadanych, jak opisujesz uprawnienia.

Przepływ pojedynczego zapytania w systemie RAG

Schemat jednego requestu (wysoko‑poziomowo) wygląda następująco:

  1. Użytkownik wysyła pytanie: tekst + kontekst (np. identyfikator użytkownika, język).
  2. Warstwa wejściowa normalizuje pytanie: usuwa zbędne białe znaki, ujednolica język, może robić korektę pisowni.
  3. Model embeddingowy tworzy wektor dla pytania.
  4. Baza wektorowa znajduje najbardziej podobne chunki, stosując filtry po metadanych (np. dział=„HR”, kraj=„PL”, poziom poufności <= poziom użytkownika).
  5. Warstwa biznesowa wybiera i układa fragmenty w kolejności, skraca je lub łączy, czasem wykonuje dodatkowe przetwarzanie.
  6. Orkiestracja promptów buduje prompt dla LLM: instrukcja systemowa, pytanie użytkownika, kontekst z dokumentów, oczekiwany format.
  7. LLM generuje odpowiedź.
  8. Post‑processing – np. dodanie listy źródeł, ocena pewności, logowanie zdarzenia do audytu.

RAG „na surowo” vs frameworki (LangChain, LlamaIndex, Haystack)

Można zbudować RAG od zera, korzystając wyłącznie z SDK wybranego LLM i bazy wektorowej. Druga droga to użycie frameworków:

  • LangChain – popularny ekosystem w Pythonie i JS, oferuje łańcuchy (chains), narzędzia do integracji z wieloma źródłami danych, gotowe komponenty do RAG.
  • LlamaIndex (dawniej GPT Index) – bardzo nastawiony na RAG, indeksy dokumentów, różne strategie chunkingu i retrievalu.
  • Haystack – framework z silnym naciskiem na wyszukiwanie i pipeline’y NLP.

Frameworki przyspieszają start, ale niosą koszt złożoności. W małym POC często wystarczy:

  • prosty skrypt do ekstrakcji i chunkingu,
  • jedna baza wektorowa (np. Qdrant, Pinecone),
  • kilka endpointów API po stronie backendu.

Większe wdrożenia zwykle i tak kończą na pół‑customowych rozwiązaniach, z selektywnym użyciem elementów z frameworków, a nie pełnym przyjęciem całego stosu.

Logika biznesowa i filtry uprawnień w architekturze RAG

RAG w firmie musi respektować uprawnienia – inaczej skończy się spektakularnym wyciekiem wewnętrznych dokumentów dla osób nieuprawnionych. Kluczowe miejsca, gdzie powinna pojawić się logika biznesowa:

  • Metadane dokumentów – poziom poufności, dział, kraj, typ dokumentu, wersja, tagi RODO itp.
  • Warstwa retrievalu – filtry po metadanych na podstawie tożsamości użytkownika i jego ról (RBAC/ABAC).
  • Orkiestracja promptów – reguły, czy można cytować pełne fragmenty, czy trzeba je skracać lub anonimizować.
  • Post‑processing – sanity check odpowiedzi: czy w odpowiedzi nie padły słowa kluczowe sugerujące wyciek (np. numery PESEL, dane osobowe, tajemnice handlowe).

Typowy wzorzec: baza wektorowa widzi tylko te dokumenty, do których użytkownik ma dostęp. To oznacza, że filtry uprawnień muszą być stosowane przed zapytaniem lub jako część zapytania (np. where department in (…) and clearance_level <= …).

Osoba przed ekranem z świecącymi liczbami symbolizującymi dane i technologię
Źródło: Pexels | Autor: Ron Lach

Inwentaryzacja i przygotowanie danych firmowych

Mapa źródeł danych w organizacji

Pierwszy praktyczny krok to spisanie konkretnych źródeł danych, z których RAG ma korzystać. Typowe kategorie:

  • Pliki – PDF, DOCX, PPTX, XLSX, teksty na dyskach sieciowych, SharePoint, Google Drive.
  • Bazy SQL – systemy ERP, zamówienia, faktury, rejestry projektów, dane konfiguracji.
  • Wiki i intranet – Confluence, Notion, portale intranetowe.
  • Systemy ticketowe – Jira Service Management, ServiceNow, Zendesk; szczególnie bazy wiedzy i archiwa zgłoszeń.
  • CRM – Salesforce, HubSpot, Dynamics; dane o klientach, produktach, historii interakcji.
  • Komunikatory – Slack, Microsoft Teams, kanały tematyczne, wątki z często zadawanymi pytaniami.
  • Mail – e‑maile do helpdesku, skrzynki zespołowe; raczej jako dodatkowe źródło, z dużą ostrożnością prywatności.

Na tym etapie nie chodzi o dokładne modelowanie, tylko o listę: gdzie jest wiedza, w jakich formatach, kto jest właścicielem danego repozytorium.

Priorytetyzacja: od czego zacząć, aby szybko zobaczyć efekt

RAG da największy efekt tam, gdzie:

  • pracownicy lub klienci ciągle zadają powtarzające się pytania,
  • istnieją już w miarę aktualne dokumenty (FAQ, instrukcje, procedury),
  • czas reakcji jest krytyczny (np. incydenty bezpieczeństwa, awarie systemów),
  • typ pytań silnie zależy od aktualnej, specyficznej wiedzy firmy (np. konfiguracje, stany magazynowe, polityki lokalne).

Dobry punkt startu:

  • baza wiedzy helpdesku + procedury IT,
  • polityki HR i najczęstsze pytania pracowników,
  • FAQ produktowe + karty produktów,
  • wewnętrzna dokumentacja procesów (procesy zakupowe, rozliczenia delegacji, zgłaszanie incydentów).

Start z jedną dziedziną (np. „wewnętrzne IT”) umożliwia szybkie wdrożenie prototypu, zebranie feedbacku i dopiero potem rozszerzenie na kolejne obszary (HR, finanse, sprzedaż).

Chaos w plikach: nazwy, duplikaty, wersjonowanie

RAG nie rozwiąże automatycznie problemu bałaganu w plikach. Jeśli w repozytorium są dziesiątki wersji tego samego dokumentu (np. Polityka_BHP_final_v2_poprawione_ostateczne(1).pdf), to:

  • embeddingi powstaną dla wszystkich wersji,
  • retrieval będzie zwracał sprzeczne informacje,
  • LLM może mieszać stare i nowe zasady.

Minimalny porządek przed indeksowaniem:

  • wybranie źródła prawdy – jedno repozytorium, jedna „oficjalna” wersja dokumentu,
  • dodanie jasnego schematu wersjonowania (w metadanych, nie tylko w nazwie pliku),
  • Metadane jako paliwo dla retrievalu

    Techniczny porządek w danych to głównie metadane. Bez nich baza wektorowa staje się tylko drogim „full‑textem na embeddingach”. Przy każdej jednostce treści (dokumencie, sekcji, chunku) dobrze mieć:

  • Identyfikator źródłowego dokumentu – np. document_id powiązany z oryginalnym plikiem lub rekordem w systemie.
  • Wersję – numer lub znacznik czasu, który pozwala odsiać stare treści.
  • Typ treści – polityka, procedura, FAQ, log zmian, komentarz.
  • Dział / obszar – HR, IT, finanse, produkcja itd.
  • Poziom poufności – klasy bezpieczeństwa spójne z polityką firmy.
  • Język – przy wielojęzycznych organizacjach.
  • Zakres obowiązywania – kraj, region, produkt, klient.
  • Status dokumentu – roboczy, opublikowany, wycofany.

Przydaje się też prosta konwencja: nie usuwaj starych wersji, tylko oznaczaj je jako nieaktualne. Retrieval może mieć filtr status = 'published', a stary materiał wciąż da się odtworzyć na potrzeby audytu.

Proces aktualizacji i usuwania danych w indeksie

RAG jest tak dobry, jak mechanizm aktualizacji indeksu. Scenariusze do ogarnięcia:

  • Nowy dokument – pojawia się w repozytorium, pipeline importuje go, parsuje, chunkuje i dodaje embeddingi.
  • Aktualizacja dokumentu – trzeba:
    • usunąć lub oznaczyć stare chunki jako nieaktywne,
    • wygenerować nowe chunki i embeddingi,
    • zachować spójność wersji w metadanych.
  • Usunięcie dokumentu – embeddingi nie mogą dalej „żyć” w bazie; wymagane jest twarde usunięcie lub przynajmniej flagowanie deleted=true.

Najwygodniej działa mechanizm event‑driven: system plików / DMS / wiki wysyła event typu „document_changed”, a pipeline RAG reaguje i reindeksuje tylko to, co się zmieniło. Awaryjnie można robić nocny batch, ale w dynamicznych środowiskach szybko będzie widać opóźnienia w odpowiedziach.

Ekstrakcja treści z różnych formatów

Warstwa ekstrakcji jako osobny serwis

Ekstrakcja (ingest) jest wystarczająco ważna, żeby miała własny serwis lub microserwis. Jego zadania:

  • podłączenie się do źródeł (API, SMB, S3, SharePoint, SMTP),
  • wyciągnięcie surowej treści,
  • zamiana na uogólniony format wewnętrzny (np. JSON z polami: tekst, struktura, metadane, odnośniki),
  • obsługa błędów, timeoutów, ponowień.

Tip: zdefiniuj prosty format typu NormalizedDocument, który jest wspólnym mianownikiem dla DOCX, PDF, HTML i rekordów z bazy. Reszta pipeline’u nie musi wtedy znać specyfiki źródła.

PDF, DOCX i inne „biurowe” formaty

Większość wiedzy firmowej siedzi w PDF‑ach i DOCX‑ach. Problemy:

  • PDF bywa tylko obrazem (skan) – trzeba OCR.
  • Struktura nagłówków często ginie – konwersja musi próbować odtworzyć hierarchię.
  • Tabele i listy potrafią się rozpaść na losowe linijki tekstu.

Praktyczna konfiguracja:

  • dla PDF: narzędzie typu pdftotext + OCR (Tesseract, AWS Textract, Azure Form Recognizer, Google Document AI),
  • dla DOCX / PPTX: biblioteki typu python-docx, mammoth, python-pptx,
  • dla treści z Google Docs / MS365: API dostawcy zamiast ściągania surowych plików.

Jeśli treści są istotne regulacyjnie (polityki, umowy), warto zachować mapowanie: chunk → numer strony / slajdu / rozdziału. To później pozwala pokazać użytkownikowi dokładny kontekst źródła.

HTML, wiki, intranety

HTML potrafi być skarbem (sensownie zrobiona dokumentacja) albo śmietnikiem (stare intranety). Kluczem jest odfiltrowanie „chromu” (nawigacja, stopka) i zostawienie treści właściwej.

Dobrą bazą są parsery typu BeautifulSoup lub gotowe narzędzia do „readability” (wyciąganie głównego artykułu z HTML). Robią:

  • usunięcie menu, reklam, powtarzalnych bloków,
  • rozpoznanie nagłówków H1–H3, akapitów, list,
  • utrzymanie hierarchii dokumentu.

Każdej stronie HTML przypisuj stabilny source_url oraz np. page_type (FAQ, artykuł KB, news). Dzięki temu łatwo odsiać ogłoszenia sprzed lat od aktualnej dokumentacji.

Dane z baz SQL i systemów biznesowych

RAG nie musi widzieć całej bazy. W praktyce wystarczą wybrane widoki:

  • „widok na człowieka” – agregacja danych z kilku tabel w jedną czytelną reprezentację,
  • „widok na produkt” – parametry produktu, konfiguracje, statusy,
  • „widok na zgłoszenie” – opis incydentu, rozwiązanie, kategorie.

Z takich widoków da się budować tekstowe reprezentacje typu:

Produkt: X123
Kategoria: Router
Obsługiwane protokoły: ...
Wersja firmware: ...
Ograniczenia: ...

Taki opis traktujesz jak dokument wejściowy do chunkingu i embeddingu, ale trzymasz powiązanie z kluczem głównym (np. product_id), żeby później móc kliknąć z odpowiedzi w szczegóły w systemie źródłowym.

Komunikacja: Slack, Teams, maile

Historia czatów jest kusząca, ale łatwo wpaść w pułapkę szumu i problemów prywatności. Rozsądne podejście:

  • indeksować tylko wybrane kanały (np. #help-it, #faq-hr),
  • odfiltrować drobne wymiany typu „dzięki”, „ok”,
  • zachować pseudonimizację, jeśli regulacje tego wymagają.

Dla maili – raczej skrzynki zespołowe niż osobiste. I tylko w sytuacjach, gdzie da się obronić to prawnie i etycznie. Np. support@firma z odpowiedziami, które de facto są bazą wiedzy.

Smartfon z aplikacją AI na tle książki o technologii sztucznej inteligencji
Źródło: Pexels | Autor: Sanket Mishra

Chunking – jak dzielić dokumenty, żeby LLM miało sensowny kontekst

Dlaczego chunking jest krytyczny

Embeddingi działają na fragmentach tekstu, nie na całej dokumentacji naraz. Zbyt duże chunki:

  • rozmywają temat (wektor jest „średnią” z kilku tematów),
  • łatwo wylecą poza limit tokenów promptu.

Zbyt małe chunki:

  • tracą kontekst (sam nagłówek bez treści niewiele znaczy),
  • retrieval zwraca strzępy, które LLM musi sklejać na siłę.

Optimum zależy od domeny, ale zwykle waha się między 300 a 1000 tokenów na chunk, z pewnym nakładaniem się.

Chunking oparty na strukturze dokumentu

Najlepiej startować od struktury logicznej, a nie od „sztywnego” licznika znaków. Przykład:

  • jeden chunk = nagłówek + kilka kolejnych akapitów,
  • osobne chunki dla sekcji, podsekcji, punktów procedury.

Przy parsowaniu dokumentu możesz tworzyć drzewo:

  • poziom 1: rozdziały (H1),
  • poziom 2: sekcje (H2),
  • poziom 3: podsekcje (H3),
  • liście: akapity, punkty list.

Chunking polega wtedy na zjeżdżaniu po drzewie i składaniu akapitów w paczki o rozsądnym rozmiarze, z zachowaniem informacji o ścieżce w drzewie (np. chapter=„Bezpieczeństwo”, section=„Hasła”).

Fixed‑size vs sliding window

Dwa popularne podejścia:

  • Fixed‑size – tniesz tekst na bloki po X tokenów / zdań. Prosto, ale ignoruje granice semantyczne.
  • Sliding window – tworzysz okna z nakładaniem się (overlap), np. 500 tokenów z overlapem 100–150 tokenów.

W praktyce często łączy się oba:

  • najpierw chunking po strukturze (sekcje),
  • jeśli sekcja jest za duża, stosujesz sliding window w jej obrębie.

Overlap ma sens, bo pytanie użytkownika może zahaczać o przejście między dwoma sekcjami. Dublowanie fragmentu minimalizuje ryzyko przecięcia kluczowej informacji na pół.

Chunking dla FAQ, ticketów i krótkich wpisów

Nie wszystko trzeba chunkować. Dla:

  • FAQ,
  • pojedynczych ticketów,
  • krótkich artykułów KB,

najlepszy chunk to cały wpis. Zamiast dzielić, lepiej:

  • spiąć pytanie + odpowiedź w jeden dokument,
  • dodać metadane typu faq=true, category=„VPN”.

Przy wyszukiwaniu możesz najpierw odpalić osobny retriever na FAQ (wysoka precyzja), a dopiero później ogólny retriever na „ciężkich” dokumentach.

Metadane na poziomie chunków

Metadany nie kończą się na dokumencie. Część przydaje się na poziomie chunku:

  • section_title – tytuł sekcji,
  • section_path – np. „Polityka bezpieczeństwa > Hasła > Rotacja haseł”,
  • page_number / slide_number,
  • valid_from, valid_to – jeśli dana sekcja obowiązuje tylko przez pewien czas.

Da się wtedy zadać bazie wektorowej pytanie typu: „daj mi tylko chunki z sekcji ‘Bezpieczeństwo haseł’ z ostatniego roku” – bez konieczności przeszukiwania całych dokumentów.

Embeddingi i baza wektorowa – wybór, parametry, praktyka

Wybór modelu embeddingowego

Kluczowe parametry modelu embeddingowego:

  • wymiar wektora (np. 384, 768, 1024),
  • języki, które wspiera,
  • optymalizacja pod similarity search vs klasyfikację / clustering,
  • model chmurowy vs on‑prem / open‑source.

Praktyczne strategie:

  • dla środowisk wielojęzycznych – modele wielojęzyczne (np. rodzina multilingual-e5, LaBSE),
  • tam, gdzie liczy się prywatność – modele hostowane lokalnie (SentenceTransformers, Instructor, Jina, itp.),
  • dla szybkich POC – hosted embeddings (OpenAI, Azure, Cohere) bez dbania o infrastrukturę.

Tip: nie mieszaj modeli embeddingowych w jednym indeksie. Każda zmiana modelu to de facto reindeks całej bazy.

Parametry wektorów i normalizacja

Dwie rzeczy, na które łatwo machnąć ręką:

  • normalizacja wektora – w wielu scenariuszach warto normalizować do długości 1 (L2 norm = 1). Ułatwia to użycie kosinusowej miary podobieństwa i porównań między różnymi batchami.
  • pre‑ i post‑processing tekstu – consistent lowercasing, usuwanie kontrolnych znaków, ujednolicenie formatu dat/liczb.

Jeżeli baza wektorowa obsługuje różne metryki, zwykle sensownie sprawdza się cosine similarity lub dot product (dla znormalizowanych wektorów). L2 distance gorzej oddaje podobieństwo semantyczne przy embeddingach z NLP.

Wybór bazy wektorowej

RAG w firmie nie wymaga koniecznie wyspecjalizowanej bazy wektorowej – ale w praktyce ułatwia ona życie. Popularne opcje:

  • Qdrant, Weaviate, Milvus – open‑source, obsługują gęste wektory, filtry po metadanych, sharding, replikację.
  • Pinecone, Vertex Matching Engine, Azure AI Search – managed, skalowanie i HA po stronie dostawcy.
  • Postgres + pgvector – dobre dla mniejszych projektów lub gdy chcesz minimalizować stos technologiczny.

Indeksowanie, aktualizacje i wersjonowanie

Embeddingi i wektory to nie jest jednorazowy zrzut danych. W praktyce pojawia się kilka codziennych problemów: jak często reindeksować, co z wersjami dokumentów, jak usuwać dane z RAG (np. przy „prawie do bycia zapomnianym”).

Podstawowe strategie indeksowania:

  • batch – okresowe pełne lub przyrostowe indeksacje (np. raz dziennie w nocy),
  • near‑real‑time – event‑driven, po zmianie dokumentu w DMS/CRM od razu leci job aktualizujący embeddings,
  • hybryda – krytyczne systemy (np. baza wiedzy dla supportu) w trybie near‑real‑time, reszta w batchu.

Żeby nie zwariować przy aktualizacjach, przydaje się prosty model wersjonowania:

  • każdy chunk ma document_id, chunk_id, version,
  • przy edycji dokumentu tworzysz nową wersję, stare chunki oznaczasz is_active=false lub trzymasz w osobnym indeksie archiwalnym,
  • w query zawsze filtrujesz po is_active=true albo po version=current.

Jeśli regulacje wymuszają fizyczne usunięcie danych, samo oznaczenie is_active=false nie wystarczy. Trzeba mieć:

  • mechanizm „hard delete” w bazie wektorowej po kluczu (np. kombinacji document_id + user_id),
  • log, który pozwoli udowodnić, że dane zostały faktycznie usunięte (audit trail).

Tip: część zespołów trzyma osobne indeksy per domena (np. hr_index, security_index, marketing_index). Ułatwia to zarządzanie cyklem życia danych i różne okresy retencji.

Filtry po metadanych i segmentacja indeksów

Sama baza wektorowa nie wystarczy, jeśli retrieval ma ignorować dokumenty spoza kontekstu użytkownika czy procesu. Do gry wchodzą filtry po metadanych (tzw. filtered vector search).

Typowe metadane do filtrowania:

  • locale / language – unikasz mieszania PL/EN, gdy użytkownik chce odpowiedź po polsku,
  • department, region, customer_segment – pozwalają przyciąć dokumenty do właściwej części organizacji,
  • confidentiality_level – np. public / internal / restricted,
  • valid_from, valid_to – ograniczenie do aktualnych procedur.

Segmentacja indeksów (kilka indeksów wektorowych zamiast jednego) sprawdza się, gdy:

  • wymagania prawne różnią się między domenami (np. HR vs marketing),
  • chcesz łatwo odpalać różne parametry HNSW/IVF (inne dla krótkich FAQ, inne dla ciężkiej dokumentacji technicznej),
  • masz zupełnie różne języki lub rodzaje treści (np. kod źródłowy vs umowy prawne).

Uwaga: nadmierna fragmentacja indeksów zwiększa złożoność pipeline’u – każdy indeks to osobny deployment, monitoring, backupy. Lepiej mieć 3–4 sensownie zdefiniowane indeksy niż 20 mikro‑indeksów, których nikt nie ogarnia.

Parametry ANN i kompromisy dokładność <> wydajność

Większość nowoczesnych baz wektorowych korzysta z przybliżonego wyszukiwania najbliższych sąsiadów (ANN). W praktyce i tak trzeba podjąć kilka decyzji:

  • jak duży ma być indeks (liczba wektorów, np. parametry ef_construction, M w HNSW),
  • jak agresywnie szukać (np. ef_search / nprobe),
  • ile kandydatów zwracać (np. top_k=20 lub więcej).

Prosty workflow strojenia:

  1. tworzysz mały eval set (zestaw pytań + oczekiwane dokumenty/chunki),
  2. odpalasz retrieval z różnymi parametrami ANN,
  3. mierzysz recall@k (czy w top‑k jest jakiś chunk z poprawną odpowiedzią) oraz latency.

Jeżeli system będzie korzystany interaktywnie (chat dla pracowników), latency powyżej kilkuset milisekund za sam wektorowy search zaczyna być odczuwalne. W takich sytuacjach:

  • redukujesz wymiar wektorów (niższy wymiar = szybsze indeksowanie i zapytania),
  • filtrujesz po metadanych przed search’em, żeby przeszukiwać mniej kandydatów,
  • trzymasz hot‑index (ostatnie/ulubione dokumenty) w szybszej konfiguracji, a resztę w wolniejszej.

Od pytania użytkownika do odpowiedzi – pipeline zapytań w RAG

Warstwa wejścia – co naprawdę dostaje system

Użytkownik nie wysyła „czystego” zapytania NLP. Zazwyczaj jest kontekst:

  • historia czatu (kilka ostatnich wiadomości),
  • tożsamość i uprawnienia użytkownika,
  • kanał (Slack, portal, plugin w CRM),
  • tryb pracy (chat vs pytanie ad‑hoc w polu wyszukiwarki).

Warstwa wejścia powinna:

  • wyciągnąć „rdzeń” pytania (np. ostatnią wiadomość użytkownika + ewentualny skrócony kontekst),
  • dołączyć informacje o użytkowniku (rola, dział, kraj) jako metadane do filtrów w retrieval,
  • oznaczyć typ interakcji (np. mode=qa, mode=assist, mode=explain), co później przyda się w prompt engineeringu.

Query rewriting i normalizacja

Surowe pytania bywają nieprecyzyjne: „VPN nie działa”, „nie mogę wejść do CRM”. Zanim wjedzie wektorowy search, opłaca się krótkie przetworzenie zapytania:

  • normalizacja (usunięcie emotek, skrótów typu „pls”, rozwinięcie znanych aliasów produktów),
  • opcjonalne doprecyzowanie (np. dopisanie kontekstu: „użytkownik z działu sprzedaży, region: PL, produkt: CRM X”),
  • query rewriting – przebudowa pytania na pełniejsze zdanie (LLM może pomóc),
  • query expansion – dodanie synonimów lub słów kluczowych (np. z ontologii firmowej).

Przykład:

Input użytkownika:
"VPN nie działa"

Znormalizowane / rozszerzone zapytanie do retrieval:
"Problem z połączeniem VPN dla pracownika działu sprzedaży w Polsce.
Użytkownik próbuje połączyć się z VPN <nazwa rozwiązania> z komputera służbowego."

Takie wzbogacone zapytanie generuje embedding bardziej zbliżony do realnych artykułów KB i procedur.

Hybrdowy retrieval: wektory + pełnotekst

Czyste similarity search bywa ślepe na krótkie frazy kluczowe (np. numery błędów, kody produktów). W wielu wdrożeniach lepiej łączyć:

  • retrieval wektorowy – dla semantyki,
  • retrieval pełnotekstowy (Elasticsearch/Solr/Postgres) – dla fraz dokładnych,
  • czasem prosty BM25 jako dodatkowy sygnał.

Prosty schemat:

  1. odpalasz wektorowy search po indeksie chunków, np. top_k=30,
  2. równolegle odpalasz BM25 po polach typu title, tags, error_code,
  3. łączysz wyniki (np. late fusion): przeliczasz score’y do wspólnej skali, robisz ranking, obcinasz do top_k=10.

Tip: dla krytycznych bytów (kody błędów, nazwy systemów) warto trzymać osobny indeks słownikowy i przed wektorowym search’em sprawdzać, czy w pytaniu nie występuje któryś z nich. Jeśli tak – doklej go jawnie do zapytania lub priorytetyzuj dokumenty, gdzie występuje.

Filtry, reranking i wybór kontekstu

Po zebraniu kandydatów zaczyna się właściwe „gotowanie” kontekstu dla LLM. Typowy krok to filtrowanie:

  • po uprawnieniach użytkownika (ACL),
  • po czasie (np. tylko dokumenty obowiązujące dziś),
  • po języku i kraju,
  • po typie źródła (np. preferuj aktualną dokumentację nad starymi ticketami).

Następnie można zastosować reranking – tu LLM lub mniejszy model rankingowy ocenia trafność fragmentów względem pytania i przypisuje nowe score’y. Kilka praktycznych opcji:

  • cross‑encoder (np. z modeli SentenceTransformers) – dostaje parę (pytanie, chunk), zwraca score trafności,
  • LLM‑reranking – LLM dostaje listę chunków i polecenie: „uszykuj ranking fragmentów od najbardziej do najmniej przydatnych do odpowiedzi na to pytanie”,
  • heurystyki – boost po metadanych (np. nowsze dokumenty +10%, dokumentacja oficjalna +20%).

Finalnie trzeba wybrać kilka chunków do promptu. Mechanika:

  • ustalasz docelowy budżet tokenów na kontekst (np. 2–4 tys. tokenów),
  • wybierasz chunki w kolejności po rerankingu, pilnując, żeby nie przekroczyć limitu,
  • dla chunków z tego samego dokumentu możesz dołączyć skróconą „ścieżkę” (tytuł dokumentu, sekcja), żeby LLM miał bardziej zrozumiały kontekst.

Budowa promptu z kontekstem

Prompt w RAG ma zwykle trzy komponenty:

  • instrukcje systemowe (jak ma zachowywać się model),
  • kontekst z retrieval (wybrane chunki),
  • pytanie użytkownika wraz z ewentualną historią rozmowy.

Przykładowa struktura (uproszczona):

[System]
Jesteś asystentem ds. procedur IT w firmie <nazwa>.
Odpowiadasz na podstawie dostarczonych dokumentów.
Jeśli nie znajdujesz odpowiedzi w dokumentach, mów wprost, że nie wiesz.

[Kontekst]
<DOC 1>
Tytuł: [...]
Treść: [...]

<DOC 2>
Tytuł: [...]
Treść: [...]

[Pytanie użytkownika]
<treść pytania>

Kilka praktycznych zasad:

  • wyraźnie oddziel sekcję kontekstu od pytania (model lepiej rozumie strukturę),
  • poproś model, by cytował lub streszczał fragmenty dokumentów, ale nie wymyślał nowych polityk,
  • zmieść w promptcie kluczowe metadane (data dokumentu, wersja) – później można je pokazać użytkownikowi obok odpowiedzi.

Strategie odpowiedzi: answer, citations, fallback

Sam tekst odpowiedzi to dopiero początek. Jeżeli RAG ma być używany produkcyjnie, przydają się standardowe „szyny” zachowań:

  • odpowiedź z cytatami – obok odpowiedzi zwracaj ID chunków/dokumentów, z których korzystał model; na froncie zamieniasz to na linki „źródło 1 / źródło 2”,
  • stopnie pewności – szacunkowy confidence (np. na podstawie średniego similarity top‑k lub score’u rerankera); przy niskim – prośba o doprecyzowanie pytania lub przekierowanie do człowieka,
  • fallback – gdy retrieval nic sensownego nie zwróci (np. brak chunków powyżej minimalnego similarity), lepiej powiedzieć „nie wiem” niż halucynować.

Praktyka z wdrożeń: dobrze działa prosty próg, np. „jeśli średnie similarity top‑3 chunków < X – tryb low confidence”. W tym trybie model:

  • zamiast pełnej odpowiedzi podaje kilka możliwych tropów,
  • zachęca do zawężenia pytania („czy chodzi o VPN służbowy, czy prywatny?”),
  • może wyświetlać samą listę potencjalnie powiązanych dokumentów, bez generowania narracji.

Multi‑turn: utrzymanie kontekstu rozmowy

RAG w trybie czata musi ogarniać dialog wieloturnowy. Pytania typu „a co z wersją mobilną?” pochodzą z kontekstu poprzednich wypowiedzi, nie są samowystarczalne.

Technicznie można to rozwiązać kilkoma sposobami:

  • okno historii – do promptu doklejasz kilka ostatnich tur (użytkownik + asystent),
  • skrót historii (conversation summarization) – dłuższe rozmowy streszczasz do krótkiego opisu celu/tematu, który potem trafia do sekcji kontekstu,
  • Najczęściej zadawane pytania (FAQ)

    Co to jest RAG i jak działa w praktyce z danymi firmowymi?

    RAG (retrieval augmented generation) to sposób użycia LLM, w którym model przed wygenerowaniem odpowiedzi dostaje kontekst wyszukany z Twoich dokumentów. Najpierw pytanie użytkownika jest zamieniane na wektor (embedding), system wyszukuje najbardziej podobne fragmenty treści w bazie wektorowej, a dopiero potem te fragmenty są „doklejane” do promptu przekazywanego do modelu.

    W efekcie LLM nie polega wyłącznie na ogólnej wiedzy z treningu, tylko odpowiada na podstawie aktualnych polityk, procedur, cenników czy umów. Dzięki temu można trzymać wiedzę w dokumentach, a nie „wypalać” jej w modelu przez fine‑tuning przy każdej zmianie.

    Kiedy RAG ma sens w firmie, a kiedy lepiej użyć fine-tuningu albo prostego promptowania?

    RAG ma największy sens, gdy masz dużo dokumentów, wiedza często się zmienia i potrzebujesz śledzić źródła odpowiedzi. Przykład: procedury HR i bezpieczeństwa w PDF‑ach, baza ticketów helpdesku, dokumentacja produktów, umowy i polityki compliance.

    Fine‑tuning jest sensowny, gdy zależy Ci na specyficznym stylu, tonie wypowiedzi albo działasz w środowisku bez dostępu do zewnętrznych API i musisz mieć własny model on‑premise. Proste promptowanie sprawdza się przy małych, jednorazowych zadaniach i prototypach – tam, gdzie wystarczy wkleić kilka akapitów do promptu i nie zależy Ci na skalowalności ani automatycznej aktualizacji wiedzy.

    Jakie są typowe zastosowania RAG w organizacji?

    Najczęstsze use case’y w firmach to:

  • wewnętrzna wyszukiwarka po dokumentach (procedury, regulaminy, instrukcje),
  • asystent wiedzy o produktach dla sprzedaży, customer success i partnerów,
  • wsparcie helpdesku i IT na bazie ticketów i bazy wiedzy,
  • onboarding pracowników zasilany politykami HR i materiałami szkoleniowymi,
  • asystent prawny/compliance, który wyszukuje i streszcza klauzule z umów i regulacji.

Przykład z życia: pracownik pyta „Jak zgłosić utratę służbowego laptopa?”, a system RAG automatycznie znajduje właściwą procedurę wśród setek PDF‑ów i cytuje odpowiednie paragrafy z aktualnej wersji dokumentu.

Jak wygląda podstawowa architektura systemu RAG w firmie?

Prosty, ale realistyczny system RAG składa się z kilku modułów: źródeł danych (np. SharePoint, Confluence, dyski sieciowe, CRM), modułu ekstrakcji (parsowanie PDF, DOCX, HTML), chunkingu (dzielenie dokumentów na fragmenty), modelu embeddingowego, bazy wektorowej oraz warstwy zapytań (retrieval + logika biznesowa) i samego LLM.

Przepływ pojedynczego zapytania jest następujący: użytkownik wysyła pytanie, system normalizuje tekst, tworzy embedding pytania, szuka podobnych wektorów (chunków) w bazie z użyciem filtrów po metadanych, wybiera i układa kontekst, buduje prompt i przekazuje go do modelu. LLM generuje odpowiedź, a warstwa post‑processing może dodać listę źródeł, ocenić pewność czy zalogować zdarzenie do audytu.

Jak w RAG zadbać o bezpieczeństwo i uprawnienia do dokumentów?

Kluczowe jest spięcie RAG z systemem uprawnień (RBAC/ABAC). Dokumenty muszą mieć metadane opisujące m.in. poziom poufności, dział, kraj, typ dokumentu czy tagi RODO. Na tej podstawie warstwa retrievalu filtruje wyniki wyszukiwania tak, by użytkownik widział wyłącznie te fragmenty, do których ma dostęp.

Dobry wzorzec to sytuacja, w której baza wektorowa „widzi” tylko dokumenty dostępne dla danego użytkownika. Dodatkowo w warstwie promptów i post‑processingu można wprowadzić reguły anonimizacji (np. zaciemnianie danych osobowych) oraz sanity‑check wykrywający potencjalny wyciek, np. dzielenie się danymi wrażliwymi w odpowiedzi.

Jak zacząć wdrażanie RAG: od zera czy z użyciem frameworków typu LangChain lub LlamaIndex?

Dla małego POC (proof of concept) zwykle wystarczy prosty stos: skrypt do ekstrakcji i chunkingu dokumentów, jedna baza wektorowa (np. Qdrant, Pinecone) i kilka endpointów backendowych do obsługi zapytań. To pozwala szybko zweryfikować, czy RAG ma sens dla Twoich danych i pytań użytkowników.

Frameworki typu LangChain, LlamaIndex czy Haystack przyspieszają integrację z różnymi źródłami i dostarczają gotowe komponenty RAG, ale wnoszą dodatkową złożoność. W większych wdrożeniach często kończy się na rozwiązaniu pół‑customowym: korzystasz z wybranych elementów frameworka (np. retriever, loader), a resztę – logikę uprawnień, orkiestrację promptów – piszesz sam.

Jak aktualizować wiedzę w systemie RAG przy zmianach procedur i dokumentów?

Przy RAG aktualizacja wiedzy polega na odświeżeniu danych w bazie wektorowej, a nie trenowaniu modelu od nowa. Gdy zmienia się procedura lub regulamin, w praktyce robisz:

  • wgranie nowej wersji dokumentu do źródła,
  • ponowne pocięcie treści na chunki,
  • ponowną wektoryzację i podmianę rekordów w bazie wektorowej (z aktualnymi metadanymi).

Dzięki temu LLM przy kolejnym zapytaniu dostanie już nowy kontekst z aktualnych dokumentów. Tip: trzymaj w metadanych wersję dokumentu i datę publikacji – łatwiej wtedy kontrolować, skąd dokładnie pochodzi odpowiedź.