Paweł Łukasiewicz: programista blogger
Paweł Łukasiewicz
2026-04-01
Paweł Łukasiewicz: programista blogger
Paweł Łukasiewicz
2026-04-01
Udostępnij Udostępnij Kontakt
Wprowadzenie

W poprzednim artykule nauczyłeś się tworzyć agentów – wyspecjalizowanych ekspertów których przywołujesz przez /agent. Skills to mechanizm komplementarny, ale działający inaczej: zamiast zmieniać jak Copilot myśli, Skills definiują konkretne kroki które wykonuje automatycznie, bez żadnego wywołania.

Wyobraź sobie że za każdym razem gdy piszesz "zrób code review", Copilot automatycznie stosuje pełną 10-punktową checklistę Twojego zespołu. Nie musisz jej wpisywać, nie musisz wywoływać żadnej komendy – Copilot sam rozpoznaje kontekst i ładuje odpowiedni Skill.

Czym są Skills i jak działają

Skills to foldery z plikami instrukcji które Copilot automatycznie ładuje gdy Twój prompt pasuje do opisu Skill. Mechanizm jest prosty:

  • Wpisujesz prompt w naturalnym języku
  • Copilot czyta opis każdego dostępnego Skill'a
  • Jeśli prompt pasuje – ładuje Skill i stosuje jej instrukcje
  • Ty dostajesz wynik zgodny ze zdefiniowanymi standardami bez żadnego dodatkowego wysiłku
🌟 Bez Skills vs z Skills – konkretna różnica

Bez Skills: Musisz za każdym razem pisać długi prompt:

> Przejrzyj kod sprawdzając: brak XML docs na publicznych metodach,
  brak walidacji parametrów, niespójną obsługę wyjątków, metody dłuższe
  niż 30 linii, brak async/await gdzie potrzeba, nullable reference types...

Z Skills: Po prostu pytasz naturalnie:

> Przejrzyj @TaskService.cs pod kątem jakości kodu

Copilot rozpoznaje "jakość kodu" jako pasujące do Twojej Skill dotnet-checklist i automatycznie stosuje całą checklistę – bez wpisywania jej za każdym razem.

Możesz też wywoływać Skill bezpośrednio jako slash komendę:

copilot

> /dotnet-checklist Przejrzyj @TaskService.cs
> /xunit-gen Wygeneruj testy dla @TaskService.cs
> /commit-message Wygeneruj commit message dla staged zmian
🔍 Skills vs Agenci vs MCP – kiedy co?
Mechanizm Co zmienia Kiedy używać
Agenci Sposób myślenia i ekspertyzę AI Specjalistyczna wiedza przez wiele zadań (dotnet-reviewer, security-reviewer)
Skills Konkretne kroki dla powtarzalnych zadań Standardowe procedury: checklista review, szablon testów, format commitów
MCP Dostęp do zewnętrznych danych i usług Połączenie z GitHub API, bazą danych, zewnętrznymi narzędziami (artykuł 06)

Agent i Skill mogą działać razem: agent dotnet-reviewer może automatycznie zastosować Skill dotnet-checklist gdy robisz code review.

Format pliku SKILL.md

Każda Skill to folder z plikiem SKILL.md. Dwie lokalizacje – te same co dla agentów:

  • .github/skills/ – Skills projektu, wersjonowane w repozytorium, dostępne dla całego teamu
  • ~/.copilot/skills/ – Skills osobiste, dostępne we wszystkich projektach

Struktura folderu Skill:

.github/skills/
└── dotnet-checklist/          # nazwa folderu = nazwa Skill
    ├── SKILL.md               # WYMAGANY: definicja i instrukcje
    ├── examples/              # opcjonalnie: przykłady do których może się odwołać
    │   └── good-method.cs
    └── scripts/               # opcjonalnie: skrypty które Skill może uruchomić
        └── run-analysis.sh

Format pliku SKILL.md:

---
name: dotnet-checklist
description: Comprehensive .NET/C# code quality checklist checking XML docs,
  nullable reference types, async/await patterns, exception handling,
  and SOLID principles. Use for code reviews and quality checks.
license: MIT
---

# .NET Code Quality Checklist

Instrukcje w zwykłym Markdown...
(szczegółowa zawartość poniżej)
🔍 Właściwości YAML w SKILL.md
Właściwość Wymagana? Uwagi
name Tak Lowercase z myślnikami; używasz jako /nazwa przy bezpośrednim wywołaniu
description Tak Kluczowe: na podstawie tego Copilot decyduje czy załadować Skill automatycznie
license Nie Przydatne gdy dzielisz Skills z zespołem lub community
⚠️ Najważniejsza zasada: description decyduje o wszystkim

Pole description to mechanizm auto-discovery. Copilot porównuje Twój prompt z opisami wszystkich dostępnych Skills i ładuje pasujące. Jeśli opis jest zbyt ogólny – Skill nigdy się nie załaduje automatycznie.

Słabe: description: Reviews code

Dobre: description: .NET/C# code quality checklist for code reviews, checking XML documentation, nullable reference types, async patterns, exception handling, and SOLID principles

Złota zasada: wpisuj słowa kluczowe których naturalnie używasz gdy o to prosisz. Jeśli mówisz "jakość kodu", wpisz "jakość kodu" w description.

Trzy gotowe Skills dla projektu .NET

Poniżej trzy kompletne Skills gotowe do skopiowania. Każda rozwiązuje inny problem z codziennej pracy .NET developera.

Skill 1: dotnet-checklist – checklista jakości kodu C#

Utwórz plik .github/skills/dotnet-checklist/SKILL.md:

---
name: dotnet-checklist
description: .NET/C# code quality checklist for code reviews, quality checks,
  finding issues in C# code. Checks XML documentation, nullable reference types,
  async/await patterns, exception handling, and SOLID principles.
---

# .NET Code Quality Checklist

Sprawdzaj kod C# według poniższej listy i raportuj wyniki.

## Dokumentacja i czytelność
- [ ] Wszystkie publiczne metody i klasy mają XML documentation (`///`)
- [ ] Nazwy zmiennych i metod są opisowe i zgodne z konwencją PascalCase/camelCase
- [ ] Brak magicznych liczb – zamiast nich nazwane stałe

## Null Safety
- [ ] Nullable reference types są respektowane (brak `!` bez uzasadnienia)
- [ ] Brak jawnych `NullReferenceException` – kod jest defensywny
- [ ] `ArgumentNullException.ThrowIfNull()` lub null-conditional operators zamiast ręcznych checków

## Obsługa błędów
- [ ] Brak pustych bloków catch (`catch { }` lub `catch (Exception) { }`)
- [ ] Wyjątki mają sensowne komunikaty z kontekstem
- [ ] Nie łapie się `Exception` gdy można łapać bardziej specyficzny typ
- [ ] Brak swallowania wyjątków przez logowanie i re-throw bez re-throw

## Async/Await
- [ ] Brak `.Result` lub `.Wait()` na Task (ryzyko deadlocka)
- [ ] Brak `async void` (poza event handlerami)
- [ ] `ConfigureAwait(false)` w bibliotekach (nie w aplikacjach)
- [ ] CancellationToken propagowany przez cały łańcuch wywołań

## Architektura
- [ ] Metody nie przekraczają 30 linii
- [ ] Klasy mają jedną odpowiedzialność (SRP)
- [ ] Brak bezpośrednich zależności – zamiast tego interfejsy
- [ ] Brak statycznych metod z side effects

## Format raportu
Dla każdej kategorii: [PASS] jeśli OK, [WARN] jeśli warto poprawić,
[FAIL] jeśli wymaga naprawy przed mergem. Na końcu podsumowanie.

Skill 2: xunit-gen – generator testów xUnit

Utwórz plik .github/skills/xunit-gen/SKILL.md:

---
name: xunit-gen
description: Generate xUnit tests for .NET/C# code with FluentAssertions and Moq.
  Use when generating unit tests, creating test coverage, writing test cases for C# classes.
---

# xUnit Test Generator

Generuj testy xUnit zgodnie z poniższymi standardami.

## Struktura testu
- Używaj sekcji Arrange/Act/Assert z komentarzami
- Nazewnictwo: `MethodName_Scenario_ExpectedResult`
  Przykłady: `Search_EmptyQuery_ThrowsArgumentException`,
             `MarkDone_ValidNumber_ReturnsTrueAndSetsFlag`
- Jedna asercja logiczna per test (wiele FluentAssertions na tym samym obiekcie jest OK)

## Asercje – zawsze FluentAssertions
```csharp
// TAK:
result.Should().Be(expected);
result.Should().BeEmpty();
result.Should().Throw().WithMessage("*query*");
// NIE:
Assert.Equal(expected, result);
Assert.Empty(result);
```

## Mocki – Moq z MockBehavior.Strict
```csharp
var mockRepo = new Mock(MockBehavior.Strict);
mockRepo.Setup(r => r.GetAll()).Returns(testTasks);
```

## Pokrycie – dla każdej metody publicznej wygeneruj:
1. Happy path z typowymi danymi
2. Minimum 2 edge cases (null, pusty string, granica zakresu)
3. Test dla każdego wyjątku który metoda rzuca
4. [Theory] z [InlineData] dla metod z wieloma wariantami wejścia

## Dane testowe
- Używaj `[Fact]` dla jednostkowych przypadków
- Używaj `[Theory][InlineData(...)]` dla parametryzowanych
- Builder pattern lub małe metody pomocnicze dla złożonych obiektów testowych

Skill 3: commit-message – generator conventional commits

Utwórz plik .github/skills/commit-message/SKILL.md:

---
name: commit-message
description: Generate conventional commit messages for staged git changes.
  Use when writing commit messages, creating git commits, describing code changes.
---

# Conventional Commit Message Generator

Generuj wiadomości commitów zgodne z Conventional Commits.

## Format
```
(): 

[opcjonalne ciało – jeśli zmiany są nieoczywiste]

[opcjonalne stopki – BREAKING CHANGE, refs #issue]
```

## Typy
- `feat` – nowa funkcja
- `fix` – naprawa buga
- `refactor` – zmiana kodu bez zmiany zachowania
- `test` – dodanie lub zmiana testów
- `docs` – tylko dokumentacja
- `chore` – konfiguracja, zależności, CI
- `perf` – poprawa wydajności
- `style` – formatowanie, brak zmiany logiki

## Scope dla projektu .NET
Używaj nazwy klasy, modułu lub warstwy:
`feat(TaskService): ...`, `fix(Program): ...`, `test(TaskServiceTests): ...`

## Zasady
- Opis max 72 znaki
- Tryb rozkazujący: "add validation" nie "added validation"
- Jeśli jest BREAKING CHANGE – zawsze dodaj stopkę `BREAKING CHANGE: opis`
- Jeśli dotyczy issue GitHub – dodaj `refs #123` lub `closes #123`

## Przykłady
```
feat(TaskService): add case-insensitive search method

fix(Program): prevent crash when tasks.json is corrupted

test(TaskServiceTests): add edge cases for Remove() method boundary values

refactor(TaskService): replace bool returns with custom exceptions
```
Zarządzanie Skills

Podstawowe komendy /skills

copilot

> /skills list              # lista wszystkich zainstalowanych Skills
> /skills info dotnet-checklist   # szczegóły konkretnej Skill
> /skills reload            # przeładuj po edycji SKILL.md
> /skills add        # zainstaluj Skill z marketplace/repozytorium
> /skills remove     # usuń Skill
🔍 Kiedy używać /skills reload?

Po stworzeniu lub edycji pliku SKILL.md musisz przeładować Skills żeby zmiany były widoczne w bieżącej sesji. Nie trzeba restarować CLI – /skills reload wystarczy.

copilot

# Edytowałeś SKILL.md...
> /skills reload
Skills przeładowane pomyślnie.

# Teraz możesz od razu używać zaktualizowanej Skill
> Przejrzyj @TaskService.cs pod kątem jakości kodu

Dobra wiadomość: Skills działają poprawnie po /compact – nie musisz ich przeładowywać po kompresji kontekstu.

Weryfikacja czy Skill zadziałała

copilot

# Po otrzymaniu odpowiedzi – zapytaj wprost
> Których Skills użyłeś dla tej odpowiedzi?

# Lub przed zadaniem pytania
> Jakie Skills masz dostępne do code review?

# Porównanie z/bez Skills
copilot --allow-all -p "Review @TaskService.cs" --no-custom-instructions
# vs
copilot --allow-all -p "Review @TaskService.cs"
⚠️ Trzy najczęstsze błędy przy tworzeniu Skills
  • Plik nazwany inaczej niż SKILL.md – plik musi nazywać się dokładnie SKILL.md, wielkość liter ma znaczenie
  • Zbyt ogólny description – "Reviews code" nigdy się nie dopasuje; pisz konkretne słowa kluczowe
  • Zła lokalizacja – Skill musi być w .github/skills/nazwa-skill/SKILL.md lub ~/.copilot/skills/nazwa-skill/SKILL.md, nie bezpośrednio w .github/skills/SKILL.md
Skills dla codziennej pracy .NET developera

Trzy Skills które stworzyliśmy wyżej to dobry start. Oto kilka pomysłów na kolejne, specyficznych dla ekosystemu .NET:

Nazwa Skill Kiedy się ładuje Co robi
ef-migration "dodaj migrację", "zmień schemat bazy" Generuje migrację EF Core z dobrymi praktykami (nullable, indeksy, rollback)
aspnet-controller "dodaj endpoint", "stwórz kontroler" Scaffold kontrolera ASP.NET z walidacją, obsługą błędów i XML docs
pr-review "przejrzyj PR", "sprawdź zmiany" 10-punktowa checklista PR specyficzna dla Twojego projektu
changelog-entry "dodaj do changelogu", "opisz zmianę" Generuje wpis CHANGELOG.md w Keep a Changelog format
dto-mapper "stwórz DTO", "zmapuj model" Generuje DTO, extension methods do mapowania i testy mapowania
🔍 Skills vs alias shellowy – kiedy co?

Możesz mieć alias shellowy: alias review='copilot -p "przejrzyj ten kod..."'. Kiedy Skill jest lepszy?

  • Alias shell – prosta, zawsze ta sama komenda, bez AI; szybki dostęp do komendy terminalowej
  • Skill – gdy instrukcje są złożone i wielokrokowe; gdy chcesz że Skill ładuje się automatycznie w kontekście; gdy chcesz dzielić z teamem przez git

Prosta reguła: jeśli instrukcja mieści się w jednej linii – alias. Jeśli to wielopunktowa checklista albo szczegółowy szablon – Skill.

Ćwiczenie – zbuduj swój zestaw Skills

💪 Ćwiczenie: trzy Skills dla projektu TaskList

Stwórz trzy Skills z powyższych przykładów i przetestuj je:

# Stwórz strukturę folderów
mkdir -p .github/skills/dotnet-checklist
mkdir -p .github/skills/xunit-gen
mkdir -p .github/skills/commit-message

# Skopiuj zawartość SKILL.md z artykułu do każdego folderu, następnie:

copilot

# Przeładuj Skills
> /skills list
> /skills reload

# Test 1: auto-trigger dotnet-checklist
> Przejrzyj @TaskService.cs pod kątem jakości kodu C#

# Test 2: auto-trigger xunit-gen
> Wygeneruj testy jednostkowe dla @TaskService.cs

# Test 3: bezpośrednie wywołanie commit-message
> /commit-message Wygeneruj commit message dla staged zmian

Po każdym teście zapytaj: > Których Skills użyłeś? – zweryfikuj że automatyczne wykrywanie działa.

Porównanie: Uruchom ten sam prompt z flagą --no-custom-instructions i bez niej. Jak bardzo różni się output?

Podsumowanie

Skills to mechanizm który zamienia Twoje best practices w automatyczne standardy – raz napisane, zawsze stosowane, dla całego teamu.

  • Auto-trigger – Copilot ładuje Skills automatycznie gdy prompt pasuje do description; nie musisz nic wywoływać
  • Bezpośrednie wywołanie – zawsze możesz wywołać Skill przez /nazwa-skill gdy chcesz mieć pewność że zostanie użyta
  • SKILL.md – plik musi nazywać się dokładnie tak; name i description są wymagane
  • Description = discovery – to jedyna rzecz która decyduje o automatycznym ładowaniu; pisz konkretne słowa kluczowe
  • Agenci + Skills – agent dotnet-reviewer może automatycznie stosować Skill dotnet-checklist; oba mechanizmy się uzupełniają

W następnym artykule wyjdziemy poza granice lokalnego projektu: MCP Servers pozwalają Copilotowi połączyć się z GitHub API, bazami danych i zewnętrznymi usługami – i zadawać pytania o żywe dane, nie tylko o pliki na dysku.

Do zobaczenia w artykule 06! 🚀