UXAIRFORCE

Jak kodować z AI w 2025? Sprawdzony workflow bez „vibe coding” by Theo #EN353

A

Adam Michalski

5 grudnia 2025

Uwaga: Ten artykuł to moje notatki z prezentacji autora opisującego swój workflow kodowania z AI. Wszystkie przemyślenia, obserwacje i rekomendacje pochodzą bezpośrednio z jego doświadczenia.

TL;DR

  • Planowanie jest fundamentem – zaawansowane modele tworzą plan, tanie wykonują implementację
  • Verification harnesses zmieniają wszystko – dzięki testom, dry run i type checking AI dostaje pętlę informacji zwrotnej
  • Work trees (drzewa robocze) pozwalają eksperymentować – można uruchamiać ten sam task na różnych modelach równolegle
  • Kod jest tani, można go wyrzucać – lepiej zacząć od nowa z poprawionym planem niż naprawiać błędy
  • To nie zastępstwo dla wiedzy – AI automatyzuje rzeczy, które już rozumiesz, nie uczy od zera
  • 20 dolarów miesięcznie wystarczy – mądre wykorzystanie drogich i tanich modeli trzyma koszty w ryzach
  • Lepsze instrukcje dla AI równają się lepszemu zarządzaniu ludźmi – skill komunikacji przenosi się na pracę z zespołem

Kontekst: Dwa lata rewolucji

Od czasu pierwszego materiału o Copilot minęły niemal dwa lata. W tym okresie podejście do kodowania z AI zmieniło się fundamentalnie. Autor dzieli się workflow, który wykształcił podczas intensywnej pracy nad własnymi projektami.

Materiał nie jest tutorialem o „vibe coding”. Od początku pojawia się zastrzeżenie – skierowany jest do osób, które już umieją programować i chcą być bardziej produktywne. Bez podstawowej wiedzy o kodowaniu lepiej najpierw ją zdobyć.

Autor wspomina też o swoich inwestycjach w niektóre z omawianych firm. Lubi tę przestrzeń i wspiera projekty, które uważa za wartościowe. Warto o tym pamiętać, choć materiał nie jest sponsorowany.

1. Fundamenty: Planowanie przede wszystkim

Największa zmiana w podejściu to odkrycie mocy planowania. Sam prompt to za mało. Model klasy premium pisze plan, szybki i tani model go implementuje.

Cały proces wygląda następująco: najpierw powstaje szczegółowy prompt, potem generowany jest plan, następnie plan przechodzi edycję i dopiero wtedy uruchamiana jest implementacja. Gdy coś nie działa, zamiast naprawiać kod należy przeanalizować problem, poprawić plan i uruchomić ponownie.

Kluczowa zasada: Prompt jako maintained artifact

Pojawia się tu fundamentalna zmiana myślenia. Między kolejnymi próbami należy utrzymywać i ulepszać prompt, nie kod. Kod jest tani i można go wyrzucić. Prompt i plan to elementy, które warto rozwijać między iteracjami.

W praktyce wygląda to tak: dla każdego większego zadania autor wykonuje 4-5 prób zanim zaakceptuje wynik i go scali z głównym kodem. Każda nieudana próba dostarcza lekcji, która trafia do ulepszonego promptu.

Preferencje modeli dla planowania

Opus to główny model w codziennej pracy. Jednak autor ma też „soft spot” dla GPT-4 (wersja 5.1) w kontekście planowania. Mimo że Opus jest dobry w wywoływaniu narzędzi, GPT-4 czasem lepiej radzi sobie z samym planowaniem. Warto eksperymentować z różnymi opcjami.

Praktyczny przykład: autodraftify

Demonstracja odbywa się na żywo podczas tworzenia narzędzia do porównywania stylów pisania różnych modeli AI. Projekt działa tak: jeden model pisze esej, drugi daje feedback, pierwszy poprawia na podstawie uwag. Wszystko zapisywane jako markdown.

Zamiast od razu kodować, autor najpierw wypowiada głosowo swoje wymagania, korzystając z Whisper Flow. Dlaczego głos? Bo podczas mówienia pojawia się więcej kontekstu niż przy pisaniu, a czasem w trakcie wypowiedzi przychodzą nowe przemyślenia.

2. Setup projektu: Rób to sam

Zanim w ogóle uruchomione zostanie AI, kilka rzeczy wykonywanych jest ręcznie. To ważna praktyka, którą łatwo przeoczyć.

Inicjalizacja projektu

Pierwszy krok to zawsze samodzielna inicjalizacja projektu. Autor korzysta z narzędzi takich jak create-t3-app, better-tstack, create-next-app czy bun init.

Powód jest prosty – łatwiej jest dać AI dobrze skonfigurowany punkt startowy niż pozwolić mu zgadywać wszystko od zera. Dobre fundamenty to połowa sukcesu.

Kluczowa zasada: Inicjalizacja projektu i konfiguracja środowiska powinny być zawsze wykonywane ręcznie przez człowieka. Agent wchodzi do pracy dopiero na stabilnym, przygotowanym gruncie. To nie podlega dyskusji.

Skrypt setup dla work trees

W katalogu .cursor/ znajduje się przygotowany skrypt setup.sh, który automatycznie uruchamia bun install gdy tworzony jest nowy work tree oraz kopiuje pliki .env z głównego katalogu.

To rozwiązuje problem z tym, że work trees nie kopiują plików z .gitignore. Bez tego każdy nowy work tree wymagałby ręcznej konfiguracji, co byłoby żmudne i czasochłonne.

Konfiguracja workspace w Cursor

Narzędzie bun init jest teraz na tyle inteligentne, że automatycznie dodaje do .cursor/cursor_rules informację o używaniu buna zamiast npm, yarn czy pnpm. Dzięki temu workspace rules pomagają modelom używać właściwych narzędzi od samego początku.

3. Work trees: Równoległa praca z wieloma modelami

Work trees (drzewa robocze) to funkcja git pozwalająca mieć kilka branchy w różnych katalogach jednocześnie. Autor wykorzystuje to do równoległego testowania modeli.

Dla projektu autodraftify uruchamiane są jednocześnie trzy różne modele: Composer, Opus i Gemini 3 Pro. Każdy dostaje ten sam plan, jednak każdy pracuje w swoim katalogu. To pozwala porównać wyniki i wybrać najlepszy.

Composer okazuje się najszybszy – wykonuje zadanie podczas gdy pozostałe są dopiero na początku. Nie jest najmądrzejszy, ale przy dobrym planie wystarcza. Jest za to znacznie szybszy i tańszy.

Konkretne korzyści z work trees:

  • Równoległe testowanie – możesz uruchomić Opus, Composer i Gemini jednocześnie na tym samym zadaniu
  • Izolacja środowiska – każdy eksperyment działa w pełnej separacji, bez ryzyka konfliktów
  • Szybka ocena – natychmiast widać który model poradził sobie najlepiej z konkretnym problemem
  • Zero cleanup – po wyborze najlepszego rozwiązania reszta po prostu znika

Work trees w Cursor

Cursor ma wbudowane wsparcie dla work trees. Autor wspomina, że przekonał team do dodania przycisku „Copy worktree path”. Wcześniej był tylko „Open terminal in worktree”, co otwierało terminal w instancji VS Code/Cursor, a to było irytujące.

Work trees działają też jak warstwa pośrednia między agentem w edytorze a background agentami w chmurze. Agent działa lokalnie, ale równolegle do głównej pracy. Jest to wygodne gdy potrzeba szybko przetestować coś bez zaśmiecania obecnego brancha.

4. Cursor: Tryb edytora vs tryb agenta

Praca odbywa się w dwóch trybach Cursor: widok edytora (Editor view) i tryb agenta (Agent mode) uruchamiany przez Command+E.

Dlaczego tryb agenta?

Tryb agenta sprawdza się świetnie do planowania rzeczy i przeglądania kodu jako rezultatu pracy. Zamiast wciskać interfejs chat w tradycyjny edytor tekstu, cały ekran staje się przestrzenią do pracy z AI.

W trybie agenta cały ekran to przestrzeń do pracy z AI. Z kolei w trybie edytora to tradycyjny edytor z opcjonalnym sidebar’em.

Command+I vs Command+K

To dwa różne tryby interakcji:

  • Command+I otwiera sidebar w edytorze do dłuższych konwersacji
  • Command+K pozwala na inline edits bezpośrednio w kodzie dla szybkich zmian

Zakładka Review

Zakładka Review (przeglądu) to jedna z funkcji, która szczególnie przypadła do gustu. Grupuje wszystkie zmienione pliki w jeden widok, przez który można przewijać. To znacznie ułatwia przegląd tego co AI zmieniło zanim zmiany zostaną zaakceptowane.

5. Verification harnesses: Klucz do lepszych wyników

Tu pojawia się największe odkrycie. Modele działają nieporównywalnie lepiej gdy mają sposób na sprawdzenie, czy coś działa.

Przykład: snitchbench

W portfolio autora znajduje się benchmark, który normalnie działa 6-8 godzin. Początkowo modele próbowały uruchamiać cały projekt i nie dostawały żadnego feedbacku. W rezultacie wyniki były słabe.

Rozwiązanie przyszło w postaci trzech dodatków:

  • Tryb dry run – szybki test na prostszych danych
  • Proste testy matematyczne – zamiast pełnego benchmarku
  • Komenda bun run tsc – sprawdzanie typów TypeScript

Te trzy elementy dramatycznie poprawiły jakość. Model mógł szybko sprawdzić, czy jego kod działa, zobaczyć błędy typów i iterować bez czekania 8 godzin na feedback.

Checklist: Czy Twój projekt jest gotowy na autonomiczne agenty?

  • [ ] Ścisłe typowanie – TypeScript z komendą tsc dostępną w package.json
  • [ ] Skrypt dry-run – szybki test „na sucho” bez pełnego uruchomienia
  • [ ] Testy implementacyjne – małe, szybkie testy kluczowych funkcjonalności
  • [ ] Kontekst z testów bibliotek – dla słabo udokumentowanych zależności, katalog testów jako dokumentacja
  • [ ] Komendy w package.json – wszystkie verification commands łatwo dostępne dla agenta

Bez tego oprzyrządowania agent pracuje w ciemno. Z nim – ma pętlę informacji zwrotnej i może sam się korygować.

Ewolucja promptu

Pokazana zostaje ewolucja promptu do migracji AI SDK v5. Wersja pierwotna zawierała tylko: „Upgrade do v5, tu jest guide”.

Nowa wersja jest znacznie bogatsza:

  • Link do migration guide
  • Instrukcja sprawdzenia wersji paczek (bo modele często nie aktualizują wszystkich)
  • Komenda do uruchomienia: bun run dry run
  • Instrukcja walidacji: sprawdź wyniki w katalogu
  • Sprawdzenie typów: użyj bun run tsc
  • Wywołanie konkretnych problemów: „Miałem problemy gdzie output okazywał się pustym obiektem zamiast oczekiwanego wyniku”

Kluczowa obserwacja: Połowa promptu to nie tyle „co zrobić”, co „jak to zweryfikować”. To zmienia wszystko w kontekście efektywności.

Analogia do junior engineera

Całość dobrze podsumowuje analogia: tak jak junior engineer, AI potrzebuje odpowiednich narzędzi i zasobów do przepracowania błędów, które może popełnić.

6. Code review z AI

Do automatycznego review wykorzystywane są narzędzia takie jak Greptile czy Code Rabbit. Po stworzeniu PR, Greptile indeksuje kod i wykonuje przegląd.

Praktyczny przykład

W jednym z PR-ów Greptile złapało błąd: kod używał output zamiast result przy ekstrakcji wyników z narzędzi AI SDK v5. Skutek byłby taki, że wszystkie wyniki okazałyby się undefined.

Można było od razu zacommitować sugestię Greptile’a lub skopiować prompt do editora. Kluczowe jest to, że review odbywa się na platformie do review (GitHub), nie w edytorze. To rozdziela konteksty i daje lepszą perspektywę.

Inny przykład to problem z timeoutId w TypeScript. Greptile wskazało, że zmienna może być niezainicjalizowana. Wówczas wykorzystany został Command+K w edytorze z prośbą do Opus o naprawę. Model dodał | undefined do typu, rozwiązując problem.

Pojawia się też moment nauki – autor nie myślał, że to będzie rozwiązanie, ale dowiedział się czegoś nowego. Z drugiej strony przyznaje, że osobiście nie użyłby let w tym kontekście, ale każdy ma swój styl.

7. Kontekst i przykłady: Sekretna broń

Modele działają lepiej gdy mają dobre przykłady. To nie tylko dokumentacja – to konkretny kod pokazujący wzorce.

Elementy pomocne w pracy:

  • Istniejący kod w projekcie – gdy projekt jest większy, model ma wzorce do naśladowania
  • Testy – pokazują jak rzeczy powinny działać
  • Klonowanie repo – dla bibliotek jak Effect TS, gdzie dokumentacja jest słaba

Pojawia się wskazówka od Ben’a (channel managera autora): sklonuj repo biblioteki jako subtree i powiedz modelowi żeby używał testów jako dokumentacji. Testy zawierają mnóstwo praktycznych przykładów.

W JS/TS można też pisać custom scripty w package.json. Model może je uruchamiać i czytać output. To również forma verification harness.

8. Filozofia i dobre praktyki

Nie używaj AI do rzeczy, których nie rozumiesz

Ten punkt jest wielokrotnie i bardzo mocno podkreślany. AI ma automatyzować rzeczy, które już się umie, ale nie ma ochoty robić ręcznie. Nie służy do budowania systemów, których działania nie potrafisz zweryfikować.

To fundamentalna zasada: jeśli nie rozumiesz co AI wygenerowało, to nie powinieneś tego używać. Narzędzia AI przyspieszają pracę eksperta, nie zastępują kompetencji.

Dzięki AI autor:

  • Częściej tworzy eksperymenty i side projekty
  • Częściej pisze testy
  • Częściej formalizuje plany

Projekt autodraftify? Pomysł ze środka nocy, zapisany w telefonie. Rano gotowy w 10 minut. Wcześniej zajęłoby to 30-60 minut pełnej koncentracji.

Kiedy przestać i samemu kodować

Czasem łatwiej po prostu napisać kod. Trzeba rozwinąć gut feeling – wyczucie, kiedy walka z modelem zajmie więcej czasu niż samodzielne rozwiązanie.

Kiedy przestać iterować promptem

Autor ostrzega przed pułapką nieskończonego poprawiania promptów. Jeśli agent po 3-4 próbach wciąż nie trafia w sedno, to znak że potrzebuje sztywniejszych ram, nie lepszych instrukcji.

W takiej sytuacji najlepiej:

  1. Przestań iterować prompt
  2. Wkrocz ręcznie i napisz szkielet – konkretne wywołania funkcji
  3. Dopiero wtedy poproś agenta o implementację

To nie jest porażka – to efektywne zarządzanie czasem. Niektóre problemy wymagają ludzkiej intuicji do zdefiniowania struktury.

Technika „Pretend API”

Czasami stosowana jest technika udawania, że API już istnieje. Kod pisany jest dokładnie tak, jak powinien działać – ze wszystkimi błędami typów. Potem instrukcja brzmi: „Zrób plan który sprawi, że to zadziała”.

To odwrócenie normalnego flow. Zamiast planować jak API powinno wyglądać, piszesz kod jakbyś go już używał, a następnie AI tworzy implementację spełniającą te oczekiwania.

Transfer umiejętności

Nauka jasnego instruowania AI rozwija umiejętności komunikacji. Pisanie dobrych reproduction steps, tworzenie testów, jasne formułowanie wymagań – to wszystko przydaje się w pracy z ludźmi.

Gdy nauczysz się dobrze komunikować z AI, stajesz się lepszym współpracownikiem. Jeśli zostaniesz managerem, będziesz lepiej zarządzać zespołem.

9. Ekonomia i praktyczność

Autor wciąż jest na planie 20 dolarów miesięcznie w Cursor. Nigdy nie zapłacił dodatkowych opłat mimo intensywnego użycia.

Sekret? Drogie modele (Opus) używane są do planowania, tanie (Composer, Grok) do implementacji. To trzyma koszty w ryzach przy zachowaniu jakości.

Większość osób z którymi autor pracuje, nie zbliżyła się nawet do limitów subskrypcji.

Co ważne, taki koszt utrzymuje się mimo zaawansowanej metodyki z wieloma agentami działającymi równolegle. To pokazuje, że sophisticated workflow nie musi oznaczać wysokich rachunków – wymaga tylko świadomego rozdysponowania mocy obliczeniowej.

10. Git workflow: Lazy Git > GitHub CLI

Pojawia się mocne zdanie o GitHub CLI. Demonstracja na żywo pokazuje jak wysyłanie repo przez gh wymaga 11 kroków i 3 network blocków.

Rozwiązanie? Lazy Git.

LG3O – to sekwencja, która wryła się w pamięć. Lazy Git, wciśnij 3, wciśnij O. Gotowe.

Zabawne jest to, że z całego Lazy Git wykorzystywana jest tylko ta jedna funkcja – jako sposób na szybsze otwieranie PR.

11. Co autor NIE używa (i dlaczego)

MCP servers

Nie są wykorzystywane żadne MCP servery. Nie ma takiej potrzeby. Finalna uwaga w materiale jest jasna – MCP serwery zapychają context window śmieciową dokumentacją. Lepiej nauczyć się jasno pisać i wyjaśniać czego się potrzebuje.

GitHub CLI

Jak pokazano wyżej – 11 kroków kontra LG3O.

Context7

Krótko wspomina się, że narzędzie nie sprawdziło się w praktyce.

CLI tools do AI coding

CLI tools nie mają wystarczająco dobrego workflow gdy trzeba coś zmieniać czy edytować. Dodatkowo nie mają wsparcia LSP, więc nie wiedzą natychmiast gdy coś jest nie tak z typami, chyba że dostają komendę do uruchomienia. To irytujące.

LSP (Language Server Protocol) to kluczowa przewaga edytorów – wiedzą natychmiast gdy coś jest nie tak z typami. CLI tools tego nie mają.

12. Współpraca z zespołem Cursor

Ciekawostka – ostatnio były spore problemy z bugami w Cursor. Trwa bliska współpraca z zespołem nad ich naprawianiem.

Pokazane jest też jak szybko pracują: wiadomość od zespołu informuje, że będą mieli nowy build z naprawami w ciągu 45 minut. Ten zespół naprawdę ciężko pracuje.

To pokazuje, że nawet najlepsze narzędzia mają problemy. Jednak dobry team je szybko naprawia.

Kompletny workflow: Checklist

Przygotowanie

  • [ ] Ręcznie zainicjuj projekt (create-t3-app, bun init, etc.)
  • [ ] Skonfiguruj .cursor/ z setup script dla work trees
  • [ ] Dodaj verification commands do package.json (dry run, type check)
  • [ ] Stwórz szczegółowy prompt (voice > typing dla większego kontekstu)
  • [ ] Użyj zaawansowanego modelu (Opus, GPT-4) do wygenerowania planu
  • [ ] Przeczytaj i zatwierdź plan

Implementacja

  • [ ] Uruchom implementację na szybkim modelu (Composer, Grok)
  • [ ] Opcjonalnie: równolegle na kilku modelach przez work trees
  • [ ] Model wykonuje kod używając verification harnesses

Weryfikacja

  • [ ] Sprawdź wyniki dry run / testów
  • [ ] Uruchom type checking (bun run tsc)
  • [ ] Przejrzyj zmiany w zakładce Review
  • [ ] Wyślij i stwórz PR (Lazy Git: LG+3+O)
  • [ ] Review przez AI tool (Greptile/Code Rabbit)

Iteracja (jeśli potrzebna)

  • [ ] Przeanalizuj co poszło nie tak
  • [ ] Popraw PLAN/PROMPT (nie kod) – to maintained artifact
  • [ ] Wyrzuć stary kod
  • [ ] Restart z poprawionym planem
  • [ ] Powtarzaj 4-5 razy jeśli potrzeba
  • [ ] Jeśli po 3-4 próbach wciąż nie działa – wkrocz ręcznie i napisz szkielet

Finalizacja

  • [ ] Zaakceptuj najlepszą implementację
  • [ ] Scal z głównym branchem

Narzędzia i zasoby

Editor i modele

  • Cursor – główne środowisko
    • Tryb agenta (Command+E) do planowania
    • Tryb edytora do kodowania
    • Zakładka Review do przeglądania zmian
    • Command+I dla konwersacji w sidebar
    • Command+K dla inline edits
  • Opus 4.5 – do planowania i trudniejszych tasków
  • GPT-4 (5.1) – alternatywa do planowania, czasem lepsza
  • Composer – szybki i tani do implementacji, świetne wywoływanie narzędzi
  • Gemini 3 Pro – alternatywa do testowania

Code review

  • Greptile – główne narzędzie do review (łatwe do konfiguracji w open source)
  • Code Rabbit – alternatywa

Workflow

  • Work trees – równoległa praca na różnych branchach
  • Whisper Flow – dyktowanie do promptów (więcej kontekstu niż pisanie)
  • Lazy Git – szybkie tworzenie PR (LG3O = Lazy Git + 3 + O)

Setup projektu

  • create-t3-app
  • better-tstack
  • create-next-app
  • bun init

Co autor NIE używa

  • MCP servers – zapychają context window, lepiej jasno pisać
  • GitHub CLI – 11 kroków żeby wysłać repo
  • Context7 – nie sprawdził się
  • CLI coding tools – brak wsparcia LSP, gorszy workflow

Biblioteka promptów: Sprawdzone wzorce z transkryptu

Autor pokazuje ewolucję swoich promptów od prostych do bardzo efektywnych. Oto konkretne przykłady do wykorzystania.

1. Prompt do planowania nowego projektu

Kontekst: Tworzenie nowego projektu od zera, gdy AI ma najpierw zrobić plan.

Przykład z autodraftify:

Ten projekt to demonstracja tego, jak różne modele AI radzą sobie 
z zadaniami pisarskimi. Cel jest prosty: Wygeneruj esej na podstawie 
promptu od użytkownika. Następnie inny model AI ma zrecenzować ten 
esej i dać feedback, a potem feedback wraca do oryginalnego modelu 
żeby zaktualizował esej.

Wszystkie trzy kroki mają być zapisane jako pliki markdown gdy 
następuje generacja, żeby łatwo było je przejrzeć w edytorze tekstu.

Użyj AI SDK od Vercel i OpenRouter w OpenRouter provider dla AI SDK 
do prowizjonowania inference.

Upewnij się, że wszystko co piszesz jest type safe.

Kiedy stosować:

  • Na początku projektu greenfield
  • Gdy jest jasna wizja co chcesz osiągnąć
  • Preferuj mówienie (Whisper Flow) nad pisaniem – daje więcej kontekstu

Kluczowe elementy:

  • Jasny cel projektu
  • Konkretne wymagania techniczne (jakie biblioteki)
  • Ograniczenia (type safety, format outputu)

2. Feedback do planu: Chwytanie błędów

Kontekst: Po wygenerowaniu planu, gdy zauważysz błędy lub niedokładności.

Przykłady z transkryptu:

Dlaczego dodajesz paczkę OpenAI? 
Będziemy używać OpenRouter, nie OpenAI.
Nadal masz OpenAI w sekcji Setup DEPS.

Kiedy stosować:

  • Zawsze czytaj plan przed uruchomieniem implementacji
  • Wyłapuj niespójności między instrukcjami a planem
  • Wskazuj konkretnie co jest źle

Kluczowa zasada: Nie przechodź do implementacji dopóki plan nie jest idealny. Tani czas na poprawki to teraz, nie potem.

3. Quick fixes: Formatowanie i style

Kontekst: Szybkie poprawki stylu kodu bez większych zmian logicznych.

Przykład:

Czy możemy użyć dedent lub czegoś podobnego żeby 
formatowanie stringów było mniej ohydne?
Wcięcia w plikach markdown są pokręcone. 
Zrobiłem screenshoty przykładów. Proszę to naprawić.

Kiedy stosować:

  • Po implementacji, gdy wszystko działa ale wygląda źle
  • Używaj Command+K w Cursor (inline edit) zamiast pełnego Agenta
  • Dołączaj screenshoty problemów

4. Type errors: Od prostego do precyzyjnego

Kontekst: Naprawianie błędów TypeScript.

Wersja prosta (odrzucona przez autora):

Dostaję błąd typów przy tym sprawdzeniu, proszę to naprawić.

Wersja lepsza (zaakceptowana):

Timeout ID pokazuje błąd typów w bloku finally 
z powodu potencjalnego braku inicjalizacji. Napraw to proszę.

Kiedy stosować:

  • Im precyzyjniej opiszesz problem, tym lepszy fix
  • Wskaż GDZIE jest problem (która linia, który blok)
  • Wskaż DLACZEGO jest problem (potencjalnie niezainicjalizowany)
  • Dla prostych rzeczy użyj Command+K

5. ⭐ Prompt do migracji/refactoringu: Ewolucja od złego do świetnego

To najważniejszy przykład, bo autor pokazuje dokładnie jak ulepsza prompt przez iteracje.

WERSJA 1.0 (ZŁA) ❌

Zaktualizuj projekt żeby używał najnowszej wersji AI SDK version 5.

Problem: Brak kontekstu, brak weryfikacji, modele często robiły błędy.

WERSJA 2.0 (ŚWIETNA) ✅

Zaktualizuj projekt żeby używał najnowszej wersji AI SDK version 5.

Załączyłem guide jak zrobić upgrade poniżej. Proszę upewnij się, 
że przejrzałeś guide przed rozpoczęciem implementacji.
[link do migration guide]

Upewnij się, że używasz najnowszej wersji paczki AI SDK 
jak również ZOD i OpenRouter provider.

Przetestuj swoją implementację uruchamiając następującą komendę:
bun run dry run

Każdy test powinien mieć wynik zapisany do katalogu results/dry-run/. 
Upewnij się, że walidowałeś te outputy i że tool calls zawierają 
parametry, które zostały przekazane przez model.

Miałem problemy gdzie output okazywał się pustym obiektem zamiast 
oczekiwanego wyniku tego co model przesłał w tool call.

Upewnij się, że cały typescript w projekcie jest zwalidowany. 
Nie chcemy wysyłać żadnego niebezpiecznego kodu w tym projekcie. 
Proszę unikaj używania any i innych rzeczy, które mogłyby złamać 
type safety systemu.

Upewnij się, że walidowałeś zmiany które robisz używając 
komendy bun run tsc.

Co się zmieniło:

  1. ✅ Link do dokumentacji
  2. ✅ Hint o aktualizacji wszystkich paczek (nie tylko głównej)
  3. Konkretna komenda do testowania (bun run dry run)
  4. Co sprawdzić (wyniki w katalogu, parametry w tool calls)
  5. Konkretne problemy z przeszłości („output okazuje się pustym obiektem”)
  6. Type safety check (bun run tsc)
  7. Anti-patterns (unikaj any)

Kluczowa obserwacja autora: Połowa promptu to nie tyle „co zrobić”, co „jak to zweryfikować”.

Kiedy stosować:

  • Każda migracja biblioteki
  • Każdy większy refactor
  • Gdy zauważasz, że modele robią te same błędy – dodaj to do promptu
  • Gdy task jest złożony i będzie trwał więcej niż 10 minut

Struktura idealnego promptu do większych tasków:

[CO ZROBIĆ]
- Główny cel
- Link do dokumentacji/guide jeśli istnieje

[UWAGA NA DETALE]
- Hint: zaktualizuj też X, Y, Z (nie tylko główną rzecz)

[VERIFICATION HARNESSES]
- Komenda do uruchomienia: [command]
- Co powinno się stać: [expected output]
- Gdzie sprawdzić wyniki: [path]

[ZNANE PROBLEMY]
- Miałem problem z X, upewnij się że...
- Output czasem jest Y zamiast Z, sprawdź czy...

[TYPE SAFETY / CODE QUALITY]
- Komenda do sprawdzenia: [command]
- Czego unikać: [anti-patterns]

6. Technika „Pretend API”: Odwrócony workflow

Kontekst: Gdy wiesz JAK chcesz używać API, ale nie chcesz go najpierw projektować.

Jak to działa:

  1. Napisz kod używający nieistniejącego API
  2. Zostaw wszystkie błędy typów
  3. Napisz kod dokładnie tak, jak chciałbyś go używać
  4. Potem prompt:
Zrób mi plan który spełni tę funkcjonalność 
żeby ten kod zachowywał się jak napisany.

Przykład (konceptualny, autor tego nie pokazał dosłownie):

// Najpierw piszesz kod jakby wszystko działało:
const result = await processUserData(userId, {
  includeHistory: true,
  validateEmail: true
});

console.log(result.summary);
// ^ Wszystko podkreślone na czerwono, nic nie istnieje

// Potem mówisz AI:
// "Zrób mi plan który implementuje processUserData() 
// żeby ten kod działał dokładnie tak jak napisany"

Kiedy stosować:

  • Gdy masz jasną wizję user experience swojego API
  • Gdy łatwiej wyrazić „jak chcę to używać” niż „jak to zaimplementować”
  • Dla internal tooling gdzie ty jesteś głównym userem

Zalety:

  • API jest zaprojektowane od strony użytkownika, nie implementacji
  • Unikasz over-engineering
  • Kod jest czytelniejszy bo projektowałeś go od strony użycia

7. Prompt testowy: Dobry przykład user input

Kontekst: Testowanie wygenerowanego systemu na konkretnym przypadku użycia.

Przykład z autodraftify:

Napisz dokładne wyjaśnienie dlaczego explicite return types 
w TypeScript mogą nie być dobrym pomysłem, mimo że są 
w innych językach.

Dlaczego to dobry test:

  • Jest konkretny i wymaga zrozumienia tematu
  • Jest kontrowersyjny (dobre do testowania argumentacji)
  • Wymaga technical depth
  • Pozwala porównać różne modele (jak radziły sobie Opus vs 4o-mini)

Kiedy stosować:

  • Po implementacji systemu do testowania jakości
  • Wybieraj testy które pokażą różnice między modelami
  • Unikaj banalnych testów typu „napisz o kotach”

Meta-wzorce: Jak ulepszać swoje prompty

Autor pokazuje proces ciągłego ulepszania. Oto framework:

Checklist po każdej nieudanej implementacji:

  • [ ] Czy model miał wystarczający kontekst? (docs, examples, tests)
  • [ ] Czy miał sposób na weryfikację że działa? (dry run, tests, type check)
  • [ ] Czy wskazałem konkretne problemy z poprzednich prób?
  • [ ] Czy dałem mu komendy do uruchomienia?
  • [ ] Czy powiedziałem CO sprawdzić w wynikach?
  • [ ] Czy zaznaczyłem anti-patterns?

Czerwone flagi w promptach:

  • ❌ „Napraw to” – za mało kontekstu
  • ❌ „Zrób to lepiej” – niejasny cel
  • ❌ Brak komend do weryfikacji
  • ❌ Brak linków do dokumentacji dla complex tasks
  • ❌ Nie wspominanie o known issues

Zielone flagi w promptach:

  • ✅ Konkretny cel + link do docs
  • ✅ Lista rzeczy do zaktualizowania (nie tylko główna)
  • ✅ Komendy do uruchomienia
  • ✅ Opis co powinno być w output
  • ✅ Znane problemy z przeszłości
  • ✅ Type safety / quality checks
  • ✅ Anti-patterns do uniknięcia

Podsumowanie: Prompt to maintained artifact

Najważniejsza lekcja z całego materiału: Traktuj prompt jako rzecz którą utrzymujesz między próbami, nie kod.

Kod jest tani. Można go wyrzucić i zregenerować. Natomiast prompt to coś, co zbiera wiedzę o tym:

  • Co działa
  • Co nie działa
  • Jakie błędy się pojawiają
  • Jak to weryfikować

Dobre prompty rosną z doświadczenia. Za każdym razem gdy model robi błąd, pojawia się okazja do ulepszenia promptu. Po 4-5 iteracjach powstaje prompt, który działa świetnie.

To nie jest wstyd mieć długie prompty. To znak uczenia się i dokumentowania tego co działa.

Kluczowy wniosek

Projektowanie przez fikcję

Standardowo myślimy: Najpierw prosimy AI o stworzenie funkcji i logiki, a następnie próbujemy dopasować nasz kod, aby z tych funkcji skorzystać.

W praktyce okazuje się, że: Znacznie skuteczniejsze jest ręczne napisanie kodu, który używa nieistniejących jeszcze funkcji (symulując idealne API), a dopiero potem zlecenie AI „dośpiewania” reszty.

Dlaczego to jest istotne: Modele językowe lepiej radzą sobie z rozwiązywaniem problemów w narzuconych ramach (np. „spraw, by ten kod przestał rzucać błędy”) niż z abstrakcyjnym projektowaniem interfejsów od zera. Zmienia to miejsce, gdzie inwestowany jest wysiłek mentalny – najpierw definiujesz strukturę i sposób użycia, a AI wypełnia szczegóły implementacyjne.

Test na jutro: Gdy będziesz potrzebować nowego modułu, napisz w pliku main 5-10 linii kodu używającego tego modułu tak, jakby był już gotowy. Następnie wklej to do AI z poleceniem implementacji i porównaj czas oraz jakość z tradycyjnym podejściem „najpierw zaprojektuj API”.


Ten wpis jest częścią mojej kolekcji notatek z ciekawych podcastów, webinarów i innych treści, które uważam za wartościowe i do których sam chcę wracać. Jeśli chcesz sprawdzić oryginalne źródło, znajdziesz je tutaj: How I code with AI right now

More from the blog