Liderzy opinii

Przyszłość budowy aplikacji AI zależy od bezpieczeństwa typów

mm
Dodaj Unite.AI do preferowanych źródeł w Google

Kod wygenerowany przez AI może się skompilować, ale bez surowego bezpieczeństwa typów ten sukces jest niezwykle krótkotrwały. Bezpieczeństwo typów jest barierą, która powstrzymuje kruchy kod przed rozkładaniem się na ukryte błędy i awarie czasu wykonywania wraz ze skalowaniem systemu.

Musimy zacząć wymuszać na AI surowe typowanie przez kontekst, instrukcje, linting i pętle sprzężenia zwrotnego. To zajmuje kilka dodatkowych godzin, ale wytwarza kod, który trwa.

Problem zachęt

AI chce cię zadowolić. Optymalizuje funkcję nagrody, którą otrzymuje, a większość czasu jest to po prostu “czy się skompiluje?”. To oznacza, że będzie ciąć każdy zakręt niezbędny, aby dostać się do zielonej ticka. Te skróty wyglądają dobrze w czasie kompilacji, ale zapadają się w czasie wykonywania.

To dlatego AI kocha dowolny. Albo wybiera szeroki typ, taki jak ciąg, gdzie coś bardziej ścisłego, takiego jak UUID, jest oczekiwane. Kod się skompiluje, ale poprawność jest już naruszona. Co gorsza, AI nie pamięta, co napisało kilka plików temu, więc bez bezpieczeństwa typów projekt szybko zapada się pod własnym ciężarem wraz ze wzrostem złożoności.

Dwa rodzaje błędów

Gdy kod wygenerowany przez AI działa, zwykle widzisz dwa rodzaje problemów z bezpieczeństwem typów:

1. Błędy czasu kompilacji

  • Co się dzieje: Kompilator wyłapuje niezgodność między deklarowanym typem a tym, co zostało przekazane.
  • Jak to naprawia człowiek: Decyduje, czy wywołujący jest niepoprawny (przekonwertuj 42 na ciąg) czy sygnatura funkcji jest niepoprawna (zmień ją, aby zaakceptować typ liczba).
  • Jak to “naprawia” AI: Zmień typ argumentu na dowolny. Problem “rozwiązany”, ale właśnie usunąłeś barierę, która powstrzymywałaby przyszłe błędy.

2. Błędy czasu wykonywania

  • Co się dzieje: Kompilator uważa, że wszystko jest w porządku (często dlatego, że typy zostały poluzowane), ale rzeczywista wartość w czasie wykonywania nie odpowiada założeniu.
  • Jak to naprawia człowiek: Śledzi zmienną do jej źródła (jak API lub zapytanie do bazy danych) i naprawia typ na granicy, aby dane przychodziły jako poprawny ciąg.
  • Jak to “naprawia” AI: Bez kontekstu, zgaduje. Może otoczyć wszystko w String(…) lub po prostu poszerzyć typ ponownie. Awaria znika w tym miejscu, ale teraz logika jest złamana. Liczby przeznaczone do matematyki stają się nagle ciągami.

Ten cykl błędów czasu wykonywania → “naprawy” AI → luźniejsze typowanie szybko się kumuluje. Wynikiem jest kod, który się skompiluje i rzadziej wyrzuca błędy czasu wykonywania, ale nie można mu ufać. Wyobraź sobie system planowania wizyt lekarskich, w którym zmiany lekarzy są zarządzane przez aplikację. Wprowadzony zostaje błąd typowy: int dla godzin jest traktowany jako ciąg. AI “naprawia” to, luzując typ na dowolny. Kod się skompiluje i błąd zniknie, ale obliczenia zmian pękają, podwajając lekarzy i pozostawiając całe skrzydło szpitala bez obsługi.

Mnożnik bazy danych

W momencie, gdy połączysz się z bazą danych, błędy się mnożą i ich przyczyny stają się trudniejsze do śledzenia. SQL jest typowany z powodu.
Każdy schemat (INT, TEXT, UUID, BOOLEAN) zakodowuje założenia dotyczące Twoich danych.

Gdy AI spłaszcza wszystko do ciąg | dowolny, tracisz te gwarancje:

  • Błędne zapisy: wstawienie “true” do pola logicznego skompiluje się, ale skazi bazy danych.
  • Błędne odczyty: zapytanie zwraca NULL, ale AI założył ciąg, prowadząc do awarii czasu wykonywania.
  • Popisane relacje: jeśli klucz relacji jest oczekiwany jako UUID, ale AI traktuje go jako ciąg i mylnie wysyła wartości śmieci, dołączenia nie spowodują awarii, ale nie zwrócą danych. To ukrywa błędy, aż nie pojawią się później jako brakujące lub niespójne wyniki..

To dlatego poważne zespoły używają języków typowanych i egzekwują bezpieczeństwo typów od schematu do API. Jeśli nie, baza danych przestaje cię chronić i ukryte problemy się kumulują.

Dlaczego dojrzałe zespoły egzekwują surowe typowanie

Surowe typowanie nie jest sprawą spowalniania deweloperów. Chodzi o to, aby skalowanie było możliwe.

Typy:

  • Zakodują intencję w kodzie.
  • Ubezpieczają refaktoryzacje i sprawiają, że są przewidywalne.
  • Wyłapują całe klasy błędów, zanim trafią do produkcji.
  • Pokazują przyszłym deweloperom (i AI) dokładnie, jak używać funkcji lub obiektu.

Bez bezpieczeństwa typów, niedbałość kodu AI się kumuluje. Z nim, ten sam AI wytwarza kod, któremu można ufać i rozbudowywać.

Jak wymuszać na AI bezpieczeństwo typów

Musisz traktować AI jak juniora inżyniera. Szybkiego, utalentowanego, ale bezdbałego bez kierunku.

Podaj odpowiedni kontekst

Daj mu interfejsy i typy, których może użyć. Pokaż przykłady użycia. Bądź stanowczy co do słusznego sposobu strukturyzacji kodu.

Podaj surowe instrukcje

Bardzo wyraźnie powiedz AI, aby nie używał dowolnego, nigdy nie pozwalał nieznanemu i aby każda metoda, obiekt i zmienna były typowane. Oczekuj, że będzie miał trudności z tymi instrukcjami (szczególnie w pierwszym przejściu).

Egzekwuj za pomocą lintingu

Tak jak przy przeglądaniu kodu juniora inżyniera, musisz sprawdzić kod AI. Zaprojektuj niestandardowe reguły lintingu, które definiują, co “dobry kod” oznacza dla ciebie. Wróć niepowodzenia lintingu do modelu, aż przejdzie. Może to potrwać kilka rund, ale przesuwa funkcję nagrody w kierunku uwzględniania bezpieczeństwa typów.

Iteruj z kontrolami

Błędy czasu kompilacji, rejestrowanie czasu wykonywania, testy kliknięć. Każda iteracja zmusza AI do zacieśniania typów i zbliżania się do kodu o jakości produkcyjnej.

Lepszy sposób budowania

Nauczyłem się, że poświęcanie surowej szybkości generacji na rzecz wyższej jakości się opłaca w dłuższej perspektywie. To oznacza walkę o zero tolerancji dla typów dowolnych, egzekwowanie wielu pętli sprzężenia zwrotnego i surowych reguł lintingu, których AI musi spełnić, zanim nazwie kod “gotowym”. To wymaga stałego wysiłku, ale jest to jedyny sposób, aby utrzymać jakość od spadku.

Wcześniej wspomniałem o kluczowym punkcie: jak tylko AI zacznie łatać błędy czasu wykonywania, luzując typy, wkraczasz w złe koło. Każda “naprawa” odbiera kolejną barierę, a wynik kumuluje się w kodzie, który się skompiluje, ale jest kruchy i nieutrzymany. Odwrotnie jest również prawdziwe: jeśli wymusisz na AI poszanowanie bezpieczeństwa typów w każdym przejściu, tworzysz dobre koło. Każda iteracja zacieśnia bariery, kod staje się czystszy, a jakość kumuluje się w coś, czemu można ufać i budować.

To jest system, w który wierzę, że dostarcza trwałą jakość kodu. Każda iteracja jest zaprojektowana, aby zacieśniać standardy, a nie osłabiać ich. To ten sam powód, dla którego najlepsze zespoły inżynierskie wybierają języki silnie typowane. Bezpieczeństwo typów jest podstawową barierą dla utrzymania, a pozwalanie AI ignorować je gwarantuje, że Twoja aplikacja nigdy nie osiągnie jakości produkcyjnej.

Brad Eckert jest całkowitym przedsiębiorcą i liderem inżynieryjnym z ponad dekadą doświadczenia w przygotowywaniu produktów od etapu pomysłu przez dostawę do klienta i dalej. Jako absolwent MIT, jest teraz współzałożycielem i dyrektorem technicznym Woz, platformy AI wspieranej przez Y Combinator, która umożliwia każdemu budowanie i skalowanie biznesów oprogramowania bez konieczności posiadania umiejętności programistycznych.