Przejdź do treści

Ustrukturyzowane dane wyjściowe: uzyskiwanie niezawodnego JSON z modelu językowego

Blog / Opublikowany 

Pierwsza wersja każdej integracji LLM analizuje prozę. Prosisz o „trzy główne ryzyka, po jednym na linię”, podzielone na znaki nowej linii i działa to do dnia, w którym model najpierw napisze zdanie wprowadzające. Istnieją uporządkowane dane wyjściowe, które kończą tę pętlę: przekazujesz modelowi schemat JSON, dekoder jest ograniczony, więc nie może wyemitować niczego, co go narusza, i otrzymujesz z powrotem ładunek z polami, o które prosiłeś. Ta gwarancja jest realna, ale węższa, niż się wydaje, a różnica polega na tym, gdzie żyją błędy.

Co faktycznie obejmuje gwarancja

Ograniczone gwarancje dekodowania kształt. Odpowiedź zostanie przeanalizowana jako JSON, będzie zawierać klucze, typy będą zgodne, a pola wyliczeniowe będą zawierać jedną z wymienionych wartości. Jest to duża poprawa w stosunku do zasady „szybkość i nadzieja”.

Nie gwarantuje niczego treść. Pole wpisane jako ciąg będzie zawierało ciąg; to, czy ten ciąg jest dokładny, czy też wymyślony w celu spełnienia schematu, pozostaje niezmieniony od poprzedniego. Tak naprawdę ścisły schemat zwiększa prawdopodobieństwo wynalezienia, ponieważ wymagane pole musi być czymś wypełnione, a model nie ma możliwości powiedzenia „nie występuje w źródle”. Jest to najczęstsza awaria w produkcji: wymagana invoice_number w dokumencie, który ich nie ma.

Projektuj wokół tego. Zezwól na wartość null, jeśli możliwa jest nieobecność, dodaj jawnie found: boolean lub "unknown" enum i nigdy nie wymagaj pola, chyba że odpowiedź rzeczywiście istnieje w każdym wejściu.

Projektowanie schematu, który model może wypełnić

Schematy pisane do walidacji i schematy pisane do generowania wyglądają inaczej. Kilka zasad obowiązujących u różnych dostawców:

Dostawcy ograniczają również obsługiwane przez siebie słowa kluczowe schematu JSON w trybie ścisłym: oneOf, ograniczenia wzorcowe, granice liczbowe i rekurencja są zwykle ograniczane lub ignorowane. Załóżmy, że schemat ogranicza tylko strukturę i samodzielnie egzekwuj reguły biznesowe po przeanalizowaniu.

Mimo wszystko zweryfikuj

Nawet w trybie ścisłym sprawdzaj poprawność każdej odpowiedzi, zanim dotrze ona do Twojej bazy danych. Tryb ścisły może zostać wyłączony przez zmianę konfiguracji, ścieżka rezerwowa może trafić na model, który go nie obsługuje, ponowna próba połączenia sieciowego może zwrócić obiekt błędu, a odpowiedź może zostać obcięta przez obiekt środkowy z limitem tokenu — co powoduje wygenerowanie nieprawidłowego kodu JSON bez trybu schematu.

Kiedy ładunek ulegnie awarii, użytecznym pytaniem jest, które pole i dlaczego. The Walidator schematu JSON pobiera dokument i schemat i zgłasza po jednym wierszu na każdy problem, ze ścieżką wskaźnika JSON, słowem kluczowym, które się nie powiodło, i faktycznie znalezioną wartością. Jest to dokładnie taka forma, jakiej potrzebujesz do dwóch celów: naprawienia schematu podczas programowania i przekazania informacji o ponownej próbie — raport o nieudanej walidacji wklejony do wiadomości uzupełniającej jest niezwykle skutecznym monitem o naprawę, ponieważ model może dokładnie zobaczyć, co poszło nie tak.

Ogranicz liczbę ponownych prób do jednego lub dwóch. Model, który dwukrotnie zawiódł schemat, jest zwykle proszony o coś, czego dane wejściowe nie zawierają, a trzecia próba spowoduje wynalezienie tego.

Od przykładowego ładunku do kodu

Większość schematów zaczyna życie jako przykładowa odpowiedź, którą ktoś wkleił na czacie. Ręczne przekształcanie tego w wpisany na maszynie, zweryfikowany kod jest żmudne i podatne na błędy, więc tego nie rób.

Wklej próbkę do Schemat JSON do Zoda i otrzymasz schemat Zoda oraz wywnioskowany typ TypeScript. Wnioskuje na podstawie pola, zamiast wpisywać wszystko jako ciąg znaków: pobierane są wartości, które wyglądają jak e-maile, adresy URL, identyfikatory UUID lub daty ISO .email(), .url(), .uuid() I .datetime() zamiast gołego z.string(), tablice przenoszą swój typ elementu, a pole, którego typ różni się w zależności od wystąpienia, staje się sumą, a nie dyskretnym wybieraniem pierwszego, które zobaczyło. To ostatnie zachowanie warto świadomie wprowadzić: wklej trzy lub cztery rzeczywiste odpowiedzi połączone, a nie jedną, tak aby pola opcjonalne i polimorficzne pojawiały się jako związki, a nie były powiązane z tym, co zawierała pierwsza próbka.

Jeśli potrzebujesz tylko typów, a nie sprawdzania poprawności w czasie wykonywania — ponieważ ładunek pochodzi ze źródła, któremu już ufasz — JSON na TypeScript tworzy interfejsy bezpośrednio, z zagnieżdżonymi obiektami podzielonymi na nazwane podinterfejsy, a nie wbudowane anonimowe obiekty BLOB.

Utrzymuj prosty kierunek prawdy: jedna definicja schematu i wszystko inne z niej generowane. Schematy Zoda i schematy JSON utrzymywane oddzielnie będą niezgodne w ciągu miesiąca, a różnica zdań ujawni się jako błąd analizy produkcyjnej, a nie niepowodzenie testu.

Czytanie tego, co wróciło

Odpowiedzi modelu są zminimalizowane w jednej linii, co sprawia, że patrzenie na nie jest nieszczęśliwe. The Formater JSON wcina i sortuje je w coś czytelnego, a jego sprawdzanie poprawności natychmiast wychwytuje przypadek obcięcia — ładunek kończący się w połowie ciągu jest sygnaturą limitu tokenów trafień, a poprawką jest wyższy limit wyjściowy lub mniejszy schemat, a nie szybka zmiana.

Kiedy porównujesz, jakie dwa modele wygenerowano na podstawie tych samych danych wejściowych, lub sprawdzasz, czy szybka zmiana zmieniła wynik w sposób niezamierzony, różnicuj sformatowane ładunki, zamiast czytać oba. Różnice strukturalne, które są niewidoczne w ścianie JSON — polu, które po cichu stało się ciągiem cyfr zamiast liczby — natychmiast wyróżniają się różnicą.

Wersjonowanie

Schematy zmieniają się, a wraz z nimi zmienia się wynik modelu. Umieść pole wersji w ładunku od pierwszego dnia, aby przechowywane rekordy zachowały kształt, w jakim zostały zapisane. Dopasowanie po milionie wierszy nieoznaczonego JSON jest rodzajem migracji, na który nikt nie planuje czasu.

Wszystkie te narzędzia działają lokalnie w przeglądarce, co w przypadku tego przepływu pracy ma większe znaczenie niż zwykle: przykładowe ładunki, które przekształcasz w schematy, są zwykle prawdziwymi odpowiedziami API zawierającymi prawdziwe dane klientów i nie należy ich przesyłać do usługi formatowania w celu upiększenia.

Napisane przez Ján Turský

Twórca TextArray — tworzenia bezpłatnych narzędzi zapewniających prywatność, które działają całkowicie w przeglądarce.