Notatki praktyczne: Nie można odzyskać numeru, którego nikt nie zapisał: OKF kontra Vector
Szczegółowy przewodnik po Notatkach praktycznych: Nie można odzyskać numeru, którego nikt nie zapisał: OKF kontra Vector: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów stosujących ten wzorzec.
Niech to służy jako wersja przeznaczona dla operatorów, zawierająca zasady przedstawione w artykule „You Can’t Retrieve a Number Nobody Wrote Down: OKF vs. Vector Databases for RAG Chatbots”: wyraźne etapy, uporządkowane sekcje kodu oraz notatki dotyczące napraw, które przetrwają przeniesienie obowiązków.
Kompiluj swoje dane, odzyskuj tekst
Etap kompilacji danych działa najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań przed rozszerzeniem zakresu. Zdokumentuj zarówno pomyślny przebieg, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa nieudanych prób należą do samego produktu, a nie do późniejszych ulepszeń. Oddziel zasady dzielenia na fragmenty od zasad odzyskiwania danych. Zmiana jednych nie powinna zmuszać do przepisywania drugich, gdy zmieniają się metryki jakości.
Odpowiedź OKF
Faza odpowiedzi OKF działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. 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. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
Zamiana: jeden Lambda
Faza Lambda służąca do wymiany działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przekaz, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, 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 zadania. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
// amplify/functions/askOkf/handler.ts — the essence
export const handler: Schema["askOkf"]["functionHandler"] = async (event) => {
// in-process TF-IDF over the bundle
const hits = search(event.arguments.question, 3);
const top = hits[0];
// Grounded-or-refuse: below the score floor,
// nothing verified matches → refuse
// before ever calling the model.
if (!top || top.score < MIN_SCORE) {
return { answer: refusal().text, citation: "", grounded: false, mode };
}
// read the verified figure straight from frontmatter
if (mode === "extractive") {
// 0 model calls - sub-millisecond
const a = extractiveAnswer(hits);
return { answer: a.text, citation: a.citations[0] ?? "", grounded: true, mode };
}
// generative: ground Claude on the ONE retrieved concept,
// safety-prompted grounded-or-refuse
const concept = top.concept;
const context = `Concept: ${concept.label}\nSource: ${conceptSource(concept.frontmatter)}\n\n${concept.text}`;
const response = await bedrock.send(
new ConverseCommand({
modelId: env.MODEL_ID,
// grounded-or-refuse; declines medical-advice intent
system: [{ text: SYSTEM_PROMPT }],
messages: [{ role: "user", content: [{ text: `Verified concept:\n${context}\n\nQuestion: ${question}` }] }],
inferenceConfig: { maxTokens: 400, temperature: 0 },
})
);
const text = response.output?.message?.content?.[0]?.text ?? "";
return { answer: `${text}\n\nSource: ${citation}`, grounded: true, mode };
};
Baza referencyjna: rzeczywisty wektor RAG dla tych samych plików PDF
Baza odniesienia rzeczywistej platformy funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. 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 proces przechodzi 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.
Wyniki: poprawność
Faza sprawdzania poprawności w The Results działa najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. 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. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości. Faza sprawdzania poprawności w The Results działa najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Wolimy małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną ścieżkę przetwarzania.
Wyniki: opóźnienie
W fazie opóźnienia wyników 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. 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. 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.
Wynik: pobieranie vs. kompilacja
Aby uzyskać informacje o fazie poszukiwań, 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. 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.
Ograniczenia i kompromisy OKF
Z uwagi na ograniczenia i etapy OKF, 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ć bez konieczności czytania całej struktury. Należy podawać konkretne fragmenty tekstu, które stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie są w stanie odróżnić halucynacji od braku danych w indeksie. Z uwagi na ograniczenia i etapy OKF, 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. 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ą strukturę procesów.
e.Dopowiedzenie: trzeci narzędzie
Gdy przechodzisz przez etap dopowiedzenia, jako trzeci krok 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ływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania.
Aktywne i niezależnie weryfikowane
Gdy przechodzisz przez etap testowania w czasie rzeczywistym oraz niezależnej weryfikacji, 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 tokena lub zapytania. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Zmierz dokładność odzyskiwania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabe możliwości wyszukiwania.
Wniosek: opracuj swoje dane, stwórz swój tekst
Gdy przechodzisz przez etap tworzenia wykresów w części dotyczącej wniosków, 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. 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 grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania. Gdy przechodzisz przez etap tworzenia wykresów w części dotyczącej wniosków, 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. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na jedną konkretne odpowiedzialność, a nie na skomplikowaną sekwencję operacji.
List kontrolny operacyjny
Podczas przechodzenia 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 prawidłowy przebieg działania, jak i ścieżkę odzyskiwania. Próby ponowne, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.
Zmierz skuteczność wyszukiwania na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.
Zaznacz wersje zależności i zapisz hash obrazu użytego do demonstracji. Reprodukowalność jest ważniejsza od wiedzy opartej na doświadczeniach zespołu.
Wolę małe, testowalne jednostki niż rozbudowane skrypty. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji.
Mierzyć stopień przywoływania informacji w ustalonym zestawie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabą efektywność wyszukiwania.
Zanim przejdziemy do dalszych kroków, zamroź wersje oprogramowania, utwórz „złoty” zapis transkrypcji dla kluczowych ścieżek oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji uprawnień użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Lepiej wybrać nudną niezawodność niż pomysłowe, jednorazowe demonstracje.
Uwaga dotycząca wersji 286fa7c42234: nie umieszczaj kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików używanych do oceny, 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 na podstawie 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ół wzmocnienia bezpieczeństwa 0/768: 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/768 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 funkcjonuje 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/768: 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/768: 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/768: 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, Embeddings i bazy danych wektorowych — Wyjaśnione z nuła — Krok po kroku instrukcja obsługi Praktycznych notatek: RAG, Embeddings i bazy danych wektorowych — Wyjaśnione z nuła: kontrakty, sprawdzenia oraz miejsca na kod do wklejenia dla zespołów wdrażających ten wzorzec.
- Praktyczne notatki: Znaczenie jako koordynaty: Search semantyczny, bazy danych wektorowych i — Krok po kroku instrukcja obsługi Praktycznych notatek: Znaczenie jako koordynaty: Search semantyczny, bazy danych wektorowych i: kontrakty, sprawdzenia oraz miejsca na kod do wklejenia dla zespołów wdrażających ten wzorzec.