Wskazówki praktyczne: Co to jest generowanie wzbogacone o wyszukiwanie (RAG)? Praktyczne informacje
Praktyczny przewodnik po notatkach: Co to jest Retrieval-Augmented Generation (RAG)? Praktyczne wskazówki dotyczące umów, sprawdzeń oraz gotowych elementów kodu przeznaczonych dla zespołów wdrażających ten wzorzec.
Poniższe notatki przedstawiają praktyczny plan działania oparty na książce „What Is Retrieval-Augmented Generation (RAG)? A Practical Guide with Python Examples — Geeky Codes”. Nacisk kładziony jest na umowy, sprawdzania oraz miejsca zastępcze dla kodu, a nie na motywacyjne aspekty.
Dowiedz się, jak działa RAG, dlaczego modele LLM tworzą iluzje oraz stwórz swój pierwszy pipeline generacji wzbogaconej o dane z zewnętrznych źródeł w Pythonie.
Podczas przechodzenia przez etap „Dowiedz się, jak działa RAG”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zachowaj konfigurację poza kodem aplikacji – pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zapisuj ID żądania, ID modelu oraz czas reakcji przy każdej wywołaniu. Bez tych informacji przerywane błędy dostawcy mogą wyglądać jak błędy aplikacji.
Pobieranie
Podczas prace na etapie pobierania najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dopinane później. Zapisuj ID żądania, ID modelu oraz opóźnienie przy każdej próbie połączenia. Bez tych informacji przerywane błędy dostawcy wyglądają jak błędy aplikacji.
Rozszerzone
Gdy przechodzisz przez etap rozszerzenia, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki od rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zapisuj ID żądania, ID modelu oraz opóźnienie przy każdym wywołaniu. Bez tych informacji przerywane błędy dostawcy wyglądają jak błędy aplikacji.
Generowanie
Podczas przechodzenia przez etap generowania, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Zapisuj identyfikator żądania, identyfikator modelu oraz czas opóźnienia przy każdym wywołaniu. Bez tych informacji przerywane błędy dostawcy wyglądają jak błędy aplikacji.
Documents
│
▼
Data Ingestion
│
▼
Text Extraction
│
▼
Chunking
│
▼
Embedding Model
│
▼
Vector Database
──────────────────────────────────────────
User Question
│
▼
Query Embedding
│
▼
Similarity Search
│
▼
Top-K Relevant Chunks
│
▼
Prompt Builder
│
▼
Large Language Model
│
▼
Final Answer
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
documents = [
"Employees receive 20 days of paid leave every year.",
"Annual bonuses are paid in December.",
"Health insurance covers hospitalization expenses."
]
model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode(documents)
index = faiss.IndexFlatL2(embeddings.shape[1])
index.add(np.array(embeddings).astype("float32"))
query = "How many leave days do employees receive?"
query_embedding = model.encode([query])
D, I = index.search(
np.array(query_embedding).astype("float32"),
k=1
)
print(documents[I[0][0]])
Powszechne wyzwania w produkcji
Gdy przechodzisz przez etap „Powszechne wyzwania w produkcji”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czas trwania operacji oraz koszt tokena lub zapytania obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Zapisuj ID żądania, ID modelu oraz opóźnienie przy każdym wywołaniu. Bez tych informacji przerywane błędy dostawcy wyglądają jak błędy aplikacji. Gdy przechodzisz przez etap „Powszechne wyzwania w produkcji”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego awarii. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Dokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę odzyskiwania. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.
Główne wnioski
Etap kluczowych wniosków działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustal wartości interpretera oraz pliku blokującego zależności przed omawianiem pętli. Różnice między laptopem a środowiskiem CI to najczęstsza, niewidoczna przyczyna awarii w demonstracjach API.
Odnośniki
Etap referencji działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki częściowego ukończenia bez żadnych informacji. Ustal stałe wartości interpretera oraz pliku blokującego zależności przed nauczeniem pętli. Rozbieżności pomiędzy laptopem a środowiskiem CI są najczęstszą przyczyną ukrytych awarii w demonstracjach API.
Lista kontrolna operacyjna
W ramach etapu listy kontrolnej operacyjnej zdefiniuj dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia pracy przed dokonaniem zmian w kodzie. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu systemu.
Zachowaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności przeglądania całej struktury.
Rozdziel budowę klienta od pętli przekazywania wiadomości, aby można było zmieniać dostawców bez konieczności przepisywania maszyny stanu rozmowy.
Pomierz stopień odnalezienia odpowiedzi na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.
Zamroź idealny zestaw parametrów przed modyfikacją promptów lub modeli. Zmiana zarówno systemu, jak i kryteriów oceny ukrywa możliwe regresje.
Dodaj test dymny, który sprawdza kluczową ścieżkę działania w procesie CI przy użyciu narzędzi testowych, a nie rzeczywistych płatnych API, o ile pozwala na to budżet.
Zanim wdrożysz tę architekturę, zamroź wersje, utwórz dokładny zapis dla kluczowych etapów realizacji oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Wolimy nudną niezawodność od pomysłowych, jednorazowych demonstracji.
Uwaga dotycząca ce641ce6bc02: trzymaj klucze dostawcy poza repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj zapisy obok plików przygotowawczych do testowania, aby późniejsze zmiany modeli pozostały porównywalne.