Скилл для ИИ-агента: как превратить пожелание в правило

Меня зовут Илья, я разработчик и пишу про разработку с ИИ. В этой статье речь пойдёт про скиллы — инструмент, без которого я уже не начинаю работать с агентом на своих проектах. Начну с того, как я до него дошёл.

Сначала это даже приятно. Просишь ИИ-агента сделать одну фичу — он делает, код работает, переключаешься на следующую задачу. Потом просишь написать похожее для другой фичи — и он делает снова, но чуть иначе: во второй фиче другой подход к написанию тестов, в третьей своя структура папок, в четвёртой вызов внешнего сервиса делается напрямую, а в пятой через класс-обёртку. Каждая реализация по отдельности нормальная. А через пару месяцев ты открываешь проект и понимаешь, что получился зоопарк, который невозможно поддерживать.

Я почувствовал это на себе в первый же месяц плотной работы с агентом. И довольно быстро понял, что объяснять ему правила работы в каждом промпте бесполезно: контекст меняется, в новой сессии он старые договорённости уже не помнит. Так в моей работе с агентами появился инструмент, которого раньше не было, — скиллы.

Что такое скилл

Скилл — это инструкция для агента: что сделать и в каком порядке, чтобы результат задачи получился таким, как надо тебе. Писать в неё «пиши аккуратно» бесполезно: агент и так уверен, что пишет аккуратно. Нужны твои правила под конкретную задачу в конкретном проекте или проекте на определенном фреймворке — и подхватывает он их сам, когда за такую задачу берётся.

И это не фишка одного провайдера. Формат скилла открытый, со своей спецификацией: одни и те же файлы понимают агенты от разных провайдеров — и Claude Code от Anthropic, и инструменты от OpenAI, Google, и не только. Написал инструкцию один раз — и она работает у любого из этих агентов, без переписывания под конкретный инструмент.

Физически это просто текстовый файл SKILL.md с инструкцией в Markdown. Рядом с ним может лежать что угодно, что помогает выполнить задачу: более подробные инструкции для отдельных шагов, куски кода или команды, которые агент запускает по ходу дела, готовые заготовки, которые остаётся только подставить. Всё это опционально — минимальный скилл состоит из одного файла.

Целиком скилл в контекст не грузится. Агент держит в памяти только имя и пару строк описания — это называют прогрессивным раскрытием. Если возьмётся за подходящую задачу — дочитает инструкцию. Дойдёт до шага, где нужен соседний файл в папке скилла, — откроет и его, не раньше. Поэтому скиллов в проекте может лежать сколько угодно: пока они не сработали, платить за них почти не приходится.

Чем скилл отличается от других артефактов агента — промпта, проектных правил в CLAUDE.md, MCP-сервера? Промпт живёт одну сессию и забывается. CLAUDE.md висит в контексте всегда, поэтому держать в нём два десятка частных процедур накладно: они занимают место постоянно, даже когда не нужны. MCP-сервер даёт агенту новый инструмент: доступ к данным, к API. Скилл же даёт инструкцию, как работать именно в твоём проекте.

Для примера соберём скилл под конкретную задачу: писать посты для моего Telegram-канала в едином стиле. В итоге получится такая структура файлов скилла:

<каталог-агента>/skills/tg-post/
├── SKILL.md                 # инструкция: процесс и правила стиля
├── references/
│   └── stop-list.md         # выжимка стоп-слов, читается по требованию
├── assets/
│   └── post-template.md     # шаблоны подкатегорий поста
└── scripts/
    └── check_post.py        # валидатор: стоп-слова, штампы, запрещённые символы

Папка skills/ живёт в каталоге агента. У меня это Claude Code, поэтому дальше в командах будет .claude/skills/; у другого агента каталог свой, а внутри всё то же самое.

С чего начать

Легче всего испортить скилл в самом начале: открываешь агента и просишь — «напиши скилл про посты». Получишь воду: «соблюдай единый стиль», «избегай клише». Агент и так знает, что текст должен быть хорошим; ему нужно то, чего он про твой проект не знает, — твои конкретные правила, известные ошибки и образец нужного результата. Поэтому скилл не генерят с нуля, а собирают из того, что у тебя уже записано в виде различных документов или заметок. У меня это были примеры постов, которые мне нравятся, информация о том, что я пишу, и несколько заметок из прошлых промптов: писать без хэштегов, дефис только ASCII и др. Если собирать не из чего — рано писать скилл: сначала нужно пройти задачу руками и отметить, что повторяешь агенту из раза в раз.

Когда материал собран я начинаю с написания description. Одна строка, но очень важная: по ней агент выбирает, использовать его или нет, тело читает уже только после выбора. Значит, в неё надо уложить условие срабатывания: что скилл делает, когда его подключать, по каким словам искать. И писать от третьего лица — описание уезжает в системный промпт, где «Пишет…» работает лучше, чем «я помогу тебе…».

Вот что получилось у меня:

name: tg-post
description: >-
  Пишет и редактирует пост для Telegram-канала в стиле проекта
  (инженер инженеру, без маркетинга, с конкретикой и признанием ограничений).
  Подключать, когда нужно написать TG-пост, тизер лонгрида, короткую реакцию,
  наблюдение или заметку, либо вычитать черновик на стоп-слова и LLM-штампы.
  Ключевые слова: пост, телеграм, тг, тизер, заметка, наблюдение, стиль,
  стоп-слова, вычитка.

У description жёсткий потолок — 1024 символа, но забивать его под завязку незачем: нескольких предложений, как выше, достаточно. Имя с описанием постоянно висят в контексте (около сотни токенов на каждый скилл в проекте), так что чем оно короче и точнее, тем дешевле обходится.

Тело скилла: пишем только то, чего агент не знает

Дальше идёт тело скилла, инструкция, описывающая что делать и в каком порядке. Правило в данном случае одно: писать только то, чего агент не знает (особенности структуры проекта, подходы к написанию кода, созданию моделей и т.п.). Каждую строку можно проверять вопросом «модель это и так уже знает?». Если информация общеизвестная, то писать ее не нужно. Что такое PDF и как устроен HTTP, модель и так знает, такие абзацы просто жгут токены. Остаётся только то, что в проекте сделано не как в общепринятых подходах.

Ниже я для примера хочу показать все разделы по порядку, из которых состоит скилл, с пометкой об их обязательности и реальное содержимое из tg-post.

Заголовок и контекст (обязательно) — Основной заголовок с названием скилла и пара строки: что он делает, в каких случаях вызывается, когда его не использовать.

# Пост в Telegram

Про канал, темы и аудиторию - в `strategy/`. Стиль и стоп-листы - в
`styleguide.md`; эталон - `templates/short-tg.md`. Скилл сводит всё это в процесс:
от первой строки до вычитанного черновика.

Шаги (обязательно) — сама инструкция, что делать по порядку. У меня их четыре: подкатегория и заход, черновик в стиле, вычитка валидатором, финальный чек-лист. Первый выглядит так:

### Шаг 1. Подкатегория, длина и заход

Первым действием открой `assets/post-template.md` и скопируй оттуда болванку нужной
подкатегории как каркас черновика. Не пиши пост с чистого листа - болванка задаёт
структуру и подсказки. Подкатегории: наблюдение, мини-урок, тизер лонгрида, вопрос
аудитории, заметка/цитата.

Примеры (вход и выход) (по желанию) — показывает, что должны включать в себя входящие запросы от пользователя, а также что должен представлять из себя результат работы скилла.

- Вход: «короткий пост про то, как скилл сужает веер вариантов ИИ»
  → Выход: пост-наблюдение 800-1500 знаков, заход = боль (зоопарк кода),
  1-2 жирных акцента, CTA на лонгрид без маркетинга, валидатор зелёный.

Ловушки (по желанию) — неочевидные подвохи/нюансы при работе скилла, которые агент сам не угадает. Список пополняется каждый раз, когда скилл работает не так, как ожидается в силу каких-то неучтенных моментов.

- Пишем **без хэштегов** (решение 2026-05-18): таксономию проставим ретроспективно.
- **Ссылку не в первую строку** - превью Telegram съедает заход.

Помимо указанных выше, раздел включает в себя: заметку про ASCII-дефис вместо длинного тире, которое редактор Telegram показывает как «?»; про то, что ссылка вешается гиперссылкой в слове и ведёт на первоисточник; и про де-брендинг по умолчанию.

Чек-лист (по желанию) — что агент должен проверить сам, прежде чем отдать результат.

- [ ] Первая строка - заход, не анонс.
- [ ] Регистр peer-to-peer, не лекторский («вы должны», «вам стоит» - нет).
- [ ] Конкретика есть (цифра/версия/имя/пример), не «много» и «значительно».
- [ ] `scripts/check_post.py` зелёный (пограничные флаги сняты осознанно).

Плюс три пункта — про длину поста, жирные акценты и запрещённые символы.

Сопутствующие файлы (по желанию) — что и, главное, когда подгружать из references/, scripts/, assets/.

- `references/stop-list.md` - выжимка стоп-слов и LLM-tells; грузи при срабатывании
  валидатора или сомнении во фразе.
- `assets/post-template.md` - болванки подкатегорий; копируй в начале как каркас.
- `scripts/check_post.py` - запускай на финальном черновике (шаг 3).

Тело грузится целиком в контекст, поэтому за размером нужно следить: ориентир — 5000 токенов, примерно пятьсот строк. У меня tg-post занял 101 строку, и это с запасом. Стоп-лист на 84 строки и валидатор на 171 строку в тело не попали — они лежат рядом и открываются только на вычитке.

От пожелания к правилу

Отсюда же правило, какую информацию и файлы куда класть. Необходимые инструкции, используемые почти каждый раз при вызове скилла — в SKILL.md. Громоздкие и нерегулярно используемые файлы, референсы и т.п. (например набор шаблонов для скиллов, примеры постов, стайлгайды для различных типов текстов, скрипты автоматических проверок) уезжают в отдельные файлы, чтобы не висеть в контексте на каждом прогоне.

Так я и сделал со списком стоп-слов. В теле осталась строчка-ссылка «references/stop-list.md — выжимка стоп-слов и LLM-tells», агент открывает его, только когда дошёл до этого места в инструкции. Важна формулировка для чтения нужного файла. «Детали — в references/» не работает: по такой фразе агент либо тащит файл в контекст всегда, либо не открывает никогда. Работает указание момента: «открой references/stop-list.md, когда валидатор что-то нашёл».

Файлы рядом со SKILL.md бывают трёх видов, и агент обращается с каждым по-разному. То, что лежит в папке references/, он читает как справку. То, что в scripts/, — запускает как программу. То, что в assets/, — берёт готовым шаблоном и подставляет, не вчитываясь. И ещё одно правило: ссылайся на файл прямо из SKILL.md, не выстраивая цепочку, где один файл отсылает к другому, тот к третьему. По длинной цепочке агент может поскупиться и прочитать только начало очередного файла.

Самый сильный из этих файлов — скрипт-проверка. Вот зачем он нужен. Всё, что мы до сих пор писали в скилл, оставалось пожеланием: «пиши без штампов», «не используй длинное тире». Агент может это выполнить, а может прочитать по-своему и решить, что и так сойдёт, — текстовую инструкцию легко обойти, не нарушив буквально. Скрипт так не обманешь: он либо находит проблему и завершается ошибкой, либо нет. Поэтому туда, где правило можно проверить машиной, я кладу маленькую программу-проверку.

В моём скилле это scripts/check_post.py. На вход он принимает файл с черновиком поста. Сам текст поста внутри файла обёрнут в три обратные кавычки (```) — в Markdown так помечают блок кода, и это удобно: внутри блока живёт сам пост, а снаружи можно держать рабочие заметки, которые публиковать не надо. Скрипт достаёт текст из этого блока и проверяет на стоп-слова, штампы, запрещённые символы (длинное тире, стрелки) и хэштеги — те самые правила, что записаны в стайлгайде. Запускают его командой python <путь>/check_post.py <файл-черновика>.

Покажу, что он правда ловит. Беру черновик, в который нарочно набил маркетинговых слов, штампов и поставил длинное тире, и прогоняю:

$ python .claude/skills/tg-post/scripts/check_post.py bad_draft.md
Найдено 8 проблем(ы) в теле поста:
  строка 1: стоп-слово/приём: «революцион»
  строка 1: стоп-слово/приём: «невероятн»
  строка 1: LLM-штамп: «стоит отметить»
  строка 1: LLM-связка: «не только ___, но и ___»
  строка 2: стоп-слово/приём: «магическ»
  строка 2: LLM-штамп: «давайте разберёмся»
  строка 2: запрещённый символ: em-dash (—) -> ASCII-дефис '-'
  строка 3: хэштег: постим без хэштегов (решение 2026-05-18)

А на чистом черновике, где всё по правилам, он молчит и завершается с нулевым кодом — у программ это значит «ошибок нет»:

$ python .claude/skills/tg-post/scripts/check_post.py good_draft.md
OK: стоп-слов, LLM-штампов и запрещённых символов не найдено

Остаётся связать скрипт с самим скиллом. В SKILL.md я завёл отдельный шаг — «Вычитка валидатором», и в нём явно написано: прогони проверку и исправляй черновик, пока проверка не пройдет. Теперь агент в конце сам запускает скрипт и исправляет пост до тех пор, пока тот не прошёл проверку. Вот здесь пожелание и становится правилом. Пока текст проверял только человек глазами, инструкция оставалась пожеланием — её можно было тихо проигнорировать. Как только за проверку отвечает программа/скрипт, обойти её, не оставив следа, уже нельзя. И наоборот: любую инструкцию, которую нельзя проверить, агент рано или поздно нарушит, а вы об этом даже не узнаете.

Важно отметить одно допущение скрипта — проверка алгоритмическая: она ищет слова по списку и не понимает смысла всей фразы. Допустим, у нас есть правило не использовать маркетинговый жаргон, возводящий в превосходную степень что-либо (грандиозный, революционный и т.п.). Если я напишу «ничего революционного» — живую фразу, где слово «революционный» стоит в насмешку — скрипт всё равно подсветит его как маркетинговое. Это ложное срабатывание, и нужно явно говорить агенту, что надо проигнорировать это отклонение. Я выбрал такой путь намеренно: пусть лучше проверка изредка прицепится к нормальной фразе, чем пропустит некорректные.

Первый драфт всегда сырой

С первого раза скилл никогда не выходит таким, как задумано. Обязательно будут уточнения, исправления и улучшения на следующих прогонах на реальных задачах. Обычно даю агенту новое задание в новой сессии, где скилл подхватывается с чистого листа, и смотрю не только на результат его работы, но и на трейс — след работы агента: какой скилл он взял, какие файлы открыл, в каком порядке вызывал инструменты, где застревал. Это позволяет найти узкие места в описании скилла и уточнить или дополнить их.

Вообще читать сам трейс глазами не удобно, так как он не сильно читабельный, но можно попросить того же агента его проанализировать и показать человекочитаемый вариант. Если агент при работе со скиллом перебирает подходы один за другим — инструкция расплывчатая, нужна конкретика; не открыл файл из references/, хотя ответ лежал там, — у ссылки не указан момент, когда её читать ну или вообще нет ссылки на файл. А если скилл вообще не включился на подходящей задаче, дело в описании: неподходящие или неполные слова-триггеры.

Покажу на живом примере из этого же скилла. Я дал агенту обычную задачу — написать короткий пост — и потом заглянул в трейс. В сокращённом виде он выглядел так:

Skill: tg-post                     — скилл активирован
Write: draft.md                    — черновик готов
Bash: check_post.py draft.md       — OK, ошибок нет

Пост получился приличный, валидатор зелёный — на первый взгляд всё хорошо. Но трейс показывает и то, чего агент НЕ сделал: он ни разу не открыл assets/post-template.md — ту самую болванку, с которой по инструкции полагалось начать. Он написал пост сразу, в обход заготовки. Причина нашлась в формулировке: в первой версии Шага 1 болванка была мягким советом в конце абзаца («скопируй болванку как каркас»), и агент спокойно его проскочил. Я переписал шаг так, чтобы копирование болванки стало явным первым действием — именно в таком виде Шаг 1 и показан выше. Одна правка по одному прогону, и скилл перестал терять этот шаг. Так это и работает: даже одна итерация прогона скилла по конкретной задаче и его корректировка, заметно подтягивает скилл.

Заключение

Если коротко, то голый агент пишет код, который работает сегодня, но который через полгода некому передать. Скилл — это способ оставить агенту не пожелание, а правило, которое он не обойдёт. Следить за этими правилами и проверять, что их соблюдают, — отдельная инженерная работа, которой пару лет назад попросту не существовало. Я к ней пока только привыкаю.


Про язык. Сами скиллы я обычно держу на английском — вся экосистема агентов англоязычная. В статье скилл показан на русском, поэтому отдельные обороты внутри него могут звучать чуть непривычно по-русски; в английском оригинале они на месте.

Источники

Комментарии (1)


  1. kondratskaya
    03.08.2026 16:39

    Ты бы ещё скрипт на питоне в скилл засунул. А потом удивляешься, что агент тупит на ровном месте