Przejdź do głównej zawartości

Zbuduj swoją pierwszą funkcję z pomocą AI

Pierwsza funkcja budowana z pomocą AI w Cursorze to mała, pełna pętla: najpierw powstają kryteria akceptacji, Plan Mode zamienia je w przejrzany plan, agent buduje krok po kroku z commitem po każdym kroku, a testy przypisane do kryteriów dowodzą wyniku. Funkcja jest gotowa, gdy te dowody przechodzą, a nie gdy agent ogłosi sukces.

Ten samouczek jest dla programisty, który zainstalował Cursora, napisał kilka reguł projektu i chce teraz dowieźć coś prawdziwego. Prosisz agenta o rate limiting, a on w jednej odpowiedzi zmienia dziewięć plików. Testy, które sam napisał, przechodzą, a ty nie masz pojęcia, czy /health za load balancerem wciąż odpowiada. Poniższy proces utrzymuje każdy krok na tyle mały, żeby dało się go sprawdzić, a samo sprawdzanie zamienia w mechaniczną czynność.

  • Zadanie wielkości jednej funkcji, wybrane według czterech kryteriów, dzięki czemu pierwsze podejście czegoś uczy i nie naraża produkcji.
  • Kryteria akceptacji spisane przed pierwszą linią kodu. Stają się zarazem kontraktem planu i listą testów.
  • Pięć promptów do skopiowania: plan, budowa jednego kroku, podpięcie w aplikacji, dowód siły testów i retrospektywa, która aktualizuje reguły.
  • Procedurę weryfikacji (mapa kryterium–test, celowe zepsucie kodu pod każdy test, git status --short --untracked-files=all i git diff --stat, zapytanie do działającego serwera), która zastępuje czytanie całego diffu.
  • Sposoby wyjścia z sześciu sytuacji, w których pierwsza funkcja zwykle idzie źle.

Wybierz zadanie, które sprawdzi agenta, ale na które niczego nie stawiasz.

KryteriumDlaczego ma znaczenie przy pierwszym podejściu
Dotyka 3–8 plikówNa tyle dużo, żeby zobaczyć, czy agent koordynuje zmiany i trzyma się twoich konwencji, i na tyle mało, żeby dało się sprawdzić każdy krok.
Kryteria akceptacji mieszczą się w pięciu linijkachKryteria dają planowi kontrakt, a testom wyrocznię. Mgliste zadania kończą się pewnym siebie kodem, którego nie da się przetestować.
Integruje się z istniejącym kodemPokazuje, czy reguły i indeks repozytorium kierują agenta ku twoim wzorcom.
Leży poza ścieżką krytycznąPomyłka kosztuje revert, a nie incydent.

Dobre pierwsze funkcje: endpoint API z walidacją żądania, obsługa webhooka, panel ustawień, okno preferencji powiadomień. Przebudowę uwierzytelniania i migracje produkcyjnej bazy zostaw na później, gdy będziesz mieć procedurę weryfikacji, której ufasz.

Przykładem na tej stronie jest middleware ograniczający liczbę żądań (rate limiter) z licznikami w pamięci, dla API w Node.js napisanego w TypeScripcie, z Expressem i Vitestem. Obejmuje middleware, konfigurację, routing i testy, a kryje dwie klasyczne pułapki (IP klienta za proxy oraz timery w testach), które pokazują, dlaczego dowody wygrywają z czytaniem.

  1. Zacznij od czystego drzewa roboczego na osobnej gałęzi. W terminalu:

    Okno terminala
    git status --short # nie może nic wypisać; najpierw commit albo stash
    git switch -c feat/rate-limiter
  2. Upewnij się, że każda bramka uruchamia się jednym poleceniem, i zanotuj te polecenia do promptów. W tym przykładzie: npx vitest run, npm run typecheck i npm run lint. Jeśli projekt nie ma jednego polecenia do testów albo sprawdzania typów, napraw to najpierw; zobacz jak przygotować repozytorium do pracy agentów.

  3. Sprawdź, czy reguły projektu są zacommitowane i opisują, gdzie leży middleware i jak czytana jest konfiguracja. Agent robi to, co mówią reguły, więc brakująca konwencja wyjdzie później jako plik w złym katalogu.

  4. Zdecyduj, które polecenia agent może uruchamiać bez pytania. Jeśli tryb uruchamiania (run mode) twojego workspace’u w ustawieniach bezpieczeństwa agenta w Cursorze pozwala z góry zatwierdzać polecenia, zatwierdź w ten sposób tylko polecenia testów, sprawdzania typów i lintera; w przeciwnym razie zatwierdzaj je na bieżąco. Dla wszystkiego innego zostaw zatwierdzanie włączone. Ustawienia agenta opisuje strona niezbędna konfiguracja.

  5. W nowym czacie zadaj agentowi jedno pytanie orientacyjne i porównaj odpowiedź z tym, co wiesz: „Where do the HTTP middleware functions in this repository live, and how do they read configuration?” Błędna odpowiedź oznacza, że przed budową trzeba zająć się indeksem albo regułami.

Kryteria to jedyny artefakt, który musisz przeczytać uważnie, bo wszystko, co powstanie później, sprawdza się właśnie względem nich. Ponumeruj je, żeby plan, testy i przegląd kodu mogły się do nich odwoływać. Pełną metodę opisuje strona o kryteriach akceptacji, których agent nie odczyta źle.

AC1 Requests are counted per client IP. Behind our proxy the client IP comes
from req.ip with Express "trust proxy" set to 1, never from a raw header.
AC2 Window and limit come from RATE_LIMIT_WINDOW_MS (default 900000) and
RATE_LIMIT_MAX (default 100).
AC3 Request number MAX+1 inside the window gets 429 with a JSON error body in
our standard error format and a Retry-After header in whole seconds.
AC4 GET /health and GET /ready are never limited.
AC5 Counters reset when the window ends (fixed window).
AC6 Counters live in memory. Each instance counts separately; this is accepted
until the Redis store ships.

AC6 to celowo zapisane ograniczenie. Recenzent, który wie, że je zaakceptowano, nie traci na nie czasu, a następna osoba nie weźmie go za błąd.

Przełącz agenta w Plan Mode, który tworzy plan implementacji, zanim napisze jakikolwiek kod. Wklej kryteria do promptu, żeby plan powstał względem nich.

Zanim pozwolisz agentowi budować, sprawdź plan według krótkiej listy:

  • Każde kryterium AC1–AC6 ma co najmniej jeden krok i jeden nazwany test.
  • Nowe pliki trafiają tam, gdzie leży istniejący middleware, a plan używa twojego helpera błędów zamiast wymyślać nowy.
  • Nie pojawia się żadna nowa zależność, o którą nie prosiłeś. Nieoczekiwany pakiet to pytanie do rozstrzygnięcia teraz, a nie po instalacji; zobacz kontrolę zależności w zmianach agentów.
  • Testy AC5 używają fake timerów (vi.useFakeTimers()) zamiast prawdziwego czekania.

Poprawiaj plan w tym samym czacie („Middleware goes in src/middleware/, not src/lib/”), aż lista będzie spełniona. Poprawka na tym etapie kosztuje jedno zdanie; ta sama poprawka po budowie kosztuje przepisanie kodu.

Wyjdź z Plan Mode, przełączając czat z powrotem na Agent mode, jak pokazuje sekcja budowanie w Agent mode, i wykonuj plan krok po kroku. Jeden krok na prompt sprawia, że każdą zmianę da się sprawdzić przez git status --short --untracked-files=all, które pokazuje zmienione pliki oraz każdy nowy, nieśledzony plik (oznaczony ??), a ty masz commit, do którego możesz wrócić. Samo git diff --stat tu nie wystarczy, bo pomija pliki utworzone przez agenta. Zostaw --untracked-files=all (krótko -uall): bez tej opcji nowy katalog zwija się do jednej linii katalog/ i ukrywa pliki w środku.

  1. Zbuduj główny moduł razem z testami jednostkowymi. Testy pisane w tym samym kroku co kod utrwalają kryteria, póki są świeże.

    Potem sprawdź zakres i zrób commit:

    Okno terminala
    git status --short --untracked-files=all # oczekuj tylko dwóch plików z promptu
    git add -A && git commit -m "feat: rate limiter core (AC1, AC3, AC5)"
  2. Dodaj konfigurację. Poproś o AC2 osobnym promptem: „Implement plan step 2: read RATE_LIMIT_WINDOW_MS and RATE_LIMIT_MAX the way our other middleware reads config, with the defaults from AC2, and add tests for the defaults and for an override.” Sprawdź git status --short --untracked-files=all i zrób commit.

  3. Podepnij middleware w aplikacji. Ten krok dotyka wspólnego kodu, więc wprost nazwij plik i wyjątki.

    Zrób commit, gdy wszystkie trzy bramki przejdą.

Jeśli agent zmieni albo utworzy plik, którego nie wskazałeś, nie dyskutuj z nim w tym samym czacie. Wróć do ostatniego commita: git reset --hard cofa zmiany w śledzonych plikach, a git clean -fd usuwa nieśledzone pliki utworzone przez agenta. Samo git restore . nie wystarczy: cofa zmiany w śledzonych plikach, ale po cichu zostawia wszystkie nowe pliki utworzone przez agenta. Najpierw podejrzyj to usuwanie przez git clean -nd, bo usunie ono także każdy twój własny nieśledzony plik. Potem powtórz prompt z listą plików oraz wyraźnym „Do not touch any other file.”

Okno terminala
git clean -nd # podgląd: lista nieśledzonych plików do usunięcia
git reset --hard && git clean -fd # powrót do ostatniego commita

Jak udowodnić, że funkcja działa, bez czytania każdej linii

Dział zatytułowany „Jak udowodnić, że funkcja działa, bez czytania każdej linii”

Przechodzące testy napisane przez agenta dowodzą tylko tego, że kod zgadza się z testami. Musisz wiedzieć, że testy wyłapałyby błędną implementację. Następny prompt każe agentowi pokazać to dla każdego kryterium; to mała, ręczna odmiana testowania mutacyjnego. Koncepcję opisuje strona jak silna jest twoja wyrocznia testowa.

Każde „no” w tabeli to prawdziwe znalezisko: albo kryterium nie ma testu, albo test nie potrafi zawieść. Poproś o test, który zawodzi po zepsuciu kodu, i wygeneruj tabelę ponownie. Resztę dowodów zbierz już sam:

  1. Sprawdź, czy cała zmiana ma oczekiwany rozmiar:

    Okno terminala
    git diff --stat main...HEAD

    Każdy plik spoza middleware, konfiguracji, src/app.ts i testów wymaga uzasadnienia.

  2. Sprawdź, czy żaden test nie został osłabiony. Przeszukaj diff gałęzi pod kątem usuniętych asercji i pominiętych testów:

    Okno terminala
    git diff main...HEAD -- '*.test.ts' | grep -E '^-.*expect\(|^\+.*\.(skip|only)\('

    Pusty wynik to dobry wynik. Jak wymusić to poza czatem, wyjaśnia przewodnik chroń wyrocznię.

  3. Odpytaj działający serwer. Ustaw lokalnie RATE_LIMIT_MAX=3, a potem uruchom (albo zrestartuj) serwer deweloperski, żeby wczytał nową wartość. W drugim terminalu wykonaj poniższe polecenia, zamieniając /api/items na dowolną limitowaną ścieżkę:

    Okno terminala
    for i in 1 2 3 4; do curl -s -o /dev/null -w "%{http_code} " http://localhost:3000/api/items; done; echo
    curl -si http://localhost:3000/api/items | grep -i retry-after
    curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3000/health

    Oczekuj 200 200 200 429, nagłówka Retry-After i 200 z /health.

  4. Otwórz pull request z tabelą kryteriów w opisie. Jeśli twój zespół używa Bugbota, przejrzy on pull request pod kątem błędów, problemów bezpieczeństwa i jakości kodu; traktuj jego uwagi jako materiał dla recenzenta, a nie jako bramkę.

Recenzent, ty albo ktoś z zespołu, zatwierdza trzy rzeczy: kryteria, tabelę kryterium–test i zakres z git diff --stat. Czytanie kodu zostaje dla tych fragmentów, których dowody nie obejmują, na przykład logiki wyciągania IP z AC1, bo ma ona znaczenie dla bezpieczeństwa. Gdzie przebiega ta granica, gdy procedura dojrzewa, opisuje strona dowody zamiast diffów.

Co idzie źle przy pierwszej funkcji i jak z tego wyjść

Dział zatytułowany „Co idzie źle przy pierwszej funkcji i jak z tego wyjść”
ObjawPrawdopodobna przyczynaWyjście
Plan umieszcza pliki w złym katalogu albo wymyśla helper, który już maszReguły nie opisują konwencji albo agent nie sprawdził koduPopraw to w Plan Mode przed budową, a potem dopisz konwencję do reguły projektu
Jeden prompt zmienia pliki, o których nie wspominałeśZakres był domyślny, a nie podany wprostPodejrzyj przez git clean -nd, potem wróć do ostatniego commita przez git reset --hard && git clean -fd; powtórz prompt z odwołaniami @ do konkretnych plików i „Do not touch any other file”
Testy przechodzą, ale sprawdzenie curl na działającym serwerze zawodziTesty mockują to, co się zepsuło (często req.ip albo router)Poproś o test integracyjny przez prawdziwą aplikację z supertestem, a potem ponów prompt z psuciem każdego kryterium
Agent kręci się w kółko przy tym samym teścieCzat zawiera kilka nieudanych prób, które ciągną kolejną w tę samą stronęZatrzymaj agenta, wróć do ostatniego commita przez git reset --hard && git clean -fd (podgląd: git clean -nd) i zacznij nowy czat z własną diagnozą; zobacz odzyskiwanie po błędach w Cursorze
Agent „naprawia” test, zmieniając jego oczekiwanieNic nie zabraniało edycji testówCofnij plik testu; dopisz do promptu „Do not modify test files” i sprawdź to poleceniem grep z kroku dowodowego. Żeby wymusić to mechanicznie, dopisz zakaz do reguły projektu albo zablokuj zapis do *.test.ts hookiem Cursora na czas kroków budowania; zobacz ochronę wyroczni testowej
W package.json pojawia się nowy pakietPlan nie wykluczył zależnościCofnij go, chyba że go akceptujesz, a przed ponowną instalacją zweryfikuj nazwę i wydawcę

Każda poprawka, którą wpisałeś przy tej funkcji, to reguła, którą następna sesja powinna już znać. Zanim zamkniesz czat, przeprowadź krótką retrospektywę.

Przyjmuj tylko reguły, które zapobiegłyby prawdziwej poprawce. Plik reguł rozrośnięty o ogólnikowe rady zużywa kontekst przy każdym zapytaniu i niczego nie zmienia.

Ta sama pętla działa dla większych funkcji po trzech zmianach. Podziel kryteria na wycinki, z których każdy kończy się przechodzącym testem, i prowadź jeden czat na wycinek, żeby każdy zaczynał z czystym kontekstem. Zatwierdzony plan zapisz jako plik Markdown w repozytorium i na początku każdego czatu wskaż go przez @, bo plan trzymany tylko w historii czatu znika razem z czatem. Rób commit po każdym kroku planu, a nie po każdym wycinku, żeby zły krok nigdy nie pociągnął za sobą dobrej pracy.

Gdy wycinki są od siebie niezależne, Cursor może uruchomić agentów równolegle, każdego we własnym worktree, z poziomu Agents Window (ręczne worktree opisuje strona o checkpointach i gałęziach); rób to dopiero wtedy, gdy pętla z jednym agentem stanie się rutyną. Zespołową wersję tego procesu opisuje etap Build w cyklu życia.

Używasz też innego agenta? Ta sama pętla w terminalu jest opisana na stronie proces pracy w Claude Code, a w Codexie na stronie pierwsze zadanie w Codexie.