Wskazówki praktyczne: Budowa pipeline RAG korygującego do funkcji Q&A na YouTube – co poszło nie tak
Krok po kroku praktyczne wskazówki: tworzenie pipeline RAG korygującego dla formularzy Q&A na YouTube – co poszło nie tak: umowy, sprawdzania oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.
Poniższe notatki przedstawiają praktyczny plan działania dotyczący tematu „Tworzenie poprawnej pipeline RAG do pytań i odpowiedzi na YouTube: Co się zepsuło i dlaczego?”. Nacisk kładziony jest na umowy, sprawdzenia oraz miejsca zastępcze dla kodu, a nie na motywacyjne aspekty. Podczas przechodzenia przez etap przeglądu, 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ć możliwość cichego, częściowego ukończenia zadania.
Dzielenie na fragmenty:
Etap dzielenia na fragmenty działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
Model embedding:
Etap modelu Embedding działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, skrytki z danymi poufnymi oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Ustal budżet tokenów na jeden ruch i na jedną sesję. Narzędzia typu agentic intensywnie rozszerzają kontekst; sztywne limity zapobiegają temu, by demonstracje przerodziły się w niespodziewane rachunki.
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=800, # Notice: 800 characters limit here (~200 tokens)
chunk_overlap=200,
length_function=len,
is_separator_regex=False,
)
docs = text_splitter.create_documents([text])
sentence_transformer = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
vector_store = Chroma(
collection_name=get_config("vectorDB_collection_name"),
embedding_function=sentence_transformer,
)
Stan LangGraph i ChromaDB:
Etap LangGraph State i ChromaDB funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę przywracania do normalności. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w przypadku zmian wskaźników jakości. Etap LangGraph State i ChromaDB funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.
app.aupdate_state(
config={
"configurable": {
"thread_id": thread_id,
"recursion_limit": 30,
"vector_store": vector_store, # Pass the Vector DB here
}
}
)
Wykonywanie asynchroniczne i funkcja input( ):
Dla etapu wykonywania asynchronicznego i wprowadzania danych należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy odnotować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Należy podać fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.
await app.aupdate_state(
config={
"configurable": {"thread_id": thread_id, "recursion_limit": 30}
}, # adjust as needed
values={
"user_query": user_query # Send the user inputs using the 'values' property
},
)
Tłumaczenie lokalne vs. oparte na chmurze
W fazie lokalnej w porównaniu z wersją chmurową należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić, nie musząc czytać całej struktury. Należy podawać konkretne fragmenty tekstu, na których opiera się odpowiedź. Bez tych odniesień operatorzy nie będą w stanie odróżnić fałszywych informacji od braków w indeksowaniu.
Wnioski:
W fazie wyciągania wniosków należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, 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 dodawane później. Należy podać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu. W fazie wyciągania wniosków należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań.
Lista kontrolna operacyjna
W fazie listy kontrolnej operacyjnej należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie wykonać dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu.
Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces.
Należy podawać konkretne fragmenty tekstu, które stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą mogli odróżnić fałszywych informacji od braków w indeksowaniu.
Napisz krótki przewodnik: jak rotować klucze, jak opróżnić kolej z zadań, jak cofnąć ostatnie operacje importu.
Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań.
Należy podać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez cytatów operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.
Zanim wdrożymy nową wersję, należy zamrozić istniejące wersje, utworzyć „złoty” zapis transkrypcji dla kluczowych ścieżek oraz potwierdzić kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji dostępności oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Lepiej wybrać nudną niezawodność niż sprytnie przygotowane jednorazowe demonstracje.
Uwaga dotycząca wersji 93e5d15be033: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików testowych, aby późniejsze zmiany modeli pozostały porównywalne.
Dla etapu 0 notatki dotyczącej wzmocnienia bezpieczeństwa należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.
Szczegóły wzmocnienia bezpieczeństwa 0/813: należy zmierzyć czas wykonywania operacji, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecydować o utrzymaniu zmiany na podstawie ustalonego zestawu pytań, a nie opisów przypadków.
Gdy przechodzisz przez pierwszy etap notatki dotyczącej wzmocnienia bezpieczeństwa, 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ć przypadki częściowego ukończenia bez żadnych informacji.
Szczegół 1/813 dotyczący wzmocnienia bezpieczeństwa: zmierz czas wykonywania, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie jedynie informacji anegdotycznych.
Etap notatki dotyczącej wzmocnienia bezpieczeństwa nr 2 działa najlepiej, gdy jest traktowany jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przykład działania, jeden przypadek niepowodzenia oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres prac. Utrzymuj 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.
Szczegół wzmocnienia 2/813: zmierz czas wykonywania, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie jedynie anegdoty.
W trzecim etapie notatki dotyczącej wzmocnienia określ dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie wykonać dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powód awarii powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces.
Szczegół wzmocnienia 3/813: zmierz czas wykonywania, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie jedynie anegdoty.
Gdy przechodzisz przez etap nr 4 notatki dotyczącej wzmocnienia bezpieczeństwa, najpierw zapisz warunki kontraktu: 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. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokena lub zapytania. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk.
Szczegóły wzmocnienia bezpieczeństwa 4/813: zmierz czas wykonywania, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie jedynie informacji anegdotycznych.
Literatura pokrewna
- Praktyczne notatki: RAG to coś więcej niż chatbot – co naprawdę dzieje się wewnątrz — Szczegółowy przewodnik po Praktycznych notatkach: RAG to coś więcej niż chatbot – co naprawdę dzieje się wewnątrz: kontrakty, sprawdzania oraz miejsca na kod do wklejenia dla zespołów wdrażających ten model.
- Praktyczne notatki: Budowanie systemów RAG, które naprawdę działają w produkcji — Szczegółowy przewodnik po Praktycznych notatkach: Budowanie systemów RAG, które naprawdę działają w produkcji: kontrakty, sprawdzania oraz miejsca na kod do wklejenia dla zespołów wdrażających ten model.