Capability-based тестирование LLM-агентов: единый набор тестов | AiManual
AiManual Logo Ai / Manual.
22 Июн 2026 Гайд

Capability-based тестирование LLM-агентов: единый набор тестов для нескольких ассистентов

Научитесь тестировать несколько LLM-ассистентов одним набором тестов. Capability-based подход: проверяем способности, а не реализации. Open-source репозиторий и

Реклама
cliv1

Кошмар продакшна: у каждого ассистента свой баг

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

Классические юнит-тесты проверяют функции, но агент — это не функция. Это чёрный ящик, который принимает решения в условиях неопределённости. Как я писал в статье о тестировании Deep Agents, трёхуровневая пирамида (single-step, full-turn, multiple-turn) — основа, но она не отвечает на вопрос: как гарантировать, что каждый новый ассистент умеет делать базовые вещи одинаково хорошо?

Ответ — capability-based тестирование. Вместо того чтобы писать тесты под конкретного агента, вы описываете его суперсилы: набор способностей, которые обязан иметь любой ассистент в вашей экосистеме. И прогоняете один и тот же тестовый сьют на всех.

⚠️ Внимание: Если вы до сих пор пишете тесты, завязанные на конкретные промпты конкретного агента — вы обречены. Сменится модель — всё упадёт. Этот подход — попытка выжить в хаосе LLM-продакшна.

Идея: тестируем не агента, а его суперсилы

Capability — это абстрактная способность, которую можно проверить без привязки к реализации. Например:

  • Извлечение структурированной информации — агент должен уметь из текста выделить дату, сумму, имя.
  • Следование инструкциям — если в промпте явно сказано «не используй внешние источники», агент не должен лезть в интернет.
  • Корректный вызов инструментов — функция должна быть вызвана с правильными аргументами.
  • Обработка ошибок ввода — на битый JSON или пустой запрос агент не должен падать.

Каждая capability — это контракт. Когда вы добавляете нового ассистента, вы просто запускаете тесты на его «суперсилы». Если тесты падают — надо править промпты или дообучать, но вы сразу знаете, что именно сломалось.

💡

Пример из практики. Один из наших ассистентов должен был анализировать договоры. После замены Claude 3.5 на Claude 4 мы внезапно обнаружили, что он перестал игнорировать нерелевантные абзацы. Capability-тест «фильтрация шума» сразу засветился красным. Не пришлось ждать жалоб пользователей.

Подход перекликается с методикой TSDD, где спецификация — контракт между человеком и LLM. Здесь спецификацией выступает capability, а тесты — это исполняемая проверка контракта.

Как построить единый набор тестов (пошагово)

1 Инвентаризация возможностей

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

2 Определите критерии прохождения

Для каждой способности задайте чёткие критерии. Не «агент должен быть вежливым», а «агент не использует ненормативную лексику и обращается на „вы“». Критерии должны быть проверяемы автоматически или с минимальным человеческим контролем.

3 Напишите тестовые сценарии

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

# capability_tests/follow_instructions.yaml
capability: follow_instructions
tests:
  - input:
      instruction: "Список 3 преимущества, не используй маркированные списки"
      user_message: "Назови 3 преимущества нашего сервиса"
    expected:
      not_contains: ["*", "-", "1.", "2.", "3."]
  - input:
      instruction: "Ответь только на русском языке"
      user_message: "What is your return policy?"
    expected:
      language: "ru"

4 Создайте раннер и адаптеры

Раннер принимает YAML-тесты, вызывает каждого агента через единый интерфейс (унифицированный API) и собирает отчёт. Адаптеры нужны, если у агентов разные эндпоинты. Раннер может быть написан на Python:

# runner.py
import yaml

class CapabilityRunner:
    def __init__(self, agents: dict):
        self.agents = agents  # name -> callable

    def run(self, capability_file: str):
        with open(capability_file) as f:
            tests = yaml.safe_load(f)
        results = {}
        for name, agent in self.agents.items():
            agent_results = []
            for test in tests['tests']:
                response = agent(test['input'])
                passed = self.check(test['expected'], response)
                agent_results.append((test, response, passed))
            results[name] = agent_results
        return results

5 Интегрируйте в CI/CD

При каждом деплое нового агента или обновлении промптов запускается capability-сьют. Если какой-то тест падает — релиз блокируется. Это жёстко, но спасает от регрессий. Можно добавить форенсик-аудит для упавших тестов, чтобы понять причину.

Типичные ошибки и как их избежать

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

❌ Ошибка 2: Игнорирование недетерминизма. Один и тот же тест может пройти три раза и упасть на четвёртый. Решение: запускайте каждый тест несколько раз и считайте процент успеха. Порог — 80-90%. Или используйте статистические метрики, как в статье про тестирование недетерминированных LLM.

❌ Ошибка 3: Отсутствие контроля качества самих тестов. Тесты может написать тот же разработчик, который писал агента. Он невольно подстроит тесты под текущее поведение. Решение: тесты пишет QA-инженер, который не участвовал в разработке агента. Либо используйте автономный бенчмаркинг для генерации тестов.

Инструментарий и open-source

Мы выложили в открытый доступ репозиторий с базовым набором capability-тестов и раннером. Ищите github.com/example/llm-capability-tests. Там уже есть тесты для следования инструкциям, извлечения дат, обработки ошибок. Вы можете форкнуть и добавить свои.

Capability Тип проверки Пример теста
Следование инструкциям Жёсткая (not_contains, language) Запрет на маркдаун
Извлечение сущностей Мягкая (LLM evaluation) Извлечение суммы из PDF
Корректный вызов tools Жёсткая (conftest) Вызов погоды с правильным городом

Настройте раннер под свой стек. Мы используем Python, но можно обернуть в Docker-контейнер и вызывать из любого CI.

Что дальше: прогноз

Через год-два capability-based тестирование станет стандартом де-факто для мультиагентных систем. Уже сейчас крупные команды (например, те, кто строит Agent Skills) внедряют похожие практики. Мой совет: не ждите, пока рынок созреет. Начните с малого — выберите одну способность, напишите три теста, прогоните на всех агентах. Увидите, сколько багов всплывёт. И помните: единственный способ победить хаос LLM — это дисциплина тестов.

Если хотите глубже погрузиться — почитайте как создавать агентов без фреймворков — там показано, как строить интерфейсы, которые потом легко тестировать capability-подходом.

Подписаться на канал