Wszystkie wpisy

3 czerwca 2026

Claude Code Skills vs Rules — probabilistyczny agent kontra deterministyczna reguła

Budując tę stronę przez dwa dni z Claude Code — i przenosząc ją na własną domenę po drodze — trafiłem na konkretne rozdroże. Chcę, żeby agent zawsze trzymał się konwencji mojej taksonomii zdarzeń, kiedy dotyka pliku events.ts — ale jednocześnie żeby pisał wpis na bloga tylko wtedy, gdy o to poproszę. To dwie różne potrzeby, które w Claude Code obsługują dwa mechanizmy o przeciwnej naturze: jeden probabilistyczny, drugi deterministyczny. I jest to dokładnie ta sama różnica, którą znam z architektury analitycznej.

Claude Code Skills vs Rules: probabilistyczne kontra deterministyczne

Claude Code Skills vs Rules to dwa narzędzia, które łatwo pomylić, bo oba to pliki w .claude/:

  • Skills — probabilistyczne. Trigger jest semantyczny: piszesz „napisz nowy artykuł”, model czyta pole description skilla i sam decyduje, że pasuje do Twojej intencji. Decyduje model.
  • Rules (pliki w .claude/rules/) — deterministyczne. Trigger jest techniczny: reguła ma w nagłówku paths z wzorcem glob, a harness ładuje ją automatycznie, gdy czytany plik pasuje do wzorca. Zero interpretacji. Decyduje harness.
SkillsRules
Charakterprobabilistycznydeterministyczny
Triggersemantyczny (intencja)ścieżka pliku (glob)
Decydujemodelharness
Podstawapole descriptionpole paths
Do czegoprocedury, zadania intencyjnestałe zasady obszaru kodu

events.ts jako kandydat na Rule

W tym projekcie mam plik, który jest podręcznikowym przykładem na Rule: src/data/events.ts — rejestr zdarzeń dataLayer, jedno źródło prawdy taksonomii. Dodanie nowego eventu to sztywna procedura:

  1. stała w EVENTS (klucz camelCase → wartość snake_case),
  2. wpis w EVENT_CATALOG z metadanymi,
  3. import stałej tam, gdzie pushujesz — pushEvent(EVENTS.x), nigdy goły string.

Plus niezmienniki: EVENT_CATALOG nie wolno importować po stronie klienta (inaczej trafia do bundla), a 4 nazwy cookie_consent_* są mirrorem w <head> i muszą być synchronizowane.

Do wczoraj te zasady żyły jako komentarz w pliku i akapit w CLAUDE.md. Problem: CLAUDE.md jest probabilistyczny — to prośba w kontekście. Model stara się ją respektować, ale gdy dotyka events.ts po długiej sesji, może o niej po prostu nie pamiętać. Dla taksonomii, gdzie jedna literówka w nazwie zdarzenia rozjeżdża raport w GA4, „stara się” to za mało.

Rozwiązanie: przeniosłem te zasady do .claude/rules/events.md z nagłówkiem:

---
paths:
  - "src/data/events.{ts,js}"
---

Najważniejsze, gdzie ten plik leży w drzewie projektu — a właściwie, że jego położenie nie ma znaczenia:

Personal-Page/
├── .claude/
│   ├── CLAUDE.md              # instrukcje projektu (probabilistyczne)
│   ├── rules/
│   │   └── events.md          # paths: ["src/data/events.{ts,js}"]
│   └── skills/
│       └── nowy-artykul/      # Skill (trigger semantyczny)
└── src/
    └── data/
        └── events.ts          # plik pilnowany przez regułę

Reguła i pilnowany przez nią kod siedzą w zupełnie innych gałęziach drzewa. Jedyne, co je łączy, to wzorzec paths — nie sąsiedztwo folderów, nie żaden podkatalog. Reguły są wykrywane rekurencyjnie w .claude/rules/, więc podfoldery (frontend/, backend/) służą wyłącznie porządkowi: to paths, a nie struktura katalogów, decyduje o wyzwoleniu. Od teraz, ilekroć agent czyta lub edytuje events.ts, harness gwarantuje, że reguły są w kontekście — bez polegania na tym, że model sam je sobie przypomni. Wzorzec dopasowuje ścieżkę, reguła wjeżdża, koniec.

Skill nowy-artykul — druga strona medalu

Dla kontrastu: pisanie tego artykułu odpalił Skill, nie Rule. I słusznie — „napisz wpis na bloga” to intencja, nie ścieżka pliku. Nie ma globa, który by to sensownie wyzwalał (plik artykułu jeszcze nie istnieje, gdy proszę o jego napisanie). Zadanie wielokrokowe, twórcze, zależne od intencji — domena Skilla.

Reguła kciuka:

  • Skill — gdy trigger to intencja („zrób mi X”), a zadanie jest proceduralne/twórcze.
  • Rule — gdy trigger to miejsce w kodzie („gdy ktoś dotyka tego pliku”), a zasady są stałe.

Co to daje przy rozbudowie architektury analitycznej

Tu robi się ciekawie z perspektywy analityka. Architektura analityczna to nie zbiór skryptów — to taksonomia, kontrakty i niezmienniki. Dokładnie ten typ wiedzy, który gnije w głowie seniora i znika, gdy do projektu wchodzi ktoś nowy (albo agent AI). Reguła daje agentowi te niezmienniki we właściwym momencie — podobnie jak semantyczny graf repozytorium daje mu mapę kodu zamiast ślepego skanowania plik po pliku.

Gdy rozbudowuję stronę o nową funkcję — np. formularz z eventem form_submit — Rule pilnuje, że nowy event przejdzie pełną procedurę: stała, katalog, typowany push. Agent nie wrzuci gołego dataLayer.push({event:'form_submit'}) w komponencie, bo reguła jest w kontekście dokładnie w momencie edycji taksonomii. Konwencja, która kiedyś była tylko w mojej głowie, teraz egzekwuje ją maszyna.

To przesunięcie z „dokumentuję architekturę” na „architektura pilnuje się przy każdej zmianie”.

Granica: Rule kontra Hook

Żeby nie obiecać za dużo. Rule gwarantuje obecność wytycznej w odpowiednim momencie — ale model wciąż musi ją wykonać. To deterministyczny trigger, nie deterministyczne wymuszenie. Jeśli potrzebujesz twardej blokady — „nie wpuszczę commita, jeśli event nie ma wpisu w katalogu” — to zadanie dla Hooka (PreToolUse), który wykonuje harness bez udziału modelu. Oś: CLAUDE.md i Skills (model, probabilistyczne) → Rules z paths (harness ładuje, model wykonuje) → Hooks (harness wykonuje, zero modelu). Im bardziej coś musi zadziałać, tym niżej schodzisz.

Skala e-commerce: setki eventów

Na tej stronie mam kilka zdarzeń — Rule jest tu wygodą, nie koniecznością. Ale przełóż to na platformę e-commerce, gdzie tracking plan ma setki eventów (view_item, add_to_cart, begin_checkout, purchase i dziesiątki wariantów), wielu wydawców i kontrakt z GTM, w którym jedna rozjechana nazwa psuje atrybucję i raporty przychodu. Tam deterministyczna reguła na plikach tracking planu przestaje być wygodą, a staje się polisą: każdy, kto dotyka taksonomii — człowiek czy agent — dostaje te same niezmienniki w kontekście, automatycznie.

To dla mnie sedno bycia „analytics architect” przy pracy z agentami AI: nie pisać każdej linijki, tylko zaprojektować zasady tak, żeby narzędzie samo ich pilnowało.

Podsumowanie

Skills i Rules wyglądają podobnie, ale mają przeciwną naturę. Skill to probabilistyczny trigger na intencję — do zadań proceduralnych jak pisanie treści. Rule to deterministyczny trigger na ścieżkę pliku — do pilnowania obszaru kodu o stałych konwencjach, jak taksonomia eventów. Jeśli pracujesz z architekturą analityczną, Rules są naturalnym miejscem, żeby zakodować niezmienniki tam, gdzie agent na pewno je zobaczy. A gdy „na pewno zobaczy” to za mało i trzeba „na pewno wykona” — sięgasz po Hooka.

Powiązane wpisy