первыйБитБИТ.АГЕНТЫ/туториал

Agent Skills

Глава 9 из 12

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

Agent Skills— это пакеты инструкций, скриптов и справочных материалов, которые дают агенту специализированные знания и возможности. Если инструменты (tools) отвечают на вопрос "что агент умеет делать?", то скилы отвечают на вопрос "что агент знает и как ему это делать?"

Формат был представлен Anthropic для Claude в 2025 году и быстро стал открытым стандартом: его поддерживают Microsoft (Agent Framework), Google (ADK), OpenAI, GitHub Copilot и другие платформы.

Skills vs Tools vs MCP

SkillsTools / Function CallingMCP
Что даётЗнания и инструкцииИсполняемые функцииСтандартный протокол для инструментов
АналогияКарточка рецептаКухонный приборСтандарт розетки
ПриродаТекст на естественном языкеКод, который исполняетсяJSON-RPC слой
ЛатентностьНулевая (локальный текст)Зависит от функцииСетевой round-trip
Для чегоЭкспертиза, best practices, критерииAPI-вызовы, запросы к БД, операции с файламиПодключение внешних сервисов с авторизацией

Skill как слой знаний

Скилы, инструменты и MCP работают на разных уровнях и дополняют друг друга:

  1. Skill говорит агенту, как подойти к задаче и какие инструменты использовать
  2. Tools (function calling) дают агенту возможность выполнять действия
  3. MCP предоставляет стандартный способ подключать удалённые инструменты
skills-tools-mcp.ts
// Skills — агент знает, как готовить
// Tools — агент умеет пользоваться ножом и плитой
// MCP — стандартная розетка для подключения приборов

// Skill: знание рецепта
const skill = {
  name: "italian-cuisine",
  instructions: "Для пасты: вскипятить воду, добавить соль...",
}

// Tool: умение (функция, которую вызывает LLM)
const tool = {
  type: "function",
  function: {
    name: "boil_water",
    description: "Кипятит воду",
    parameters: { type: "object", properties: { temp: { type: "number" } } },
  },
}

// MCP: стандартный способ подключить термометр
// GET /tools/boil_water → JSON-RPC с описанием инструмента

Анатомия скила

Скил — это директория с файлом SKILL.md. В мета-секции (frontmatter) — имя, описание и разрешённые инструменты. В теле — пошаговые инструкции для агента. Принцип progressive disclosure: агент загружает только то, что нужно.

Уровни детализации

  • L0 (Discovery) — имя и описание из frontmatter (сканирование)
  • L1 (Load) — полный текст SKILL.md (инструкции, ~5000 токенов)
  • L2 (Resources) — дополнительные файлы (схемы БД, шаблоны, политики)
  • L3 (Execution) — скрипты, которые агент запускает (код не в контексте)
skills/code-reviewer/SKILL.md
---
name: code-reviewer
description: Проверяет код на соответствие стандартам и best practices
allowed-tools: [read_file, search_code, bash]
---

# Code Reviewer Skill

## Responsibilities
- Проверять код на ошибки, уязвимости и несоответствия стилю
- Предлагать конкретные исправления с примерами кода
- Указывать на потенциальные проблемы производительности

## Workflow
1. Прочитать файл, который нужно проверить
2. Определить язык и фреймворк
3. Проверить:
   - Синтаксические ошибки
   - Утечки памяти и ресурсов
   - Соответствие code style проекта
4. Сформировать отчёт с приоритетами:
   - 🔴 Critical — необходимо исправить
   - 🟡 Warning — рекомендуется исправить
   - 🔵 Suggestion — предложение по улучшению
5. Предложить код исправления для каждого замечания

## Related Files
- See ./standards.md for project-specific code style
- See ./security-checklist.md for security review

Как агент использует скилы

Цикл работы со скилами:

  1. Discovery: агент находит все директории с SKILL.md
  2. Matching: по frontmatter (name + description) выбирает релевантный скил
  3. Load: загружает тело SKILL.md и следует инструкциям
  4. Execute: при необходимости подгружает файлы L2 или запускает скрипты L3
skill-registry.ts
// 1. Агент сканирует файловую систему в поиске SKILL.md
async function discoverSkills(skillsDir: string): Promise<SkillMeta[]> {
  const entries = await fs.readdir(skillsDir, { withFileTypes: true })
  const skills: SkillMeta[] = []

  for (const entry of entries) {
    if (!entry.isDirectory()) continue
    const skillPath = path.join(skillsDir, entry.name, "SKILL.md")
    if (!await exists(skillPath)) continue

    const content = await fs.readFile(skillPath, "utf-8")
    const meta = parseFrontmatter(content)
    skills.push({
      name: meta.name,
      description: meta.description,
      path: skillPath,
    })
  }
  return skills
}

// 2. Агент выбирает подходящий скил по запросу пользователя
function matchSkills(query: string, skills: SkillMeta[]): SkillMeta[] {
  return skills
    .map(s => ({ skill: s, score: similarity(query, s.description) }))
    .filter(s => s.score > 0.3)
    .sort((a, b) => b.score - a.score)
    .map(s => s.skill)
}

// 3. Агент загружает инструкции скила (L1)
async function loadSkill(skill: SkillMeta): Promise<string> {
  const content = await fs.readFile(skill.path, "utf-8")
  return stripFrontmatter(content) // только тело SKILL.md
}

// 4. При необходимости — подгружает ресурсы (L2) и запускает скрипты (L3)
async function loadL2Resource(skillDir: string, name: string) {
  return fs.readFile(path.join(skillDir, name), "utf-8")
}

Регистрация скилов в коде

Скилы можно регистрировать программно через интерфейс Skill. Агент хранит реестр скилов и вызывает их по необходимости:

agent-with-skills.ts
interface Skill {
  name: string
  description: string
  load(): Promise<string>      // L1: инструкции
  readResource(name: string): Promise<string>  // L2: справочники
  runScript(name: string): Promise<string>      // L3: скрипты
}

class Agent {
  private skills: Map<string, Skill> = new Map()

  registerSkill(skill: Skill) {
    this.skills.set(skill.name, skill)
  }

  async findAndExecute(query: string, task: string) {
    // Найти подходящий скил
    const matches = Array.from(this.skills.values())
      .filter(s => query.includes(s.name))

    if (matches.length === 0) {
      return "Нет подходящего скила"
    }

    // Загрузить инструкции (L1)
    const instructions = await matches[0].load()
    console.log("Загружены инструкции:", instructions)

    // Выполнить задачу, следуя инструкциям скила
    return executeWithInstructions(matches[0], task)
  }
}

// Пример: регистрируем скилы
const agent = new Agent()
agent.registerSkill({
  name: "code-reviewer",
  description: "Проверяет код на ошибки и стиль",
  load: () => loadSkillFile("code-reviewer"),
  readResource: (name) => loadResource("code-reviewer", name),
  runScript: (name) => runBash("code-reviewer", name),
})

Skill Registry: демо

Интерактивная демонстрация progressive disclosure. Выберите скил и переключайте уровни:

Нажмите на скил, чтобы увидеть его содержимое на разных уровнях детализации:

Когда использовать скилы

✅ Хорошо для скилов

  • — Экспертиза в предметной области (бухгалтерия, юриспруденция)
  • — Стандарты кодирования и ревью
  • — Скрипты поддержки и онбординга
  • — Многошаговые рабочие процессы

❌ Лучше другим способом

  • — Часто меняющиеся данные → RAG или инструменты
  • — Детерминированные пайплайны → workflows
  • — Простые однократные задачи → прямой промпт
Далее: в главе 10 — MCP протокол: как подключать инструменты и данные к агенту.