← Wszystkie wpisy

Czy warto uczyć się programowania, skoro AI pisze kod

Dwa modele dostały to samo polecenie i oba oddały kod, który się kompiluje. Jeden myli się w 55 przypadkach na 2349 i nie zgłasza żadnego błędu.

Artur Kot 8 min czytania

Szóstego października wpisałem do dwóch modeli Anthropic to samo polecenie: „Napisz metodę w C#, która zwraca średnią ocen ucznia zaokrągloną do jednego miejsca po przecinku. Oceny dostaję jako List<int>”. Mniejszy model, Claude Haiku 4.5, oddał to:

public double ObliczSrednia(List<int> oceny)
{
    if (oceny.Count == 0)
        return 0;

    return Math.Round(oceny.Average(), 1);
}

Kod się kompiluje, jest krótki i wygląda rozsądnie. Większy model, Claude Sonnet, oddał prawie to samo: wyjątek zamiast return 0 i jeden dodatkowy argument w Math.Round.

Jedna z tych metod liczy źle.

Jeśli zastanawiasz się, czy warto uczyć się programowania, skoro taką metodę dostajesz w kilka sekund, to właśnie ten moment rozstrzyga sprawę. Model napisze za Ciebie kod, którego nie umiesz przeczytać. To dług, a nie oszczędność, i spłacasz go przy pierwszym błędzie, w dodatku z odsetkami, bo błąd zwykle znajdzie ktoś inny.

Co rozstrzyga, czy kod z modelu cokolwiek Ci oszczędza

Umiejętności modelu tu nie wystarczą, bo oba umieją programować. Rozstrzyga to, czy patrząc na dwie odpowiedzi, potrafisz wskazać tę poprawną, zanim uruchomisz program na prawdziwych danych.

Pisanie kodu przestało być wąskim gardłem. Czytanie nim zostało, i to bardziej niż przed modelami, bo kodu do przeczytania jest teraz dużo więcej, a jego autor nie wie, czego od niego oczekujesz.

Pisząc metodę samodzielnie, każdą wartość domyślną wybierasz świadomie, nawet jeśli wybierasz źle. Wiesz, że nie pomyślałeś o pustej liście, bo nikt inny o niej nie myślał. W kodzie z modelu tej wiedzy nie masz. Decyzje zostały podjęte, tylko nie przez Ciebie, i nie widać ich w tekście, bo wartości domyślnej nikt nie wpisuje.

Różnica między obiema metodami to jeden argument: MidpointRounding.AwayFromZero. Bez niego .NET zaokrągla wartość leżącą w połowie do najbliższej cyfry parzystej. To tak zwane zaokrąglanie bankierskie i jest domyślne w Math.Round.

Ile razy metoda z Haiku myli się po cichu

Sprawdziłem obie metody na wszystkich możliwych sumach ocen w skali od 1 do 6, dla uczniów mających od dwóch do trzydziestu ocen. Wynik każdej porównałem z dokładnym rachunkiem na typie decimal. Wersja z Sonnetem zgodziła się we wszystkich 2349 przypadkach.

Wersja z Haiku pomyliła się w 55:

4 grades sum 5: got 1.2
4 grades sum 9: got 2.2
4 grades sum 13: got 3.2
4 grades sum 17: got 4.2
4 grades sum 21: got 5.2
55 of 2349 wrong

Uczeń z ocenami 5, 4, 4 i 4 ma średnią 4,25. Zaokrąglenie, którego uczy się w szkole, daje 4,3, a metoda zwraca 4,2, bo dwójka jest parzysta. Żaden wyjątek, żadne ostrzeżenie kompilatora, nic w konsoli.

Przy czterech ocenach myli się w pięciu sumach na dwadzieścia jeden możliwych.

Składniowo wszystko jest w porządku. Haiku dostał polecenie, które nie mówiło, jak zaokrąglać połówki, i wypełnił tę lukę wartością domyślną, nie wspominając o tym ani słowem. Tę samą lukę Sonnet zauważył i opisał w odpowiedzi. Ty, nie czytając kodu, nie wiesz, który z nich trafił Ci się dzisiaj.

Zero, które nie jest oceną

Drugi problem jest gorszy, bo przesuwa wynik o więcej niż jedną dziesiątą. W październiku chemia często nie ma jeszcze żadnej oceny. Zbudowałem mały dziennik z trzema przedmiotami i policzyłem średnią ze średnich. Średnie przedmiotów liczyła metoda z Haiku:

5 | 4.5 | 0
3.17

Matematyka ma średnią 5, fizyka 4,5, a uczeń dostaje 3,17. Poprawny wynik, z pominięciem przedmiotu bez ocen, to 4,75.

Zero nie jest oceną w skali od 1 do 6, ale jest poprawną wartością typu double, więc program przyjmuje je bez słowa. Kto potrafi przeczytać return 0, widzi problem w pierwszej linii metody. Kto nie potrafi, zobaczy go dopiero wtedy, gdy rodzic zapyta, skąd trójka.

W opisie pod kodem Haiku wymienił sprawdzanie pustej listy jako zaletę metody. Opis jest prawdziwy, bo sprawdzanie tam jest. Nie mówi tylko, jaką wartość metoda wtedy zwraca ani co się z nią stanie dwie linie dalej.

Komunikat, którego nie naprawi kolejny prompt

Wersja z Sonnetem zachowuje się uczciwiej i na tym samym dzienniku zatrzymuje program. W programie testowym obie metody umieściłem w klasach nazwanych od modeli, a ścieżki plików skróciłem:

matematyka: 5
fizyka: 4.5
Unhandled exception. System.ArgumentException: Lista ocen nie może być pusta. (Parameter 'oceny')
   at Sonnet.ObliczSrednia(List`1 oceny) in Program.cs:line 34
   at Program.<Main>$(String[] args) in Program.cs:line 17

Komunikat jest czytelny, a mimo to sam nie mówi, co zrobić. Wyjątek nie oznacza błędu w metodzie. To zabezpieczenie, które zadziałało zgodnie z planem, a błąd znajduje się w linii 17, w kodzie, który ją wywołał. Ten sam sposób czytania stosu wywołań opisałem przy NullReferenceException, które wskazuje nie tę linię, co trzeba.

Zrobiłem to, co robi większość początkujących. Wkleiłem ten stos wywołań do obu modeli z poleceniem „Program się wysypuje, napraw to”.

Żaden niczego nie naprawił. Oba poprawnie wskazały linię 17 i oba odpowiedziały listą możliwości do wyboru. Sonnet zapytał wprost, co ma się dziać, gdy ocen brakuje, i poprosił o resztę pliku. Haiku podał trzy warianty, a drugi z nich brzmiał tak:

if (oceny == null || oceny.Count == 0)
    return 0; // lub double.NaN

To ten sam błąd, od którego zaczęliśmy. Wybierając z tej listy bez czytania kodu, masz realną szansę wrócić do średniej 3,17 i uznać problem za rozwiązany, bo wyjątek zniknął.

Decyzji, czy przedmiot bez ocen pominąć, czy wypisać „brak ocen”, żaden model nie podejmie za Ciebie, bo zależy ona od tego, jak działa szkoła, a nie od C#.

Trzy pytania do każdej wygenerowanej metody

Czytanie kodu z modelu nie wymaga, żebyś umiał napisać go od zera. Wymaga, żebyś wiedział, gdzie patrzeć. W tej metodzie wystarczą trzy pytania i każde łapie jeden z opisanych błędów.

Co się dzieje, gdy dane są puste? Pierwsza linia metody z Haiku odpowiada: zwraca zero. Żeby uznać to za błąd, musisz wiedzieć, że w dzienniku zero nie oznacza braku oceny, tylko ocenę, a Average() wywołane na średnich potraktuje je jak każdą inną liczbę.

Na jakiej wartości domyślnej opiera się kod? Math.Round z dwoma argumentami ma trzeci, niewidoczny: sposób zaokrąglania połówek. W kodzie go nie ma, bo nikt go nie podał, i dlatego trzeba wiedzieć, że istnieje. Podobnie jest z kulturą formatowania liczb. Komputer, na którym to uruchamiałem, ma ustawioną kulturę en-US i wypisuje 4.2 z kropką, a ta sama linia przy kulturze pl-PL wypisze 4,2.

Jaka wartość może wyjść, choć nie powinna? Typ double przyjmie 0, liczbę ujemną i NaN. Skala ocen dopuszcza wartości od 1 do 6. W tej różnicy między tym, co dopuszcza typ, a tym, co dopuszcza dziedzina, model zgaduje najczęściej.

Żadne z tych pytań nie wymaga znajomości wzorców projektowych. Wymaga przeczytania każdej linii i wiedzy, co robi każde wywołanie. Tej wiedzy nabiera się, pisząc podobne metody samodzielnie, zanim zacznie się je zamawiać.

Co AI robi dobrze, a gdzie się rozjeżdża

Działało sporo. Większy model napisał poprawną metodę i sam wyjaśnił, dlaczego dodaje AwayFromZero. Drugie polecenie dotyczyło podziału rachunku między kilka osób z dokładnością do grosza i oba modele odpowiedziały poprawnie: liczyły w groszach, a resztę rozdzielały po jednym groszu. Dla kwoty 100 na trzy osoby metoda Sonneta zwraca 33,34, 33,33 i 33,33, razem równo 100. Naiwne zaokrąglenie każdej części daje razem 99,99. Obie wersje uruchomiłem.

Rozjeżdża się tam, gdzie polecenie zostawia lukę, a kod kompiluje się przy każdym jej wypełnieniu. Zaokrąglanie połówek, pusta lista, strefa czasowa, kultura formatowania liczb. Model wybiera wartość domyślną i zwykle o tym nie mówi.

Odwrotnie jest z pytaniami, które mają jedną odpowiedź w dokumentacji. Sonnet bez pytania wyjaśnił, że .NET domyślnie zaokrągla 2,25 do 2,2, i miał rację. Na etapie nauki to jest najlepsze zastosowanie modelu: piszesz metodę sam, a gdy wynik Cię zaskoczy, pytasz, dlaczego Math.Round zachowuje się tak, a nie inaczej. Wyjaśnienie daje model, a Ty zostajesz z kodem, który rozumiesz, i z regułą, której następnym razem nie przeoczysz.

Frustracja dotyczy nie tylko początkujących. W ankiecie Stack Overflow Developer Survey 2025 66% programistów wskazało jako największą frustrację rozwiązania z AI, które są „prawie dobre, ale nie do końca”, a więcej z nich nie ufa trafności tych narzędzi (46%), niż ufa (33%).

Badanie organizacji METR opublikowane 10 lipca 2025 jest jeszcze mniej wygodne. Szesnastu doświadczonych programistów open source rozwiązywało zadania we własnych repozytoriach, raz z narzędziami AI, raz bez nich. Z AI pracowali o 19% wolniej, a po wszystkim nadal oceniali, że AI przyspieszyło ich o 20% (opis badania). Autorzy zastrzegają, że to wąska próba i nie da się z niej wyciągać wniosków o wszystkich programistach. Wniosek, który z niej wynika na pewno, jest skromniejszy: nawet doświadczeni ludzie źle oceniają, ile oszczędzają.

Pięć argumentów za nauką programowania mimo AI zebrałem w sekcji o AI na stronie głównej. Pomiar z dziennika ocen dotyczy drugiego z nich: wygenerowany kod się psuje, a ratuje Cię tylko rozumienie.

Komu nie warto uczyć się programowania

Jeśli potrzebujesz skryptu, który raz zmieni nazwy zdjęć w folderze albo przerobi jeden plik CSV dla Ciebie samego, model wystarczy. Wynik sprawdzisz wzrokiem, pomyłka kosztuje Cię minutę, a kod potem wyrzucasz.

Szkoda też czasu, jeśli liczysz na to, że AI skróci naukę. Pomoże Ci szybciej znaleźć wytłumaczenie, ale model w głowie budujesz, pisząc i czytając kod samodzielnie, a tego etapu nie przyspieszy żadne narzędzie.

Pozostali to ci, którzy chcą, żeby ktoś im za kod płacił. Wtedy odpowiadasz za średnią 3,17 przed kimś, kto nie wie, że kod pisał model, i pytanie, czy warto uczyć się programowania, ma prostą odpowiedź: tak, i zaczynasz od czytania. Ile godzin w tygodniu realnie masz na naukę, pomoże policzyć plan przebranżowienia dopasowany do prawdziwego tygodnia.

Tematy: AI w programowaniuNauka programowaniaKariera

Pobieranie ruszyło

DevJourney_2.1.1_x64-setup.exe · 2.1.1

Jeśli system ostrzeże i jak sprawdzić plik

Jeśli Windows ostrzeże

Komunikat „System Windows ochronił Twój komputer” nie oznacza wykrycia wirusa. SmartScreen ufa certyfikatowi, którym podpisany jest instalator, a ten jeszcze zbiera reputację poprzez licznik pobrań.

W oknie ostrzeżenia: Więcej informacji → Uruchom mimo to.

Sprawdź to sam

Zobacz wynik skanowania w VirusTotal ↗

Albo w PowerShellu, w katalogu z pobranym plikiem:

Get-FileHash .\DevJourney_2.1.1_x64-setup.exe

Powinno wypisać:

2e441de05e02ae32caad96bdca86f9ca0ff59e01cbc8b289a1f6f783e4f7bc46