AI pisze SQL: zapytanie działa, ale co właściwie policzyło?
Zapytanie SQL z AI może działać i liczyć niewłaściwe rzeczy. Jak sprawdzić złączenia, jednostkę wyniku i przypadki kontrolne na małym zestawie spraw.

W tym artykule
W hipotetycznym raporcie serwisu pojawiają się cztery zgłoszenia. Kierowniczka pamięta trzy. Asystent AI pokazuje poprawnie wykonane zapytanie, więc rozmowa na chwilę skręca w stronę zawodnej ludzkiej pamięci. Dopiero po obejrzeniu danych okazuje się, że system policzył wiersze połączone z plikami. Dodatkowe zdjęcie awarii awansowało do rangi dodatkowej sprawy.
SQL to język zapytań do bazy danych. Asystent może pomóc go napisać, lecz poprawne wykonanie oznacza przede wszystkim, że baza potrafiła przetworzyć polecenie. Nie rozstrzyga, czy polecenie odpowiadało na pytanie zespołu. Przy odbiorze sprawdź znaczenie wyniku, zanim liczba trafi do raportu, a potem zacznie żyć własnym życiem w trzech prezentacjach.
Trzy sprawy, cztery pliki, kilka możliwych liczb
Przyjmijmy mały, własny przykład: w badanym okresie utworzono sprawy A, B i C. Do A dołączono trzy pliki, do B żadnego, a do C jeden. Pytanie brzmi: ile spraw wpłynęło? Odpowiedź wynosi trzy. Można ją ustalić bez AI i bez znajomości składni, oglądając listę trzech identyfikatorów.
W bazie informacje o sprawach i plikach mogą znajdować się w osobnych tabelach. Złączenie wiąże je według uzgodnionej relacji, na przykład przypisania pliku do sprawy. Dokumentacja PostgreSQL opisuje INNER JOIN jako utworzenie wiersza dla każdego pasującego połączenia. Jedna sprawa może więc wystąpić w takim wyniku kilka razy.
W naszym zestawie złączenie obejmujące wyłącznie dopasowane pary tworzy trzy wiersze dla A i jeden dla C. B znika, bo nie ma pliku. Cztery wiersze nie oznaczają czterech spraw. Co więcej, samo usunięcie powtórzeń identyfikatora z tego wyniku da dwie sprawy. Odzyskaliśmy pojedyncze A, lecz nie przywróciliśmy pominiętego B.
To dobry moment, aby zatrzymać automatyczne poprawianie przez kolejne polecenie „napraw duplikaty”. Najpierw nazwij dwa niezależne problemy: powielenie spraw z wieloma plikami oraz pominięcie spraw bez pliku. Jedna zmiana może usunąć pierwszy, pozostawiając drugi. Wynik nadal będzie wiarygodną liczbą całkowitą, tylko odpowiedzią na inne pytanie.
Jeśli użyjemy złączenia zachowującego również sprawę bez dopasowania, nasz przykład ma pięć wierszy: trzy dla A, jeden dla B i jeden dla C. W wierszu B nie ma identyfikatora pliku. Liczba wierszy znowu nie jest liczbą spraw. Własny przykład można przeliczyć ręcznie, wypisując wszystkie pary, zanim zacznie się wybierać sposób agregacji, czyli łączenia wielu wartości w jeden wynik. Liczby z tego zestawu sprawdzono również lokalnie w SQLite. To kontrola ilustracji, a nie próba konkretnego asystenta ani test wdrożenia PostgreSQL.
Opis funkcji count w PostgreSQL rozróżnia zliczanie wszystkich wierszy przez count(*) i zliczanie wartości innych niż NULL dla wskazanego wyrażenia. NULL oznacza tu brak wartości w bazie. W tym przykładzie wyrażenie odnoszące się do pliku da cztery, a wszystkie wiersze dadzą pięć. Żadna z tych odpowiedzi nie zastępuje automatycznie liczby spraw.
Nie chodzi o zapamiętanie magicznej poprawki. Wybór unikalnego identyfikatora sprawy może być właściwy dla tego pytania, ale najpierw musisz wiedzieć, co identyfikuje jedną sprawę w rzeczywistych danych. Nazwa klienta, temat wiadomości czy widoczny numer skrócony nie muszą pełnić tej roli. Dwie różne osoby mogą zgłosić usterkę pod identycznym tytułem.
Podobny błąd pojawia się przy analizie arkusza z pomocą AI. Łatwo obliczyć poprawną sumę niewłaściwych wierszy. Różnica polega tu na tym, że dodatkowe wiersze mogą powstać dopiero w zapytaniu, więc oryginalna tabela spraw wygląda zupełnie niewinnie.
Uzgodnij pytanie, zanim odbierzesz zapytanie
„Policz zgłoszenia z października” pozostawia kilka decyzji. Czy chodzi o utworzenie sprawy, otrzymanie pierwszej wiadomości czy zakończenie obsługi? Czy sprawa ponownie otwarta jest nową sprawą? Czy liczymy zgłoszenia testowe? Tych odpowiedzi nie da się wywnioskować z samego faktu, że kolumna nazywa się date albo status.
Zapisz definicję prostym zdaniem. Na przykład: jedna sprawa ma jeden trwały identyfikator; uwzględniamy datę jej utworzenia w ustalonym okresie, niezależnie od późniejszego zamknięcia; pomijamy rekordy oznaczone jako testowe. To propozycja dla naszego scenariusza, nie uniwersalna definicja zgłoszenia. Właściciel procesu musi ją zaakceptować przed oceną wyniku.
Następnie przypisz elementy definicji do danych. Która tabela zawiera sprawę, które pole określa utworzenie i gdzie znajduje się oznaczenie testu? Poproś osobę znającą model danych o potwierdzenie relacji. Przy podobnych nazwach tabel asystent może wybrać historię zmian zamiast bieżącej listy. Raport policzy wtedy zdarzenia z życia sprawy.
Opis relacji jest równie istotny jak nazwa pola. Czy plik należy do jednej sprawy? Czy jedno zgłoszenie może mieć kilku opiekunów? Czy historia zawiera kilka wpisów o tym samym stanie? Zrozumienie takich zależności pomaga odczytać wynik przed agregacją. Szerszy problem kierunku i podstawy relacji opisuje tekst o kontroli grafu wiedzy używanego przez AI.
W dokumentacji generowania zapytań Gemini w BigQuery Google zaleca sprawdzanie wyników przed użyciem i ostrzega przed odpowiedziami, które wyglądają wiarygodnie, lecz są nieprawidłowe. W praktyce weryfikacja musi objąć właśnie uzgodnione znaczenie danych. Sam opis zapytania wygenerowany przez tego samego asystenta nie stanowi niezależnego sprawdzenia.
Jeżeli pytanie jest niejednoznaczne, doprecyzuj je, zanim zaczniesz poprawiać SQL. Zmiana definicji po zobaczeniu liczby utrudnia ocenę, czy poprawiono błąd, czy dopasowano raport do oczekiwania. Zachowaj pierwotne pytanie, uzgodnioną interpretację i wersję zapytania, która została sprawdzona. Dzięki temu późniejszy odbiorca może odtworzyć sens liczby.
Filtr może zmienić sens nawet poprawnego złączenia
Załóżmy, że raport ma objąć wszystkie sprawy, a asystent dodaje warunek dotyczący formatu załącznika. Sprawa B bez pliku może zniknąć mimo użycia złączenia zachowującego niedopasowane sprawy. Poproś osobę znającą SQL o sprawdzenie miejsca, w którym zastosowano warunek. W dokumentacji złączeń PostgreSQL pokazano, że przy złączeniu zewnętrznym ograniczenie w ON i w WHERE może dać odmienne wyniki.

Właściciel procesu powinien rozstrzygnąć, czy pytanie dotyczy wszystkich spraw, czy tylko tych z określonym plikiem. To dwie sensowne analizy, lecz wymagają innych nazw. Nie zatwierdzaj zmiany definicji tylko dlatego, że po poprawce raport przestał pokazywać powtórzenia. Usunięcie części spraw może ukryć problem, zamiast go rozwiązać.
Sprawdź również, do którego zdarzenia należy filtrowana data. Plik przesłany w listopadzie może należeć do sprawy utworzonej w październiku. Jeśli pytasz o datę utworzenia sprawy, późniejszy załącznik nie powinien sam zmienić jej przynależności do miesiąca. Przygotuj taki przypadek w zestawie, zamiast polegać na nazwie kolumny podanej w objaśnieniu asystenta.
Dla granicy okresu zapisz oczekiwanie co do godzin i strefy czasu użytej w danych. „Do 31 października” może być niejasne, jeśli pole przechowuje także godzinę. W kontroli uwzględnij późny wieczór ostatniego dnia oraz początek kolejnego miesiąca. Wynik powinien odpowiadać uzgodnionemu okresowi, a nie przypadkowej interpretacji słowa „do”.
Mały zestaw ma ujawniać różnicę
Zestaw kontrolny powinien zawierać przypadki, które zmuszają błędne zapytanie do pokazania innego wyniku. Trzy sprawy z dokładnie jednym plikiem każda nie ujawnią omawianego problemu. Wierszy po złączeniu będzie tyle samo co spraw. Próba przejdzie, ponieważ dane nie stworzyły okazji do rozpoznania błędu.
W naszym przykładzie różnicę tworzą A z trzema plikami i B bez żadnego. Dodaj też dwie sprawy o takim samym tytule, jeśli ktoś proponuje liczenie po tytule. Dla badanego okresu przygotuj sprawy tuż przed początkiem, w środku i na granicy końca. Oczekiwany wynik zapisz przed uruchomieniem ocenianego zapytania, a nie na podstawie jego odpowiedzi.
Możesz przygotować takie dane ręcznie. Jeżeli pomagasz sobie generatorem, sprawdź spójność relacji w danych syntetycznych. Plik wskazujący nieistniejącą sprawę albo dwie rzekomo unikalne tożsamości o tym samym identyfikatorze zmienią przedmiot próby. Test ma badać zapytanie w znanych warunkach, a nie rozwiązywać przypadkowo wygenerowaną zagadkę.
Po uzyskaniu poprawnego wyniku zmień jedną rzecz, która nie powinna na niego wpływać. Dołącz kolejny plik do A. Liczba spraw pozostaje trzy. Jeśli raport rośnie, wiesz, że nadal zależy od liczby załączników. Potem dodaj nową sprawę bez pliku. Tym razem wynik powinien wzrosnąć o jeden. Obie zmiany badają inny fragment znaczenia.
Dodaj rekord z brakującym oznaczeniem testowym, jeśli taki stan występuje w danych. Uzgodnij, czy ma zostać wykluczony, uwzględniony czy skierowany do wyjaśnienia. Brak oznaczenia nie jest automatycznie dowodem, że sprawa jest rzeczywista albo testowa. Zapisana reguła pozwoli ocenić wynik także wtedy, gdy baza zawiera mniej staranne dane niż przykład demonstracyjny.
Przejrzyj również listę identyfikatorów składających się na wynik. Ta sama suma może ukryć dwa błędy, które akurat się równoważą: jedną pominiętą sprawę i jedną policzoną podwójnie. Dopiero sprawdzenie członków zbioru pozwala to zobaczyć. Przy odbiorze małego przykładu masz tę przewagę, że każdy rekord da się wyjaśnić.
Poproś wykonawcę o pokazanie etapów, jeśli wynik nadal się nie zgadza. Lista spraw przed złączeniem, lista po złączeniu i lista po filtrze ujawniają miejsce rozbieżności szybciej niż kolejny rozbudowany komentarz AI. Nie trzeba każdemu odbiorcy pokazywać całej składni. Trzeba umożliwić osobie sprawdzającej ustalenie, skąd wzięły się konkretne sprawy.
Liczba potrzebuje opisu także po kontroli
Po zaakceptowaniu zapytania zachowaj jego wersję, definicję sprawy, zakres danych i oczekiwane wyniki prób. Zapisz też, na jakiej kopii danych je sprawdzano i z którego momentu pochodziła. Jeśli między kontrolą a porównaniem do raportu dopisano nowe sprawy, różnica liczb sama nie dowodzi błędu zapytania. Obie odpowiedzi trzeba najpierw odnieść do tego samego zbioru.
Jeśli później zmieni się model bazy albo sposób oznaczania testowych zgłoszeń, ktoś powinien wiedzieć, które założenie ponownie sprawdzić. Nie wystarczy zostawić w notatce „SQL sprawdzony”, bez wskazania, do czego odnosi się ta ocena.
Oddziel wynik zapytania od objaśnienia dopisanego przez model. Gdy tabela zawiera trzy sprawy, a podsumowanie mówi o czterech klientach, kontrola SQL nie zatwierdza tego zdania. Zmieniła się jednostka. To ten sam rodzaj rozbieżności co poprawna struktura danych JSON ze złym znaczeniem: technicznie przyjęty wynik może opisywać coś innego niż uzgodniono.
Nazwa wskaźnika powinna zachować definicję. „Sprawy utworzone w październiku” jest dokładniejsze niż „aktywność serwisu”, jeśli policzono wyłącznie nowe sprawy. Nie rozciągaj wyniku na jakość obsługi, liczbę osób czy obciążenie pracą bez dodatkowych danych. Jeden pomiar nie odpowiada sam na wszystkie pytania kierowniczki.
Uwzględnij czas sprawdzania w ocenie korzyści z narzędzia. Gdy mierzysz pracę z AI, zapisz także doprecyzowanie pytania, poprawki zapytania i kontrolę wyniku. Krótsze pisanie SQL może nadal być przydatne, ale nie powinno wymazywać pracy koniecznej do przyjęcia raportu.
W Aeneia Audit ocena takiego zastosowania dotyczy procesu korzystania z AI i dowodów potrzebnych do jego odbioru. Zależnie od rozwiązania analizę samej bazy trzeba prowadzić z osobą odpowiedzialną za dane. Dobry rezultat tej pracy określa, które analizy zespół może przyjmować po uzgodnionej kontroli, a które nadal wymagają dodatkowego sprawdzenia.
Do raportu z naszego przykładu mogą trafić trzy sprawy wraz z jasnym zakresem. Trzy zdjęcia A pozostają trzema zdjęciami A. Jeśli po dodaniu czwartego nagle wzrośnie liczba zgłoszeń, wracamy do zapytania, zanim kierowniczka zacznie planować dodatkowe stanowisko obsługi.



