Создание качественного навыка агента Claude: уроки из проекта с тренером по бегу
Создание надежного навыка агента Claude: точные описания, оценка перед написанием текста, SKILL.md в качестве маршрутизатора, скрипты вместо текста и разделение учетных данных в CI.
Источники: I Missed My Running Goal Three Years Running. So I Built an Agent Skill.
Представьте бегуна, который три года подряд ставил себе цель пробежать 1 000 км, но каждый раз её не достигал, в итоге за три года пробежав всего около 2 500 км. Проблемой не была сама отдача усилий. Были травмы, необходимость начинать всё сначала и занятые недели. Отсутствовал план — ведь мотивация работает хорошо до того дня, когда это перестаёт быть так.
Одним из решений является отказ от зависимости от силы воли и создание системы. Именно так появился running-coach — навык Claude Agent, который планирует индивидуальные пробежки и целые недели на основе личного опыта человека, превращает каждую неделю в рассылку в стиле статьи и даже формирует плейлист под длительность предстоящей пробежки.
Здесь бег является лишь фоном. Более важной темой является то, что необходимо для развития хорошего навыка — такого, который надежно срабатывает, редко использует контекст, ведет себя одинаково на всех платформах и не теряет эффективности со временем. Ниже каждая из опубликованных Anthropic методик создания контента сопоставлена с тем, как этот проект их применяет.
Что такое навык агента
Навык представляет собой папку. В ее корне находится файл SKILL.md, который начинается с YAML-метаданных, содержащих name и description, а затем следуют инструкции в формате Markdown. Рядом с ним могут находиться справочные документы, скрипты, шаблоны и другие ресурсы.
Интересной частью является способ загрузки навыка с использованием трехуровневой модели под названием постепенное раскрытие информации:
- Уровень 1: метаданные. Загружаются всегда при запуске, примерно по 100 токенов на навык. Они включают только название и описание.
- Уровень 2: инструкции. Загружаются только тогда, когда активируется навык, и их объем ограничен примерно 5 тыс. токенов. Это содержимое файла
SKILL.md. - Уровень 3: ресурсы. Загружаются по требованию с помощью bash и остаются доступными до момента использования. Здесь хранятся ссылочные файлы, скрипты и ресурсы.
Компания Anthropic сравнивает навык с руководством по адаптации, предназначенным для нового сотрудника. Основной принцип заключается в том, что окно контекста является общим ресурсом. То, что занято навыком, недоступно для остальной информации, которую агент пытается сохранить в памяти.
1. Описание выступает в роли API
На уровне 1 всё, что модель видит относительно той или иной навыка, — это её описание. Оно служит скорее таблицей маршрутизации, чем документацией, поскольку модель сопоставляет поступающий запрос с этим описанием, чтобы решить, следует ли применить соответствующий навык. В описании должны быть указаны как функции навыка, так и моменты его применения; оно должно быть написано в третьем лице и не превышать 1 024 символов, причем практический лимит для отображения без обрезки в выбрасывателе claude.ai составляет около 200 символов. Вот описание, которое использует running-coach:
name: running-coach
description: >-
Plans a run or a whole week as Google Calendar blocks, builds a weekly
running digest email, and makes playlists — from Strava, Spotify, AccuWeather
and Calendar. Use for pacing or planning a week.
Посмотрите, как это построено. Сначала описывается, что может делать данная функция (планирование пробежки, создание краткого обзора, формирование плейлистов), затем — когда её следует использовать (для контроля темпа или планирования недели), а также указываются источники данных, чтобы вопрос в стиле Strava мог связываться с этой функцией. Название пишется с заглавных букв и совпадает с именем каталога — это строгое правило, а не вопрос стиля, и процесс сборки проекта обеспечивает его соблюдение, как будет показано позже.
Невозможно заранее определить, будет ли описание эффективным. Его необходимо протестировать, и именно поэтому в репозитории в первую очередь находится набор оценок, а не документация.
2. Сначала пишите оценки, а уже потом дорабатывайте текст
Совет компании Anthropic — сначала разработать механизмы оценки, чтобы решать реально существующие проблемы, а не те, которые вы себе представили. В папке evals/ проект содержит четыре файла с сценариями, по одному на каждую функциональность. Это не тесты на единицы кода. Это контракты поведения, написанные простым языком. Вот файл для планирования запуска:
{
"skills": ["running-coach"],
"query": "I'm heading out for 8k this evening, how long is that going to take me?",
"expected_behavior": [
"Triggers the running-coach skill without being named, and routes to the planning capability",
"Reads references/run-planning.md and does not read the digest or playlist references",
"Runs scripts/cache.py status before projecting…",
"Executes scripts/planning/plan_run.py 8 rather than reading its source or reimplementing Riegel inline",
"Reports the projected finish time, the pace, and the recommended effort band…",
"Never asks for or uses a Strava access token"
]
}
Каждое утверждение отражает лучшую практику. Запуск тестов без указания их описания оценивает качество описаний. Чтение только соответствующих эталонных тестов является примером постепенного раскрытия информации. Запуск скрипта без его повторной реализации проверяет предпочтение скриптов перед прозой. Полное игнорирование токенов тестирует границы допустимых данных. Все это вместе превращает всю философию проектирования в наблюдаемое поведение, а остальная часть процесса сборки направлена на обеспечение её соблюдения.
3. Использование SKILL.md в качестве навигатора
Самый распространённый способ исчерпания ресурсов контекста для описания навыка — это помещение всего содержимого в файл SKILL.md. Лучший подход — рассматривать этот файл как оглавление, указывающее на более подробные материалы при необходимости. Держите его кратким, а ссылки — на уровне одного уровня глубины, поскольку агенты обычно читают глубоко вложенные файлы лишь частично, в результате чего получают неполное представление.
Чтобы объяснить каждую из четырех возможностей здесь, потребуется целая страница, поэтому SKILL.md не описывает ни одной из них. Он направляет на:
| Capability | Reference | Entry point |
| -------------- | -------------------------------- | --------------------------------- |
| Plan a run | references/run-planning.md | scripts/planning/plan_run.py |
| Plan the week | references/week-planning.md | scripts/planning/plan_week.py |
| Weekly digest | references/weekly-digest.md | scripts/digest/run_pipeline.py |
| Run playlist | references/run-playlist.md | scripts/playlist/build_playlist.py|
Work out which one is wanted, then read only that capability's reference.
При запросе на плейлист агент открывает только run-playlist.md, и ничего больше. Спецификация рабочего процесса, особенности и примечания к шаблону никогда не учитываются, поскольку ненужный встроенный контент не стоит ничего. Уровень 2 остается минималистичным, а уровень 3 добавляет ровно один файл. Строка «читает X, не читает Y» в коде проверки именно это.
4. Скрипты вместо прозы: запускайте их, а не читайте
Это, возможно, самая ценная идея в проектировании навыков. Когда агент запускает скрипт через bash, в контекст попадает только результат выполнения, а исходный код — никогда. Заранее написанные скрипты также надежнее кода, созданного «на лету», и всегда дают одинаковый результат.
Таким образом, логика running-coach реализована на Python, и инструкции прямо указывают агенту не трогать исходный код:
**Run the scripts, don't read them.** They print everything needed; every one
takes --help and most take --json. Reading their source wastes context.
Прогноз времени завершения гонки Riegel, расчёт диапазона усилий и анализ краткого отчёта выполняются с помощью детерминистического Python и возвращают краткий результат. Агент координирует процесс, но не пересчитывает данные. Сравните агента, который оценивает вашу скорость, которая медленная, переменчивая и требует большого количества вычислений, с агентом, который использует калькулятор скорости и сообщает число, что делает его быстрым и одинаковым в каждый раз.
5. Каждый скрипт — это полноценная командная строка с общепринятыми конвенциями
Чтобы принцип «запустить, а не читать» сработал, агенту необходимо запускать скрипт, открытие которого ему запрещено. Это возможно благодаря единому, самоописательному интерфейсу, поэтому каждый скрипт соблюдает одни и те же конвенции:
- один позиционный аргумент для всего, что всегда требуется (расстояние для планирования и создания списков воспроизведения);
--data DIRприсутствует везде, что позволяет любому скрипту обращаться к другой кэш-системе, что обеспечивает возможность офлайн-тестирования и использования индивидуальных сред для каждой сессии;--jsonимеется практически во всех скриптах, что позволяет выводу одного скрипта стать входными данными для следующего;--helpприсутствует во всех скриптах и служит альтернативным способом действия агента при неопределенности относительно того или иного параметра. Агент читает текст с помощью, что дешево и не требует обработки исходного кода, что дорого и запрещено.
Вот основные возможности, перечисленные по порядку.
Планирование запуска осуществляется с помощью plan_run.py:
python3 scripts/planning/plan_run.py 8 # 8 km, defaults
python3 scripts/planning/plan_run.py 8 --band steady # force an effort band
python3 scripts/planning/plan_run.py 8 --start-in 3 # start 3h from now (weather-aware)
python3 scripts/planning/plan_run.py 8 --json # machine-readable plan
Единственным обязательным аргументом является distance_km. Факультативными флагами являются --exp, который корректирует экспоненту усталости Ригеля, и --band, который задаёт определённый диапазон нагрузки. При отсутствии указаний программа определяет диапазон на основе предыдущей нагрузки бегуна в тренировках. Хеуристическая часть обеспечивает свободу действий, в то время как точная проекция остаётся детерминистской.
Плейлист формируется с помощью скрипта build_playlist.py, который намеренно имитирует структуру планировщика:
python3 scripts/playlist/build_playlist.py 8 # size to the 8 km finish
python3 scripts/playlist/build_playlist.py 8 --genre "lo-fi"
python3 scripts/playlist/build_playlist.py 8 --minutes 55 # size by time instead
python3 scripts/playlist/build_playlist.py 8 --band hard
Поскольку оба процесса преодолевают одинаковое расстояние в пространстве координат, эти две функции дополняют друг друга: время завершения plan_run соответствует продолжительности, необходимой для формирования плейлиста, заданной build_playlist. Скрипт генерирует запрос, а не сам плейлист, после чего агент передаёт этот запрос коннектору Spotify. Здесь снова проявляется разделение задач: скрипт выполняет арифметические операции, а агент занимается вводом-выводом.
Еженедельный обзор представляет собой небольшую систему обработки данных, а не монолит. Файл run_pipeline.py проверяет кэш, а затем выполняет два этапа:
python3 scripts/digest/run_pipeline.py # validate → analyse → render
python3 scripts/digest/run_pipeline.py --plan-km 8 # lead the digest with a planned run
python3 scripts/digest/run_pipeline.py --seed 3 # pin the masthead title choice
python3 scripts/digest/run_pipeline.py --skip-validate # skip the pre-flight cache check
Под ним analyze.py объединяет данные за неделю из кэша в один файл digest_data.json, а build_email.py преобразует этот JSON в самодостаточное HTML-письмо. Разделение анализа и отображения позволяет изменять внешний вид письма без вмешательства в процесс анализа, а флаг --seed обеспечивает воспроизводимость единственного случайного выбора — заголовка верхней части письма, что удобно для двукратного снимка экрана той же недели.
Планирование недели — это самый интересный интерфейс командной строки, поскольку он представляет собой цепочку операций «планирование — проверка — выполнение», выраженную в виде подкоманд, которые агент выполняет по порядку:
python3 scripts/planning/plan_week.py goal # show the weekly goal in force
python3 scripts/planning/plan_week.py propose # propose the split of runs (as JSON)
python3 scripts/planning/plan_week.py draft --split - # lay the split across the days
python3 scripts/planning/plan_week.py brief --draft - # hand the agent a per-run contract
python3 scripts/planning/plan_week.py events --draft - --content - # emit calendar blocks
Каждый этап выводит JSON, который следующий этап получает через stdin. Там, где это применимо, этапы также принимают распространённые параметры переопределения (--km, --runs) и опции планирования, такие как --start-date, --time, --weekend-time, --location и --tz. Рекомендации предлагают использовать именно такой формат «проверяемых промежуточных результатов» для работ с нестабильными данными: агент никогда не создаёт план произвольно. Он выдает структурированный план, скрипт его проверяет и форматирует, а только после этого он преобразуется в календарные события.
На серединном этапе происходит целенаправленная передача задачи. На этапе brief скрипт определяет расстояние, диапазон темпа и день выполнения, затем предоставляет агенту контракт на каждую поездку. Агент пишет текст, имитирующий человеческую речь, чтобы описания поездок не были одинаковыми. Скрипт отвечает за то, что должно быть точным, а модель — за то, чтобы текст звучал естественно. Принцип «оптимальных степеней свободы» заключается в ограничении свободы при работе с чувствительными к ошибкам математическими расчетами и предоставлении большей свободы для написания прозы в рамках одного приказа.
6. Решайте проблемы, а не откладывайте их
Слабо сформулированные инструкции заставляют агента разбираться с сложными случаями на основе нечетких указаний вроде «если данные кажутся устаревшими, найдите решение». В Anthropic предпочитают ясно указывать на необходимость решения проблемы, а не откладывать ее: ошибки должны обрабатываться непосредственно в скрипте, без передачи их другим лицам. running-coach реализует это с помощью модели свежести — для каждого кэшированного данных он фиксирует его возраст, а status указывает конкретный вызов MCP, необходимый для устранения каждой проблемы:
python3 scripts/cache.py status # what's cached, how stale, what to call
python3 scripts/cache.py put streams --file - # ingest an MCP response from stdin
python3 scripts/cache.py show week --json # a compact summary, not the raw blob
python3 scripts/cache.py validate --for digest # shape-check before a run
cache.py содержит четыре функции (status, put, show, validate), каждая из которых представляет собой этап в процессе обновления данных. Функция status выводит список всех ключей вместе с информацией о сроке их действия: для текущей недели этот срок указывается в краткой форме, поскольку он меняется при каждом запуске, а для уже завершившихся недель и данных об атлетах — в формате, характерном для недельных данных; при наличии устаревших или отсутствующих данных она указывает конкретный инструмент MCP, необходимый для их получения. Агент выполняет этот запрос и сразу передает полученный ответ в функцию put. Затем функция validate --for <capability> проверяет, пригоден ли результат для дальнейшего использования, прежде чем запустится следующий скрипт, так что некорректное получение данных приводит к сразу же возникающей ошибке, а не к проблемам позже.
Дополнительные меры безопасности: функция put принимает только ключи из заранее определённого списка разрешённых значений, функция show выводит краткое резюме, а не исходный JSON, поэтому при просмотре кэша в контекст не попадает мегабайт данных GPS, к тому же агенту запрещено вручную редактировать эти JSON-файлы. В результате агенту не нужно самостоятельно решать, следует ли перезагружать данные или какие именно данные загружать, поскольку это указано в скрипте. Неопределённое решение вроде «достаточно ли данные свежие?» превращается в чёткое указание, что и имеется в виду под выполнением команды cache.py status перед обработкой данных.
7. Границы учётных данных
Это центральный архитектурный выбор, а также мера безопасности: проведение аудита на наличие неожиданных сетевых запросов и способов доступа к файлам. Данная технология делает такой аудит по своей структуре простым, поскольку ничто внутри неё не хранит учётные данные и не открывает сокеты.
agent --(Strava / Spotify / AccuWeather MCP)--> cache.py put --> the cache
the cache --> plan_run.py / run_pipeline.py / build_playlist.py --> output
Только агент взаимодействует с коннекторами MCP, а только cache.py записывает данные в кэш. Все остальные скрипты лишь преобразуют данные из кэша офлайн, при этом во всем пакете отсутствуют HTTP-клиенты, ключи API и токены доступа.
# cache.py — the only gateway to the running-coach data cache.
# The agent is the only thing that talks to MCP; this script is the only thing
# that reads or writes the cache. Nothing here needs an access token.
Следуют три преимущества. Что касается безопасности, то здесь нет ничего, что могло бы утекнуть, а поверхность сети для аудита пуста. Что касается портативности, то данная технология не зависит от того, являютсяся ли соединители локальными, удаленными или отсутствуют, поскольку она использует только кэш. Что касается возможности тестирования, то заполненный кэш позволяет каждому скрипту выполняться полностью офлайн, что делает возможным проведение простых тестов в рамках CI.
8. Одно требование к среде выполнения: Python 3.10
Технологии не синхронизируются между разными средами, и у каждой среды есть свои ограничения по среде выполнения. API Claude не предоставляет доступа к сети и возможности установки пакетов, тогда как Claude Code имеет все необходимое. Чтобы технология работала везде, необходимо проектировать ее с учетом самой ограниченной среды.
Именно поэтому running-coach не использует никаких внешних компонентов. Здесь нет файла requirements.txt, нет виртуальной среды virtualenv и нет этапа установки. В инструкциях указано, что достаточно Python 3.10 или новее, причем простой python3 работает без изменений даже в хостинговой среде с песочницей, где невозможна установка пакетов.
Все необходимое для работы этого инструмента находится внутри каталога skills/running-coach/. Помещение этой папки в ~/.claude/skills/ обеспечивает работу с Claude Code, а загрузка в формате архива — работу с Cowork или claude.ai; поведение в обоих случаях идентично. Во всех путях используются пробелы вместо слешей, что позволяет избежать проблем при работе на разных платформах. Файлы кэша и результатов сохраняются в месте, находящемся вне каталога с инструментом, что делает установленную копию только для чтения, и они никогда не сохраняются в git, поскольку кэш содержит реальные GPS-полилинии, которые декодируются в маршруты, начинающиеся у дома пользователя.
9. Проверки упаковки и инструменты контроля качества, подтверждающие заявленные характеристики
Упаковка — это этап, который часто игнорируют. Неправильно настроенный скилл может проявлять себя в незаметных проблемах: архив с отдельными файлами в корне будет тихо отклонён при загрузке. Поэтому проект включает файл package.py — валидатор без зависимостей, который повторяет проверки, используемые в собственном репозитории скиллов Anthropic. Он проверяет допустимые ключи frontmatter, имя в формате kebab-case, совпадающее с названием директории, длину описания в пределах спецификаций (с предупреждением при превышении примерно 200 символов, установленных на claude.ai), а также наличие в архиве ровно одной верхней уровня директории с файлом SKILL.md в её корне.
GitHub Actions затем блокирует публикацию каждой версии на основе этих проверок. При добавлении тега v* рабочий процесс выполняет следующее:
- byte-compiles каждый скрипт (
python -m compileall) для выявления синтаксических ошибок; - проверяет frontmatter на соответствие спецификации;
- запускает каждую точку входа с параметром
--help, что как минимум показывает, что каждый скрипт импортирует и парсит код в чистой среде Python 3.10; - проверяет, что файл
running-coach/SKILL.mdнаходится в корне архива; - и только после этого публикует zip-архив.
# 3.10 is the version the skill claims to support, so building on it is
# also how that claim stays honest.
- uses: actions/setup-python@v5
with:
python-version: "3.10"
Универсальные уроки
Из процесса разработки выделяются несколько ключевых моментов:
Описание длиной около 100 токенов выполняет 90% работы. Поскольку именно оно всегда загружается, его неправильная работа делает всё остальное нерелевантным. Уделяйте ему особое внимание и добавляйте тесты, проверяющие корректность его работы, без упоминания названия соответствующей навыка.
Перенесите логику из промптов в детерминированные скрипты. Текст, который читает агент, различается и потребляет токены, тогда как скрипт, который он выполняет, стоит дешево и всегда даёт один и тот же результат. Главная идея — выполнять, а не читать.
Доверяйте правилам, которые можно сформулировать за одно предложение. Фраза «Только агент общается с MCP, один скрипт записывает кэш, всё остальное работает офлайн» ценнее, чем кучи защитного кода, поскольку целые категории ошибок и утечек становятся структурно невозможными.
Пусть система сборки проверяет ваши утверждения. Навык, обещающий поддержку Python 3.10 и отсутствие зависимостей, должен собираться именно так в системе CI при каждой публикации. Без этого обещание остается лишь надеждой.
Сама цель бега остается открытой, но теперь существует «тренер», который планирует неделю, дает честную оценку по утрам понедельника и еженедельно пересчитывает цель на основе пройденного расстояния. Бег превратился в решаемую инженерную задачу, как только его стали рассматривать именно так.
Любому, кто устанавливает подобный навык, необходимо включить выполнение кода и использовать собственный коннектор Strava, поскольку навык не содержит учетных данных. То же самое касается источников, которые стоит прочитать: обзор Agent Skills от Anthropic и страница с рекомендациями по созданию навыков, обе из документации Claude Platform.
Связанные материалы
- Gemini Spark: объяснение, задачи, навыки, расписание, безопасность и стоимость — что делает круглосуточный агент Gemini Spark от Google в Gmail, Календаре и Docs, как работают механизмы безопасности, сколько он стоит, где он заблокирован и кому стоит им воспользоваться.
- Применение технологий Advanced RAG в производстве: архитектура, инструменты и компромиссы — обзор реализации Advanced RAG в производстве: ввод данных, парсинг, разбиение на фрагменты, генерация векторных представлений, хранилища векторов, гибридные методы поиска, переранжирование результатов, оценка эффективности и меры безопасности, а также компромиссы, связанные с каждым из этих элементов.