Dobry prompt do kodu opisuje cztery rzeczy: co ma robić funkcja (cel), w jakim środowisku działa (kontekst), czego nie wolno (ograniczenia) i jak sprawdzić wynik (przykłady wejścia i wyjścia albo gotowy test). Najmocniejszym elementem jest to ostatnie: test, który możesz uruchomić, mówi więcej niż pięć akapitów opisu i od razu pokazuje, czy AI trafiło.
Większość słabych odpowiedzi AI w programowaniu nie wynika z tego, że model jest słaby. Wynika z tego, że zadanie zostało opisane jednym zdaniem, a prawdziwe wymagania siedzą w głowie autora. Ten artykuł pokazuje, jak zamienić te wymagania w prompt, który da się sprawdzić.
Dotyczy pojedynczego zadania w jednej rozmowie. Stałe reguły dla agenta (styl kodu, komendy, struktura projektu) opisuje osobny artykuł o pliku AGENTS.md i CLAUDE.md, a cały proces ze specyfikacją przed kodem spec-driven development. Jeśli dopiero poznajesz ten styl pracy, zacznij od artykułu co to jest vibe coding, czyli programowania przez opisywanie zadań AI.
Z czego składa się dobry prompt do kodu?
Pięć elementów. Nie każde zadanie potrzebuje wszystkich, ale każdy brak to miejsce, w którym AI zgaduje.
| Element | Pytanie, na które odpowiada | Przykład |
|---|---|---|
| Cel | Co dokładnie ma robić kod? | „Funkcja zamienia cenę zapisaną tekstem na liczbę groszy” |
| Kontekst | Gdzie to będzie działać? | „Python 3.13, bez zewnętrznych bibliotek, dane z formularza” |
| Ograniczenia | Czego nie wolno albo co jest ważne? | „Bez float (błędy zaokrągleń), cena ujemna to błąd” |
| Przykłady | Jak wyglądają dane wejściowe i wyniki? | „'12,99 zł' → 1299, 'abc' → ValueError” |
| Kryterium sprawdzenia | Skąd wiem, że działa? | „Oto testy w pytest, wszystkie muszą przechodzić” |
Ostatni wiersz jest najważniejszy i najczęściej pomijany. Do niego wracamy niżej.
Jak wygląda zły prompt, a jak dobry?
Zadanie: aplikacja pobiera ceny z formularza i trzeba je zapisać w bazie jako grosze.
Zły prompt:
Napisz funkcję w Pythonie, która parsuje cenę.
Co tu jest niewiadome? Format wejścia (przecinek czy kropka, „zł” czy bez?), typ wyniku (float, Decimal, grosze?), co zrobić ze złym tekstem, czy dopuszczać wartości ujemne. AI wybierze za Ciebie, a Ty dowiesz się o tym, gdy cena w sklepie będzie się różnić o grosz.
Lepszy prompt:
Napisz funkcję
parse_price(text: str) -> intw Pythonie 3.13, bez zewnętrznych bibliotek. Zamienia cenę z formularza na liczbę groszy.Wejście: polski zapis ceny, z przecinkiem lub kropką jako separatorem, opcjonalnie ze spacjami lub twardą spacją jako separatorem tysięcy i z końcówką „zł”. Przykłady:
'12,99 zł'→1299,'1 299,00 zł'→129900,'1299'→129900,'12.5'→1250.Ograniczenia: bez
float(błędy zaokrągleń). Każde wejście, które nie jest poprawną nieujemną ceną z najwyżej dwoma miejscami po przecinku, ma rzucaćValueError:'abc', pusty tekst,'-5 zł','12,999'.Zwróć sam kod funkcji i krótko wypisz założenia, które przyjąłeś.
Zwróć uwagę na ostatnie zdanie. Prosimy AI o jawne założenia, bo wtedy luki w opisie widać od razu, a nie po tygodniu w produkcji.
Dlaczego test jest lepszym kryterium niż opis słowny?
Bo opis słowny można zrozumieć na dwa sposoby, a test nie. Najlepszy prompt kończy się tym, co możesz uruchomić. Oto testy w pytest dla naszej funkcji (to samo możesz wkleić do prompta):
import pytest
from prices import parse_price
@pytest.mark.parametrize(
"text, expected",
[
("12,99 zł", 1299),
("1 299,00 zł", 129900),
("1 299,00 zł", 129900),
("1299", 129900),
("12.5", 1250),
("0,99", 99),
("19,99 zł", 1999),
],
)
def test_valid_prices(text, expected):
assert parse_price(text) == expected
@pytest.mark.parametrize("text", ["abc", "", "-5 zł", "12,999", "12,5,3"])
def test_invalid_prices(text):
with pytest.raises(ValueError):
parse_price(text)
Dlaczego to działa lepiej niż „pamiętaj o przypadkach brzegowych”? Pokażę na przykładzie. Takie rozwiązanie wygląda rozsądnie i większość osób napisałaby je w minutę (to mój kod, nie wynik konkretnego modelu, ale AI często proponuje dokładnie to samo):
def parse_price(text: str) -> int:
return int(float(text.replace("zł", "").replace(",", ".")) * 100)
Uruchomiłem na nim powyższe testy w Pythonie 3.13.7 i pytest 9.2.0. Wynik: 5 niezaliczonych testów, 7 zaliczonych. Najciekawszy błąd:
AssertionError: assert 1998 == 1999
+ where 1998 = parse_price('19,99 zł')
Cena 19,99 zł zamienia się w 1998 groszy, bo 19.99 * 100 w arytmetyce zmiennoprzecinkowej daje liczbę odrobinę mniejszą niż 1999, a int() ucina część ułamkową. W opisie słownym „parsuje cenę” nikt by o tym nie wspomniał. Test wyłapał to w milisekundę. Pozostałe cztery błędy to wejścia ze spacją jako separatorem tysięcy (ValueError) oraz dwa przypadki, w których funkcja powinna odrzucić dane ('-5 zł', '12,999'), a przyjęła je bez słowa.
Poprawna wersja (też mój kod, 12 testów zaliczonych) zamiast float operuje na tekście i liczbach całkowitych:
import re
def parse_price(text: str) -> int:
"""Zamienia cenę zapisaną tekstem na grosze."""
cleaned = text.replace("zł", "").replace(" ", "").replace(" ", "").strip()
if not re.fullmatch(r"\d+([.,]\d{1,2})?", cleaned):
raise ValueError(f"Niepoprawna cena: {text!r}")
zloty, _, grosze = cleaned.replace(",", ".").partition(".")
return int(zloty) * 100 + int(grosze.ljust(2, "0") or 0)
Wniosek praktyczny: nie pytaj AI „czy to działa?”, tylko je uruchom na testach. Jeśli test nie przechodzi, wklej pełny komunikat błędu z powrotem do rozmowy. To dużo skuteczniejsze niż „popraw to”, a jeśli po dwóch próbach nadal nie działa, zamiast prosić o trzecią poprawkę, zdebuguj błąd samodzielnie. Jak pisać takie testy przed implementacją, pokazuje artykuł o TDD i BDD w pytest.
Czy im więcej szczegółów w prompcie, tym lepiej?
Nie zawsze, i to potwierdzają najnowsze badania. Dwie prace z 2026 roku (z abstraktów, pełnych tekstów nie omawiam):
- Akli, Papadakis, Cordy i Le Traon (arXiv:2604.24712, kwiecień 2026) przetestowali dziesięć modeli na zbiorach HumanEval i LiveCodeBench. Zmiany w sformułowaniu zadania mocno szkodziły tam, gdzie opis miał jedną linijkę, a prawie nie miały wpływu przy opisach bogatych: z opisem, ograniczeniami, przykładami i formatem danych. Niektóre zmiany nawet poprawiały wynik, bo usuwały mylące wskazówki.
- Cheng i Mastropaolo (arXiv:2602.15228, luty 2026) sprawdzili 360 konfiguracji. Dodawanie kolejnych szczegółowych ograniczeń do prompta systemowego nie poprawiało wyników w sposób konsekwentny, a przykłady w prompcie (few-shot) bywały gorsze niż ich brak.
Co z tego wynika dla Ciebie? Dwie rzeczy:
- Jednozdaniowy prompt to loteria. Wynik zależy od szczęścia w doborze słów, bo model musi zgadywać resztę. Dopisanie celu, formatu danych i przykładu zmniejsza ten rozrzut.
- Dłuższy nie znaczy lepszy. Kolejne akapity ograniczeń „na wszelki wypadek” mogą sobie przeczyć albo odciągać uwagę od tego, co ważne. Pisz tyle, ile zmienia wynik, i nic ponad to. Jeśli nie wiesz, czy dany akapit pomaga, usuń go i uruchom testy jeszcze raz.
Badania mierzyły generowanie funkcji w benchmarkach, a nie pracę nad prawdziwym projektem, więc traktuj je jako wskazówkę kierunku, a nie twardą regułę.
Jakie są najczęstsze błędy w promptach do kodu?
| Błąd | Skutek | Poprawka |
|---|---|---|
| Brak kryterium sprawdzenia | Wygląda dobrze, nie wiesz, czy działa | Dołącz test albo konkretne przykłady wejścia i wyniku |
| Zadanie za duże („napisz aplikację do…”) | AI podejmuje dziesiątki decyzji za Ciebie | Podziel na funkcje i proś o jedną rzecz naraz |
| Sprzeczne wymagania („krótko, ale z pełną obsługą błędów”) | AI wybiera jedno po cichu | Ustal priorytet: „ważniejsza jest czytelność niż zwięzłość” |
| Brak kontekstu (wersja języka, framework, styl kodu) | Kod z innej wersji albo z biblioteką, której nie używasz | Podaj wersję i listę dozwolonych zależności |
| Wklejony cały projekt „na wszelki wypadek” | Ważny fragment ginie w szumie | Wklej tylko plik i funkcje, których dotyczy zadanie |
| „Popraw to” po błędzie | AI łata objaw, nie przyczynę | Wklej pełny komunikat błędu i dane, które go wywołały |
| Brak prośby o założenia | Luki w opisie wychodzą dopiero w produkcji | Dodaj: „wypisz założenia, które przyjąłeś” |
| Ślepe zaufanie do nazw funkcji i bibliotek | AI wymyśla nieistniejące API | Sprawdź w dokumentacji, zob. halucynacje AI w kodzie |
Co zrobić, gdy AI nadal nie trafia?
Najpierw sprawdź, czy problem leży w prompcie, czy w kodzie:
- Uruchom testy i przeczytaj pierwszy komunikat błędu, nie ostatni.
- Dopisz do prompta brakujące wymaganie, jeśli test wykrył coś, czego opis nie przewidział (jak spacja jako separator tysięcy w naszym przykładzie), a nie samą prośbę „popraw”.
- Zacznij czystą rozmowę, jeśli po dwóch próbach kod się nie poprawia. Długa historia nieudanych poprawek utrudnia modelowi zadanie.
- Przejrzyj wynik jak cudzy kod, zanim go wkleisz do projektu: na co patrzeć w diffie agenta i jakie luki bezpieczeństwa najczęściej wnosi AI.
Jeśli dopiero uczysz się programować z pomocą AI, a nie pracujesz jeszcze nad kodem produkcyjnym, zacznij od artykułu o ChatGPT w nauce programowania. Przegląd narzędzi, w których te prompty wpisujesz, znajdziesz w porównaniu Cursor, Claude Code, Copilot i Codex.
Podsumowanie
- Dobry prompt do kodu ma cel, kontekst, ograniczenia, przykłady i kryterium sprawdzenia.
- Najlepszym kryterium jest test, który uruchamiasz: w naszym przykładzie wyłapał błąd o jeden grosz (1998 zamiast 1999), którego nie widać gołym okiem.
- Więcej szczegółów nie zawsze pomaga: jednozdaniowy prompt to loteria, ale nadmiar sprzecznych ograniczeń też szkodzi.
- Po błędzie wklejaj pełny komunikat i dane, a nie „popraw to”, a po dwóch nieudanych próbach zacznij od nowa albo zdebuguj sam.
- Zawsze proś o jawne założenia, bo wtedy luki w opisie widać od razu.
- Prompt to tylko jeden z elementów vibe codingu. Jego realne ryzyka i sposoby ich ograniczania opisuje artykuł co to jest vibe coding.


