Создание скилов
Пошаговое руководство по добавлению новых возможностей в твой проект Arc OS.
Прежде чем писать новый скил — проверь глобальную библиотеку
Arc OS поставляется с 40+ generic-скилами в skills/, покрывающими типовые роли. Прежде чем писать новый, проверь, не покрывает ли существующий твою потребность:
| Домен | Доступные скилы |
|---|---|
| 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 |
| Startup ops | market-analysis, gtm-strategy, financial-modeling, pitch-deck, customer-development, fundraising, founder-brand, metrics-dashboard, legal-startup |
| Marketing | seo-foundations, founder-brand |
| Process | standup-aggregator, commit-discipline |
| Database | postgres-patterns |
Полный список: GET /api/crm/skills?category=<X> или bun -e "console.log(JSON.stringify(require('./skills/_registry.json').skills.map(s=>s.name),null,2))".
Скил = trigger-matched, а не always-on
Скил авто-инжектится в промпт воркера, когда сообщение матчится с его triggers (в _registry.json). Поле description — это trigger-логика («когда использовать»), а не пересказ. Context Router выбирает топ-5 совпадений на сообщение.
Что такое скил
Скил — это переносимый набор инструкций, который обучает твоего AI-бота конкретной экспертизе. Скилы хранятся в директории skills/ и состоят из:
<name>.md— файл инструкций (обязательно)<name>.evals.json— правила автоматической проверки качества (опционально, но рекомендуется)references/— вспомогательные документы, схемы, примеры (опционально)
skills/
├── _registry.json ← Central registry
├── my-new-skill/
│ ├── skill.md ← What the AI should do
│ ├── my-new-skill.evals.json ← How to validate the output
│ └── references/ ← Context documents
└── library/
└── domain-expert.md ← Simple single-file skills
Шаг 1: Напиши skill.md
Это основная инструкция. Claude читает её при активации скила.
Шаблон
# 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
Рекомендации
- До 500 слов — длинные скилы размывают контекст
- Повелительное наклонение — «Проверь репозиторий», а не «Тебе стоит проверить»
- Конкретные примеры — показывай ожидаемые пары ввод/вывод
- Ссылки на конкретные инструменты — называй команды, API или паттерны, которые нужно использовать
Пример: 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
Шаг 2: Напиши evals (правила качества)
Evals — это декларативные правила, которые автоматически проверяют каждый ответ. Они запускаются после того, как Claude генерирует ответ, и добавляют предупреждения в сноски, если правила нарушены.
Именование файлов
skills/<name>/<name>.evals.json
Схема
{
"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"
}
]
}
Доступные типы правил
| Тип | Что проверяет | Использует поле |
|---|---|---|
string_contains |
Ответ содержит конкретный текст | value (string) |
string_not_contains |
Ответ НЕ содержит текст | value (string) |
regex_match |
Ответ соответствует regex | pattern (string) |
regex_not_match |
Ответ НЕ соответствует regex | pattern (string) |
max_length |
Длина ответа <= N символов | value (number) |
min_length |
Длина ответа >= N символов | value (number) |
Уровни серьёзности
warning— указывает на проблему с качеством. Отображается как⚠️.info— информационная заметка. Отображается какℹ️.
Пример
{
"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"
}
]
}
Советы
- Начни с 2-3 правил. Добавляй больше по мере того, как находишь паттерны в исправлениях.
- Безопасность прежде всего:
string_not_containsдля опасных команд,regex_not_matchдля паттернов с учётными данными. - Соглашение по ID:
<префикс-скила>-<номер>(например,oe-001,gm-002). - Тестируй: отправь сообщение, которое должно активировать скил, и проверь, появляются ли предупреждения корректно.
Шаг 3: Зарегистрируй в _registry.json
Реестр сообщает Context Router о твоём скиле, чтобы он мог рекомендовать его для релевантных сообщений.
Добавь запись
{
"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 очка каждый): прямые сигналы вызова. Пользователь явно хочет этот скил.
- "deploy", "review", "scaffold", "odoo", "audit"
Keywords (1 очко каждое): более широкие термины, которые указывают на релевантность без явного вызова.
- "OWASP", "Docker", "CI/CD", "production", "module"
Рекомендации
- Добавляй украинские эквиваленты в triggers для двуязычных команд
- Держи описания до 80 символов (усекаются в SKILLS_HINT)
- 5-8 triggers на скил (больше = шумное совпадение)
- Keywords опциональны, но значительно улучшают маршрутизацию
Шаг 4: Library-скилы (простой формат)
Для предметной экспертизы, которой не нужны evals или отдельная директория, используй skills/library/:
skills/library/
├── docker-ops.md
├── postgres-pro.md
└── react-patterns.md
Это одиночные .md-файлы. Без директории, без evals, без references. Подходят для скилов с упором на знания и минимальной валидацией.
Чеклист
-
skills/<name>/skill.md— инструкция с Purpose, Protocol, Constraints -
skills/<name>/<name>.evals.json— минимум 2 правила валидации - Запись в
skills/_registry.json— с triggers и keywords - Имя совпадает везде — имя директории = имя скила в eval = имя в реестре
- Тест: отправь trigger-сообщение → проверь SKILLS_HINT в логах
- Тест: намеренно спровоцируй ошибку eval → проверь, появляется ли предупреждение
Что происходит в рантайме
1. Bot starts → loadRegistry() reads _registry.json
loadEvals() reads all .evals.json files
loadLearnings() reads learnings.md
2. Message arrives → routeContext() scores skills → SKILLS_HINT injected
formatForPrompt() adds LEARNINGS block
3. Claude responds → checkOutput() runs eval rules
formatEvalWarnings() appends footnotes
4. Fix It / thumbs-down → addLearning() writes to learnings.md
qualityTracker logs feedback
5. Nightly → findUnderperformingSkills() checks metrics
Proposals sent to CEO for approval
Загрузка скилов в глобальную DB
Скилы в DB (таблица skills_global) — это SSOT для Context Router. Файл на диске — source of truth для контента; DB — быстрый индекс для матчинга + авто-инжекции. Синхронизируются через seeder-скрипты.
Generic seeder по категории
# Reads skills/_registry.json, filters by category, upserts skills_global rows.
# Idempotent + drift-aware (skip if no change, update on content drift).
bun scripts/seed-skill-category.ts --category engineering
bun scripts/seed-skill-category.ts --category frontend
bun scripts/seed-skill-category.ts --category marketing
Работает для любой категории, присутствующей в _registry.json. Берёт первую категорию из массива как значение DB-колонки.
Специфичные seeders
scripts/seed-startup-skills.ts— захардкожен для category="startup" (10 startup operations скилов)scripts/migrate-skills-to-db.ts— историческая bulk-миграция (все файлы, только insert, без update)
Когда запускать
- После создания нового
.md+ записи в_registry.json→ запусти seeder один раз - После обновления контента существующего
.md→ drift-aware seeder обновит DB - Bootstrap нового проекта → seeders запускаются через
vps-sync.shStep 1.5 (planned)
Проверка
sqlite3 data/citadel.db "SELECT name, category, owner_project FROM skills_global ORDER BY id"
owner_project = NULL → глобальный (видят все проекты). owner_project = 'my-project' → project-only (только этот проект).
Project-only vs глобальные скилы
| Тип скила | owner_project |
Use case |
|---|---|---|
| Глобальный (template) | NULL | Generic-методология (TDD, Conventional Commits, AARRR) — полезна любому проекту |
| Project-only | '<project-name>' |
Документы, специфичные для НАШЕЙ кодовой базы (напр. crm-api-reference лежит только в arc-v2) |
Перевести существующий скил в project-only:
sqlite3 data/citadel.db "UPDATE skills_global SET owner_project='my-project' WHERE name='internal-api-docs'"
Фильтр listForProject гейтит видимость: другие проекты не увидят project-only скил.