Что такое skill и зачем его декларировать

Skill — это объявленная единица способности агента: «я умею X». Ключевое слово — объявленная. Способность мало иметь, её надо задекларировать так, чтобы машина (другой агент, оркестратор, реестр) поняла, что агент умеет, не запуская его и не читая исходники.

Зачем разбивать агента на навыки, а не описывать одним абзацем «что я умею»:

  • Обнаружение. В реестре ищут по навыкам: «кто умеет translate?». Гранулярные skills = агента находят точно под задачу.
  • Роутинг. Оркестратор/LLM сопоставляет задачу с конкретным навыком, а не гадает по общему описанию.
  • Переиспользование. Чётко очерченный навык подключается в разные пайплайны как кирпичик.
  • Контракт. Навык — обещание: объявил — обязан выполнять. Это единица ответственности и версионирования.
ℹ️ Skill — это «что», а не «как»

Декларация навыка описывает что агент умеет и как его вызвать — но не как он это делает внутри. Реализация скрыта (это может быть один вызов LLM или целый под-пайплайн). Как Agent Card прячет вендора агента, так skill прячет реализацию способности. Снаружи виден только контракт.

Анатомия skill

Хороший навык — самоописанный. Разберём поля, которые делают его находимым и вызываемым. Набор перекликается с skills[] в Agent Card и с JSON Schema инструмента (модуль 02) — это один и тот же принцип на разных уровнях.

100%
колёсико — масштаб  ·  зажать и тянуть — перемещение
Skill id машинный ключ · стабильный · уникальный name · description для человека и LLM-роутера tags[] поиск в реестре · категоризация examples[] примеры запросов → роутинг по смыслу input/output modes форматы: текст / файлы / JSON реализация скрыта — виден только контракт Реестр индексирует по tags / description Роутер (LLM) матчит задачу по description/examples
Skill: описание навыка перевода
json
{
  "id": "translate_ru_en",
  "name": "Перевод RU↔EN",
  "description": "Переводит текст между русским и английским с сохранением смысла и стиля. Подходит для документов, статей, писем. НЕ юридический/медицинский перевод.",
  "tags": ["translation", "ru", "en", "text"],
  "examples": [
    "Переведи это письмо на английский",
    "Translate this article to Russian",
    "Сделай англ. версию README"
  ],
  "inputModes": ["text/plain"],
  "outputModes": ["text/plain"]
}

Обрати внимание на description: он говорит не только что навык делает, но и границы («НЕ юридический перевод»). Это спасает роутер от ложного выбора. А examples — самое недооценённое поле: именно по ним LLM-роутер и семантический поиск понимают, о чём навык, лучше, чем по сухому названию.

Роутинг: как задача находит навык

Декларация нужна ради одного — чтобы задачу сматчили с правильным навыком. Это и есть роутинг. Три уровня, от простого к умному:

Способ роутингаКак работаетКогда
По ключам/тегамТочное совпадение id или tagКлиент точно знает нужный навык
Семантический поискЭмбеддинги description/examples ↔ запросМного навыков, поиск в реестре
LLM-роутерLLM читает список skills и выбираетНеоднозначные задачи, оркестрация

На практике чаще всего работает LLM-роутер: оркестратору дают список навыков (из Agent Card или MCP list_tools), а он сам решает, какой вызвать под задачу — ровно как LLM выбирает tool по JSON Schema (модуль 02).

LLM-роутинг: задача → навык (концептуально)
python
# Собираем каталог навыков из доступных агентов/серверов
catalog = [
    {"id": "translate_ru_en", "description": "перевод RU↔EN...", "examples": [...]},
    {"id": "web_research",    "description": "поиск и выжимка...", "examples": [...]},
    {"id": "summarize",       "description": "краткое содержание...", "examples": [...]},
]

# Роутер = LLM: даём каталог + задачу, просим выбрать навык(и)
prompt = f"""Задача: {task}
Доступные навыки:
{format_skills(catalog)}
Верни id навыка(ов), которые нужно вызвать, в порядке выполнения."""

chosen = llm(prompt)   # напр. ["web_research", "summarize", "translate_ru_en"]

# Именно поэтому description и examples важны:
# роутер выбирает по СМЫСЛУ, а не по названию функции
✅ Хорошее описание = хороший роутинг

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

Гранулярность: как нарезать навыки

Главный вопрос дизайна: насколько мелко дробить? Две крайности одинаково плохи.

❌ Слишком крупно

do_everything — «умею всё по тексту». Роутер не понимает, когда звать; переиспользовать нельзя; описание расплывчатое. Навык-невидимка.

✅ В самый раз

translate, summarize, extract_entities — каждый решает одну понятную задачу. Роутер точно матчит; каждый переиспользуется отдельно.

❌ Слишком мелко

translate_word, translate_sentence, translate_paragraph — дробление без смысла. Каталог раздут, роутер путается между близнецами, накладные расходы на выбор.

✅ Ориентир

Один навык = одна цель пользователя, которую можно назвать глаголом и объяснить в одном предложении. Если для описания нужен союз «и» между разными действиями — дели.

⚠️ Правило одного предложения

Если description навыка невозможно уложить в одно ясное предложение без «и ещё, и также» — навык слишком крупный, режь. Если два навыка отличаются только размером входа или тривиальным параметром — они слишком мелкие, объединяй и параметризуй. Гранулярность = «одна цель, названная глаголом».

Переиспользование: навык как кирпичик

Смысл декларации навыков раскрывается, когда один навык живёт в разных системах. Хорошо описанный summarize подключается и в исследовательский пайплайн, и в почтового ассистента, и в новостной дайджест — без переписывания.

            навык summarize (объявлен один раз)
                        │
      ┌─────────────────┼─────────────────┐
      ▼                 ▼                 ▼
исследователь      почтовый бот      новостной дайджест
(сжать выжимку)   (краткий ответ)   (аннотации статей)

один контракт → много точек переиспользования

Условия, при которых навык реально переиспользуется:

  • Самодостаточность — навык не зависит от скрытого контекста конкретной системы. Всё нужное — во входных параметрах.
  • Стабильный контракт — id и сигнатура не меняются капризно; изменения — через версии.
  • Честные границы — description говорит, где навык применим, а где нет. Тогда его подключают уместно.
  • Идемпотентность где возможно — предсказуемый навык проще встроить в разные потоки.
🎯 Связь с протоколами модуля

Skills — общий знаменатель всего раздела. В Agent Card навыки объявляются для A2A-обнаружения; в MCP способности выставляются как tools. Один принцип — декларируемая, обнаружимая, переиспользуемая единица — под разными протоколами. Освоив дизайн навыков, ты одинаково хорошо описываешь и A2A-skills, и MCP-tools.

Типичные ошибки

❌ Ошибка 1: пустые examples

Без примеров LLM-роутер и семантический поиск плохо понимают навык. Examples — главный сигнал для роутинга по смыслу. Заполняй 2–3 реальными запросами.

❌ Ошибка 2: навык-«швейцарский нож»

«Умею всё» невозможно сматчить и переиспользовать. Один навык — одна цель. Крупные способности разбивай на понятные единицы.

❌ Ошибка 3: описание без границ

Если не сказать, чего навык НЕ делает, роутер вызовет его не по адресу (перевод юридического текста «общим» переводчиком). Указывай область применимости.

❌ Ошибка 4: нестабильный id

Переименовал id — сломал всех, кто на него роутил. id — контракт. Меняй через версии, не задним числом.

Шпаргалка

Skills — всё в одном месте
text
SKILL = объявленная единица способности: «что умею» + «как вызвать» (НЕ «как делаю»)
  свойства: декларируемый · обнаружимый · переиспользуемый · контракт

АНАТОМИЯ:
  id              — машинный ключ, стабильный, уникальный
  name/description— для человека и LLM-роутера + ГРАНИЦЫ («НЕ делает X»)
  tags[]          — поиск/категоризация в реестре
  examples[]      — примеры запросов → роутинг по смыслу (недооценено!)
  input/outputModes — форматы (текст/файлы/JSON)

РОУТИНГ (задача → навык):
  по ключам/тегам  — точное совпадение (клиент знает навык)
  семантический    — эмбеддинги description/examples ↔ запрос
  LLM-роутер       — LLM читает каталог и выбирает (как выбор tool по schema)
  → качество роутинга = качество description/examples

ГРАНУЛЯРНОСТЬ:
  слишком крупно (do_everything) → невидим, не переиспользовать
  слишком мелко (translate_word/_sentence) → раздутый каталог, путаница
  ОРИЕНТИР: 1 навык = 1 цель, глагол, одно предложение без «и»

ПЕРЕИСПОЛЬЗОВАНИЕ: самодостаточность · стабильный контракт · честные границы

СВЯЗЬ: Agent Card skills (A2A) + MCP tools = один принцип на разных протоколах

ГРАБЛИ: пустые examples · швейцарский нож · описание без границ · нестабильный id

Практическое задание

Задание: спроектируй каталог навыков

  1. Возьми агента-ассистента по документам. Задекларируй 3–4 навыка (id, name, description с границами, tags, examples, io-modes). Проверь: каждый описывается одним предложением?
  2. Найди в своём каталоге «швейцарский нож» или переизбыточное дробление — и исправь гранулярность.
  3. Смоделируй LLM-роутинг: дай каталог и три задачи («переведи договор», «сделай выжимку статьи», «найди в тексте даты»). Какой навык выберет роутер? Где он может ошибиться и почему?
  4. Для одного навыка покажи, как он переиспользуется в двух разных системах без изменений. Что делает это возможным?
  5. Сравни свой skill с MCP-tool из прошлого урока и с JSON Schema инструмента (модуль 02): что общего в полях, в чём разница уровней?
  6. Со звёздочкой: реализуй семантический роутер — сложи описания навыков в эмбеддинги, матчи запрос по косинусной близости (модуль 04: embeddings) и сравни с LLM-роутером по точности.

Что дальше

Ты собрал весь словарь протоколов: A2A, Agent Card, MCP, Skills. Последний урок раздела — reference flows: как эти кирпичики складываются в типовые проверенные схемы взаимодействия агентов, которые можно брать за основу.