Gdy bot typu RAG cytuje niewłaściwą kwotę wolną od składki ubezpieczeniowej
Narzędzie do dzielenia na fragmenty o stałej wielkości rozkłada kwotę w dolarach na poszczególne linie; należy ponownie przeprowadzić analizę i przejść przez cztery poziomy dzielenia – od rekurencyjnych podstawowych metod po wyszukiwanie informacji w dokumentach nadrzędnych – zanim można zaufać uzyskanym odpowiedziom.
Wszystko poniżej stanowi fikcyjną opowieść służącą do nauczania. Nazwy firm, osoby oraz kwoty pieniężne są wymyślone; opisane sposoby awarii to te, z którymi napotykają się w rzeczywistości systemy RAG używane w produkcji w regulowanym ubezpieczeniu oraz podobnych obszarach o wysokim stopniu ryzyka.
Późnym wieczorem w wtorek kierownik działu roszczeń skontaktował się z działem inżynieryjnym: asystent poinformował klienta, że kwota wolna od składki w przypadku powodzi wynosi 500 dolarów, podczas gdy polisa przewidywała 5000 dolarów. Bot wzbogacony o możliwości wyszukiwania – „Atlas” – był już w użyciu od trzech tygodni, wykorzystując bazę wektorową, solidny model embeddingu, zaawansowany model językowy oraz dopracowaną interfejs użytkownika. Brakowało mu jednak skutecznej strategii dzielenia danych na fragmenty.
Uzyskany fragment wyglądał następująco:
...applies to all covered perils. Deductible: $5
00 for flood events in Zone A, $500 for wind events, and $1,0
Ekstrakcja z pliku PDF rozdzieliła liczbę na kilka wierszy. Następnie narzędzie do dzielenia na fragmenty o stałej wielkości podzieliło tekst co 500 znaków w miejscu tego rozdzielenia. Moduł embeddingowy utworzył indeks fragmentów zawierających informacje „50 dolarów” oraz „500 dolarów”. Model odpowiedział z pewnością siebie – ale błędnie.
Poniżej opisano, w jaki sposób zbudowano ponownie pipeline przetwarzania danych: jedna etap analizy, która określa górny limit, a następnie cztery poziomy dzielenia na fragmenty, które stopniowo zbliżają się do tego limitu przy rosnących kosztach.
Jedno proste podejście zapewnia uczciwość pod względem kosztów: prawie cały koszt dzielenia na fragmenty to jednorazowe obliczenia niezbędne do tworzenia indeksu. Odbywają się one offline, przed każdym zapytaniem użytkownika. Jedynym kosztem związanym z dzieleniem na fragmenty, który pojawia się w wartości p95 zapytań, jest sam model embeddingowy. Określenie „drogie” dla wyższych poziomów oznacza drogie koszty jednorazowo na dokument, a nie za każde zapytanie.
Etap 0: Nie można podzielić na fragmenty struktury, którą zniszczono podczas analizy
Pierwszym rozwiązaniem jest inteligentniejszy narzędzie do dzielenia tekstu na fragmenty. Lepsze pierwsze pytanie brzmi: pokazać tekst, który ma być podzielony, a nie plik PDF. Tekst w wersji Early Atlas składał się z jednej wielkiej ściany znaków. Nagłówki zmieszały się z treścią główną, a tabela z wykluczeniami finansowymi stała się jednym ciągiem tekstu, w którym wartości z różnych wierszy znajdowały się obok siebie. Informacja o stronie („Formularz ubezpieczeniowy HO-3 — Strona 14 z 62”) powtarzała się co kilka tysięcy znaków.
Żadne narzędzie do dzielenia tekstu nie może przywrócić granic, które już zostały zniszczone przez parsera. Jeśli nagłówki zniknęły, narzędzie do dzielenia na nagłówki w Markdown nie ma czego podzielić. Jeśli tabele się rozpadły, nic nie zapobiega łączeniu wierszy.
Należy dopasować każdy typ wejściowego tekstu do parsera, który generuje strukturę, którą może wykorzystać narzędzie do dzielenia tekstu na fragmenty:
Rdzenny plik PDF i DOCX (formularze polisy, zaświadczenia, wytyczne). Należy preferować parserzy rozumiejące układ — LlamaParse, Unstructured.io, Docling, Azure Document Intelligence — zamiast prostych wyeksportowanych tekstów. Wymagany jest format markdown z określeniem typów elementów (tytuł, tabela, lista), a nie zwykła ciąg znaków.
Zeskanowane pliki PDF, obrazy i faksy. Należy zastosować OCR (Tesseract jest najgorszy; PaddleOCR, Textract, Document AI, Azure są lepsze). Wymagany jest tekst wraz z blokami układu oraz poziom pewności dla każdego bloku. Później ten poziom pewności może wskazywać, że „ta liczba jest niepewna — nie należy na jej podstawie obliczać składek”.
HTML i wewnętrzne wiki. Należy usunąć dodatkowe elementy i wygenerować czysty format markdown z zachowanymi nagłówkami.
Karty prezentacyjne i arkusze kalkulacyjne. Trzeba zachować granice slajdów lub arkuszy, aby żaden fragment nie łączył niespowiązanych ze sobą slajdów.
Audio i wideo (rozmowy, webinary). Usługi takie jak Whisper, Deepgram czy AssemblyAI powinny generować transkrypcję z oznaczeniem, kto i kiedy mówił. Jeśli mówcy nie są oddzieleni, sprzeczne stwierdzenia ze strony negocjatora i klienta mogą połączyć się w jeden mylący akapit.
Po ponownej analizie z uwzględnieniem struktury tekstu, sekcja dotycząca kwoty do odliczenia wyglądała następująco:
## Section 4 — Deductibles
### 4.2 Peril-specific deductibles
| Peril | Zone A | Zone B |
|----------------|---------|---------|
| Flood | $5,000 | $2,500 |
| Wind / hail | $500 | $500 |
| Named storm | $1,000 | $1,000 |
Została przywrócona tabela. Został przywrócony drzewo nagłówków. „5 000 dolarów” ponownie stanowiło jeden token. Kod do dzielenia tekstu na fragmenty jeszcze się nie zmienił, a proces wydobywania informacji stał się już bezpieczniejszy.
Poziom 1: Dzielenie tekstu syntaktyczne — tanie, szybkie i punkt wyjścia
Rozmiar stały: prototyp, który trafił do użycia przypadkowo
Dzieli każde N znaków lub tokenów (CharacterTextSplitter, tiktoken). Koszt indeksowania jest niemal zerowy. Wystarczający przy nagłym wzroście obciążenia; śmiertelny w produkcji. Przerywa zdania, tabele, liczby – dokładnie w momencie wystąpienia problemu. Zasada po tamtej nocy: rozwiązania o stałej wielkości nigdy nie mogą być używane w notatnikach.
Zespoły ciągle odkrywają ten sam wzorzec: korpus demonstracyjny składający się z krótkich postów na blogu przetrwa dzielenie na znaki, ale gdy pojawia się pierwszy PDF z wieloma kolumnami lub dokument skanowany OCR, jakość odpowiedzi spada błyskawicznie. Traktuj okna o stałej wielkości jako narzędzia pomocnicze do eksperymentów lokalnych, z wyraźnym punktem na liście kontrolnej dotyczącym ich zastąpienia przed przyjęciem ruchu od użytkowników z zewnątrz.
Nakładanie się: pokrętło, a nie strategia
chunk_overlap powtarza koniec fragmentu N na początku fragmentu N+1. Od dziesięciu do piętnastu procent jest standardem (na przykład 50 w fragmencie składającym się z 500 tokenów). Przełożenie fragmentów stanowi tanie rozwiązanie dla poziomów 1–2; nie naprawia złych granic – jedynie je powtarza. Można oczekiwać około 10% więcej wektorów oraz powtórzonych wyników w metodzie top-k, gdy dopasowanie znajduje się w obszarze przełożenia.
Gdy duplikaty dominują na liście sąsiednich fragmentów, narzędzia do ponownego rankowania oraz modele LLM marnują przestrzeń kontekstową na tę samą zdanie dwa razy. Usunięcie duplikatów za pomocą identyfikatora rodzica lub haseł tekstu niemal identycznych po pobraniu danych jest tanim sposobem na złagodzenie tego problemu, jeśli przełożenie fragmentów musi pozostać duże z innych powodów.
Zdanie/akapit: uwzględnia gramatykę, ignoruje treść dokumentu
Zgrupuj całe zdania w jedną grupę (NLTK, spaCy, LlamaIndex SentenceSplitter). Nigdy nie dzieli w środku zdania — w przeciwnym razie mogłoby to zakłócić podział na linie — ale nie rozpoznaje nagłówków, tabel ani list wykluczeń. Doskonałe do transkrypcji rozmów; przeciętne w przypadku ustrukturyzowanych formularzy polisy.
Cecha rekurencyjna: domyślna opcja do użycia najpierw
RecursiveCharacterTextSplitter testuje separatorzy w kolejności priorytetów — pusta linia, nowa linia, zdanie, słowo — i ucieka się do innych metod tylko wtedy, gdy fragment nadal jest zbyt duży, po czym łączy mniejsze fragmenty tak, aby osiągnąć rozmiar chunk_size. Powszechnym standardem jest 500 tokenów z 50% nakładaniem się:
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", ". ", " ", ""],
)
chunks = splitter.split_text(policy_markdown)
W ponownie przetworzonej sekcji dotyczącej kwoty wolnej od podatku zachowano całość wartości 4,2 – włącznie z tabelą – ponieważ puste linie tworzyły naturalną jednostkę składającą się z mniej niż 500 tokenów. Błąd zniknął. Należy wysłać rozwiązanie recursive-500/50 jako podstawę do porównania, a nie jako ostateczny projekt.
Napisz tę wartość bazową na tablicy i odrzuć propozycje „mądrzejszych” narzędzi do dzielenia tekstu, które nie są w stanie jej przewyższyć przy tych samych testach. Wiele drogich rozwiązań wydaje się genialnych, dopóki nie zostaną porównane z prostym narzędziem rekurencyjnym działającym na czystym formacie Markdown.
Poziom 2: Dzielenie tekstu z uwzględnieniem struktury – dziel w miejscach, gdzie dokument już ma wyznaczone granice
Przy zestawie około 80 rzeczywistych pytań rozwiązanie recursive-500/50 osiągnęło wynik około 71%. Błędy występowały głównie w długich sekcjach oraz w odpowiedziach, gdzie model nie był w stanie określić, która polityka lub sekcja była źródłem błędu.
Dzielenie nagłówków Markdown / HTML
MarkdownHeaderTextSplitter / HTMLHeaderTextSplitter dzielą treść według hierarchii nagłówków i przenoszą ścieżkę nagłówka do metadanych:
from langchain_text_splitters import MarkdownHeaderTextSplitter
header_splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=[("#", "h1"), ("##", "h2"), ("###", "h3")]
)
sections = header_splitter.split_text(policy_markdown)
# then apply the recursive splitter inside each section
Każdy fragment pochodzący z podrozdziału 4.2 powinien zawierać ścieżkę nawigacyjną typu formularz HO-3 → składniki odliczeniowe → tabela specyficzna dla zagrożenia. Tę ścieżkę należy połączyć z tekstem przed wstawieniem, aby wektor kodował zarówno lokalizację, jak i liczby. Błędy typu „Który rozdział?” znikają; cytaty mogą zawierać informację „zgodnie z rozdziałem 4.2”. Koszt pozostaje niemal zerowy – ale tylko wtedy, gdy etap 0 wygenerował prawdziwy format Markdown. Spłaszczony tekst w ten sposób staje się jednym ogromnym fragmentem. Najlepiej sprawdza się to na witrynach wiki, dokumentacji technicznej oraz politykach z nagłówkami.
Pola metadanych powinny być przekazywane razem z wektorem: identyfikator dokumentu źródłowego, ścieżka do rozdziału, data wejścia w życie oraz jurysdykcja, jeśli polityki różnią się w zależności od stanu. Te pola umożliwiają użycie filtrów („tylko HO-3 obowiązujące od 2024-01-01”), których czysty wyszukiwacz podobieństwa nie może obsłużyć.
Zorientowany na układ / by_title
Nieustrukturyzowane narzędzia typu chunk_by_title (oraz podobne w LlamaParse/Docling) przestrzegają granic elementów parsera: tabele pozostają nienaruszone, nagłówki rozpoczynają poszczególne fragmenty, a listy zachowują swoje zdanie wprowadzające. Doskonałe rozwiązanie do umów i złożonych plików PDF. Usługi analizy API kosztują pieniądze tylko raz, podczas tworzenia indeksu. Tani parser zewnętrzny unieważnia korzyści płynące z droższych rozwiązań – nie kupuj luksusowego kierownicy do samochodu bez silnika.
Zorientowany na kod (AST)
Nieistotne dla korpusów polityk, niezbędne przy Terraform/Python RAG. Dzielenie na linie oddziela podpisy od treści. Narzędzia takie jak tree-sitter lub zorientowane na język rozdzielacze działają na poziomie węzłów funkcji/klas. Są standardem, gdy korpus składa się z repozytoriów lub plików IaC.
Mieszanie zasad prozy i kodu źródłowego w jednym indeksie bez oddzielenia elementów rozdzielających zazwyczaj skutkuje najgorszym z obu światów: funkcjami przeciętymi w połowie treści oraz tabelami zasad zniszczonymi przez heurystyki oparte na nawiasach.
Poziom 3: Dzielenie na fragmenty w oparciu o model – płacimy za ocenę tylko tam, gdzie brakuje struktury
U około 84% próbek z zestawu referencyjnego pojawiła się nowa klasa błędów: nieustrukturyzowane transkrypcje rozmów bez nagłówków. Recurencyjne bloki po 500 tokenów obejmowały zmiany tematu – najpierw żądanie odszkodowania, potem adres pocztowy – więc embeddingi reprezentowały średnio dwa tematy i nie pasowały do żadnego z nich dobrze.
Dzielenie na fragmenty semantyczne
Wbuduj tekst zdanie po zdaniu; przerwij w miejscach, gdzie kolejne wartości podobieństwa kosinowego spadną poniżej określonego progu (SemanticChunker, każdy przyzwoity narzędzie do wbudowywania). Jedna próba wbudowania na każdym etapie przetwarzania. Metoda ta ma zastosowanie w przypadku mowy; progi są specyficzne dla danego korpusu. Próg stosowany w przypadku rozmów telefonicznych rozbił gęsty tekst regulaminowy na małe fragmenty — dlatego używaj segmentacji semantycznej tylko w przypadku nieustrukturyzowanej mowy, a regulaminy trzymaj na poziomie 2.
Rozdzielenie dokumentów według kategorii — mowa, formularze, wiki — jest lepsze niż szukanie jednego uniwersalnego narzędzia do segmentacji. Kosztem jest klasyfikator lub prosty mechanizm zmiany typu pliku podczas wprowadzania danych; korzyścią są mniej niejasnych wyników segmentacji.
Segmentacja propozycji / faktów atomowych
Niewielki LLM przepisuje fragmenty na samodzielne stwierdzenia („Odpis za powódź dla strefy A w polisie HO-3 wynosi 5 000 dolarów”). Dokładność rośnie, ponieważ każda jednostka to jeden fakt z kontekstem włączonym bezpośrednio. Koszt to jedna wywołanie LLM na fragment – co jest rozsądne dla małych, wysokodokładnych zbiórów danych, takich jak 40-stronicowy FAQ. Pułapka: propozycje mogą odbiegać od oryginalnego sformułowania. Gdy klienci kwestionują odpowiedzi, dosłowne cytowanie jest lepsze od parafrazowania. Traktuj propozycje jako narzędzie pomocnicze do wyszukiwania i zwracaj oryginalny fragment w celu cytowania.
Organizacje zajmujące się zgodnością i rozpatrywaniem roszczeń w końcu będą żądać obrazu strony lub wyróżnień z PDF za daną odpowiedzią. Zaprojektuj identyfikatory cytowań wcześnie, aby indeksy propozycji pozostały narzędziem przyspieszającym pracę, a nie głównym systemem przechowywania danych.
Agentic chunking
Przekaż cały dokument modelowi flagowemu w celu wyznaczenia granic. Metoda ta funkcjonuje, ale ma niską skalowalność: koszt rośnie liniowo wraz z rozmiarem korpusu, podczas gdy wartość nie. Nadaje się do kilkuset najważniejszych dokumentów; nie do milionów.
Poziom 4: Dzielenie na fragmenty w czasie wyszukiwania — wyszukiwanie małych jednostek, zwracanie większych
Poziomy 1–3 zakładają, że jednostka indeksowana to również ta zwracana. To wymusza fałszywy kompromis: małe fragmenty umożliwiają czyste embedowanie, ale pozbawiają LLM kontekstu; duże fragmenty dostarczają kontekstu, ale psują embedowanie. Dostosowywanie chunk_size nigdy nie prowadzi do znalezienia uniwersalnego optymalnego rozwiązania.
Poziom 4 dzieli role: jednostka wyszukiwania dostosowana do narzędzia embedującego oraz jednostka dostarczania dostosowana do LLM. Test diagnostyczny: jeśli potrzebujesz drugiego magazynu (docstore, mapę rodziców, drzewo), znajdujesz się na poziomie 4.
Dokument rodzicowski / od małego do dużego
Indeks małych dzieci (150–200 tokenów). W przypadku dopasowania zwróć większego rodzica (całą sekcję 4.2 lub podsekcję o około 1 500 tokenach):
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1500)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=200)
retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=InMemoryStore(), # the "second store"
child_splitter=child_splitter,
parent_splitter=parent_splitter,
)
retriever.add_documents(policy_docs)
LlamaIndex AutoMergingRetriever oferuje podobną hierarchię. Dodatkowy koszt indeksowania jest niemal zerowy – wstawiasz ten sam tekst w mniejszych fragmentach. Już dzięki temu zmianie na zbiorze testowym wynik Atlas wzrósł z około 84% do około 91%; zapytanie „what’s my flood deductible” trafiło dokładnie do odpowiedniej wiersza tabeli, podczas gdy model LLM nadal widział otaczające je notatki (w tym definicję strefy A). Koszt operacyjny: docstore kluczowany według ID rodzica, który pozostaje zsynchronizowany przy aktualizacjach.
Tutaj istotne są usuwanie i wersjonowanie: gdy sekcja 4.2 jest poprawiana, dzieci i rodzice muszą zostać odświeżone razem, w przeciwnym razie system pobraje dokładne dziecko, które otwiera przestarzałego rodzica. Traktuj proces wprowadzania danych jako transakcyjne publikowanie rodzica, dzieci oraz embeddingów – a nie trzy oddzielne zadania.
Pobieranie kontekstowe
Zanim wstawisz treść, poproś mini LLM o jedno lub dwa zdania kontekstowe i umieść je na początku; połącz to z metodą BM25. Fragmenty takie jak „Strefa A: 5 000 $ / Strefa B: 2 500 $” stają się dostępne do odzyskiwania. Koszt to jedna wywołanie LLM na każdy fragment — co jest bardzo drogie bez buforowania promptów; przy buforowaniu prefiks dokumentu pozostaje aktywny, a wywołania na poszczególne fragmenty są tańsze.
Późne dzielenie na fragmenty
Wstaw cały dokument za pomocą narzędzia do embedowania długiego kontekstu, a następnie oblicz średni wektor tokenów w obrębie każdego fragmentu. Wektory fragmentów przenoszą kontekst dokumentu bez konieczności wywoływania LLM na każdy fragment. Jest to konkurencyjne z metodą odzyskiwania informacji w kontekście, ale zmusza do użycia modeli embedowania długiego kontekstu.
Hierarchiczne / RAPTOR
Klasteryzuje fragmenty, tworzy streszczenia, a następnie ponownie klasteryzuje te streszczenia w formie drzewa; indeksuje każdy poziom. Ogólne pytania trafiają do streszczeń, a szczegółowe – do najniższych poziomów drzewa. Najwyższe koszty na poziomie 4 sprawiają problemy przy zmianach w dokumentach – odbudowa drzewa jest kosztowna. Kwartalne aktualizacje polityk sprawiły, że RAPTOR stał się odpowiednim wyborem dla Atlasu.
Bazy wiedzy statyczne – wewnętrzne encyklopedie zmieniane co rok – mogą tolerować odbudowę drzewa. Formularze ubezpieczeniowe nie mogą tego zrobić. Wybieraj metody hierarchiczne tylko wtedy, gdy wskaźnik zmian i budżet na odbudowę są jasno określone.
Co mówi odbudowana instrukcja
Sześć tygodni po ćwiczeniach przeciwpożarowych w Slack, Atlas osiągnął wynik bliski 93% na zestawie z około 300 pytaniami. Krótka wersja przeznaczona do przeglądu projektu:
Najpierw zastosuj rekurencyjne dzielenie tekstu na znaki w połączeniu z cięciami uwzględniającymi strukturę przy około 500 tokenach i 50% nakładania się — nie kosztuje to prawie nic i dostarcza mierzalnej bazy porównawczej. Najpierw zaktualizuj system do wyszukiwania dokumentu nadrzędnego, aby rozmiary wyników dopasowania i dostarczanych treści mogły się różnić. Dopiero wtedy inwestuj w wyszukiwanie kontekstowe, jeśli zestaw oceny nadal wskazuje na problemy z odzyskiwaniem wszystkich danych.
Żadne z powyższych rozwiązań nie naprawi złego analizatora tekstu. Najpierw popraw proces wydobywania informacji, zanim dostosujesz narzędzia do dzielenia tekstu.
Wersja jednostronicowa
Etap 0 — Analiza. Dobierz odpowiednie analizatory do rodzaju danych wejściowych: strukturyzowany markdown dla dokumentów oryginalnych; tekst wraz z informacjami o układzie i wynikami OCR dla skanów; czysty markdown z nagłówkami dla plików HTML; granice slajdów lub kartek w prezentacjach; transkrypcje z podziałem na fragmenty dla plików audio. To ustala górny limit możliwości.
Poziom 1 — Składniowy. Wymiary stałe, dostępne tylko dla prototypów. Przeplatanie treści regulowane jest za pomocą suwaka (10–15%), co powoduje duplikację wyników typu top-k. Dzielenie zdań odbywa się zgodnie z gramatyką, ignorując logikę dokumentu. Recurencyjny podział 500/50 stanowi domyślną linię wyjścia, a nie cel końcowy.
Poziom 2 — Biorący pod uwagę strukturę. Dzielenie treści w nagłówkach uwzględnia ścieżki sekcji; efektywność zależy od jakości parsera. Rozkład by_title zachowuje całość tabel; tanie parsery to unieważniają. Dzielenie treści w formacie AST stosowane jest w repozytoriach kodu.
Poziom 3 — Oparty na modelu. Decyzje semantyczne opierają się na stopniu podobieństwa; konfiguracja dostosowywana jest do poszczególnych korpusów. Propozycje poprawiają dokładność w małych korpusach, ale mogą odbiegać od oryginalnego sformułowania. Decyzje oparte na mechanizmach agentowych rzadko są uzasadnione w dużych skali.
Poziom 4 — Czas pobierania. Dopasowywanie na małych jednostkach; dostarczanie dużych. Dokument macierzysty to wersja z najwyższym zwrotem z inwestycji. Wyszukiwanie kontekstowe wymaga buforowania. Późne dzielenie na fragmenty jest tańsze, ale ograniczone funkcjonalnościami narzędzia do włączania danych. RAPTOR ulega przestarzeniu przy aktualizacjach. Jeśli potrzebuje drugiego magazynu, należy do poziomu 4.
Problem nie dotyczył w rzeczywistości wyboru między LangChain a LlamaIndex. Chodziło o uszanowanie struktury dokumentu przed przeprowadzaniem obliczeń, ocenę narzędzi do dzielenia na fragmenty na podstawie rzeczywistych pytań klientów oraz o odmowę przekazywania modelowi fragmentów, które nie mogły zawierać kompletnych faktów liczbowych.
Buduj złoty zestaw na podstawie biletów, które już powodowały problemy w produkcie — błędne kwoty odliczeń, brakujące wyłączenia, mylące zastrzeżenia — a nie na podstawie syntetycznych informacji. Oceniaj oddzielnie poprawność odpowiedzi oraz wierność cytowania, aby błędna liczba nigdy nie wyglądała jak zwycięstwo. Gdy pojawi się nowy rozdzielacz, wymagaj od niego przewyższenia rekurencyjnej bazy w obu metrykach, zanim dotrze do ruchu produkcyjnego.
Na koniec zachowaj mechanizm wyłączenia awaryjnego: jeśli poziom pewności OCR w przypadku liczbowego fragmentu jest niski lub wersje rodzica i potomka się różnią, asystent powinien odrzucić pytanie dotyczące kwoty odliczenia i przekazać je do dalszej analizy, zamiast wymyślać wartość pewności. Użytkownicy znacznie szybciej wybaczają informację „nie można to zweryfikować na podstawie złożonej formy” niż przypadkową, błędną odpowiedź w wysokości pięciuset dolarów. Taka ścieżka odrzucenia powinna znajdować się w wymaganiach produktu, a nie tylko w slajdach analizy postmortem udostępnianych po powstaniu szkód.
Literatura pokrewna
- Stwórz assistenta do rozmów w Wikipedii z użyciem LlamaIndex i ReAct — Indeksuj strony Wikipedii na żądanie, wstawiaj fragmenty za pomocą małego kodera i pozwól agencie ReAct wywołać narzędzie silnika zapytań, aby odpowiedzi Chainlit były oparte na uzyskanych dowodach.
- Hybrydowe wyzyskiwanie danych z Wikipedii z użyciem pgvector, BM25 i kodera do przegrupowania — Dowiedz się, dlaczego czyste wyszukiwanie wektorowe pomija numery części i kody błędów, oraz jak połączyć pgvector, BM25 i mechanizm przegrupowania w LangChain dla precyzyjnego wyzyskiwania danych z Wikipedii.