Средний

Набор навыков для работы с AI-агентами

Алексей Кузнецов
Алексей Кузнецов
Системный администратор29 октября 2026 г.16 мин чтения

Разбираем репозиторий mattpocock/skills: как структурировать инструкции и навыки для создания предсказуемых и эффективных автономных AI-агентов.

Набор навыков для работы с AI-агентами

Разбираем репозиторий mattpocock/skills: как структурировать инструкции и навыки для создания предсказуемых и эффективных автономных AI-агентов.

Зачем агентам специализированные навыки

Зачем агентам специализированные навыки

Когда мы говорим об автономных агентах, часто возникает соблазн создать один «всемогущий» промпт. Идея кажется логичной: дать модели широкую роль, описать все возможные задачи и ждать, что она справится. Но на практике такой подход быстро заводит в тупик. С практической точки зрения, попытка запихнуть всю логику работы в одно системное сообщение превращает агента в непредсказуемый черный ящик.

Если вы строите сложную систему, вам нужна предсказуемость. А она достигается через декомпозицию. Вместо того чтобы просить модель «быть системным администратором», мы даём ей набор узкоспециализированных инструментов — навыков (skills), — каждый из которых отвечает за конкретное действие.

Проблема универсальных промптов

Главная беда универсальных инструкций — это деградация качества при росте контекста. Чем больше задач вы описываете в одном промпте, тем выше вероятность, что модель начнет путаться в приоритетах или игнорировать часть инструкций. Это явление часто называют «потерей в середине» (lost in the middle).

Представьте, что вы настраиваете автоматизацию для управления домашним сервером. Если ваш промпт выглядит примерно так:

text
Ты — умный помощник. Ты можешь проверять статус Docker-контейнеров, 
чистить логи, делать бэкапы в TrueNAS и перезагружать Raspberry Pi. 
Если видишь ошибку в логах, анализируй её и предлагай решение...

...то при возникновении реальной проблемы агент может начать «галлюцинировать». Вместо того чтобы выполнить конкретную команду docker ps, он начнет рассуждать о том, почему контейнер упал, пропуская этап диагностики. В итоге вместо предсказуемого результата вы получаете поток текста, который не приближает вас к исправлению ситуации.

Разделение логики и инструкций

Чтобы избежать хаоса, нужно разделять высокоуровневую логику принятия решений и низкоуровневые инструкции по выполнению задач. В подходе, который продвигает Мэтт Покок в репозитории mattpocock/skills, навыки рассматриваются как отдельные модули.

Логика (Reasoning) отвечает на вопрос: «Что нужно сделать?». Навык (Skill) отвечает на вопрос: «Как именно это сделать?».

Если мы переложим это на архитектуру системы, то управление агентом будет напоминать работу системного инженера. У вас есть общая стратегия (план работ), но каждая конкретная операция выполняется через четко определенный интерфейс.

Например, вместо того чтобы описывать процесс бэкапа внутри основного промпта, вы выносите его в отдельный навык со строгой структурой. В конфигурационном файле (например, в формате JSON или YAML, который агент использует для вызова инструментов) это может выглядеть так:

yaml
skill:
  name: backup_to_truenas
  description: "Создает архив директории и отправляет его на NFS-шару TrueNAS"
  parameters:
    source_dir: "/etc/nginx"
    destination_path: "/mnt/storage/backups/nginx"
    compression_level: 9
  execution_steps:
    - "tar -czf /tmp/backup.tar.gz $source_dir"
    - "cp /tmp/backup.tar.gz $destination_path"
    - "rm /tmp/backup.tar.gz"

Такой подход гарантирует, что агент не будет «изобретать» способ копирования файлов. Он получит четкий алгоритм. Если завтра вы решите сменить NFS на протокол S3, вам не придется переписывать логику мышления агента — вы просто обновите описание конкретного навыка. Это и обеспечивает ту самую инженерную предсказуемость, на которой строятся надежные системы.

Архитектура навыков в репозитории skills

Архитектура навыков в репозитории skills

Когда мы говорим об автономных агентах, главная проблема, с которой я сталкивался — это не отсутствие «ума» у модели, а отсутствие предсказуемости. Если вы дадите агенту одну огромную инструкцию на пять страниц, он неизбежно начнет путаться в контексте, галлюцинировать или пропускать важные шаги. Подход, который предлагает репозиторий mattpocock/skills, решает эту проблему через декомпозицию. Вместо того чтобы учить агента «быть инженером», мы даем ему набор узкоспециализированных инструментов.

Структура директории .agents

В этой архитектуре навыки не лежат в одной куче. Они организованы в иерархическую структуру внутри директории .agents, что позволяет агенту быстро находить нужный контекст, не перегружая своё «окно внимания».

С практической точки зрения, это напоминает файловую систему в Linux: вы не держите все конфиги в /etc, вы распределяете их по поддиректориям, чтобы управление было прозрачным. В репозитории структура обычно выглядит так:

text
.agents/
├── search/
│   ├── web_search.md
│   └── academic_search.md
├── coding/
│   ├── python_refactor.md
│   └── unit_test_gen.md
└── communication/
    └── email_drafting.md

Каждый файл .md — это не просто текст, а строго структурированный манифест навыка. Если мы посмотрим на типичный файл навыка, он будет содержать описание того, что навык может делать, и, что более важно, что он делать не должен. Это создает те самые границы, которые делают поведение агента предсказуемым.

Принципы атомарности задач

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

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

  1. Навык поиска: Находит сырые данные.
  2. Навык анализа: Извлекает из данных факты.
  3. Навык форматирования: Превращает факты в текст.

Пример того, как должна выглядеть логика атомарного навыка в конфигурации (условно, в формате Markdown-инструкции):

markdown
# Skill: SQL Query Validator

## Purpose
Проверяет синтаксис SQL-запроса перед его выполнением в базе данных.

## Constraints
- НЕ пытайся оптимизировать запрос.
- НЕ предлагай изменения схемы данных.
- Только проверка на наличие синтаксических ошибок.

## Input
Raw SQL string.

## Output
JSON object: {"valid": boolean, "error": string | null}

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

Практическое применение навыков

Интеграция в рабочие процессы

Когда мы говорим об автономных агентах, главная ловушка — это попытка скормить модели сразу всё. В итоге вы получаете «галлюцинации» или бесконечные циклы размышлений, когда агент не понимает, за что хвататься. Если опираться на методологию из репозитория mattpocock/skills, подход должен быть модульным.

Вместо одного гигантского системного промпта, я рекомендую разделять возможности агента на атомарные навыки (skills). Это похоже на то, как мы настраиваем микросервисы в Docker: каждый компонент отвечает за свою узкую задачу. Один навык умеет только читать файлы, другой — только делать запросы к API, третий — анализировать логи.

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

  1. Skill: Log Reader — навык извлечения последних 50 строк из journald.
  2. Skill: Error Analyzer — навык классификации ошибок.
  3. Skill: Notifier — навык отправки сообщения в Telegram или Mattermost.

Если вы используете инструменты вроде LangChain или AutoGPT, конфигурация навыка может выглядеть как описание функции (tool definition). Вот пример того, как можно описать навык для работы с системными логами через JSON-схему, чтобы агент понимал границы своей ответственности:

json
{
  "name": "get_system_logs",
  "description": "Извлекает последние записи системного журнала через journalctl для анализа ошибок",
  "parameters": {
    "type": "object",
    "properties": {
      "service_name": {
        "type": "string",
        "description": "Название юнита systemd, например, nginx или docker"
      },
      "lines": {
        "type": "integer",
        "description": "Количество строк для вывода",
        "default": 50
      }
    },
    "required": ["service_name"]
  }
}

Такая структура позволяет агенту не гадать, как получить данные, а четко следовать протоколу.

Обеспечение предсказуемости ответов

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

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

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

Во-вторых, применяйте принцип наименьших привилегий к знаниям агента. Если навык предназначен для работы с базой данных PostgreSQL, в его инструкции (skill description) должно быть четко прописано: «Используй только SELECT-запросы. Любая попытка модификации данных (INSERT, UPDATE, DELETE) должна быть пресечена на уровне парсера».

Для контроля за тем, что агент на самом деле делает, я всегда настраиваю логирование его «мыслей» (Chain of Thought) и фактических вызовов инструментов. Если вы разворачиваете агента локально, например, через Ollama, полезно проксировать его запросы через Nginx, чтобы иметь возможность перехватывать и анализировать трафик:

nginx
# Пример конфига для логирования запросов к AI-агенту
server {
    listen 8080;

    location /v1/chat/completions {
        proxy_pass http://localhost:11434;
        # Логируем полный body запроса, чтобы видеть, какие навыки вызывает агент
        access_log /var/log/nginx/ai_agent_access.log combined;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

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

Оценка эффективности системы

Оценка эффективности системы

Когда вы переходите от простых чат-ботов к автономным агентам, работающим по методологии mattpocock/skills, фокус смещается с качества текста на качество выполнения задач. Если раньше мы оценивали, насколько «умно» ответила модель, то теперь мы смотрим на то, насколько предсказуемо она достигает целевого состояния.

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

Мониторинг выполнения задач

Для оценки эффективности нельзя полагаться на интуицию. Вам нужны метрики. В случае с агентами я выделяю три ключевых показателя: Success Rate (процент успешно завершённых задач), Latency (время на выполнение одного цикла рассуждений) и Tool Call Accuracy (насколько точно агент выбирает нужный навык из базы).

Чтобы не превращать мониторинг в хаос, я рекомендую логировать каждый шаг агента в структурированном виде. Если вы используете Docker для запуска агентов, удобно собирать логи через стек Prometheus и Grafana. Но на уровне приложения важно видеть не просто «ошибку», а цепочку рассуждений (Chain of Thought).

Пример структуры лога, который стоит отдавать в систему сбора данных (например, в Loki), чтобы понимать, на каком этапе навык «сломался»:

json
{
  "timestamp": "2023-10-27T14:20:01Z",
  "agent_id": "Vinni-Pukh-Agent-01",
  "task_id": "backup_verification_442",
  "status": "failed",
  "thought_process": "Attempting to verify ZFS pool status using 'zpool status' skill.",
  "skill_used": "linux_system_query",
  "error": "Permission denied: user 'agent_user' lacks sudo privileges",
  "retry_count": 1
}

С практической точки зрения, если вы видите, что retry_count растёт, а status остаётся failed, проблема не в модели, а в описании навыка или в правах доступа, которые агент пытается использовать.

Когда пора обновлять базу навыков

База навыков — это не статичный справочник, а живой инструмент. Если вы один раз прописали инструкцию для работы с Nginx, через полгода она может стать бесполезной из-за обновления синтаксиса или изменения вашей инфраструктуры.

Я выделяю три признака того, что пора проводить ревизию ваших навыков:

  1. Рост галлюцинаций в параметрах. Если агент начинает выдумывать флаги команд (например, пытается использовать несуществующий параметр в docker compose), значит, описание навыка слишком размыто. Нужно добавить в инструкцию конкретные примеры синтаксиса.
  2. Циклические ошибки. Если агент раз за разом пытается выполнить одно и то же действие, которое приводит к результату error, значит, в логике навыка заложена неверная предпосылка.
  3. Дрейф контекста. В моей домашней лаборатории это случалось, когда я менял структуру хранения данных с NFS на локальные ZFS-пулы. Агент, привыкший искать конфиги по одному пути, начинал «тупить», потому что его база навыков всё ещё ссылалась на старую топологию.

Чтобы автоматизировать этот процесс, можно настроить простой скрипт, который анализирует частоту ошибок по конкретным навыкам. Если частота ошибок для навыка deploy_service превышает порог в 15% за последние 100 запусков, система должна генерировать алерт.

Пример проверки через grep по логам (для быстрой диагностики на сервере):

bash
# Поиск навыков, которые чаще всего завершаются ошибкой в логах
grep "status\":\"failed\"" agent_logs.json | jq -r '.skill_used' | sort | uniq -c | sort -nr

Эта команда покажет вам список навыков и количество их провалов. Если на вершине списка оказывается навык, который вы считали «отлаженным», — это сигнал к немедленному пересмотру его описания и примеров использования.

Заключение

Итоговая предсказуемость

Работа с AI-агентами через призму подхода Matt Pocock — это не про написание длинных «промптов», а про проектирование систем. Если мы посмотрим на репозиторий mattpocock/skills, становится ясно: агент эффективен не тогда, когда он «умный», а когда его область ответственности ограничена и чётко описана.

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

Как внедрить этот подход

Если вы строите систему на базе LangChain или AutoGPT, не пытайтесь скормить модели всю документацию вашего проекта сразу. Вместо этого разбейте функционал на мелкие, независимые модули.

Во-первых, опишите каждый навык как отдельную функцию. Во-вторых, предоставьте агенту не просто описание, а строгую схему данных. Например, вместо текстового описания «помоги мне с базой данных», используйте JSON-схему для конкретного действия.

Пример того, как может выглядеть описание навыка в конфигурации вашего агента (в формате, близком к инструментам вызова функций):

json
{
  "skill_name": "query_system_logs",
  "description": "Извлекает последние записи из journald для конкретного сервиса",
  "parameters": {
    "service_name": {
      "type": "string",
      "description": "Имя юнита systemd, например, 'nginx.service'"
    },
    "lines": {
      "type": "integer",
      "description": "Количество строк для вывода",
      "default": 50
    }
  },
  "expected_output": "Текстовый лог с метками времени"
}

Такой подход позволяет вам контролировать состояние системы. Если агент пытается выполнить команду, которая не описана в его наборе навыков, система должна не просто выдать ошибку, а заблокировать выполнение на уровне планировщика.

Когда этот подход перестанет работать

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

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

FAQ

Как добавить новый навык в систему?

Процесс добавления навыка в рамках методологии mattpocock/skills сводится к созданию нового структурированного описания, которое агент сможет извлечь из своего контекста. Вам не нужно переписывать системный промпт целиком — достаточно добавить новый блок в реестр навыков.

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

yaml
# Пример добавления навыка для работы с файловой системой
skill:
  name: file_system_audit
  description: Проверка прав доступа к критическим директориям Linux
  when_to_use: Когда пользователь просит проверить безопасность или права доступа
  steps:
    - "Выполни команду ls -la для указанной директории"
    - "Проверь соответствие владельца (owner) и группы (group) стандартам безопасности"
    - "Если найдены права 777, сформируй рекомендацию по их изменению"

После добавления описания убедитесь, что агент понимает границы применения этого навыка, чтобы он не начал «аудировать» файлы там, где это не требуется.

Чем навыки отличаются от обычных промптов?

Главное отличие — в предсказуемости и модульности. Обычный промпт часто представляет собой «свалку» инструкций: «будь вежливым, отвечай кратко, используй Python и не делай ошибок». В такой конструкции инструкции перемешиваются, и агент может игнорировать важные детали из-за перегрузки контекста.

Навык же — это атомарная единица. Если промпт — это общая инструкция по эксплуатации завода, то навык — это конкретная технологическая карта для одного станка.

ХарактеристикаОбычный промптНавык (Skill)
СтруктураСвободный текстЧёткий алгоритм (Steps)
ПрименениеВсегда активенВызывается по условию
МасштабируемостьСложно добавлять новоеЛегко расширять реестр
ОтладкаТрудно найти, где ошибкаПонятно, на каком шаге сбой

Нужно ли использовать этот подход для простых чат-ботов?

Если ваша задача — сделать бота, который просто отвечает на вопросы по FAQ или поддерживает светскую беседу, этот подход будет избыточным. Вы потратите больше времени на структурирование навыков, чем на саму разработку.

Однако, если чат-бот должен выполнять действия (вызывать API, анализировать логи, управлять конфигурациями), то переход к модели навыков необходим. Как только количество инструкций в системном сообщении переваливает за пару страниц текста, агент начинает «галлюцинировать» или путать приоритеты. В этот момент разделение логики на отдельные навыки становится единственным способом сохранить управляемость системы.

Как избежать конфликтов между разными навыками?

Конфликты возникают, когда два навыка имеют слишком похожие описания (description) или когда их условия активации (when_to_use) пересекаются. Это заставляет агента метаться между двумя алгоритмами, что приводит к непредсказуемому результату.

Чтобы минимизировать такие риски, придерживайтесь трёх правил:

  1. Уникальность триггеров. Описание навыка должно содержать специфические ключевые слова, которые не встречаются в других навыках.
  2. Иерархия действий. Если один навык является частью другого, явно укажите это. Например, навык check_disk_space может быть поднавыком более широкого процесса system_health_check.
  3. Тестирование на граничных условиях. Проверяйте агента запросами, которые находятся на стыке двух функций.

Если вы заметили, что агент выбирает неверный путь, отредактируйте секцию when_to_use, сделав её более узкой и специфичной. Например, вместо «при работе с сетью» напишите «при необходимости диагностики доступности портов по протоколу TCP».

Часто задаваемые вопросы

Как понять, что пора выделять навык в отдельный инструмент?

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

Можно ли использовать один и тот же навык для разных задач?

Да, навыки должны быть атомарными и переиспользуемыми, как функции в программировании. Например, навык «анализ логов Nginx» может использоваться как для поиска ошибок в конфигурации, так и для диагностики падения сервиса. Главное — не перегружать сам навык лишней логикой, чтобы он оставался универсальным инструментом, а не превращался в мини-агента.

Не слишком ли сложно управлять множеством мелких навыков?

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

Как проверить, что новый навык работает корректно?

Для проверки эффективности навыка нужно использовать метод unit-тестирования промптов. Вы подаёте агенту конкретный входной параметр и проверяете, вызывает ли он нужный навык и выдаёт ли предсказуемый результат без лишних рассуждений. Если агент вместо выполнения команды начинает писать философские размышления о проблеме, значит, границы навыка размыты и его нужно уточнить.

Поделиться:TelegramX / TwitterVK