Wskazówki praktyczne: RAG, embeddingi i bazy danych wektorowych — wyjaśnione od podstaw
Praktyczny przewodnik krok po kroku: notatki dotyczące RAG, embeddingów i baz danych wektorowych — wyjaśnione od podstaw: umowy, sprawdzania oraz gotowe miejsca na kod dla zespołów wdrażających ten wzorzec.
Niech to służy jako wersja przeznaczona dla operatorów, zawierająca zasady przedstawione w „RAG, Embeddings i bazy danych wektorowych — wyjaśnione od zera”: jasne etapy, uporządkowane sekcje kodu oraz notatki pomocnicze, które przetrwają przeniesienie obowiązków. Etap Przeglądu działa najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Woląć lepiej małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.
Czym jest RAG?
W fazie „Co to jest RAG” 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 zadania. Wymień fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od braku danych w indeksie.
[ Documents ] --> [ Chunk ] --> [ Embed ] --> [ Store in Vector DB ]
|
User Question --> [ Embed Question ] --> [ Find Similar Chunks ] --> [ LLM ] --> Answer
Co to jest embedding?
W etapie „Co to jest embedding?” należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten 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 rejestrować 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 podawać fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.
"king" → [0.21, -0.05, 0.87, ..., 0.33] (384 numbers)
"queen" → [0.19, -0.03, 0.85, ..., 0.31] (384 numbers)
"banana" → [-0.72, 0.44, 0.01, ..., -0.56] (384 numbers)
Jak tekst staje się liczbami
W etapie „Jak tekst staje się liczbami” należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od 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ć bez konieczności czytania 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ć halucynacji od braku danych w indeksie. W etapie „Jak tekst staje się liczbami” należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki nad rozbudowanymi skryptami. Gdy krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sieć powiązań.
pipeline.Krok 1: Tokenizacja
Podczas pracy na etapie tokenizacji, 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. Zachowuj w pamięci tymczasowej stabilne instrukcje systemowe oraz schematy narzędzi. Ponowne wysyłanie identycznego nagłówka jest częstą przyczyną marnotrawstwa zasobów.
"backend engineer jobs in bangalore"
Tokens: ["backend", "engineer", "jobs", "in", "bang", "##alore"]
Krok 2: Warstwy Transformera
Gdy przechodzisz przez etap warstw Transformer w Kroku 2, 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. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabe możliwości wyszukiwania.
"backend" → [0.52, -0.18, 0.83, 0.45, ...] (384 numbers)
"engineer" → [0.48, -0.15, 0.79, 0.41, ...] (384 numbers)
"jobs" → [0.31, -0.05, 0.67, 0.22, ...] (384 numbers)
"in" → [0.07, 0.02, 0.11, 0.04, ...] (384 numbers)
"bang" → [0.39, 0.27, 0.55, 0.30, ...] (384 numbers)
"##alore" → [0.14, 0.10, 0.21, 0.11, ...] (384 numbers)
Krok 3: Pooling
Gdy przechodzisz przez etap Pooling w kroku 3, 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. Trzymaj 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. Zmierz stopień odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania. Gdy przechodzisz przez etap Pooling w kroku 3, 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 nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną ścieżkę przetwarzania.
Dimension 1: (0.52 + 0.48 + 0.31 + 0.07 + 0.39 + 0.14) / 6 = 0.318
Dimension 2: (-0.18 + -0.15 + -0.05 + 0.02 + 0.27 + 0.10) / 6 = 0.002
... same for all 384 dimensions ...
Final: [0.318, 0.002, ...] ← ONE vector for the entire sentence
Szybkie wyjaśnienie: Wektory a wymiary
Szybkie wyjaśnienie dotyczące wektorów i wymiarów działa najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przykład, jeden przypadek niepowodzenia oraz notatkę dotyczącą cofnięcia działań przed rozszerzeniem zakresu. Traktuj tę fazę 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ń. Oddziel zasady dzielenia na fragmenty od zasad wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
2D point (on a map): [x, y] → 1 vector, 2 dimensions
3D point (in a room): [x, y, z] → 1 vector, 3 dimensions
Embedding: [n1, n2, ..n384] → 1 vector, 384 dimensions
Czym jest baza danych wektorowych?
Etap „Co to jest wektor?” 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. 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. Rozdziel politykę dzielenia na fragmenty od polityki wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
┌──────────────────────────────────────────────────┐
│ Vector DB │
│ │
│ Entry 1: │
│ text: "Senior Backend Engineer Wipro..." │
│ vector: [0.21, -0.05, 0.87, ...] │
│ │
│ Entry 2: │
│ text: "Frontend dev needed Chennai..." │
│ vector: [0.71, 0.55, -0.30, ...] │
│ │
│ Entry 3: │
│ text: "Backend Engineer Flipkart..." │
│ vector: [0.19, -0.03, 0.85, ...] │
│ │
└──────────────────────────────────────────────────┘
Ile wektorów jest przechowywanych?
Etap „Ile wektorów otrzymać” funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Przechowuj 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łego grafu. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w przypadku zmian wskaźników jakości. Etap „Ile wektorów otrzymać” funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.
Page 1 (naukri.com) → 3000 chars → split into 6 chunks → 6 vectors
Page 2 (linkedin.com) → 5000 chars → split into 10 chunks → 10 vectors
Page 3 (indeed.com) → 2000 chars → split into 4 chunks → 4 vectors
Page 4 (glassdoor.com) → 4500 chars → split into 9 chunks → 9 vectors
Page 5 (some blog) → 1500 chars → split into 3 chunks → 3 vectors
─────────
32 vectors in the database
Jak działa pobieranie danych
W etapie „Jak działa wyszukiwanie” 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 ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Podaj fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.
Krok 1: Wbuduj zapytanie za pomocą TEGO SAMEGO modelu
W pierwszym kroku, zanim zmieni się kod, należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten krok oraz kryteria zakończenia. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Obok wyników funkcjonalnych należy rejestrować czas trwania oraz koszt tokena lub zapytania. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. W przypadku, gdy następnym krokiem jest kod lub wywołanie narzędzia, lepiej używać ustrukturyzowanych wyników z walidacją schematu niż tekstu w formie swobodnej.
"backend engineering jobs in Bengaluru" → [0.20, -0.04, 0.86, ...]
Krok 2: Porównanie z każdym przechowywanym wektorem
W etapie 2 „Porównanie z bazą” należy przed zmianą kodu określić dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia. Operatorzy powinni móc ponownie uruchomić ten etap od 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ć bez konieczności przeglądania 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. W etapie 2 „Porównanie z bazą” należy przed zmianą kodu określić dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia. Operatorzy powinni móc ponownie uruchomić ten etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy etap się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną strukturę przepływu danych.
Query vector vs Chunk 1 ("Senior Backend Engineer Wipro, Bengaluru...")
→ similarity: 0.95 ✅
Query vector vs Chunk 2 ("Frontend dev needed Chennai...")
→ similarity: 0.23 ❌Query vector vs Chunk 3 ("Backend Engineer Flipkart Bengaluru...")
→ similarity: 0.97 ✅
Krok 3: Zwrócenie najważniejszych k fragmentów
Podczas pracy nad etapem Krok 3: Zwrócenie, 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. Zmierz stopień przywoływalności na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.
Problem fragmentowania
Gdy przechodzisz przez etap rozwiązywania problemu dzielenia na fragmenty, 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. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokenów lub zapytań. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Zmierz stopień odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabą skuteczność wyszukiwania.
Original text:
"...looking for a talented software engineer with 5 years of backend experience..."
Chunk 1 (chars 0-500): "...looking for a talented software engi"
Chunk 2 (chars 500-999): "neer with 5 years of backend experience..."
"Home About Careers Login Contact Us Senior Backend Eng"
Lepsze podejścia:
Gdy przechodzisz przez etap lepszych rozwiązań, 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. Trzymaj 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. Zmierz stopę odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania. Gdy przechodzisz przez etap lepszych rozwiązań, 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 nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję operacji.
Kompleksowe omówienie z rzeczywistymi danymi
A Complete Walkthrough With – ta faza działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przykład realizacji, jeden przypadek niepowodzenia oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Traktuj tę fazę 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 zadań. Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
"Home Jobs Companies Senior Backend Engineer Wipro, Bengaluru
Build scalable APIs using Java Spring Boot. 5+ years experience required."
Tokowizacja (29 tokenów):
Etap tokenizacji 29 tokenów działa najlepiej, gdy traktuje się go jako mierzalną wartość. Zapisz jeden idealny przepis transkrypcji, jeden przypadek awarii oraz notatkę o cofnięciu działań przed rozszerzeniem zakresu. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Przydziel 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 nieoczekiwane rachunki.
["[CLS]", "home", "jobs", "companies", "senior", "backend", "engineer",
"wi", "##pro", ",", "bengal", "##uru", "build", "scala", "##ble",
"api", "##s", "using", "java", "spring", "boot", ".", "5", "+",
"years", "experience", "required", ".", "[SEP]"]
Wektory na token (wyświetlające 8 wymiarów zamiast 384 dla lepszej czytelności):
Wektory na token, przedstawiające 8 etapów, działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. 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łego grafu. 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.
"[CLS]" → [ 0.01, 0.03, -0.02, 0.05, 0.01, -0.04, 0.02, 0.06]
"home" → [ 0.44, 0.12, -0.33, 0.08, -0.21, 0.55, 0.09, -0.17]
"jobs" → [ 0.31, -0.05, 0.67, 0.22, 0.14, -0.08, 0.43, 0.11]
"companies" → [ 0.28, 0.09, 0.51, 0.18, 0.07, -0.12, 0.38, 0.05]
"senior" → [ 0.15, -0.22, 0.71, 0.33, 0.41, 0.09, 0.55, 0.27]
"backend" → [ 0.52, -0.18, 0.83, 0.45, 0.38, 0.21, 0.61, 0.34]
"engineer" → [ 0.48, -0.15, 0.79, 0.41, 0.35, 0.18, 0.58, 0.31]
"wi" → [ 0.11, 0.04, 0.22, 0.09, 0.03, 0.07, 0.14, 0.02]
"##pro" → [ 0.08, 0.02, 0.19, 0.06, 0.01, 0.05, 0.11, -0.01]
"," → [ 0.00, 0.01, 0.00, 0.01, -0.01, 0.00, 0.01, 0.00]
"bengal" → [ 0.39, 0.27, 0.55, 0.30, 0.22, 0.33, 0.41, 0.19]
"##uru" → [ 0.14, 0.10, 0.21, 0.11, 0.08, 0.12, 0.15, 0.07]
"build" → [ 0.35, -0.11, 0.62, 0.28, 0.19, 0.15, 0.47, 0.22]
"scala" → [ 0.29, -0.09, 0.54, 0.24, 0.16, 0.11, 0.40, 0.18]
"##ble" → [ 0.10, 0.03, 0.18, 0.07, 0.05, 0.04, 0.13, 0.06]
"api" → [ 0.41, -0.14, 0.73, 0.37, 0.30, 0.19, 0.53, 0.28]
"##s" → [ 0.03, 0.01, 0.05, 0.02, 0.01, 0.01, 0.04, 0.01]
"using" → [ 0.07, 0.02, 0.11, 0.04, 0.03, 0.02, 0.08, 0.03]
"java" → [ 0.46, -0.20, 0.77, 0.39, 0.32, 0.17, 0.56, 0.29]
"spring" → [ 0.42, -0.16, 0.70, 0.35, 0.28, 0.14, 0.51, 0.25]
"boot" → [ 0.38, -0.13, 0.65, 0.31, 0.25, 0.12, 0.48, 0.23]
"." → [ 0.00, 0.01, 0.00, 0.01, -0.01, 0.00, 0.01, 0.00]
"5" → [ 0.05, 0.01, 0.09, 0.03, 0.02, 0.01, 0.06, 0.02]
"+" → [ 0.01, 0.00, 0.02, 0.01, 0.00, 0.00, 0.01, 0.00]
"years" → [ 0.20, -0.07, 0.44, 0.19, 0.13, 0.08, 0.33, 0.14]
"experience" → [ 0.33, -0.10, 0.61, 0.27, 0.20, 0.13, 0.45, 0.21]
"required" → [ 0.18, -0.06, 0.39, 0.16, 0.11, 0.07, 0.29, 0.12]
"." → [ 0.00, 0.01, 0.00, 0.01, -0.01, 0.00, 0.01, 0.00]
"[SEP]" → [ 0.02, 0.01, -0.01, 0.03, 0.00, -0.02, 0.01, 0.04]
Wektory na token, przedstawiające 8 etapów, działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.
Pooling — 29 wektorów staje się 1:
Dla metody Pooling 29 wektorów staje się etapem – należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Podaj fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.
Dim 1: (0.01 + 0.44 + 0.31 + 0.28 + 0.15 + 0.52 + 0.48 + 0.11 + 0.08 + 0.00
+ 0.39 + 0.14 + 0.35 + 0.29 + 0.10 + 0.41 + 0.03 + 0.07 + 0.46 + 0.42
+ 0.38 + 0.00 + 0.05 + 0.01 + 0.20 + 0.33 + 0.18 + 0.00 + 0.02) / 29
= 0.231
Dim 2: (0.03 + 0.12 + -0.05 + 0.09 + -0.22 + -0.18 + -0.15 + 0.04 + 0.02 + 0.01
+ 0.27 + 0.10 + -0.11 + -0.09 + 0.03 + -0.14 + 0.01 + 0.02 + -0.20 + -0.16
+ -0.13 + 0.01 + 0.01 + 0.00 + -0.07 + -0.10 + -0.06 + 0.01 + 0.01) / 29
= -0.030... same for all 384 dimensions ...
Zachowywane w bazie danych wektorowej:
Dla elementów przechowywanych na etapie wektorowym 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 na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować 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 podawać fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie są w stanie odróżnić halucynacji od luki w indeksowaniu.
text: "Home Jobs Companies Senior Backend Engineer Wipro, Bengaluru..."
vector: [0.231, -0.030, 0.421, 0.189, ...]
Teraz użytkownik wyszukuje: „senior backend engineer at Wipro”
W fazie wyszukiwania przez użytkownika w Now a 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 od 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ć bez konieczności przeglądania całej struktury. Należy podawać konkretne fragmenty tekstu, na których opiera się odpowiedź. Bez tych odniesień operatorzy nie są w stanie odróżnić halucynacji od braku danych w indeksie. W fazie wyszukiwania przez użytkownika w Now a 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 od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną ścieżkę przetwarzania.
Query vector: [0.228, -0.028, 0.418, 0.185, ...]
Chunk vector: [0.231, -0.030, 0.421, 0.189, ...]
Dwa modele, dwa zadania
Gdy przechodzisz przez etap „Dwa modele, dwa zadania”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co się dzieje 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. Zachowuj w pamięci tymczasowej stabilne instrukcje systemu oraz schematy narzędzi. Ponowne wysyłanie identycznego nagłówka jest częstą przyczyną marnotrawstwa zasobów.
Dlaczego RAG jest ważne
Gdy przechodzisz przez etap „Dlaczego RAG jest ważne”, 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. Obok wyników funkcjonalnych zapisz czas wykonywania oraz koszt tokenów lub zapytań. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Zmierz stopień odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.
Czym charakteryzuje się dobry model embeddingów?
Gdy pracujesz nad etapem „Co czyni coś dobrym”, 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. Trzymaj 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. Zachowuj w pamięci podręcznej stabilne instrukcje systemowe oraz schematy narzędzi. Ponowne wysyłanie identycznego prefiksu to częsty powód marnotrawstwa zasobów. Gdy pracujesz nad etapem „Co czyni coś dobrym”, 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 nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję operacji.
A: "Senior Backend Engineer at Wipro"
B: "Software Developer role in Bengaluru"
C: "Best chocolate cake recipe"
Lista kontrolna operacyjna
Gdy przechodzisz przez etap listy kontrolnej operacyjnej, 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.
Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę przywracania stanu. Próby ponowne, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.