Tworzenie skillów

Przewodnik krok po kroku dotyczący dodawania nowych kompetencji do projektu Arc OS.


Zanim napiszesz nowy skill — sprawdź globalną bibliotekę

Arc OS dostarcza 40+ generycznych skilli w skills/ pokrywających typowe role. Zanim napiszesz nowy, sprawdź, czy istniejący nie pokrywa Twojej potrzeby:

Domena Dostępne skille
Engineering commit-discipline, tdd-flow, react-best-practices, postgres-patterns, mcp-builder
Frontend / Design frontend-design-principles, svg-graphics, slide-deck-html, service-design, scss-modular-architecture, responsive-mobile-first
Operacje startupowe market-analysis, gtm-strategy, financial-modeling, pitch-deck, customer-development, fundraising, founder-brand, metrics-dashboard, legal-startup
Marketing seo-foundations, founder-brand
Proces standup-aggregator, commit-discipline
Baza danych postgres-patterns

Pełna lista: GET /api/crm/skills?category=<X> lub bun -e "console.log(JSON.stringify(require('./skills/_registry.json').skills.map(s=>s.name),null,2))".

Skill = dopasowany triggerami, nie always-on

Skill jest automatycznie wstrzykiwany do promptu workera, gdy wiadomość pasuje do jego triggers (w _registry.json). Pole description to logika triggerów ("kiedy tego użyć"), nie streszczenie. Context Router wybiera top-5 dopasowań per wiadomość.


Czym jest skill

Skill to przenośny zestaw instrukcji, który uczy twojego bota AI określonej umiejętności. Skille znajdują się w katalogu skills/ i składają się z:

skills/
├── _registry.json              ← Centralny rejestr
├── my-new-skill/
│   ├── skill.md                ← Co AI powinno robić
│   ├── my-new-skill.evals.json ← Jak walidować wynik
│   └── references/             ← Dokumenty kontekstowe
└── library/
    └── domain-expert.md        ← Proste skille jako jeden plik

Krok 1: Napisz skill.md

To jest główna instrukcja. Claude czyta ją, gdy skill jest aktywowany.

Szablon

# Skill Name

## Purpose
What this skill accomplishes in one sentence.

## When to Use
- Trigger condition 1
- Trigger condition 2

## Protocol
1. First action
2. Second action
3. Third action

## Output Format
What the response should look like.

## Constraints
- What NOT to do
- Safety boundaries

Wytyczne

Przykład: Odoo Expert

# Odoo Expert

## Purpose
Odoo ERP module development: models, views, security, QWeb templates.

## When to Use
- Building or modifying Odoo modules
- Writing QWeb templates
- Configuring access rules and record rules
- Working with the ORM (create, write, search, browse)

## Protocol
1. Check if modifying an existing module or creating new
2. Follow Odoo 17 conventions (manifest, models/, views/, security/)
3. Use self.env['model.name'] for ORM operations
4. Always use _t() or t-call for translatable strings
5. Test with --test-tags after changes

## Constraints
- Never use cr.execute() for direct SQL — use ORM
- Never use sudo() unless security context explicitly requires it
- No inline JavaScript in QWeb templates

Krok 2: Napisz evals (reguły jakości)

Evals to deklaratywne reguły, które automatycznie walidują każdą odpowiedź. Uruchamiają się po wygenerowaniu odpowiedzi przez Claude i dodają ostrzeżenia jako przypis, gdy reguły nie są spełnione.

Nazewnictwo pliku

skills/<name>/<name>.evals.json

Schemat

{
  "version": 1,
  "skill": "my-new-skill",
  "rules": [
    {
      "id": "ms-001",
      "name": "Human-readable rule description",
      "type": "rule_type",
      "value": "for string/length types",
      "pattern": "for regex types",
      "severity": "warning"
    }
  ]
}

Dostępne typy reguł

Typ Co sprawdza Używa pola
string_contains Odpowiedź zawiera dosłowny tekst value (string)
string_not_contains Odpowiedź NIE zawiera tekstu value (string)
regex_match Odpowiedź pasuje do wyrażenia regularnego pattern (string)
regex_not_match Odpowiedź NIE pasuje do wyrażenia regularnego pattern (string)
max_length Długość odpowiedzi <= N znaków value (number)
min_length Długość odpowiedzi >= N znaków value (number)

Poziomy ważności

Przykład

{
  "version": 1,
  "skill": "odoo-expert",
  "rules": [
    {
      "id": "oe-001",
      "name": "Must use ORM, not raw SQL",
      "type": "string_not_contains",
      "value": "cr.execute",
      "severity": "warning"
    },
    {
      "id": "oe-002",
      "name": "Must use translation helpers",
      "type": "regex_match",
      "pattern": "_t\\(|t-call|t-esc",
      "severity": "warning"
    },
    {
      "id": "oe-003",
      "name": "Response under 5000 chars",
      "type": "max_length",
      "value": 5000,
      "severity": "info"
    }
  ]
}

Wskazówki


Krok 3: Zarejestruj w _registry.json

Rejestr informuje Context Router o twoim skllu, żeby mógł go rekomendować dla odpowiednich wiadomości.

Dodaj wpis

{
  "name": "my-new-skill",
  "description": "One sentence (shown in SKILLS_HINT, max 80 chars).",
  "triggers": ["direct-command", "explicit-request", "пряма команда"],
  "keywords": ["broader", "semantic", "related-term"],
  "agents": ["rick"],
  "category": ["complex"],
  "phase": "21.5"
}

Triggers vs Keywords

Triggers (2 punkty każdy): Sygnały bezpośredniego wywołania. Użytkownik wyraźnie chce tego skilla.

Keywords (1 punkt każdy): Szersze terminy sugerujące trafność bez bycia komendami.

Wytyczne


Krok 4: Skille biblioteczne (prosty format)

Dla wiedzy dziedzinowej, która nie potrzebuje evalów ani dedykowanego katalogu, użyj skills/library/:

skills/library/
├── docker-ops.md
├── postgres-pro.md
└── react-patterns.md

To są pojedyncze pliki .md. Bez katalogu, bez evalów, bez references. Dobre dla skillów bogatych w wiedzę, gdzie walidacja jest mniej istotna.


Checklista


Co się dzieje w trakcie działania

1. Bot startuje → loadRegistry() czyta _registry.json
                  loadEvals() czyta wszystkie pliki .evals.json
                  loadLearnings() czyta learnings.md

2. Wiadomość trafia → routeContext() ocenia skille → SKILLS_HINT wstrzyknięty
                      formatForPrompt() dodaje blok LEARNINGS

3. Claude odpowiada → checkOutput() uruchamia reguły eval
                      formatEvalWarnings() dodaje przypisy

4. Fix It / thumbs-down → addLearning() zapisuje do learnings.md
                           qualityTracker loguje feedback

5. Nocnie → findUnderperformingSkills() sprawdza metryki
            Propozycje wysyłane do CEO do zatwierdzenia

Seeding skilli do globalnej DB

Skille w DB (tabela skills_global) to SSOT dla Context Routera. Plik na dysku to source of truth dla treści; DB to szybki indeks do dopasowywania + auto-iniekcji. Synchronizują się przez skrypty seedera.

Generyczny seeder po kategorii

# Czyta skills/_registry.json, filtruje po kategorii, upsertuje wiersze skills_global.
# Idempotentny + świadomy driftu (pomija bez zmian, aktualizuje przy drifcie treści).
bun scripts/seed-skill-category.ts --category engineering
bun scripts/seed-skill-category.ts --category frontend
bun scripts/seed-skill-category.ts --category marketing

Działa dla dowolnej kategorii obecnej w _registry.json. Bierze pierwszą kategorię z tablicy jako wartość kolumny DB.

Seedery specyficzne

Kiedy uruchamiać

Weryfikacja

sqlite3 data/citadel.db "SELECT name, category, owner_project FROM skills_global ORDER BY id"

owner_project = NULL → globalny (widzą wszystkie projekty). owner_project = 'my-project' → project-only (tylko ten projekt).


Skille project-only vs globalne

Typ skilla owner_project Use case
Globalny (szablon) NULL Generyczna metodologia (TDD, Conventional Commits, AARRR) — przydatna każdemu projektowi
Project-only '<project-name>' Dokumenty specyficzne dla NASZEGO codebase (np. crm-api-reference żyje tylko w arc-v2)

Przeniesienie istniejącego skilla do project-only:

sqlite3 data/citadel.db "UPDATE skills_global SET owner_project='my-project' WHERE name='internal-api-docs'"

Filtr listForProject gate'uje widoczność: inne projekty nie zobaczą skilla project-only.