Як синхронізувати skills агента між репозиторіями
Копії skill у восьми репозиторіях неминуче розходяться. Дізнайтеся, як винести їх у спільний репозиторій, закріпити версію та перевіряти оновлення.
Як спільно використовувати навички агента в різних репозиторіях
Щоб спільно використовувати навички агента в різних репозиторіях, припиніть копіювати файл і почніть залежати від нього. Створіть один репозиторій навичок, додайте до нього тег і дозвольте кожному проєкту фіксувати потрібний тег. Потім додайте smoke test для кожної навички та перевіряйте кожне оновлення так само, як оновлення залежності.
Це складається з чотирьох частин: спільного джерела істини, зафіксованої версії для кожного репозиторію, smoke test для кожної навички та процесу перевірки. Нижче пояснюється, навіщо потрібна кожна частина, як інструменти, що випускаються у 2026 році, працюють із цим і як побудувати всю схему на self-hosted git remote без використання зовнішніх сервісів.
Навичка агента — це папка, яка містить файл SKILL.md, а також потрібні їй скрипти та довідкові файли. Якщо цей компонент для вас новий, спочатку прочитайте що таке навичка агента і як працює SKILL.md. Ця сторінка присвячена ланцюжку постачання навколо цього компонента.
Де зберігається skill і чому його складно поширювати
Claude Code завантажує skills із трьох місць, кожен шлях наведено в документації зі skills.
~/.claude/skills/<skill-name>/SKILL.md— особистий шлях. Skills із нього завантажуються в усіх ваших проєктах і не завантажуються в проєктах інших користувачів..claude/skills/<skill-name>/SKILL.md— шлях рівня проєкту. Skills із нього завантажуються для всіх, хто клонує цей репозиторій.<plugin>/skills/<skill-name>/SKILL.md— шлях усередині plugin. Skills із нього завантажуються всюди, де ввімкнено цей plugin.
Для команди найкорисніший другий варіант, оскільки його вміст додається до репозиторію, і всі, хто його клонує, отримують ці файли. Саме тут і виникає проблема. Skill у .claude/skills/ належить одному репозиторію. У вас вісім репозиторіїв. Отже, skill доводиться копіювати вісім разів.
Frontmatter не допомагає. Специфікація Agent Skills дозволяє шість ключів, а засоби поширення, які забезпечують цю вимогу, виводять список, якщо ви використовуєте інший ключ:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, nameЗверніть увагу, чого немає: ключа version не передбачено. Усередині файлу ніде не зазначено, яка копія є новішою. Це логічно, оскільки skill є документом, а не пакетом. Водночас це означає, що версіювання має забезпечувати зовнішній щодо файлу рівень, і відповідальність за нього лежить на вас.
Проблема 1: вісім копій, які непомітно розходяться
Копіювання та вставлення працює в перший день. На шістдесятий день воно вже дає збій. Хтось виправляє неправильну інструкцію в репозиторії payments, але не змінює інші сім копій. Хтось інший додає правило щодо пагінації в orders. Тепер одна й та сама назва skill дає різні результати перевірки залежно від того, з якого каталогу запустився агент, і жоден розробник про це не знає.
Збій непомітний, оскільки стану помилки немає. Skill — це текст. Застаріла інструкція призводить до впевненої, але неправильної відповіді, а саме такі помилки обходяться найдорожче. Агент не порівнює вашу копію з копіями в інших репозиторіях, тому єдиний сигнал — людина має помітити, що два репозиторії не узгоджуються.
Проблема 2: версію не зафіксовано
Навіть якщо команда зберігає навички в одному місці, зазвичай їх поширюють через крок копіювання: setup-скрипт, рядок curl у документі з інструкціями для онбордингу або shell-аліас, який синхронізує каталог. Усі ці способи встановлюють поточний стан гілки без фіксації версії.
Через це два розробники можуть працювати з одним і тим самим комітом одного застосунку, але використовувати різні інструкції, якщо вони виконали синхронізацію в різні дні. Також після невдалого запуску агента неможливо відповісти на важливе запитання: яка версія навички це спричинила? Без записаної ревізії запуск неможливо відтворити, тому звіт про помилку не дає змоги виконати діагностику.
Проблема третя: ніхто не знає, чи навичка досі працює
Навичка не має компілятора. Це інструкції для моделі, тому вона може перестати працювати, хоча файл залишиться ідентичним до останнього байта. Оновлення моделі змінює те, наскільки точно вона дотримується довгих інструкцій. Інструмент командного рядка, який викликає навичка, перейменовує прапорець. URL у довідковому файлі починає повертати 404, і агент працює зі сторінкою помилки.
У жодному з цих випадків не виникає явної помилки. Агент і далі відповідає. Просто відповідь стає гіршою, ніж минулого місяця, а це важко помітити, якщо перевіряти зміни по одному pull request.
Що вирішують інструменти, випущені у 2026 році
Кілька рішень уже доступні, і вони по-різному визначають, де має зберігатися версія.
Lockfiles. Інструмент командного рядка skills від Vercel Labs (vercel-labs/skills, ліцензія MIT, v1.5.22 станом на 5 August 2026) встановлює skills із git-репозиторію в каталог, якого очікує ваш agent, і знає структуру більш ніж сімдесяти agents. npx skills add <repo> встановлює, npx skills update оновлює, а npx skills list показує встановлені компоненти. Перелік встановленого зберігається один раз для кожного користувача, а не один раз для кожного репозиторію. Відкритий запит у цьому проєкті (issue 283) стосується команди skills install, яка повторно встановлює всі відстежувані skills із lock file, щоб на іншій машині отримати той самий набір. Сприймайте цей запит як звіт про поточний стан. Ідея lockfile вже усталилася. Варіант для окремого проєкту ще розробляється.
Specs і тести. SkillSpec використовує інший підхід. Він розглядає SKILL.md як контракт, який потрібно перевіряти, а не як текст, якому слід довіряти. Заявлена мета — зробити skills такими, щоб їх можна було "followable, testable, and provable". skillspec doctor <path> показує, де agent найімовірніше втратить контекст. skillspec boundary map <path> показує, до яких ресурсів skill може отримати доступ, а skillspec boundary assess <path> ранжує ці результати за ризиком. Це Rust crate із подвійною ліцензією MIT або Apache 2.0, версія 0.2.2 станом на 29 July 2026. Встановлюйте зафіксовану версію, а не найновішу:
cargo install skillspec --version 0.2.2 --locked
skillspec --version--locked виконує збірку з версіями залежностей, з якими crate було опубліковано, тому під час збірки версії не змінюються непередбачувано. skillspec --version має вивести 0.2.2. Інше число означає, що раніше у вашому PATH знаходиться старіший binary і саме він має пріоритет.
Практика vendor. Google описала, як створює skills у google/skills, у публікації як вона створює, тестує та масштабує agent skills. Якщо не враховувати масштаб, механізм є звичайною continuous integration (CI). Перед злиттям кожен skill проходить linters для frontmatter metadata, кількості рядків, структури каталогів і правил іменування. Link checker завершує збірку з помилкою для будь-якого URL, який повертає 404. Це виявляє правдоподібні посилання, вигадані agent. Автори мають додавати до skill набір evaluation prompts і scoring rubric. Заплановані evaluation jobs щотижня запускаються для всієї бібліотеки, щоб виявляти регресії. Для кожного skill також призначено owner, який має виправляти його, якщо якість знижується.
Шаблон, спільний для всіх трьох відповідей
Вам не обов’язково обирати один із цих варіантів. За ними стоїть одна структура, і звичайний git дає змогу реалізувати її повністю.
- Єдине джерело істини. Skill має рівно одне місце зберігання, а кожен репозиторій посилається на це джерело, не зберігаючи власну копію.
- Зафіксована версія для кожного репозиторію. Кожен проєкт записує точну ревізію, яку він використовує. Тому оновлення є commit у цьому проєкті із зазначеними автором і датою.
- Smoke test для кожного skill. Один виконуваний тест підтверджує, що skill і надалі дає обіцяний результат.
- Процес перевірки змін. Зміна спільного skill проходить review, а кожен споживач бачить diff перед її застосуванням.
Це і є структура залежності. Skills стали спільним артефактом швидше, ніж навколо них з’явилися відповідні інструменти, тому найнадійніше використовувати інструменти, яким ви вже довіряєте.
Структура для невеликої команди на self-hosted git remote
Один репозиторій містить інструкції. Більше в ньому нічого немає, тому його історія виглядає як журнал змін інструкцій.
agent-skills/
skills/
api-review/
SKILL.md
release-notes/
SKILL.md
tests/
api-review.sh
release-notes.sh
CHANGELOG.mdРелізи — це теги. Використовуйте анотовані теги, оскільки вони містять повідомлення та дату. У повідомленні зазначайте причину, через яку користувачеві потрібне оновлення:
git tag -a v1.4.0 -m "api-review: require pagination on list endpoints"
git push origin v1.4.0Якщо ваш remote — це Gitea, Forgejo, GitLab або bare repository через SSH на власному VPS, далі нічого не змінюється. Усе зводиться до git і symlink.
Фіксація версії за допомогою git submodule
Submodule записує один точний commit іншого репозиторію у вашому репозиторії. Цей запис і є зафіксованою версією. У кожному проєкті, який його використовує:
git submodule add https://git.example.com/team/agent-skills.git vendor/agent-skills
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills checkout v1.4.0
mkdir -p .claude/skills
ln -s ../../vendor/agent-skills/skills/api-review .claude/skills/api-review
git add .gitmodules vendor/agent-skills .claude/skills/api-review
git commit -m "Pin shared agent skills to v1.4.0"Саме symlink забезпечує цю схему. Запис skill на рівні проєкту може бути symlink на каталог в іншому місці диска, а Claude Code переходить за ним і читає SKILL.md із цільового каталогу. Тому skill завантажується як звичайний skill проєкту, а його файли зберігаються в submodule на вибраному вами commit.
Перевірте зафіксовану версію:
git submodule statusКоректний рядок починається з пробілу, далі містить commit, шлях і найближчий tag:
4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602 vendor/agent-skills (v1.4.0)Початковий - означає, що submodule ще не ініціалізовано, тому .claude/skills/api-review ні на що не вказує, а skill непомітно не завантажується. Виправте це за допомогою git submodule update --init. Початковий + означає, що checkout-нутий commit відрізняється від записаного, тому цей розробник працює з інструкціями, яких немає в інших. Для нових clone потрібна команда git clone --recurse-submodules. Її слід додати до README, оскільки звичайний clone залишає vendor/agent-skills порожнім і не виводить помилки.
Оновлення виконується свідомо, і саме в цьому полягає перевага такої схеми:
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills diff v1.4.0 v1.5.0 -- skills/
git -C vendor/agent-skills checkout v1.5.0
git add vendor/agent-skills
git commit -m "Bump shared agent skills to v1.5.0"Рядок diff є способом перевірки змін. Він показує ті самі зміни, які побачить кожен інший проєкт, що використовує цей submodule, і добре підходить для pull request.
Натомість закріплення версій через marketplace плагінів
Якщо ви не хочете, щоб кожен розробник вивчав submodules, система плагінів Claude Code виконує розповсюдження за вас і працює із self-hosted remote. Додайте каталог до .claude-plugin/marketplace.json у skills repository:
{
"name": "acme-agents",
"owner": { "name": "Platform team", "email": "platform@example.com" },
"plugins": [
{
"name": "team-skills",
"description": "Shared review and release skills",
"version": "1.4.0",
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0",
"sha": "4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602"
}
}
]
}Тут задіяні два різні джерела. Плутанина між ними є типовою помилкою. Джерело marketplace, тобто місце, звідки завантажується сам каталог, приймає ref для branch або tag і не приймає sha. Джерело плагіна всередині каталогу приймає обидва параметри. Якщо задано обидва, ефективним pin є sha. Тому exact-commit pin потрібно вказувати в записі каталогу.
Далі кожен repository, що використовує плагін, оголошує marketplace у своєму закоміченому .claude/settings.json:
{
"extraKnownMarketplaces": {
"acme-agents": {
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0"
}
}
},
"enabledPlugins": {
"team-skills@acme-agents": true
}
}Учаснику команди, який довіряє project folder, буде запропоновано встановити marketplace. Плагін буде ввімкнено для нього без wiki-сторінки з інструкцією зробити це вручну. Після цього skills доступні через /team-skills:api-review, оскільки skills плагіна мають namespace за назвою плагіна й не можуть конфліктувати з project skill з такою самою назвою. Після публікації нового tag користувачі оновлюють marketplace за допомогою /plugin marketplace update acme-agents, а потім виконують /reload-plugins, якщо це зазначено у підсумку встановлення.
Написання smoke test для однієї skill
Smoke test — це сценарний запуск агента для fixture із відомою помилкою та однією перевіркою. Claude Code запускається в неінтерактивному режимі з -p, а skill, який викликає користувач, працює і в цьому режимі: додайте /skill-name до рядка prompt, і його буде розгорнуто до початку запуску.
#!/usr/bin/env bash
set -euo pipefail
claude -p "/api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--allowedTools "Read" \
--output-format json \
--json-schema '{"type":"object","properties":{"rule_ids":{"type":"array","items":{"type":"string"}}},"required":["rule_ids"]}' \
| jq -e '.structured_output.rule_ids | index("pagination-required")' > /dev/nullfixtures/orders-api.md — це короткий файл з однією навмисно внесеною помилкою. Перевірка полягає в тому, що skill називає цю помилку. jq -e завершується з ненульовим кодом, коли його filter повертає null, тому сценарій завершується помилкою, якщо skill перестає виявляти підготовлену помилку. claude також завершується з ненульовим кодом, якщо запуск не вдався, а set -euo pipefail перетворює будь-яку з цих помилок на невдалий тест.
Модель формулює відповіді по-різному під час різних запусків, тому ніколи не перевіряйте весь текст речення. Перевіряйте ідентифікатор, який має вивести skill, або поле схеми, яку ви запросили. Fixture має бути невеликим, щоб запуск залишався дешевим.
У CI додайте --bare. Без цього claude -p завантажує той самий контекст, що й інтерактивний сеанс, зокрема hooks, plugins і CLAUDE.md із системи, на якій виконується запуск. Через це персональна конфігурація іншого учасника команди може змінити результат. Bare mode пропускає автоматичне виявлення всіх компонентів, тому він також пропускає skill, який ви тестуєте. Завантажте цей skill явно. Bare mode також не читає дані входу до вашої subscription, тому спочатку задайте ANTHROPIC_API_KEY в environment:
claude --bare -p "/team-skills:api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--plugin-dir vendor/agent-skills \
--allowedTools "Read" \
--output-format jsonЗ --output-format stream-json перша подія запуску повідомляє, які plugins завантажено, і містить масив plugin_errors для тих, що не завантажилися. Завершуйте CI job з помилкою, якщо plugin_errors не порожній. Це виявляє pin, що вказує на revision, якої більше не існує. Інакше така проблема проявляється як тихе ігнорування агентом ваших внутрішніх правил.
Спільний skill є виконуваною інструкцією
Дві функції роблять це буквальним фактом, і обидві мають значення, якщо файл надійшов від іншої команди.
По-перше, SKILL.md може виконувати shell-команди до того, як модель щось прочитає. Рядок такого вигляду в тілі документа є етапом попередньої обробки:
- Current branch: !`git rev-parse --abbrev-ref HEAD`Команда виконується на машині, яка завантажує skill, а її вивід замінює placeholder у тексті, який отримує модель. Блок із трьома зворотними апострофами на початку та ! виконує кілька команд так само. Під час виконання ніхто не підтверджує ці дії. Читання спільного skill означає читання його підстановок команд.
По-друге, frontmatter може попередньо дозволяти використання інструментів. allowed-tools надає перелічені інструменти без запиту дозволу для сеансу, у якому було викликано skill. Для project skill це надання набуває чинності після того, як користувач приймає діалог підтвердження довіри до workspace для цієї папки. У документації Claude Code наслідок сформульовано прямо: перевіряйте project skills перед тим, як довіряти репозиторію, оскільки skill може надати собі широкі права доступу до інструментів.
Тому оновлення skill слід обробляти так само, як оновлення залежності. Усюди, де це дозволяє механізм, фіксуйте точний commit, оскільки tag можна перемістити, а branch за визначенням змінюється. На машині з обмеженим доступом параметр "disableSkillShellExecution": true у settings замінює кожну підстановку команди на буквальний текст [shell command execution disabled by policy] замість її виконання. Якщо цей параметр застосовано через managed settings, користувач не може його перевизначити. На bundled і managed skills цей параметр не поширюється.
Так само уважно потрібно ставитися до даних, які читає skill. Skill, що виконує env або відкриває config-файл, додає до контексту моделі все, що там знайде. Саме цей випадок описано в як не допускати потрапляння секретів до агентів, яких ви запускаєте. Skill, що завантажує сторінку або виконує запит, створює таку саму експозицію назовні, оскільки отриманий текст потрапляє в контекст і виглядає точно так само, як написані вами інструкції. Про цю межу варто прочитати перед тим, як спрямувати агента до власного екземпляра SearXNG для вебпошуку.
Що читати під час оновлення версії
- Diff кожного тіла
SKILL.md, оскільки цей текст містить інструкції, яких дотримуватиметься ваш агент. - Кожну підстановку команди, оскільки вона виконується на вашій машині під час завантаження skill.
- Будь-яку зміну в
allowed-tools, оскільки цей рядок надає інструменти без запиту. - Результат тестового запуску, пов’язаного з tag. Якщо спільний репозиторій запускає власні smoke-тести в CI, tag, на який ви закріплюєте версію, має мати прикріплений успішний запуск.
Якщо reviewer не може прочитати весь diff за десять хвилин, skill став надто великим. Розділіть його. Те саме стосується документів репозиторію, які читають ваші агенти: зберігайте незмінні правила у файлах, описаних у розподілі між AGENTS.md і HUMAN.md, а архітектурні обґрунтування — у DESIGN.md, написаному для агентів, і залишайте skills вузькоспеціалізованими процедурами.
Коли зміна моделі або інструмента порушує роботу skill
Під час роботи skill може змінитися багато компонентів, навіть якщо ніхто не редагує сам skill. Оновлення моделі змінює надійність виконання довгих інструкцій. Через це skill, який залежав від досягнення моделлю кроку дев’ять, може перестати до нього доходити. Утиліта командного рядка може перейменувати flag. Тоді agent запускає старий flag, читає помилку та імпровізує. URL, на який є посилання, може почати повертати 404. Agent harness може змінити спосіб вибору skill. Через це description, який раніше перемагав під час зіставлення, більше не відповідає потрібному критерію. Якщо процедура через це починає завершуватися достроково, збільшення версії не усуває проблему. Самі інструкції потрібно структурувати так, щоб вони змушували виконувати останні кроки. Саме на цьому ґрунтується skill unlazy та його метод Depth Tree.
Тому в цій схемі smoke test має вирішальне значення. Запускайте тест кожного skill за розкладом, а також після push. Google щотижня запускає свої evaluation jobs для всієї бібліотеки саме з цієї причини. Для команди з десятьма skill достатньо щотижневого cron job на невеликому VPS. Це єдиний спосіб дізнатися про проблему раніше, ніж її виявить розробник.
Переносимість також допомагає. Специфікація Agent Skills обмежує frontmatter шістьма ключами. Тому skill, написаний відповідно до цієї специфікації, завантажується в різних інструментах, а не лише в тому, для якого його створили. Кожен ключ, специфічний для певного harness, є ставкою на одного vendor. Створення skill, які працюють після заміни моделі, є окремою дисципліною. Вона розглядається в матеріалі як забезпечити роботу skill на будь-якій моделі.
FAQ
Як поширити одну навичку агента між кількома репозиторіями?
Розмістіть навичку в окремому git-репозиторії, позначайте в ньому релізи тегами, а в кожному проєкті-споживачі посилайтеся на тег замість копіювання файлу. Працюють два механізми. git submodule фіксує точний коміт, а symlink із .claude/skills/<name> до submodule дає змогу завантажувати навичку як звичайну навичку проєкту. Plugin marketplace виконує те саме завдання через /plugin, а pin оголошується в .claude/settings.json репозиторію-споживача. В обох випадках версія зберігається в історії git, тому можна визначити, які інструкції сформували конкретний запуск агента.
Чи можна зафіксувати навичку агента на певній версії?
Не всередині SKILL.md, оскільки цей frontmatter не має ключа version. Pin має надходити зі шару навколо файлу. git submodule за своєю структурою фіксує точний коміт. У plugin marketplace для Claude Code джерело плагіна приймає ref для гілки або тега та sha для точного коміту; якщо вказано обидва параметри, пріоритет має sha. Саме джерело marketplace приймає лише ref. Надавайте перевагу pin на коміт, оскільки тег можна перемістити після його перевірки.
Що має перевіряти smoke test навички?
Перевіряйте стабільний результат. Запустіть навичку в неінтерактивному режимі на fixture із відомою помилкою, а потім перевірте, чи з’явився у виводі конкретний ідентифікатор, наприклад ідентифікатор правила, який навичка має повідомити. Запит структурованого виводу за допомогою --output-format json і --json-schema робить перевірку точною, а jq -e завершує скрипт із помилкою, якщо значення відсутнє. Не перевіряйте повне речення, оскільки модель може по-різному формулювати відповіді під час різних запусків.
Чи безпечно встановлювати спільну навичку з репозиторію іншої команди?
Розглядайте її як залежність коду, оскільки вона містить виконувані інструкції. SKILL.md може виконувати shell-команди під час завантаження через форму підстановки команд !, а поле frontmatter allowed-tools може попередньо дозволяти інструменти без запиту. Перевіряйте diff під час кожного оновлення, фіксуйте залежність на точному коміті, а не на гілці, і надавайте перевагу джерелу під контролем вашої команди. На керованих машинах "disableSkillShellExecution": true у settings повністю забороняє виконання підстановок команд.
Чи працюватиме спільна навичка в агентах, відмінних від Claude Code?
Це залежить від того, які поля frontmatter ви використовуєте. Специфікація Agent Skills визначає 6 ключів: name, description, license, compatibility, metadata і allowed-tools. Навичка, обмежена цими ключами, завантажується в інструментах, що реалізують специфікацію, а також працює в Claude Code без змін. Специфічні для harness ключі та функції вмісту, що виходять за межі специфікації, в інших системах ігноруються або відхиляються. Тому не використовуйте їх у навичках, які плануєте широко поширювати.