
Skill to folder zawierający SKILL.md: frontmatter YAML (name, description) i instrukcje Markdown, plus skrypty i referencje ładowane na żądanie. Tylko opis pozostaje w kontekście na stałe, i jest ucinany, co czyni go jedynym wyzwalaczem, który się liczy. Ten sam folder działa w Claude Code, Codex, Copilot i OpenCode, pod warunkiem umieszczenia go we właściwym katalogu.
Skill to folder zawierający plik SKILL.md. Napisanie go to łatwa część. Reszta wymaga wiedzy, gdzie go umieścić, żeby agent go znalazł, sprawdzenia, czy naprawdę się wywołuje, i zmierzenia, ile kosztuje przez resztę czasu. Ten przewodnik robi wszystkie trzy rzeczy, na skillu zbudowanym i uruchomionym na tę okazję.
Czym dokładnie jest skill?
Format Agent Skills został stworzony przez Anthropic, a potem opublikowany jako otwarty standard, specyfikacja mieszka dziś na agentskills.io. Mieści się w niewielu elementach: folder, obowiązkowy SKILL.md, i to, co chcesz obok.
regex-verifiee/
├── SKILL.md # wymagany: frontmatter YAML + instrukcje Markdown
├── scripts/ # opcjonalny: kod, który wykonuje agent
├── references/ # opcjonalny: dokumentacja ładowana na żądanie
└── examples/ # opcjonalny: szablony, zbiory danychFrontmatter jest krótki i ograniczony regułami. name: maksymalnie 64 znaki, tylko małe litery, cyfry i myślniki, bez myślnika na początku czy końcu, bez podwójnego myślnika, i musi być identyczny z nazwą folderu nadrzędnego. description: obowiązkowy, maksymalnie 1 024 znaki, mówi, co robi skill i kiedy go używać. Całość uzupełniają trzy pola opcjonalne: license, compatibility (500 znaków) i metadata. Szóste, allowed-tools, jest oznaczone w specyfikacji jako eksperymentalne.
Mechanizm, który czyni sprawę interesującą, nazywa się stopniowym ujawnianiem, na trzech poziomach. Na starcie agent ładuje tylko name i description każdego skilla, specyfikacja celuje w około sto tokenów. Gdy zadanie pasuje, czyta treść SKILL.md (zalecane poniżej 5 000 tokenów, maksymalnie 500 linii). Dopiero potem, jeśli tego potrzebuje, otwiera pliki z scripts/, references/ albo assets/. Wpis inżynierski Anthropic z 16 października 2025 formułuje to z drugiej strony: zadbaj o name i description, bo to na ich podstawie, i tylko na ich podstawie, agent decyduje o wywołaniu skilla.
Skill, który nigdy się nie wywołuje, i tak kosztuje więc swój opis, przy każdej sesji, w każdym oknie kontekstu. To dokładnie to, co mierzy komenda /skill-doctor Claude Code, i to pierwsza pozycja wydatku badana w relacji Spotify o rachunku za tokeny.
Gdzie każdy agent szuka skilli?
To część, której nikt nie opisuje poprawnie, bo zmienia się w zależności od narzędzia. Oto ścieżki, dokładnie tak, jak figurują w dokumentacji każdego wydawcy, otwartej 7 września 2026.
| Narzędzie | Projekt | Użytkownik |
|---|---|---|
| Claude Code | .claude/skills/<nazwa>/SKILL.md | ~/.claude/skills/<nazwa>/SKILL.md |
| Codex | .agents/skills/ (i .codex/skills/, patrz niżej) | $CODEX_HOME/skills, ~/.agents/skills |
| GitHub Copilot | .github/skills, .claude/skills, .agents/skills | ~/.copilot/skills, ~/.agents/skills |
| OpenCode | .opencode/skills, .claude/skills, .agents/skills | ~/.config/opencode/skills, ~/.claude/skills, ~/.agents/skills |
Wynikają z tego dwie rzeczy. .agents/skills staje się wspólną, neutralną ścieżką, czytają ją wszystkie trzy, Codex, Copilot i OpenCode. A Copilot i OpenCode czytają też .claude/skills, folder Claude Code pełni funkcję faktycznego formatu wymiany. Ten sam folder skilla może więc obsługiwać kilku agentów bez duplikowania. Jeśli chodzi o powierzchnie, GitHub zapowiada skille dla agenta chmurowego, przeglądu kodu, Copilot CLI, aplikacji GitHub Copilot i trybu agenta VS Code oraz IDE JetBrains.
7 września 2026 witryna agentskills.io wymienia 46 zgodnych produktów, od Cursor po Goose, przez Junie, Kiro, Roo Code, Laravel Boost, OpenCode i OpenClaw.
Zbudować skill, który się przydaje: regex-verifiee
Dobry skill koduje procedurę, którą powtarzasz i którą agent pomija, gdy mu się jej nie narzuci. Wybrany tu przypadek: wyrażenia regularne. Agent wypluwa regex w trzy sekundy, nigdy nie uruchamiając go na kontrprzykładzie. Skill regex-verifiee zabrania takiej odpowiedzi.
SKILL.md, w całości dla frontmattera i początku treści:
---
name: regex-verifiee
description: Écrire une expression régulière et la prouver avant de la livrer. À utiliser dès qu'une demande porte sur une regex, une expression régulière, une validation de format (code postal, SIRET, IBAN, e-mail, téléphone, slug, plaque), un preg_match, un preg_replace ou un RegExp. Impose un fichier de cas valides et invalides, son exécution dans le moteur cible (Node et PHP), puis la livraison regex + tableau de cas + limites.
---
# Regex vérifiée
Une regex qui n'a jamais tourné sur ses contre-exemples n'est pas une regex, c'est une intuition.
Suivez ces cinq étapes dans l'ordre. Ne sautez pas l'étape 4.
## Procédure
1. **Cadrer.** Demandez, ou décidez explicitement : le moteur (JavaScript, PCRE/PHP, POSIX), la
chaîne testée (déjà nettoyée ou brute), et si la valeur peut être vide.
2. **Proposer.** Écrivez la regex ancrée et, en une phrase par groupe, ce que chaque partie accepte.
3. **Écrire les cas.** Créez un fichier JSON : au moins six valides et six invalides. Les invalides
doivent inclure les pièges de `references/cas-types.md` pour le type de donnée concerné.
4. **Exécuter.** Lancez le script sur les deux moteurs et collez la sortie brute dans la réponse.
5. **Livrer.** Réponse finale = la regex + le tableau de cas produit par le script + les limites.Opis jest celowo gadatliwy w słownictwie wyzwalającym: „regex”, „wyrażenie regularne”, „kod pocztowy”, „SIRET”, „preg_match”, „RegExp”. To słowa, które wpisuje czytelnik. Pisz go w języku, w którym się do Ciebie mówi, nie w języku dokumentacji.
Folder zawiera następnie plik przypadków w formacie JSON, dwa moduły wykonujące (jeden w Node, jeden w PHP), które czytają ten sam plik, oraz referencję references/cas-types.md, która wylicza kontrprzykłady według typu danych. Plik przypadków wygląda tak:
{
"name": "code postal français",
"engine": "both",
"pattern": "^(?:0[1-9]|[1-8]\\d|9[0-8])\\d{3}$",
"flags": "",
"valid": ["01000", "20000", "62500", "75001", "97400", "98000"],
"invalid": ["", "00000", "99999", "7500", "750011", "75 001", "2A000", " 75001", "75001\n"]
}Oba moduły wyświetlają tę samą tabelę i zwracają niezerowy kod wyjścia, gdy tylko jakiś przypadek zawiedzie. To ten kod wyjścia wykonuje pracę: agent nie może zakończyć wniosku na komendzie zwracającej błąd.
Pierwsza niespodzianka, uzyskana przez uruchomienie zestawu testowego samodzielnie, jeszcze zanim podłączyłem agenta: ten sam regex nie daje tego samego werdyktu w obu silnikach.
$ node scripts/verifier.mjs examples/code-postal-fr.json
moteur : node v22.23.2
regex : /^(?:0[1-9]|[1-8]\d|9[0-8])\d{3}$/
...
"75001\n" false false ok
15 cas, 0 échec(s)
$ php scripts/verifier.php examples/code-postal-fr.json
moteur : PHP 8.4.19, PCRE 10.47 2025-10-21
regex : /^(?:0[1-9]|[1-8]\d|9[0-8])\d{3}$/
...
"75001\n" false true ECHEC
15 cas, 1 échec(s)W PCRE $ akceptuje końcowy znak nowej linii, w JavaScript nie. Pole formularza, które przychodzi z doklejonym na końcu \n, przechodzi więc walidację PHP i nie przechodzi walidacji JavaScript, mimo tego samego wyrażenia zapisanego w obu plikach. Obie poprawki, obie sprawdzone tutaj: modyfikator D po stronie PHP (preg_match('/^\d{5}$/D', "75001\n") zwraca 0), albo przenośne zakotwiczenie (?![\s\S]) zamiast $, które przechodzi wszystkie piętnaście przypadków w obu silnikach.
Przetestować go w Codex bez dotykania ~/.codex
Dokumentacja Codex opisuje stos katalogów źródłowych: $CWD/.agents/skills, foldery nadrzędne, $REPO_ROOT/.agents/skills, potem $HOME/.agents/skills, /etc/codex/skills i skille dostarczone z CLI. Innymi słowy, skill projektowy istnieje: nie trzeba pisać do ~/.codex/skills ani do ~/.codex/config.toml, żeby go wypróbować.
Pozostaje sprawdzić, co plik binarny robi naprawdę. Codex udostępnia w tym celu komendę diagnostyczną, która pokazuje prompt dokładnie tak, jak otrzymuje go model, bez wywoływania modelu:
$ mkdir -p demo-projet/.codex/skills
$ cp -R regex-verifiee demo-projet/.codex/skills/
$ cd demo-projet && codex debug prompt-input "test"
### Skill roots
- `r0` = `/…/demo-projet/.codex/skills`
- `r1` = `/Users/gekkode/.codex/skills`
- `r2` = `/Users/gekkode/.agents/skills`
- `r3` = `/Users/gekkode/.codex/skills/.system`
- `r4` … `r10` = caches de plugins
### Available skills
- regex-verifiee: Écrire une expression régulière et la prouver avant de la livrer. À utiliser dès qu'une deman (file: r0/regex-verifiee/SKILL.md)Skill jest widziany z <projekt>/.codex/skills, ścieżki, o której dokumentacja nie wspomina, ale którą plik binarny rzeczywiście skanuje, na pierwszej pozycji. Po umieszczeniu drugiego skilla testowego w <projekt>/.agents/skills, pojawił się katalog źródłowy r11 z tą ścieżką: oba działają, a folder .codex/ ma pierwszeństwo.
Przychodzi czas na prawdziwy test. Ten sam prompt, ten sam model, ta sama maszyna, w odstępie kilku minut: raz w projekcie zawierającym skill, raz w pustym folderze.
codex exec -m gpt-6-astra -s workspace-write --skip-git-repo-check \
"Dans un formulaire PHP, je dois valider le code postal saisi par le visiteur. Donne-moi l'expression reguliere a utiliser."Bez skilla: 19 sekund, zero wykonanych komend, i ta odpowiedź, preg_match('/\A[0-9]{5}\z/', $codePostal), ze zdaniem mówiącym, że wyrażenie sprawdza format, a nie istnienie kodu pocztowego. Przepuszczony przez zestaw testowy, ten regex zawodzi w dwóch przypadkach na piętnaście: akceptuje 00000 i 99999.
Ze skillem: 106 sekund, dziesięć wykonanych komend. Codex przeczytał SKILL.md, potem oba skrypty, potem references/cas-types.md, całe stopniowe ujawnianie, poziom po poziomie. Następnie napisał własny plik przypadków (osiemnaście przypadków, w tym "75001\n00000" i "2a000", przejęte z referencji), uruchomił oba moduły wykonujące i dostarczył to:
$codePostal = $_POST['code_postal'] ?? '';
$valide = is_string($codePostal)
&& preg_match('/\A(?:0[1-9]|[1-8][0-9]|9[0-8])[0-9]{3}\z/', $codePostal) === 1;Poniżej, obie tabele osiemnastu przypadków i sekcja „ograniczenia”. Zwróć uwagę, że nie użył tego samego wyrażenia w obu silnikach. \A … \z dla PCRE, ^ … (?![\s\S]) dla JavaScript. Skill nigdy mu tego nie kazał robić, wywnioskował to, wykonując przypadki.
Skill liczący jakieś sześćdziesiąt linii zamienił więc odpowiedź w trzy sekundy, błędną w dwóch przypadkach, w dwuminutową procedurę, której wynik da się zweryfikować. Wywołanie nastąpiło samo, na podstawie opisu: prompt nie zawiera ani słowa „skill”, ani nazwy regex-verifiee. W Codex można też wymusić to ręcznie, wpisując $regex-verifiee w prompcie, w Claude Code, przez /regex-verifiee.
Ile kosztuje opis i dlaczego jest ucinany
Podczas wykonywania Codex wyświetlił ostrzeżenie, którego się nie spodziewałem:
Skill descriptions were shortened to fit the skills context budget. Codex can still see every skill, but some descriptions are shorter. Disable unused skills or plugins to leave more room for the rest.
Weryfikacja przeprowadzona za pomocą skilla testowego, którego opis to ciąg trzystu znanych znaków: na tej maszynie, przy 146 zainstalowanych skillach, każdy opis jest ucinany do 94 znaków. Mój opis liczący 422 znaki dociera więc do modelu okrojony o dwie trzecie, w połowie francuskiego słowa „demande”. Wszystko, co przychodzi potem, „SIRET”, „IBAN”, „preg_match”, „RegExp”, nie ma żadnego znaczenia dla wywołania.
Budżet jest regulowany. Codex przyjmuje klucz skills.max_context_tokens, który można przekazać jako nadpisanie bez pisania w pliku konfiguracyjnym:
codex debug prompt-input -c skills.max_context_tokens=16000 "test"| Budżet | Zachowana długość opisu | Rozmiar bloku skilli |
|---|---|---|
| 2 000 | 40 znaków | 8 202 znaki |
| 4 000 | 54 znaki | 16 492 znaki |
| 5 000 | 82 znaki | 20 482 znaki |
| domyślny | 94 znaki | 22 230 znaków |
| 8 000 | 198 znaków | 32 295 znaków |
| 16 000 | 300 znaków (bez ucięcia) | 40 201 znaków |
Wynikają z tego dwie zasady. Umieść słowa wyzwalające w pierwszych dziewięćdziesięciu znakach opisu, reszta to bonus. I licz się z tym, że im więcej skilli instalujesz, tym mocniej okrawasz opis wszystkich pozostałych. Katalog zajmował tutaj 22 230 znaków kontekstu, przy każdej sesji, dla 146 skilli, z których używam zaledwie garstki. Odinstalowanie jest lepsze niż zwiększanie budżetu.
Claude Code stosuje tę samą zasadę, z opublikowanymi liczbami. Jego budżet listy wynosi 1% okna kontekstu modelu, regulowany przez skillListingBudgetFraction albo zmienną środowiskową SLASH_COMMAND_TOOL_CHAR_BUDGET. Każdy wpis i tak ma pułap: połączone description i when_to_use są ucinane do 1 536 znaków, pułap regulowany przez skillListingMaxDescChars. A gdy lista przekracza limit, dokumentacja jest jednoznaczna co do kolejności poświęcania: Claude Code usuwa najpierw opisy skilli, które wywołujesz najrzadziej. Nazwa zaś zawsze zostaje na liście.
Oba narzędzia oferują tę samą furtkę: wyłączyć zamiast nadmuchiwać budżet. Po stronie Claude Code ustawienie skillOverrides przyjmuje cztery stany na skill, on, name-only (nazwa bez opisu), user-invocable-only i off, a komenda /skills zapisuje je za Ciebie w .claude/settings.local.json. Po stronie Codex, blok w ~/.codex/config.toml:
[[skills.config]]
path = "/chemin/vers/le/skill/SKILL.md"
enabled = falseZaładować i dystrybuować ten sam skill w Claude Code
Folder się nie zmienia. Dwie lokalizacje, zależnie od tego, czy skill towarzyszy Ci wszędzie, czy należy do repozytorium:
cp -R regex-verifiee ~/.claude/skills/ # dla wszystkich Twoich projektów
cp -R regex-verifiee mon-projet/.claude/skills/ # wersjonowany z repozytoriumDokumentacja Claude Code dodaje pola frontmattera nieobecne w specyfikacji. disable-model-invocation: true blokuje automatyczne wywołanie i rezerwuje skill do ręcznego wywołania przez /nazwa, dobre ustawienie dla wszystkiego, co wypycha, wdraża albo usuwa. allowed-tools przyznaje uprawnienia narzędzi tylko na tę turę rozmowy, która wywołuje skill, a uprawnienie znika przy kolejnej wiadomości. user-invocable: false rezerwuje skill wyłącznie dla modelu.
Żeby dystrybuować skill do zespołu, opakowaniem jest plugin: manifest .claude-plugin/plugin.json w katalogu głównym, skill w folderze skills/, i plik .claude-plugin/marketplace.json, który deklaruje marketplace. Instalacja odbywa się potem przez /plugin marketplace add konto/repozytorium, a następnie /plugin install moj-plugin@moj-marketplace, a /reload-plugins przeładowuje bez opuszczania sesji.
Pozostaje pytanie, które drażni. Czy Twój skill się wywołuje i czy się do czegoś przydaje? Claude Code odpowiada na obie połowy. /skill-doctor, który wymaga wersji 2.1.252 lub nowszej, wypisuje załadowane skille, liczbę ich wywołań i ostatnie użycie, i sygnalizuje te, które nigdy się nie przydały, raport otwiera się w zakładce Stats menedżera pluginów i drukuje się jako czysty tekst w trybie -p. A claude plugin eval, we wczesnym dostępie, automatyzuje dokładnie to porównanie, które zrobiłem ręcznie wyżej. Pomoc tej komendy, na tej maszynie, nie pozostawia wątpliwości:
$ claude plugin eval --help
Run eval cases (evals/**/case.yaml or evals/**/prompt.md + graders/*.md) against
a plugin and report scored results.
--ablation <mode> Run a no-plugin baseline arm and report the score delta
(none | with-without; default: with-without …)
--runs <n> Override per-case runs (default: case.runs ?? 3)
--threshold <0..1> Exit 1 if any case score is below this threshold
--json Emit aggregate-result.json to stdout (for CI)Przypadek ewaluacyjny to folder evals/<przypadek>/ zawierający prompt.md, realistyczny prompt, który przede wszystkim nie nazywa skilla, oraz korektory w graders/. Opcja --ablation with-without odtwarza każdy przypadek z pluginem i bez niego i pokazuje różnicę wyniku: to jedyny uczciwy sposób na udowodnienie, że skill coś wnosi.
Udostępnić skill i sprawdzić cudze
Współistnieją trzy kanały dystrybucji. Zwykłe repozytorium Git, które się klonuje do właściwego folderu, najprostszy i najłatwiejszy do audytu. Plugin, zarówno dla Claude Code, jak i dla Codex: po stronie Codex każdy plugin żyje pod plugins/<nazwa>/, z obowiązkowym manifestem .codex-plugin/plugin.json i opcjonalnymi folderami skills/, .app.json, .mcp.json. I publiczne marketplace’y: ClawHub, Skills.sh, SkillsMP.
Zwróć przy okazji uwagę, że katalog github.com/openai/skills, wciąż cytowany wszędzie, jest oznaczony jako przestarzały i odsyła do github.com/openai/plugins. Systemowy skill $skill-installer instaluje natomiast zawsze w $CODEX_HOME/skills/<nazwa>.
Trzeci kanał wymaga nieufności. Audyt ToxicSkills opublikowany przez Snyk 5 lutego 2026 prześwietlił 3 984 skille z ClawHub i skills.sh: 1 467 z nich (36,82%) ma co najmniej jedną wadę bezpieczeństwa, a 534, czyli 13,4% całości, co najmniej jedną wadę krytyczną. Siedemdziesiąt sześć złośliwych ładunków zostało potwierdzonych przez recenzję ludzką: kradzież danych uwierzytelniających, instalacja backdoora, eksfiltracja danych, osiem z tych skilli było wciąż online w dniu publikacji. Wszystkie potwierdzone ładunki zawierają złośliwy kod, a 91% dodaje do tego wstrzyknięcie promptu.
Skill to tekst, który Twój agent będzie śledził, plus skrypty, które wykona z Twoimi uprawnieniami. Zanim jakiś zainstalujesz, przeczytaj cały SKILL.md, przeczytaj każdy plik z scripts/, szukaj wywołań sieciowych i ciągów zakodowanych w base64, i odrzucaj każdy skill, który prosi o klucz API albo token. Te same odruchy co przy sandboksie i uprawnieniach agenta kodu.
Skille czy MCP?
Skille i MCP nie odpowiadają na tę samą potrzebę. Skill wnosi procedurę i know-how, w Markdown, bez procesu, bez sieci, bez uwierzytelniania. Serwer MCP wnosi narzędzia i dane: rozmawia z bazą, z API, ze zdalnym systemem plików, wraz z odpowiednimi danymi uwierzytelniającymi.
Najszybszy test mieści się w jednym zdaniu. Jeśli Twoją potrzebę da się zapisać jako „zrób tak”, to skill. Jeśli zapisuje się jako „idź po to” albo „zapisz to gdzieś”, to serwer MCP. Różnica kosztu idzie tym samym torem: nieaktywny skill kosztuje swój opis, kilkadziesiąt tokenów, podczas gdy podłączony serwer MCP kosztuje definicję wszystkich swoich narzędzi, na stałe, przy każdej sesji.
Oba dobrze się łączą: skill, który mówi, w jakiej kolejności wywoływać narzędzia serwera MCP, jest często tym najlepszym z obu światów. To zresztą kierunek, jaki obrał sam protokół, rewizja 2026-07-28 specyfikacji MCP wymienia grupę roboczą „Skills over MCP”, której celem jest odkrywanie i konsumowanie ustrukturyzowanych instrukcji przez MCP. Część serwerową przejmuje przewodnik po serwerze MCP w PHP.
Cztery błędy, które się powtarzają
Opis, który opisuje skill zamiast mówić, kiedy go użyć. „Pomaga z regexami” nigdy się nie wywołuje. Napisz słowa, które wpisuje użytkownik, w jego języku, i umieść je na początku, z powodu ucinania zmierzonego wyżej.
SKILL.md liczący dwa tysiące linii. Cała treść wchodzi do kontekstu przy wywołaniu. Specyfikacja zaleca pozostanie poniżej 500 linii i przeniesienie szczegółów do references/, ładowanych tylko w razie potrzeby. W teście powyżej Codex otworzył cas-types.md dopiero w momencie pisania swoich przypadków.
Sekrety w skillu. Skill się udostępnia, wersjonuje, publikuje. Klucz API, który się w nim zawieruszy, trafia do publicznego repozytorium. Skill czyta zmienną środowiskową, nie zawiera jej.
Piętrzenie skilli „na wszelki wypadek”. Każdy zainstalowany skill skraca opis wszystkich pozostałych i podgryza okno kontekstu. Zrób inwentaryzację tego, co nigdy się nie wywołało, i usuń to.
Co warto zapamiętać
- Skill = folder +
SKILL.md(namemaksymalnie 64 znaki,descriptionmaksymalnie 1 024) + to, co chcesz obok. - Tylko opis jest ładowany na stałe, i jest ucinany: słowa wyzwalające idą w pierwszych 90 znakach.
.agents/skillspo stronie projektu, plus.claude/skillsczytany przez Copilot i OpenCode: ten sam folder służy kilku agentom.- Skill projektowy testuje się bez instalowania czegokolwiek u siebie:
<projekt>/.codex/skills/dla Codex,<projekt>/.claude/skills/dla Claude Code. - Dobry skill narzuca weryfikowalną procedurę i kod wyjścia, nie stylistyczną wskazówkę.
- Przeczytaj w całości każdy skill zainstalowany z marketplace’u: 13,4% tych audytowanych przez Snyk ma wadę krytyczną.
Częste błędy
references/, które agent otwiera tylko w razie potrzeby.scripts/ to kod, który wykona z Twoimi uprawnieniami. Przeczytaj wszystko wcześniej, łącznie ze skryptami.

