Przejdź do treści
21 lipca 202612 min czytania

Schematy rozmowy iteracyjnej z ChatGPT

Schematy rozmowy iteracyjnej z ChatGPT
Obraz wygenerowany lub zmodyfikowany przez AI
Jak tworzyć precyzyjne prompty do programowania z ChatGPT i Copilotem. Iteracyjne schematy rozmowy, kontekst i kryteria jakości.

Schematy rozmowy iteracyjnej z ChatGPT#

Rozmowa z ChatGPT nie powinna być jednorazowym „strzałem”, w którym próbujesz zmieścić wszystkie wymagania w jednym, idealnym poleceniu. W praktyce znacznie lepiej działa podejście iteracyjne — takie, które przypomina pracę nad backlogiem produktu albo przeglądy kodu w zespole. Zaczynasz od wersji roboczej, a potem krok po kroku ją doprecyzowujesz. Zamiast oczekiwać perfekcyjnej odpowiedzi w pierwszej próbie, traktuj AI jak współpracownika: kogoś, komu przekazujesz kontekst, a następnie wspólnie dochodzicie do coraz lepszego rezultatu.

To podejście ma kilka bardzo konkretnych zalet. Po pierwsze, zmniejsza presję na stworzenie „idealnego promptu”. Po drugie, pozwala szybciej wykrywać nieporozumienia i błędne założenia. Po trzecie, daje większą kontrolę nad jakością końcowego efektu, bo każda iteracja jest świadomą korektą kierunku. Najważniejsze jednak jest to, że uczysz się sterować rozmową — zamiast reagować na to, co wygenerował model, zaczynasz nim zarządzać.

Poniżej znajdziesz trzy praktyczne schematy rozmowy iteracyjnej wraz z rozszerzonymi wskazówkami, kiedy i jak ich używać.

---

Schemat 1: szkic → doprecyzowanie → zawężenie#

To najbardziej uniwersalny i bezpieczny model pracy. Zaczynasz szeroko, a następnie stopniowo uszczegóławiasz wymagania. Ten schemat sprawdza się zarówno przy generowaniu kodu, jak i przy tworzeniu dokumentacji, architektury czy treści merytorycznych.

Krok 1: szkic#

Najpierw formułujesz ogólny cel, najlepiej osadzony w ustalonym wcześniej kontekście technologicznym i jakościowym. Nie próbuj od razu opisać wszystkich przypadków brzegowych ani narzucać pełnej architektury. Chodzi o wygenerowanie sensownego punktu wyjścia.

Przykład:

`

Napisz serwis w C# (.NET 8), który filtruje listę zamówień po dacie i statusie. Zastosuj wzorzec Repository.

`

To wystarczy, aby otrzymać pierwszą wersję rozwiązania. Na tym etapie nie chodzi o perfekcję. Chodzi o to, żeby zobaczyć, jak model rozumie problem, jakie przyjmuje założenia i jaką strukturę proponuje.

Dobrą praktyką jest także określenie ogólnych zasad jakości już w szkicu, np.:

`

Kod ma być czytelny, zgodny z SOLID i bez efektów ubocznych.

`

Nie musisz jeszcze wymuszać detali — wystarczy sygnał kierunkowy.

Krok 2: doprecyzowanie#

Kiedy otrzymasz odpowiedź, przeczytaj ją krytycznie. Zadaj sobie pytania:

  • Czego tu brakuje?
  • Jakie założenia są niejawne?
  • Czy implementacja spełnia moje standardy jakości?
  • Czy coś zostało nadmiernie rozbudowane?

Następnie wskaż konkretne elementy do poprawy:

`

Doprecyzuj: metoda ma być deterministyczna, nie może modyfikować kolekcji wejściowej, obsłuż przypadek pustej listy oraz null.

`

Zauważ, że nie przepisujesz całego zadania od nowa. Korygujesz kierunek. To kluczowa różnica między chaotycznym poprawianiem a świadomą iteracją.

Możesz też wskazać brakujące elementy architektoniczne:

`

Dodaj interfejs dla serwisu i pokaż przykładowy test jednostkowy dla metody filtrującej.

`

Każde doprecyzowanie zawęża przestrzeń interpretacji i zmniejsza ryzyko kolejnych nieporozumień.

Krok 3: zawężenie i wymuszenie szczegółów#

Na końcu możesz przejść do poziomu detali implementacyjnych. To moment, w którym narzucasz konkretne decyzje techniczne.

`

Użyj LINQ, zwróć IReadOnlyList<Order>, dodaj jawne sprawdzenie argumentów i rzuć ArgumentNullException.

`

Albo bardziej precyzyjnie:

`

Nie używaj ToList() więcej niż raz. Zminimalizuj alokacje pamięci.

`

W tym momencie odpowiedź powinna być już zgodna z Twoimi oczekiwaniami architektonicznymi i jakościowymi. Jeśli nadal coś nie pasuje — wykonujesz kolejną iterację. Proces kończy się dopiero wtedy, gdy rezultat spełnia ustalony kontrakt.

Największą zaletą tego schematu jest kontrola. Nie polegasz na domysłach modelu. Stopniowo precyzujesz wymagania, aż rezultat stanie się przewidywalny.

---

Schemat 2: pytania kontrolne zamiast natychmiastowych poprawek#

Czasami pierwsza odpowiedź wygląda dobrze, ale masz wątpliwości. Zamiast od razu poprawiać kod czy zmieniać strukturę tekstu, możesz użyć rozmowy jako narzędzia do weryfikacji.

To podejście przypomina code review albo przegląd architektury w zespole.

Przykład:

`

Jakie przypadki brzegowe nie zostały uwzględnione?

Czy metoda spełnia wcześniejsze kryteria wydajności?

Czy istnieje ryzyko modyfikacji kolekcji wejściowej?

`

Takie pytania mają kilka istotnych zalet:

  • zmuszają model do autorefleksji,
  • pomagają wykryć niespójności logiczne,
  • pozwalają sprawdzić zgodność z wcześniejszymi wymaganiami,
  • ujawniają ukryte kompromisy.

Możesz też poprosić o analizę alternatyw:

`

Jakie są konsekwencje użycia ToList() w tym miejscu?

Czy istnieje bardziej wydajna alternatywa?

Porównaj to rozwiązanie z podejściem opartym na pętlach foreach.

`

Dzięki temu nie tylko poprawiasz rozwiązanie, ale też pogłębiasz jego uzasadnienie. To szczególnie przydatne przy decyzjach architektonicznych, gdzie liczy się nie tylko „co”, ale również „dlaczego”.

Ten schemat jest bardzo wartościowy, gdy zależy Ci na jakości koncepcyjnej, a nie wyłącznie na syntaktycznej poprawności. Sprawdza się również przy pisaniu artykułów — możesz zapytać:

`

Które argumenty są najsłabsze?

Gdzie tekst jest zbyt ogólny?

Czy struktura rozdziału jest logiczna?

`

W efekcie model staje się nie tylko generatorem treści, ale też recenzentem.

---

Schemat 3: iteracyjne uszczegóławianie zakresu#

Częstym problemem jest zbyt obszerna odpowiedź. Model może wygenerować kontroler, konfigurację DI, testy jednostkowe i dodatkowe klasy — nawet jeśli potrzebujesz tylko fragmentu.

W takiej sytuacji nie zaczynaj od nowa. Zawęź zakres.

`

Skup się wyłącznie na warstwie aplikacji. Nie generuj kontrolera ani konfiguracji DI.

`

Możesz też precyzować poziom abstrakcji:

`

Pokaż tylko sygnaturę interfejsu i implementację metody. Bez komentarzy i bez dodatkowych klas pomocniczych.

`

Albo odwrotnie — rozszerzyć konkretny fragment:

`

Rozwiń wyłącznie walidację wejścia. Nie zmieniaj pozostałej logiki.

`

Ten schemat działa także w drugą stronę. Jeśli odpowiedź jest zbyt ogólna, możesz ją pogłębić:

`

Podaj konkretny przykład użycia.

Dodaj fragment testu jednostkowego.

Rozpisz to krok po kroku.

`

Iteracyjne zarządzanie zakresem jest szczególnie ważne przy większych zadaniach, takich jak projektowanie modułu systemu czy pisanie dłuższego artykułu. Zamiast próbować wygenerować wszystko naraz, możesz budować całość etapami: najpierw strukturę, potem jeden rozdział, potem kolejny.

To podejście daje Ci pełną kontrolę nad objętością i szczegółowością odpowiedzi. Zamiast walczyć z nadmiarem informacji, świadomie nim zarządzasz.

---

Iteracja jako kontrakt jakościowy#

Najważniejsza zasada brzmi: każda iteracja powinna odnosić się do wcześniej ustalonego kontraktu jakościowego.

Jeśli na początku określiłeś:

  • brak efektów ubocznych,
  • jawne sprawdzanie argumentów,
  • zgodność z SOLID,
  • określony poziom wydajności,
  • brak zależności od infrastruktury w warstwie domenowej,

— to każda kolejna poprawka powinna być oceniana względem tych kryteriów.

Nie zaczynasz rozmowy od zera. Nie zmieniasz chaotycznie wymagań. Zamiast tego precyzyjnie korygujesz kierunek.

Możesz jawnie przypominać modelowi ustalenia:

`

Zachowaj wcześniejsze założenia: brak modyfikacji danych wejściowych i jawna walidacja argumentów.

Nie wprowadzaj zależności od bazy danych w tej warstwie.

`

To znacząco zmniejsza ryzyko „dryfowania” rozwiązania w stronę, której nie chcesz. Iteracja nie jest zmianą wizji — jest jej dopracowywaniem.

---

Najczęstsze błędy w rozmowie iteracyjnej#

Warto też wiedzieć, czego unikać.

1. Zbyt duże skoki zmian#

Jeśli w jednej iteracji zmienisz architekturę, język, wzorzec projektowy i wymagania wydajnościowe — trudno będzie ocenić, co faktycznie zadziałało. Lepsze są małe, kontrolowane kroki.

2. Brak jasnych kryteriów#

„Popraw kod” to za mało. Lepiej napisać:

„Zoptymalizuj metodę pod kątem minimalizacji alokacji pamięci.”

Albo:

„Uprość logikę warunkową tak, aby zredukować zagnieżdżenie do maksymalnie dwóch poziomów.”

Im bardziej mierzalne kryterium, tym lepsza odpowiedź.

3. Resetowanie kontekstu bez potrzeby#

Czasem użytkownicy przepisują całe zadanie od nowa, tracąc ustalenia z poprzednich kroków. Lepiej budować na tym, co już zostało wypracowane.

4. Brak podsumowań cząstkowych#

Przy dłuższej rozmowie warto co kilka iteracji zrobić krótkie podsumowanie ustaleń:

`

Podsumuj aktualne założenia architektoniczne w punktach.

`

To pomaga utrzymać spójność i uniknąć nieporozumień.

---

Praktyczna wskazówka: myśl w kategoriach dialogu#

Zamiast traktować ChatGPT jak wyszukiwarkę, myśl o nim jak o partnerze w rozmowie technicznej. Zadajesz pytanie. Otrzymujesz odpowiedź. Dopytujesz. Korygujesz. Testujesz założenia.

To podejście sprawdza się nie tylko w programowaniu. Możesz w ten sposób:

  • budować strukturę artykułu,
  • dopracowywać argumentację,
  • projektować architekturę systemu,
  • analizować ryzyka,
  • przygotowywać się do rozmów technicznych.

Schemat zawsze jest podobny: wersja robocza → informacja zwrotna → korekta → doprecyzowanie → finalizacja.

Im bardziej świadomie prowadzisz ten proces, tym bardziej przewidywalne są rezultaty.

---

Podsumowanie#

Iteracyjna rozmowa z ChatGPT to proces, nie jednorazowa komenda. Zaczynasz od szkicu, następnie doprecyzowujesz wymagania, zawężasz zakres, zadajesz pytania kontrolne i weryfikujesz jakość względem ustalonego kontraktu.

Każda iteracja powinna przybliżać Cię do jasno określonego celu. Jeśli tego celu nie definiujesz — model będzie zgadywał. Jeśli definiujesz go stopniowo i konsekwentnie — zaczynasz realnie sterować efektem końcowym.

Gdy nauczysz się świadomie prowadzić ten dialog, przestaniesz liczyć na „idealny prompt”. Zamiast tego zyskasz coś znacznie cenniejszego — kontrolę nad kierunkiem, zakresem i jakością rezultatu.

A to właśnie kontrola sprawia, że współpraca z AI staje się przewidywalna, efektywna i naprawdę użyteczna — niezależnie od tego, czy piszesz kod, projektujesz system, czy tworzysz treści eksperckie.

Schematy pracy z Copilotem w środowisku IDE#

W pracy z Copilotem kluczowe jest to, że kontekstem staje się aktualnie otwarty plik, nazwy symboli oraz komentarze bezpośrednio nad kodem. To nie jest rozmowa jak z ChatGPT, lecz ciągła podpowiedź oparta na tym, co właśnie piszesz. Dlatego komentarz pełni rolę mikro‑promptu.

Komentarz jako precyzyjna specyfikacja#

Zamiast pisać ogólnie:

Snippet
csharp
// pobierz dane użytkownika

lepiej doprecyzować wymagania funkcjonalne i niefunkcjonalne:

Snippet
csharp
// Pobiera użytkownika po Id z repozytorium.
// Zwraca null, jeśli nie istnieje.
// Metoda asynchroniczna, bez rzucania wyjątku dla braku danych.
public async Task<User?> GetUserByIdAsync(Guid userId)
{

Tak sformułowany komentarz uwzględnia deterministyczność metody, jawne definiowanie wyjątków oraz kontrakt jakościowy. Copilot znacznie częściej wygeneruje implementację zgodną z intencją.

Nazwy metod jako sygnał architektoniczny#

Nazwy powinny odzwierciedlać lokalizację kodu w architekturze. CreateOrderCommandHandler sugeruje wzorzec CQRS, a IUserRepository wymusza separację warstw. Jeśli używasz konwencji Async, Copilot będzie konsekwentnie proponował await i metody asynchroniczne.

Przykład w kontekście architektury warstwowej:

Snippet
csharp
public class CreateOrderCommandHandler
{
    private readonly IOrderRepository _orderRepository;
    public CreateOrderCommandHandler(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }
    // Tworzy nowe zamówienie i zapisuje je w repozytorium.
    // Waliduje dane wejściowe i rzuca ArgumentException w przypadku błędu.
    public async Task<Guid> HandleAsync(CreateOrderCommand command)
    {

Fragment kontekstu zamiast długiego opisu#

Czasem wystarczy kilka linii istniejącego kodu powyżej miejsca edycji. Copilot analizuje zależności, typ aplikacji i wersję środowiska na podstawie referencji w pliku. Im bardziej spójne konwencje nazewnicze i struktura plików w projekcie, tym trafniejsze podpowiedzi.

Najczęstszy błąd to zbyt lakoniczny komentarz lub sprzeczne sygnały w nazwach. W IDE każde słowo ma znaczenie – traktuj je jak precyzyjny prompt osadzony w kodzie.

Najczęstsze błędy w promptowaniu technicznym#

Jeśli korzystasz z AI do zadań programistycznych, architektonicznych albo analitycznych, prawdopodobnie przynajmniej raz pomyślałeś: „Przecież to powinno zadziałać lepiej”. W większości przypadków problem nie leży w modelu, tylko w sposobie, w jaki formułujemy polecenie. Prompt techniczny to nie luźna prośba – to miniaturowa specyfikacja. A każda luka w specyfikacji zostanie wypełniona przez założenia modelu.

Przyjrzyjmy się najczęstszym błędom i zobaczmy, jak je eliminować w praktyce.

1. Zbyt ogólne polecenia#

To klasyk. Piszesz:

„Napisz serwis do obsługi użytkowników.”

I co to właściwie znaczy? Jaka technologia? Monolit czy mikroserwis? REST czy GraphQL? Jaki ORM? Jakie wymagania biznesowe? Czy serwis ma tylko CRUD, czy też walidację, autoryzację, logowanie zdarzeń?

Model musi zgadywać. A gdy zgaduje, opiera się na najbardziej prawdopodobnym scenariuszu statystycznym, nie na Twoim projekcie. Efekt? Kod może być poprawny składniowo, ale zupełnie niepasujący do Twojej architektury.

Zamiast ogólnika, podaj kontekst:

  • język i wersję środowiska,
  • styl architektoniczny,
  • warstwę, w której ma powstać kod,
  • zależności, które wolno wykorzystać,
  • zakres funkcjonalny.

Przykład lepszego promptu:

„Napisz serwis UserService w .NET 8, w warstwie Application zgodnie z zasadami Clean Architecture. Serwis ma obsługiwać rejestrację użytkownika z walidacją adresu e-mail i hasła. Użyj wzorca Result<T> do zwracania wyników. Nie używaj wyjątków do obsługi błędów walidacyjnych.”

To wciąż krótki prompt, ale daje wyraźne ramy decyzyjne.

2. Brak jawnych ograniczeń#

Drugim częstym problemem jest brak ograniczeń. Jeśli ich nie określisz, model przyjmie własne domyślne założenia. Czasem będą trafne. Często – nie.

Nie wskazujesz wzorca projektowego? Model może użyć najprostszego rozwiązania proceduralnego.

Nie określasz konwencji nazewniczych? Otrzymasz nazwy inne niż w Twoim repozytorium.

Nie definiujesz struktury katalogów? Kod może trafić do niewłaściwej warstwy.

W projektach opartych o Clean Architecture, DDD czy architekturę heksagonalną to szczególnie niebezpieczne. Jedno przesunięcie zależności i naruszasz kierunek przepływu zależności.

Zamiast liczyć na „domyślność”, jasno określ granice:

  • gdzie kod ma się znajdować,
  • z jakich bibliotek może korzystać,
  • czego nie wolno używać,
  • jaki styl ma zostać zachowany.

Im bardziej złożony projekt, tym ważniejsze są ograniczenia.

3. Sprzeczne wymagania#

To błąd subtelny, ale bardzo częsty. Tworzysz prompt, który zawiera wewnętrzną sprzeczność.

Na przykład:

Snippet
csharp
// Napisz metodę, która zapisuje użytkownika do bazy
// Metoda ma być asynchroniczna, ale nie używaj async/await
// Zwróć bool oraz rzuć wyjątek w przypadku błędu

Tu mamy kilka problemów:

  • asynchroniczność bez async/await (w .NET to wymaga alternatywnego podejścia, które trzeba doprecyzować),
  • jednoczesne zwracanie bool i rzucanie wyjątku jako dwóch konkurencyjnych mechanizmów sygnalizacji błędu,
  • brak informacji o warstwie i kontrakcie metody.

Model spróbuje pogodzić te sprzeczności – często w sposób, który nie spełni Twoich realnych oczekiwań.

Lepsza wersja:

Snippet
csharp
// Napisz asynchroniczną metodę SaveAsync w warstwie Application
// Użyj async/await
// Zwróć Result<UserId> zamiast bool
// Nie rzucaj wyjątków dla błędów walidacyjnych
// Rzucaj wyjątek tylko w przypadku błędów infrastrukturalnych

Teraz kontrakt jest spójny. Model nie musi zgadywać, który mechanizm obsługi błędów jest nadrzędny.

4. Brak przypadków brzegowych#

AI generuje kod „optymistyczny”, jeśli nie wskażesz inaczej. To znaczy: zakłada poprawne dane wejściowe i brak sytuacji wyjątkowych.

Nie wspomnisz o null? Może nie być walidacji.

Nie określisz maksymalnej długości danych? Może jej nie uwzględnić.

Nie wspomnisz o idempotencji? Operacja może być niedeterministyczna.

W systemach produkcyjnych przypadki brzegowe to nie dodatek. To podstawa.

Dlatego warto doprecyzować:

  • jak obsługiwać wartości null,
  • jakie są ograniczenia długości i zakresów,
  • czy metoda ma być deterministyczna,
  • jakie są wymagania wydajnościowe,
  • czy operacja ma być idempotentna,
  • jak reagować na duplikaty.

Przykład rozszerzonego polecenia:

„Metoda ma być deterministyczna. Jeśli użytkownik o podanym e-mailu już istnieje, zwróć błąd domenowy zamiast tworzyć duplikat. Obsłuż przypadek null na wejściu poprzez zwrócenie błędu walidacyjnego. Załóż maksymalnie 1000 wywołań na sekundę – unikaj blokujących operacji.”

To nie jest „przesada”. To realna specyfikacja zachowania.

5. Upychanie wszystkiego w jednym promptcie#

Często próbujemy uzyskać kompletną implementację całego modułu w jednym zapytaniu:

  • encje,
  • DTO,
  • mapowanie,
  • walidację,
  • kontroler,
  • testy jednostkowe,
  • konfigurację DI.

Efekt? Odpowiedź jest długa, mniej precyzyjna i trudniejsza do zweryfikowania.

Lepszym podejściem jest iteracja.

  1. Najpierw poproś o model domenowy.
  2. Następnie o serwis aplikacyjny.
  3. Potem o testy jednostkowe.
  4. Na końcu o integrację z warstwą infrastruktury.

Takie podejście pozwala:

  • szybciej wychwycić błędy koncepcyjne,
  • doprecyzować kolejne kroki,
  • zachować kontrolę nad architekturą.

Promptowanie techniczne działa najlepiej jako dialog, nie jako jednorazowe zlecenie.

6. Brak określenia poziomu abstrakcji#

Czasem problemem nie jest brak informacji, ale brak wskazania głębokości odpowiedzi.

Czy chcesz:

  • ogólną koncepcję?
  • szkic architektury?
  • pełny kod produkcyjny?
  • kod demonstracyjny?

Jeśli tego nie określisz, możesz dostać rozwiązanie zbyt ogólne albo zbyt rozbudowane.

Warto dodać jedno zdanie:

„Odpowiedź ma zawierać kod produkcyjny gotowy do użycia.”

albo:

„Przedstaw jedynie koncepcję bez pełnej implementacji.”

To radykalnie zmienia rezultat.

7. Nieprecyzyjne kryteria jakości#

Często piszemy: „Zoptymalizuj kod” albo „Popraw jakość”. Tylko co to znaczy?

  • Zmniejszyć złożoność cyklomatyczną?
  • Usunąć duplikację?
  • Poprawić czytelność?
  • Zwiększyć wydajność?

AI nie zna Twojej definicji „lepszy”. Dlatego warto ją zdefiniować.

Zamiast ogólnego polecenia:

„Zoptymalizuj metodę.”

lepiej napisać:

„Zmniejsz złożoność metody poprzez ekstrakcję mniejszych funkcji, usuń duplikację warunków i zastąp zagnieżdżone instrukcje if wzorcem strategii.”

To konkret. A konkret daje przewidywalność.

8. Traktowanie promptu jak pytania, a nie decyzji#

Najważniejsza zasada: każda niejednoznaczność to decyzja, którą podejmie model. A skoro to Ty odpowiadasz za jakość systemu, nie możesz oddawać kluczowych decyzji przypadkowi.

Prompt techniczny to nie pytanie w stylu: „Jak byś to zrobił?”.

To raczej: „Zaimplementuj to w tych ramach, przy tych założeniach, z tym kontraktem.”

Im bardziej świadomie projektujesz prompt, tym bardziej AI staje się rozszerzeniem Twojego warsztatu, a nie generatorem przypadkowego kodu.

Podsumowanie praktyczne#

Jeśli chcesz uniknąć większości błędów:

  1. Podawaj kontekst technologiczny.
  2. Określaj architekturę i warstwę.
  3. Definiuj kontrakt błędów.
  4. Wskazuj przypadki brzegowe.
  5. Dziel problem na iteracje.
  6. Precyzuj poziom abstrakcji.
  7. Jasno definiuj kryteria jakości.

Traktuj prompt jak dokument techniczny w wersji skróconej. Każde niedopowiedzenie to miejsce, w którym model wypełni lukę własnym założeniem. A skoro to Ty projektujesz system, to Ty powinieneś projektować również zapytania.

Dobrze napisany prompt nie jest długi dla samej długości. Jest precyzyjny. A precyzja w inżynierii oprogramowania zawsze się opłaca – niezależnie od tego, czy kod pisze człowiek, czy wspiera go sztuczna inteligencja.

Linki zewnętrzne
Udostępnij
Zachowaj link lub przekaż artykuł dalej.
Newsletter

Dołącz do naszego stada

Krótko, konkretnie i bez szumu. Najnowsze artykuły oraz praktyczne materiały trafiają prosto do skrzynki.

Zapis oznacza akceptację Polityki prywatności.