Żeby dostać od AI przydatne wyjaśnienie kodu, powiedz, ile już wiesz, poproś o wyjaśnienie linia po linii i poproś o śledzenie: tabelę wartości, które każda zmienna przyjmuje podczas działania kodu. Samo "wyjaśnij ten kod" daje streszczenie napisane dla wyimaginowanego przeciętnego czytelnika, zwykle albo zbyt podstawowe, albo zbyt szybkie dla ciebie.
Linia po linii, ze śledzeniem wartości
Obie zakładki pytają o tę samą krótką funkcję. Porównaj, co każda odpowiedź pozwala ci sprawdzić.
def running_max(nums):
result = []
best = None
for n in nums:
if best is None or n > best:
best = n
result.append(best)
return result
print(running_max([3, 1, 4, 1, 5]))Ta funkcja oblicza bieżące maksimum listy. Przechodzi po liczbach w pętli, w best przechowuje największą dotąd widzianą wartość i na każdym kroku dopisuje tę wartość do result. Sprawdzenie best is None obsługuje pierwszy element. Wywołanie wypisuje [3, 3, 4, 4, 5].
Funkcja działa w czasie O(n), bo odwiedza każdy element raz.
Pierwsza odpowiedź jest trafna, ale pomaga tylko wtedy, gdy już wiesz, czym jest bieżące maksimum. Dodaje też uwagę o złożoności czasowej, o którą nikt nie prosił, czyli dodatek typowy dla sytuacji, gdy model nie wie, kto czyta. Druga odpowiedź wiąże każde zdanie z linią, którą da się wskazać, a tabela konkretnie pokazuje to, co streszczenie tylko wspomina mimochodem: result.append(best) wykonuje się przy każdym przejściu, także wtedy, gdy best się nie zmienia. Dlatego 3 pojawia się dwa razy, i widać to w wierszu 2, bez wnioskowania z samego "na każdym kroku".
Tabela śledzenia sprawdza też samo wyjaśnienie. Każdy wiersz możesz zweryfikować, uruchamiając kod z print(n, best, result) w pętli. Jeśli jakiś wiersz nie zgadza się z prawdziwym wynikiem, wyjaśnienie gdzieś jest błędne, a teraz wiesz gdzie.
Wyjaśnienie na twoim poziomie
Najbardziej przydatna pojedyncza linia w prompcie z prośbą o wyjaśnienie to informacja o tym, co już wiesz. Mówi modelowi, które linie pominąć, a przy których zwolnić. Zdanie z rolą też może pomóc ("Jesteś nauczycielem dla osób w pierwszym miesiącu nauki programowania"), ale działa przez ten sam mechanizm: mówi modelowi, kim jest czytelnik. Co rola zmienia, a czego nie, opisuje role prompting.
Ten blok to wersja wielokrotnego użytku. Zmień poziom, niejasną część albo kod, a wyjaśnienie zmieni się razem z nimi.
text = "the cat and the hat"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
top = sorted(counts.items(), key=lambda kv: kv[1], reverse=True)[:2]
print(top)Pętla liczy każde słowo: counts na końcu wygląda tak: {'the': 2, 'cat': 1, 'and': 1, 'hat': 1}.
Teraz ostatnie dwie linie, od środka na zewnątrz:
counts.items()daje pary('the', 2),('cat', 1),('and', 1),('hat', 1).lambda kv: kv[1]to malutka funkcja bez nazwy. Przyjmuje jedną parę i zwraca jej drugi element, czyli liczbę wystąpień. Dla('the', 2)zwraca2.sorted(..., key=...)sortuje pary według tego, co zwraca ta funkcja, czyli według liczby wystąpień.reverse=Truestawia największe na początku. Słowa o równej liczbie wystąpień zachowują pierwotną kolejność.[:2]zostawia dwie pierwsze pary.
Zatem top to [('the', 2), ('cat', 1)] i to właśnie zostaje wypisane.
"Słowa o równej liczbie wystąpień zachowują pierwotną kolejność" to szczegół, który pomija szybkie wyjaśnienie, a to dzięki niemu cat zajmuje drugie miejsce, a nie and czy hat. sorted w Pythonie jest stabilne, a reverse=True tę stabilność zachowuje. Trudno wpaść na pomysł, żeby o to zapytać, a na wierzch wydobyła to właśnie prośba o "wartość, jaką każdy kawałek daje dla tego wejścia".
Pytaj o jedną część, a nie o cały plik
Wklejenie pliku z 500 liniami i pytanie "co to robi" daje wycieczkę po strukturze pliku. Gdy utkniesz na jednej funkcji, wklej tę funkcję i linie, które ją wywołują, i zapytaj o nią wprost: "Dlaczego ta funkcja kończy działanie wcześniej, gdy lista jest pusta?" albo "Co robi yield w linii 12 i co by się zmieniło, gdyby było tam return?" Wąskie pytanie daje odpowiedź o twoim kodzie; szerokie daje odpowiedź o kodzie podobnym do twojego.
Przy dużej nieznanej bazie kodu odwróć kolejność: najpierw poproś o mapę ("wypisz główne moduły i to, za co odpowiada każdy z nich, po jednej linii"), a potem zapytaj o potrzebny moduł. To mały łańcuch promptów, a każdy krok utrzymuje odpowiedź modelu na tyle krótką, że da się ją sprawdzić.
Wyjaśnienie przez znany ci język
Kod w nieznanym języku łatwiej czytać, gdy wyjaśnienie jest zakotwiczone w języku, który znasz. Powiedz to w prompcie: "Znam Pythona. Wyjaśnij tę funkcję w Go i wskaż każde miejsce, w którym zachowuje się inaczej, niż spodziewałby się programista Pythona." To w różnicach kryją się nieporozumienia: dzielenie całkowite, wartości zerowe zamiast None, slice, który dzieli pamięć z tablicą, z której powstał. Zwykłe wyjaśnienie kodu w Go opisałoby te linie poprawnie i nigdy nie powiedziałoby ci, że twoje intuicje co do nich są błędne.
Sprawdź, czy rozumiesz
Wyjaśnienie, które czytasz i z którym się zgadzasz, wcale nie musi sprawić, że sam napiszesz ten kod. Tę lukę zamykają dwa prompty:
- Najpierw przewiduj. Zanim uruchomisz kod albo poprosisz o wyjaśnienie, zapisz, co według ciebie wypisze. Potem poproś model o wyjaśnienie tylko tych linii, przy których przewidywanie było błędne.
- Wyjaśnij to z powrotem. Napisz własne wyjaśnienie i poproś model, żeby wskazał wszystko, co jest błędne albo czego brakuje, bez przepisywania go.
def running_max(nums):
result = []
best = None
for n in nums:
if best is None or n > best:
best = n
result.append(best)
return result
Zadaj mi 3 pytania, które sprawdzą, czy naprawdę go rozumiem, po jednym naraz. Dołącz jedno pytanie, w którym muszę przewidzieć wynik dla nowego wejścia. Czekaj na moją odpowiedź, zanim zadasz następne pytanie, i powiedz, czy moja odpowiedź jest poprawna i dlaczego.Pytanie 1 z 3: co zwraca running_max([2, 7, 5, 9])? Oblicz to, zanim uruchomisz kod.
To samo podejście działa, gdy program działa źle, ale wtedy chcesz poznać przyczynę, a nie dostać lekcję: zobacz prompty do debugowania. Gdy kod przed tobą napisała AI, wyjaśnienie linia po linii to szybki sposób, żeby go przejrzeć, zanim go zatrzymasz; pozostałe sprawdzenia wymieniają prompty do pisania kodu.
Najczęściej zadawane pytania
Jak poprosić ChatGPT albo Claude'a o wyjaśnienie kodu?
Wklej kod i powiedz trzy rzeczy: co już wiesz, która część cię myli i w jakiej formie chcesz wyjaśnienia. "Wyjaśnij każdą linię jednym zdaniem, a potem pokaż tabelę zmiennych po każdym przejściu pętli" daje znacznie bardziej przydatną odpowiedź niż "wyjaśnij ten kod".
Czym jest tabela śledzenia?
Tabela śledzenia (trace table) podąża za programem podczas jego działania: jeden wiersz na krok (często jedno przejście pętli), jedna kolumna na zmienną i wartość każdej zmiennej w tym momencie. Prośba o nią zamienia abstrakcyjny opis w konkretne wartości, które można porównać z kodem. To zapisany ślad tego, co pokazuje debugger, gdy przechodzisz przez program krok po kroku.
Czy AI może wyjaśnić kod w języku, którego nie znam?
Tak, i to jedna z najbardziej przydatnych próśb. Nazwij język, który znasz, i poproś model o porównanie: "Znam Pythona; wyjaśnij ten kod w Ruście i wskaż, gdzie zachowuje się inaczej niż Python." Twierdzenia o zachowaniu języka sprawdzaj, uruchamiając małe przykłady, bo wyjaśnienia potrafią być pewne siebie i błędne w szczegółach.
Czy wyjaśnianie kodu przez AI szkodzi nauce?
Zależy od tego, co robisz potem. Przeczytanie wyjaśnienia i pójście dalej uczy niewiele. Przewidywanie wyniku przed uruchomieniem kodu, prośba, żeby model cię odpytał, albo własne wyjaśnienie kodu i pytanie, co jest w nim błędne, zmuszają cię do myślenia, a to właśnie wtedy zachodzi nauka.