Generowanie zadań i implementowanie kodu

Zakończone

Plany techniczne zapewniają kierunek architektury, ale implementacja wymaga konkretnych, praktycznych kroków. W tej lekcji omówiono zaawansowane techniki generowania zadań i zarządzania dla scenariuszy przedsiębiorstwa.

Przegląd podstaw zadań

Polecenie zestawu GitHub Spec Kit /speckit.tasks konwertuje wysokopoziomowe decyzje architektoniczne na określone elementy robocze w pliku o nazwie tasks.md. Każde zadanie reprezentuje dyskretną jednostkę pracy, którą można zaimplementować, przetestować i zweryfikować niezależnie.

Kluczowe cechy dobrze określonych zadań:

  • Możliwość działania: jasno określa, co należy zrobić.
  • Testowalne: weryfikacja ukończenia jest prosta.
  • Niezależne: można wykonać bez oczekiwania na niepowiązaną pracę.
  • Ograniczone czasowo: można wykonać w rozsądnym przedziale czasu (od kilku godzin do dnia).

Organizacja oparta na fazach

Złożone funkcje korzystają z organizowania zadań w fazy. Na przykład: Setup, Foundation, Core Functionality, UI/Integration, Security i Testing. Każda faza reprezentuje grupowanie logiczne, które dąży do kamienia milowego.

Zalety podziału zadań

Podziały zadań służą wielu celom poza organizowaniem pracy. Ułatwiają one generowanie ukierunkowanego kodu sztucznej inteligencji dla określonych celów zamiast próby zaimplementowania całych funkcji w ramach pojedynczych operacji. Tworzą naturalne punkty weryfikacji, w których można przetestować częściowe implementacje przed kontynuowaniem. Umożliwiają dokładne śledzenie postępu, pokazując dokładnie, co zostało ukończone i co pozostało. Ułatwiają one koordynację zespołu przez jawne tworzenie zależności.

W przypadku funkcji przekazywania dokumentu plan opisuje ogólną architekturę i opcje technologii. Lista zadań tłumaczy decyzje dotyczące architektury na określone akcje: tworzenie tabeli bazy danych, implementowanie punktu końcowego interfejsu API, kompilowanie składnika React, dodawanie logiki walidacji, pisanie testów. Każde zadanie jest wystarczająco małe, aby wykonać je w rozsądnym przedziale czasu, a jednocześnie wystarczająco duże, aby reprezentować znaczący postęp.

Badanie struktury zadań i organizacji

Dobrze ustrukturyzowana lista zadań organizuje pracę w sposób logiczny, prawidłowo określa sekwencje zależności i przedstawia jasne wskazówki dotyczące wdrożenia.

Organizacja oparta na fazach

Złożone funkcje korzystają z organizacji opartej na fazach. Każda faza reprezentuje logiczne grupowanie powiązanych zadań, które prowadzą do określonego kamienia milowego.

W przypadku funkcji przekazywania dokumentu typowa struktura fazowa może obejmować:

  • Faza 1. Podstawy i konfiguracja

    • Skonfiguruj konfigurację połączenia usługi Azure Blob Storage w appsettings.json.
    • Utwórz tabelę DocumentMetadata w bazie danych SQL z odpowiednim schematem.
    • Dodaj pakiet NuGet Azure.Storage.Blobs do projektu zaplecza.
    • Utwórz klasę DocumentService, która hermetyzuje operacje magazynowania.
  • Faza 2. Podstawowa funkcja przesyłania

    • Zaimplementuj punkt końcowy POST /api/documents/upload w DocumentsController.
    • Dodaj logikę walidacji pliku (rozmiar, typ) do usługi DocumentService.
    • Zaimplementuj metodę przesyłania do magazynu obiektów blob z obsługą błędów.
    • Zapisz metadane dokumentu w bazie danych po pomyślnym przesłaniu.
    • Zwróć wynik przesyłania z identyfikatorem dokumentu i adresem URL do klienta.
  • Faza 3. Implementacja frontonu

    • Utwórz komponent DocumentUpload React z wejściem pliku.
    • Dodaj walidację rozmiaru i typu pliku w składniku.
    • Zaimplementuj wskaźnik postępu ładowania.
    • Obsługa sukcesu przesyłania oraz odpowiedzi na błędy.
    • Odśwież listę dokumentów po pomyślnym przesłaniu plików.
  • Faza 4. Zabezpieczenia i walidacja

    • Dodaj sprawdzanie uwierzytelniania Microsoft Entra ID do punktu końcowego przesyłania.
    • Zaimplementuj walidację typu pliku po stronie serwera przy użyciu liczb magicznych.
    • Dodaj limity rozmiaru żądania, które uniemożliwiają ataki typu DoS.
    • Zweryfikuj rozszerzenia plików na liście dozwolonych.
    • Dodaj logowanie dla operacji przesyłania.
  • Faza 5. Testowanie i dokumentacja

    • Napisz testy jednostkowe dla metod przesyłania w DocumentService.
    • Tworzenie testu integracyjnego dla kompletnego procesu przesyłania.
    • Dodaj testy scenariuszy błędów (nieprawidłowy typ pliku, przekroczono rozmiar).
    • Udokumentuj punkt końcowy API w OpenAPI/Swagger.
    • Zaktualizuj dokumentację użytkownika z instrukcjami przesyłania.

Takie podejście etapowe tworzy naturalne kamienie milowe. Po fazie 2 masz działające, ale minimalne zaplecze. Po fazie 3 użytkownicy mogą przekazywać pliki. Po fazie 4 system jest bezpieczny i gotowy do produkcji. Po fazie 5 wszystko jest testowane i udokumentowane.

Stopień szczegółowości i zakresu zadań

Każde zadanie powinno być odpowiednio ograniczone — jest wystarczająco szczegółowe, aby zapewnić jasny kierunek, ale nie tak szczegółowe, że staje się to normatywne mikrozarządzanie.

Dobrze ograniczone zadania mają następujące cechy:

  • Możliwość działania: Zadanie jasno określa, co należy zrobić.
  • Możliwość testowania: możesz sprawdzić, kiedy zadanie zostało ukończone.
  • Niezależne, jeśli to możliwe: zadanie można wykonać bez oczekiwania na niepowiązaną pracę.
  • Ograniczone czasowo: deweloper może wykonać zadanie w rozsądnym przedziale czasu (zazwyczaj godzin do dnia, a nie tygodni).

Przykład dobrze ograniczonego zadania: "Implementowanie punktu końcowego POST /api/documents/upload, który akceptuje przekazywanie plików wieloczęściowych, sprawdza, czy rozmiar pliku wynosi poniżej 50 MB, przechowuje plik w usłudze Azure Blob Storage i zwraca adres URL obiektu blob i identyfikator dokumentu".

To zadanie jest specyficzne dla tego, co należy skompilować (punkt końcowy), co akceptuje (pliki wieloczęściowe), jakie walidacje mają być stosowane (limit rozmiaru), gdzie przechowywać pliki (Azure Blob Storage) i co należy zwrócić (adres URL i identyfikator). Deweloper wie dokładnie, co należy zaimplementować.

Oto przykład zadania o niewystarczającym zakresie: "Spraw, aby przesyłanie działało." Ten przykład nie zawiera praktycznych wskazówek na temat tego, co oznacza "działać" ani jakie elementy są zaangażowane.

Oto przykład nadmiernie nakazowego zadania: "W wierszu 47 DocumentsController.cs dodaj metodę o nazwie UploadDocument z parametrami (plik IFormFile, ciąg userId) i zaimplementuj ją przy użyciu dokładnie tych kroków..." Ten opis zadania usuwa agencję deweloperów i nie uwzględnia zmieniającej się struktury kodu.

Zależności zadań i sekwencjonowanie

Kolejność zadań ma znaczenie. Niektóre zadania muszą zostać wykonane, zanim inne będą mogły rozpocząć.

Zmiany schematu bazy danych zazwyczaj pojawiają się jako pierwsze, ponieważ kod zaplecza zależy od istnienia schematu. Punkty końcowe API backendu są dostępne przed komponentami frontendu, które wywołują te punkty końcowe. Konfiguracja poprzedza kod korzystający z tej konfiguracji. Testowanie następuje po tym, jak istnieje kod, który jest testowany.

Lista zadań powinna być ułożona tak, aby zminimalizować zatory. Jeśli zadania frontonu i zaplecza są niezależne, mogą one działać równolegle. Jeśli istnieje wiele punktów końcowych zaplecza, deweloperzy mogą implementować zadania współbieżnie.

W przypadku funkcji przekazywania dokumentu sekwencja logiczna zapewnia:

  1. Konfiguracja i konfiguracja bazy danych są wykonywane jako pierwsze (brak zależności).
  2. Implementacja interfejsu API zaplecza jest zgodna z konfiguracją bazy danych (zależy od schematu).
  3. Komponenty front-end są zależne od implementacji interfejsu API (zależnie od istniejących punktów końcowych).
  4. Wzmocnienie zabezpieczeń odbywa się po podstawowych funkcjach (zależy od istniejącego kodu).
  5. Testowanie odbywa się po całej implementacji (zależy od ukończonego kodu).

Ta sekwencja zadań umożliwia ciągły postęp bez oczekiwania na ukończenie niepowiązanej pracy.

Generowanie zadań przy użyciu /speckit.tasks

GitHub Spec Kit generuje listy zadań za pomocą polecenia /speckit.tasks w usłudze GitHub Copilot Chat. To polecenie przetwarza zarówno spec.md, jak i plan.md w celu utworzenia kompleksowej, uporządkowanej listy zadań implementacji.

Sztuczna inteligencja analizuje specyfikację, aby zrozumieć, co należy skompilować, przegląda plan, aby zrozumieć podejście architektoniczne i generuje zadania, które łączą luki między tymi dokumentami i rzeczywistym kodem. Wynikowy plik tasks.md zawiera ponumerowane lub punktowane zadania, często zorganizowane w fazy dla złożonych funkcji.

Wywołaj polecenie generowania zadań

Otwórz aplikację GitHub Copilot Chat w programie Visual Studio Code i wprowadź polecenie /speckit.tasks. Usługa GitHub Copilot przetwarza specyfikację i plan, aby wygenerować listę zadań ze strukturą. Proces generowania zwykle kończy się w ciągu kilku minut, tworząc kompleksowy podział prac implementacji.

Lista zadań automatycznie dziedziczy kontekst ze specyfikacji technicznej i planu. Jeśli plan określa "używanie Azure Blob Storage", wygenerowane zadania obejmują konkretne kroki konfigurowania połączeń magazynowania obiektów blob, implementowania logiki przesyłania i obsługi błędów magazynowania.

Przejrzyj i zweryfikuj listę zadań

Lista zadań wymaga krytycznego przeglądu w celu zapewnienia kompletności i poprawności.

Weryfikowanie pokrycia elementów planu

Porównaj tasks.md z plan.md systematycznie. Każdy krok podejmowania decyzji i wdrażania architektury w planie powinien odpowiadać jednemu lub kilku zadań.

Jeśli plan określa "implementowanie weryfikacji po stronie serwera", określone zadania powinny obejmować walidację typu pliku, walidację rozmiaru pliku i obsługę odpowiedzi na błędy. Jeśli plan wspomina o "rejestrowaniu zdarzeń audytu", zadanie powinno dotyczyć tworzenia wpisów dziennika dla operacji przekazywania.

Brakujące zadania wskazują na niekompletne generowanie lub elementy planu, które nie przekształcają się w konkretne zadania. Rozwiąż ten problem, dodając zadania ręcznie lub podając więcej kontekstu i ponownie generując.

Sprawdzanie luk logicznych

Poszukaj luk w funkcjach, które nie są oczywiste z planu, ale stają się widoczne podczas rozważania szczegółów implementacji.

Typowe luki obejmują:

  • Obsługa błędów: czy istnieją zadania związane z obsługą błędów sieci, awarii magazynu lub problemów z bazą danych?
  • Sytuacje brzegowe: co się stanie, gdy użytkownicy załadują pliki o identycznych nazwach? Jak obsługiwane jest współbieżne przesyłanie?
  • Konfiguracja: czy parametry połączenia, klucze interfejsu API i punkty końcowe usługi są prawidłowo skonfigurowane?
  • Opinie użytkowników: Jak użytkownicy wiedzą, czy przesyłanie zakończyło się sukcesem czy niepowodzeniem?
  • Oczyszczanie danych: jeśli przekazywanie częściowo zakończy się powodzeniem, a następnie nie powiedzie się, czy proces czyszczenia zostanie przeprowadzony?

Zidentyfikuj te luki podczas przeglądu i dodaj odpowiednie zadania przed rozpoczęciem implementacji.

Ocena kolejności i zależności zadań

Sprawdź, czy zadania są odpowiednio sekwencjonowane. Zadania schematu bazy danych powinny poprzedzać kod, który uzyskuje dostęp do tych tabel. Zadania punktów końcowych API powinny poprzedzać komponenty front-endu, które wywołują te punkty końcowe.

Jeśli znajdziesz zadania poza kolejnością, przeprowadź ich ponowne sekwencjonowanie ręcznie. Jeśli na przykład zadanie z interfejsu użytkownika pojawi się przed odpowiednim zadaniem z części back-end, przenieś je do odpowiedniego etapu.

Rozważ zależności między zadaniami w tej samej fazie. Jeśli dane wyjściowe jednego zadania są wymagane dla innego zadania, upewnij się, że pierwsze zadanie pojawi się wcześniej w sekwencji.

Weryfikowanie stopnia szczegółowości zadania

Upewnij się, że zakres każdego zadania jest odpowiednio określony. Zadania, które są zbyt duże ("implementowanie całego zaplecza") powinny być podzielone na mniejsze, możliwe do zarządzania elementy. Zadania, które są zbyt małe ("dodaj średnik do wiersza 42") powinny być łączone w bardziej znaczące jednostki.

Dobrze ograniczone zadanie zwykle trwa od kilku godzin do dnia, może być testowane niezależnie i generuje demonstrowalny postęp.

Używanie zadań do kierowania implementacją

Po zweryfikowaniu tasks.md stanie się planem implementacji.

Systematyczne przechodzenie przez zadania

Przepracuj zadania w kolejności, wykonując poszczególne zadania przed przejściem do następnego. Takie zdyscyplinowane podejście gwarantuje, że nic nie zostanie pominięte i zapewni jasne wskaźniki postępu.

Podczas wykonywania każdego zadania:

  1. Zaimplementuj wymagane funkcje.
  2. Przetestuj implementację, aby zweryfikować poprawność.
  3. Oznacz zadanie jako ukończone (dodaj pole wyboru lub zastosuj przekreślenie).
  4. Zatwierdź zmiany przy użyciu odwołania do zadania.

Takie systematyczne podejście tworzy wyraźny dziennik inspekcji łączący ukończoną pracę z określonymi zadaniami.

Śledzenie postępu i informowanie o stanie

Lista zadań zawiera obiektywną miarę postępu. Jeśli ukończono 15 z 30 zadań, funkcja jest zaimplementowana około 50%. Ta metryka pomaga w planowaniu projektu i komunikacji uczestników projektu.

Udostępnij tasks.md zespołowi, aby przekazać informacje o tym, co zostało ukończone i co pozostało. Członkowie zespołu mogą zobaczyć na pierwszy rzut oka, które obszary wymagają uwagi i gdzie skupić się na wysiłkach związanych z przeglądem.

Dostosowywanie zadań podczas implementacji

Jeśli implementacja ujawni nowe wymagania lub lepsze podejścia, należy odpowiednio zaktualizować tasks.md. Lista zadań powinna odzwierciedlać rzeczywistość, a nie nieaktualny plan.

Dystrybuuj zadania między członkami zespołu

Jasne definicje zadań umożliwiają podział pracy między wieloma deweloperami. Zespół zaplecza może pracować nad zadaniami interfejsu API, podczas gdy zespół frontonu tworzy składniki interfejsu użytkownika. Administratorzy baz danych mogą konfigurować schematy, gdy deweloperzy przygotowują konfigurację.

Jawne wywoływanie zależności zadań pomaga zapobiec blokowaniu. Jeśli zadanie B zależy od zadania A, upewnij się, że zadanie A jest przypisane i odpowiednio priorytetowe. Ustalaj kryteria dotyczące ukończenia dokumentów w zadaniach, aby zapewnić, że przekazywanie jest bezproblemowe.

Generowanie kodu przy użyciu /speckit.implement

Polecenie /speckit.implement używa tasks.md do systematycznego generowania kodu. Zamiast próbować implementować pełne funkcjonalności w jednym przebiegu, sztuczna inteligencja wykonuje zadania sekwencyjnie. Takie podejście tworzy bardziej skoncentrowany, poprawny kod.

Można wywołać /speckit.implement przy użyciu określonego numeru zadania, zakresu zadań lub opisu implementacji pobranej z pliku tasks.md. Sztuczna inteligencja odwołuje się do spec.md, plan.md i tasks.md, w celu utworzenia kodu zgodnego z ogólną architekturą i wymaganiami.

Na przykład, aby zaimplementować punkt końcowy przesyłania dokumentu, możesz wprowadzić następujące polecenie:

/speckit.implement Implement the MVP first strategy (Tasks: T001 - T027)

To polecenie nakazuje sztucznej inteligencji skupienie się na zadaniach od T001 do T027, generując kod spełniający wymagania każdego zadania w sekwencji.

Zapewnianie pomocy podczas implementacji

Sztuczna inteligencja może wymagać pomocy lub uprawnienia do kontynuowania określonych zadań. Jeśli na przykład zadanie wymaga kompilowania lub uruchamiania aplikacji, przed kontynuowaniem sztuczna inteligencja może wyświetlić monit o potwierdzenie.

Ponadto sztuczna inteligencja może wykryć usterkę podczas testowania implementacji zadania. Podaj szczegółowe informacje ułatwiające diagnozowanie problemu. Możesz również podać dodatkowy kontekst lub wyjaśnienia, jeśli sztuczna inteligencja napotka niejednoznaczności.

Po wyświetleniu monitu o pomoc w widoku czatu szybka odpowiedź pomaga w sprawnemu przebiegowi implementacji.

Punkty kontrolne weryfikacji

Po wykonaniu polecenia implementacji przed kontynuowaniem sprawdź wyniki. Uruchom aplikację, wykonaj testy i upewnij się, że każde zadanie zostało zaimplementowane, a jego cel jest osiągany. Weryfikacja przyrostowa wychwytuje problemy na wczesnym etapie, gdy najłatwiej je rozwiązać.

Konserwacja kontekstu między zadaniami

Podczas wykonywania zadań wcześniej ukończone zadania zapewniają kontekst dla kolejnych zadań. Sztuczna inteligencja może odwoływać się do wcześniejszych implementacji podczas tworzenia powiązanych funkcji, poprawy jakości kodu i utrzymania spójności architektury.

Typowe wyzwania występują podczas zarządzania zadaniami implementacji.

Zadania, które rosną w zakresie

Gdy zadanie ujawnia nieoczekiwaną złożoność podczas implementacji, wstrzymaj i ponownie oceń. Podziel jedno złożone zadanie na wiele mniejszych zadań. Zaktualizuj tasks.md, aby odzwierciedlić prawdziwy zakres. Komunikowanie rozszerzenia zakresu interesariuszom.

Zablokowane zadania

Zadania czasami są blokowane przez zależności zewnętrzne. Oznacz zadania zablokowane jawnie w tasks.md z przyczynami blokowania: "BLOCKED: Waiting for Azure Blob Storage container provisioning - ticket #1234". Śledź zablokowane zadania oddzielnie, aby upewnić się, że nie zostaną zapomniane.

Zmienianie priorytetów

Potrzeby biznesowe ewoluują. W przypadku zmiany priorytetów należy odpowiednio zaktualizować tasks.md. Zmień kolejność zadań w sposób odzwierciedlający nowe priorytety. Dodaj nowe zadania dla pojawiających się wymagań. Rozważ odroczenie lub usunięcie zadań, które nie są już cenne.

Niejednoznaczność zadania wykryta podczas implementacji

Gdy pojawia się niejednoznaczność, wstrzymaj implementację i zasięgnij wyjaśnień. Przejrzyj specyfikację i zaplanuj, aby zrozumieć oryginalną intencję. Przed kontynuowaniem zaktualizuj opis zadania za pomocą określonego, jednoznacznego języka.

Podsumowanie

Generowanie zadań przekształca plany architektury w kroki implementacji umożliwiające podejmowanie działań. Generowanie list zadań za pomocą polecenia /speckit.tasks w celu utworzenia ustrukturyzowanych podziałów opartych na fazach pracy implementacji. Przejrzyj wygenerowane zadania krytyczne w celu zapewnienia kompleksowego pokrycia, sekwencjonowania logicznego i odpowiedniego stopnia szczegółowości. Lista zweryfikowanych zadań służy do prowadzenia systematycznej implementacji, śledzenia postępu i koordynowania wysiłków zespołu.

Połączenie spec.md, plan.md i tasks.md tworzy pełne ramy rozwoju. Specyfikacja definiuje, co należy zbudować i dlaczego. Plan definiuje sposób jego tworzenia architektonicznego. Zadania definiują określone kroki do wykonania kompilacji. Razem te artefakty przekształcają niejednoznaczne wymagania w konkretne, śledzone prace programistyczne, które utrzymują dopasowanie do celów projektu w całej implementacji.