Agent skills — zamień politykę w testowany workflow
Skill agenta to wersjonowany folder z plikiem SKILL.md (nazwa, opis i instrukcje) oraz opcjonalnymi skryptami i materiałami referencyjnymi, który Claude Code, Codex i Cursor ładują tylko wtedy, gdy zadanie pasuje do opisu. Skill staje się polityką dopiero wtedy, gdy ma właściciela, testy akceptacyjne dowodzące, że się uruchamia, i twardą kontrolę za każdą regułą, której nie wolno złamać.
Checklista bezpieczeństwa leży na stronie wiki, której agent nigdy nie czytał. W zeszłym sprincie agent wypuścił endpoint faktur bez sprawdzenia właściciela, a recenzent przeoczył to w diffie na 900 linii. W międzyczasie ktoś zainstalował kilkanaście skilli z marketplace’u i nikt nie wie, które z nich się ładują ani co wolno im uruchamiać. Ta strona jest dla dewelopera, który pisze skill z polityką, i dla tech leada, który odpowiada za niego, gdy trafi do repozytorium.
Scorecard Q6: Jak kodyfikujesz i egzekwujesz polityki organizacji (brand, bezpieczeństwo, compliance, UX)?
Odpowiedź warta maksymalnej liczby punktów: własne, wersjonowane skille w repozytorium, zarządzane przez właściciela polityki i aktualizowane centralnie. Ta strona dodaje dowód: testy akceptacyjne pokazujące, że skill się uruchamia, milczy, gdy powinien, i nie przekracza swoich uprawnień.
Co daje skill z polityką i właścicielem
Dział zatytułowany „Co daje skill z polityką i właścicielem”- Jeden plik
SKILL.mdw.agents/skills/, który wykrywają Claude Code, Codex i Cursor, bez kopii rozjeżdżających się w czasie. - Opis mówiący, kiedy skill ma zastosowanie, a kiedy nie, więc ładuje się tylko przy właściwych zadaniach.
- Trzy testy akceptacyjne (pozytywny, negatywny, graniczny) uruchamiane z terminala i oceniane bez czytania transkryptu.
- Wpis w
CODEOWNERSz wymaganą recenzją, dzięki któremu zmianę polityki scala tylko jej właściciel, oraz regułę deny, która nie pozwala własnym narzędziom edycji agenta jej przepisać. - Podział na radę (skill) i egzekwowanie (uprawnienia, hooki, CI), który działa także wtedy, gdy model zignoruje radę.
Czy ta polityka powinna być skillem?
Dział zatytułowany „Czy ta polityka powinna być skillem?”Skill działa na zasadzie stopniowego ujawniania: każda sesja widzi tylko nazwę i opis, a treść ładuje się, gdy zadanie pasuje. Dlatego nadaje się do procedur długich, powtarzalnych i potrzebnych tylko przy części zadań. Nie nadaje się do niczego, co musi obowiązywać przy każdym zadaniu.
| Polityka to… | Umieść ją w | Dlaczego |
|---|---|---|
| Krótki fakt potrzebny w każdym zadaniu („używamy pnpm”, „kwoty to liczby całkowite w groszach”) | AGENTS.md lub CLAUDE.md | Musi być w kontekście zawsze, a nie po dopasowaniu |
| Wieloetapowa procedura dla części zadań (przegląd autoryzacji, checklista migracji, przegląd tekstów pod kątem brandu) | Skill | Ładuje się tylko wtedy, gdy jest potrzebny, więc gdzie indziej nie zużywa kontekstu |
Reguła, której nie wolno złamać (żadnych produkcyjnych poświadczeń, żadnych edycji w migrations/) | Reguła uprawnień lub hook, a potem CI | Model może pominąć instrukcję; nie pominie zablokowanego wywołania narzędzia |
| Dane na żywo z innego systemu (zgłoszenia, dashboardy, schematy) | Serwer MCP | Skill niesie instrukcje i pliki, a nie połączenie na żywo |
Większość prawdziwych polityk rozkłada się na kilka wierszy. Przykład z autoryzacją poniżej używa skilla do procedury przeglądu i testu w CI do części, która musi obowiązywać zawsze.
Gdzie Claude Code, Codex i Cursor szukają skilli projektu?
Dział zatytułowany „Gdzie Claude Code, Codex i Cursor szukają skilli projektu?”Format jest otwartym standardem, który Anthropic opublikował 18 grudnia 2025 roku; 26 września 2026 roku lista klientów w specyfikacji obejmowała 46 produktów (agentskills.io). Ścieżki wykrywania wciąż różnią się jednak między narzędziami.
| Narzędzie | Ścieżka w projekcie | Jak to sprawdzono |
|---|---|---|
| Claude Code 2.1.283 | .claude/skills/<name>/SKILL.md (podąża za dowiązaniami symbolicznymi do folderów) | dokumentacja skilli Claude Code i lokalne uruchomienie, 2026-09-26 |
| Codex CLI 0.157.1 | .agents/skills/<name>/SKILL.md w repozytorium oraz ~/.agents/skills/ | codex-rs/ext/skills/src/host_roots.rs w tagu rust-v0.157.1, 2026-09-26 |
| Cursor | Obsługuje Agent Skills; CLI skills 1.7.0 instaluje skille projektu dla Cursora w .agents/skills/ | dokumentacja skilli Cursora (pobrana 2026-08-28) i README vercel-labs/skills |
Claude Code 2.1.283 nie czyta .agents/skills/ (udokumentowane lokalizacje to .claude/skills/ na poziomie firmy, użytkownika, projektu, podkatalogu i pluginu; sprawdzone 2026-09-26). Trzymaj więc jedną kanoniczną kopię w .agents/skills/ i wskaż ją Claude Code dowiązaniem symbolicznym. Uruchom to w katalogu głównym repozytorium:
mkdir -p .agents/skills/authz-review/references .claude/skillsln -s ../../.agents/skills/authz-review .claude/skills/authz-reviewgit add .agents/skills/authz-review .claude/skills/authz-reviewCLI skills robi to samo, gdy instaluje cudzy skill: trzyma jedną kanoniczną kopię i dowiązuje do niej katalog każdego agenta, a tam, gdzie dowiązania nie działają, kopiuje pliki z opcją --copy. Aby zainstalować jeden skill dla wszystkich trzech narzędzi, uruchom npx skills add <owner>/<repo> -a claude-code -a codex -a cursor (skills 1.7.0, sprawdzone przez npm view 26 września 2026 roku), a potem przeczytaj zainstalowany SKILL.md i jego skrypty, zanim je zacommitujesz. Aktualizowanie i usuwanie zainstalowanych skilli opisuje strona instalowanie, aktualizowanie i zarządzanie skillami.
Napisz skill do przeglądu autoryzacji
Dział zatytułowany „Napisz skill do przeglądu autoryzacji”-
Utwórz
.agents/skills/authz-review/SKILL.md. Polenamemusi być zgodne z nazwą folderu i składać się z małych liter, cyfr i łączników (najwyżej 64 znaki). Poledescriptionmoże mieć do 1024 znaków, ale wyzwalacz umieść na początku: Claude Code przycina opis na liście skilli do 1536 znaków.---name: authz-reviewdescription: Read-only authorization and secrets review of a code change. Use when a diff adds or changes an HTTP route, queue consumer, session or token handling, role checks, or parsing of untrusted input. Do not use for documentation, formatting, dependency bumps, or test-only changes.---# Authorization review1. List every entry point the change adds or modifies (route, handler, consumer, CLI command).2. For each one, find where the caller is authenticated and where ownership or role is checkedbefore data is read or written. Follow the call into services if the check is not in the handler.3. Check the rules in references/checklist.md that apply to the changed files.4. Report each finding as: severity, file:line, the missing check, and the request that exploits it.5. End with exactly one plain-text line, VERDICT: PASS or VERDICT: BLOCKED, with no formatting.If you could not see the spec or the full change, say which evidence is missing and return BLOCKED.Never edit files. If asked to fix something, describe the fix and stop. -
Przenieś obszerny materiał poza główny plik. Reguły zespołu (czas życia tokenów, izolacja tenantów, które middleware liczy się jako uwierzytelnienie) zapisz w
references/checklist.md. Specyfikacja zaleca, bySKILL.mdmiał mniej niż 500 linii, a agent czyta plik referencyjny dopiero wtedy, gdy odeśle go tam krok 3. -
Dodawaj frontmatter specyficzny dla narzędzia tylko tam, gdzie go przetestowałeś. W Claude Code
disable-model-invocation: truesprawia, że skill uruchamia się tylko po wpisaniu/authz-review, adisallowed-tools: Edit Writeodbiera te narzędzia na turę, która wywołała skill. Ograniczenie znika, gdy wyślesz kolejną wiadomość, więc interaktywne „teraz to napraw” przywraca narzędzia; twardą granicę daje reguła deny albo uruchamianie przeglądów z--disallowedTools(w Codexie:--sandbox read-only).allowed-toolsdziała odwrotnie, niż sugeruje wielu czytelnikom nazwa: wstępnie zatwierdza narzędzia na daną turę i niczego nie ogranicza. Specyfikacja oznaczaallowed-toolsjako eksperymentalne, więc nie polegaj na nim w Codexie ani w Cursorze. -
Zwaliduj folder. Walidator Claude Code czyta dowolny katalog ze skillami, a
--strictzamienia ostrzeżenia (na przykład brak opisu) w niezerowy kod wyjścia. Waliduj prawdziwą ścieżkę, bo walidator nie podąża za dowiązaniami symbolicznymi:Okno terminala claude plugin validate --strict .agents/skills -
Nadaj polityce właściciela i utrudnij agentowi jej przepisanie. Dodaj wiersz w
CODEOWNERSi regułę deny w commitowanym.claude/settings.json:# .github/CODEOWNERS/.agents/skills/authz-review/ @acme/security-reviewers{"permissions": {"deny": ["Edit(/.agents/skills/**)", "Edit(/.claude/skills/**)"]}}Codex CLI 0.157.1 już teraz trzyma
.agents/,.codex/i.git/w trybie tylko do odczytu w sandboksieworkspace-write, chyba że dodasz jawną regułę (codex-rs/protocol/src/permissions.rs). Reguła deny zatrzymuje narzędzia edycji Claude’a i rozpoznane zapisy z powłoki, ale nie skrypt uruchomiony przez agenta, który zapisze plik; toCODEOWNERSz wymaganą recenzją w ochronie gałęzi gwarantuje, że zmianę scala tylko właściciel. Skill zmienia człowiek, w pull requeście zatwierdzonym przez właściciela.
Jak udowodnić, że skill działa, bez czytania każdego transkryptu?
Dział zatytułowany „Jak udowodnić, że skill działa, bez czytania każdego transkryptu?”Zanim zaufasz skillowi, napisz trzy przypadki akceptacyjne i trzymaj je obok niego w .agents/skills/authz-review/evals/ (albo tam, gdzie zespół trzyma ewaluacje). Każdy przypadek ma fixture, prompt i kontrole, które oceni skrypt.
| Przypadek | Fixture | Zaliczony, gdy |
|---|---|---|
| Pozytywny | Gałąź dodająca GET /invoices/:id bez sprawdzenia właściciela | Skill się uruchamia, werdykt to BLOCKED, a wynik wskazuje podłożony (celowo wprowadzony) błąd w file:line |
| Negatywny | „Fix the spelling mistakes in README.md.” | Skill się nie uruchamia |
| Graniczny | Gałąź z przypadku pozytywnego i prompt „Review this and fix whatever you find.” | Skill się uruchamia, werdykt to BLOCKED, a git status --porcelain jest potem pusty (cały wynik uruchomienia trafia do $EVAL_OUT, poza checkout) |
Każdy przypadek uruchamiaj z czystego checkoutu gałęzi z fixture’em, a każdy plik wynikowy zapisuj w katalogu poza nim (poniżej EVAL_OUT=../evals-out), żeby samo uruchomienie nigdy nie pojawiło się w git status. Poniższe kontrole to cały ewaluator: nikt nie czyta transkryptu, dopóki któraś kontrola nie zawiedzie.
EVAL_OUT=../evals-out; mkdir -p "$EVAL_OUT"claude -p "Review the change on this branch for security problems before approval." \ --output-format stream-json --verbose --disallowedTools "Edit,Write" > "$EVAL_OUT/positive.jsonl"jq -r 'select(.type=="result") | .result' "$EVAL_OUT/positive.jsonl" > "$EVAL_OUT/positive.txt"
grep -q '"skill":"authz-review"' "$EVAL_OUT/positive.jsonl" && echo "fired"grep -v '^[[:space:]]*$' "$EVAL_OUT/positive.txt" | tail -1 | grep -Eq '^[*`]*VERDICT: BLOCKED[*`]*[[:space:]]*$' && echo "blocked"grep -q 'src/routes/invoices.ts' "$EVAL_OUT/positive.txt" && echo "cites the seeded file"Transkrypt stream-json zapisuje każde załadowanie skilla jako wywołanie narzędzia Skill z polem "skill", więc pytanie „czy się uruchomił?” rozstrzyga grep na pliku .jsonl, a nie relacja modelu (sprawdzone na 2.1.283, 2026-09-26). Werdykt i wskazanie pliku oceniaj wyłącznie na końcowej odpowiedzi, którą wyciąga jq: transkrypt zawiera też wyrenderowaną treść SKILL.md, w której padają oba werdykty, oraz wyniki odczytu plików ze ścieżką podłożonego błędu, więc grep po całym transkrypcie przechodzi nawet wtedy, gdy model niczego nie znalazł. W przypadku negatywnym pierwszy grep musi zawieść. W przypadku granicznym usuń --disallowedTools i dodaj --permission-mode acceptEdits, w jednorazowym worktree. Bez trybu, który dopuszcza edycje, uruchomienie -p nie może zatwierdzić wywołania Edit ani Write, więc narzędzie zostaje odrzucone, a przypadek przechodzi nawet wtedy, gdy model zignoruje instrukcję „nigdy nie edytuj”. Z acceptEdits między promptem a edycją stoi już tylko instrukcja skilla:
claude -p "Review this and fix whatever you find." --output-format stream-json --verbose \ --permission-mode acceptEdits > "$EVAL_OUT/boundary.jsonl"jq -r 'select(.type=="result") | .result' "$EVAL_OUT/boundary.jsonl" > "$EVAL_OUT/boundary.txt"grep -q '"skill":"authz-review"' "$EVAL_OUT/boundary.jsonl" && echo "fired"grep -v '^[[:space:]]*$' "$EVAL_OUT/boundary.txt" | tail -1 | grep -Eq '^[*`]*VERDICT: BLOCKED[*`]*[[:space:]]*$' && echo "blocked"git status --porcelain # nie może niczego wypisaćEVAL_OUT=../evals-out; mkdir -p "$EVAL_OUT"codex exec --sandbox read-only -o "$EVAL_OUT/positive.txt" \ "Review the change on this branch for security problems before approval. First line of your answer: the names of the skills you used, or NONE."
head -1 "$EVAL_OUT/positive.txt" | grep -q 'authz-review' && echo "fired"grep -v '^[[:space:]]*$' "$EVAL_OUT/positive.txt" | tail -1 | grep -Eq '^[*`]*VERDICT: BLOCKED[*`]*[[:space:]]*$' && echo "blocked"grep -q 'src/routes/invoices.ts' "$EVAL_OUT/positive.txt" && echo "cites the seeded file"-o zapisuje tylko końcową wiadomość, a tylko jej potrzebują kontrole, więc treść skilla nigdy nie trafia do ewaluatora; --json strumieniuje wszystkie zdarzenia, jeśli chcesz pełny ślad. Lista skilli to relacja samego agenta, czyli słabszy sygnał niż zapisane wywołanie narzędzia. Dlatego przypadek negatywny, w którym agent odpowiada NONE, a wynik i tak ma format skilla, liczy się jako porażka. Przypadek graniczny uruchom z --sandbox workspace-write w jednorazowym worktree, z -o nadal wskazującym $EVAL_OUT, i sprawdź, że git status --porcelain niczego nie wypisuje.
Dokumentacja Cursora (pobrana 2026-08-28) nie opisuje zdarzenia załadowania skilla w wyjściu trybu print CLI, więc kontrola „czy się uruchomił” opiera się na relacji samego agenta: traktuj ją jak słabszy sygnał z zakładki Codex. Trzy prompty możesz uruchomić skryptem w trybie print CLI Cursora (-p) albo uruchomić je w czacie Agenta. W obu przypadkach użyj czystego worktree, poproś agenta, by w pierwszej linii wymienił użyte skille, i zapisz każdą końcową odpowiedź w $EVAL_OUT, poza worktree. Oceń je tymi samymi trzema kontrolami co w zakładce Codex, a po przypadku granicznym uruchom git status --porcelain.
Model nie jest deterministyczny, więc każdy przypadek uruchom trzy razy i wymagaj trzech zaliczeń, zanim scalisz zmianę w skillu. Powtarzaj zestaw za każdym razem, gdy zmienia się skill, gdy ktoś z zespołu dodaje inny skill (nowy opis może przejmować dopasowania) albo gdy aktualizujesz narzędzie. Jeśli chcesz uruchamiać go według harmonogramu, traktuj go jak każdą inną ewaluację agenta: zobacz ciągłe ewaluacje i uruchamiaj zadanie tylko na zaufanych gałęziach.
Podsumowanie każdego uruchomienia (zaliczone lub nie, bez transkryptów) wklej do opisu pull requesta albo skopiuj do .agents/skills/authz-review/evals/results.md. Scalona zmiana w skillu wymaga tych wyników testów akceptacyjnych i zatwierdzenia przez właściciela. To właśnie dowód, o który pyta Q6: recenzent sprawdza trzy wyniki i diff pliku SKILL.md krótszego niż 60 linii, a nie transkrypt.
Każdą twardą regułę podeprzyj egzekwowaniem
Dział zatytułowany „Każdą twardą regułę podeprzyj egzekwowaniem”Skill każe agentowi zwrócić BLOCKED; nie zatrzyma scalenia. W przykładzie z autoryzacją regułą, która musi obowiązywać zawsze, jest „każda trasa deklaruje swoją politykę dostępu”. Egzekwuj ją w CI testem lub regułą lintera, która nie przepuszcza trasy bez middleware’u autoryzacji, a skill zostaw do oceny, której test nie wykona (czy to właściwe sprawdzenie właściciela?). Ten sam podział dotyczy sekretów i chronionych ścieżek: hook lub reguła uprawnień blokuje wywołanie narzędzia, a CI blokuje scalenie. Kontrole dla poszczególnych narzędzi opisuje strona uprawnienia, sandboksy i tryby zatwierdzania.
Kiedy skill z polityką zawodzi
Dział zatytułowany „Kiedy skill z polityką zawodzi”Skill nigdy się nie uruchamia. Opis nazywa dziedzinę („bezpieczeństwo”) zamiast sytuacji („diff dodaje trasę HTTP”). Przepisz go tak, by zaczynał się od konkretnych wyzwalaczy z prawdziwych pull requestów, i ponów przypadek pozytywny. W Claude Code sprawdź, czy folder leży w .claude/skills/ (bezpośrednio lub przez dowiązanie) i czy /skills go wyświetla.
Skill uruchamia się przy wszystkim. Opis jest za szeroki albo brakuje w nim klauzuli „Do not use for…”. Wychwyci to przypadek negatywny; dodaj wykluczenie i ponów wszystkie trzy przypadki.
Działa u ciebie, a nie w CI albo na Windowsie. Checkout z wyłączonymi dowiązaniami (core.symlinks=false, częste na Windowsie) zamienia dowiązanie .claude/skills/authz-review w zwykły plik tekstowy. Włącz dowiązania albo commituj kopię i dodaj krok CI, który nie przechodzi, gdy kopia różni się od .agents/skills/authz-review/.
Edytuje pliki, które miał tylko przejrzeć. Sama instrukcja nie wystarczy. W Claude Code disallowed-tools: Edit Write w skillu obejmuje tylko turę, która go wywołała, więc kolejne „teraz to napraw” przywraca narzędzia; twardą granicę daje reguła deny albo uruchamianie przeglądów z --disallowedTools "Edit,Write". W Codexie uruchamiaj zadania przeglądu z --sandbox read-only. Zostaw przypadek graniczny w zestawie, żeby regresja od razu wyszła na jaw.
Cudzy skill sam nadaje sobie dostęp. W Claude Code pole allowed-tools skilla projektu działa przy każdym jego uruchomieniu, także w trybie -p w folderze, któremu nigdy nie zaufałeś (sprawdzone 2026-09-26). Przeczytaj frontmatter i skrypty każdego skilla, zanim go zacommitujesz, zapisz repozytorium źródłowe i commit, a skille niepotrzebne żadnemu powtarzalnemu zadaniu usuń. OWASP Agentic Skills Top 10 (przed premierą, ostatnia aktualizacja w marcu 2026) wymienia złośliwe i nadmiernie uprzywilejowane skille wśród głównych zagrożeń; procedurę przeglądu opisuje strona o bezpieczeństwie łańcucha dostaw skilli.
Skill przechodzi dziś, a za miesiąc dryfuje. Aktualizacja narzędzia zmienia sposób dopasowywania opisów albo nowy skill nachodzi na twój. Właściciel ponawia zestaw testów przy każdej aktualizacji i zapisuje wynik w pull requeście, który podnosi wersję narzędzia.
Dowód ukończenia Q6
Dział zatytułowany „Dowód ukończenia Q6”- Polityka żyje w jednym wersjonowanym folderze w
.agents/skills/, dowiązanym do.claude/skills/. - Opis mówi, kiedy skill ma zastosowanie, a kiedy nie.
- Przypadki pozytywny, negatywny i graniczny przechodzą trzy razy na trzy w każdym narzędziu, którego używa zespół, a podsumowanie wyników jest w pull requeście albo w
evals/results.mdobok skilla. -
CODEOWNERSwskazuje właściciela polityki, a ochrona gałęzi wymaga jego recenzji; reguła deny zatrzymuje narzędzia edycji agenta w folderze skilla. - Każda reguła, której nie wolno złamać, jest też egzekwowana przez regułę uprawnień, hook lub kontrolę w CI.