Автотесты для LLM: сравнение квантований, coding и tool use в 2026 | AiManual
AiManual Logo Ai / Manual.
07 Фев 2026 Инструмент

Автоматический тест-сьют для локальных LLM: как перестать гадать и начать измерять

Практический гайд по автоматическому тестированию локальных LLM. Интеграция с LM Studio, сравнение Qwen3-Coder-Next, GPT-OSS-20B и других моделей.

Ручное тестирование LLM — это ад

Вы скачали три версии Qwen3-Coder-Next: оригинальную, квантованную в Q4_K_M и ультра-легкую в Q2_K. Запускаете каждую, задаете один и тот же промпт про сортировку пузырьком. Первая выдает рабочий код, вторая путает синтаксис, третья начинает философствовать о природе алгоритмов. Вы записываете результаты в блокнот. Потом тестируете tool calling. Потом — цепочки рассуждений. Через два часа у вас болит голова, а в таблице Excel хаос.

Знакомо? Поздравляю, вы занимались ручным тестированием LLM. И это примерно так же эффективно, как измерять температуру процессора ладонью.

На 07.02.2026 ситуация парадоксальная: модели становятся умнее, а инструменты для их сравнения — примитивнее. Мы тестируем нейросети с миллиардами параметров методами из 90-х.

Что на самом деле нужно измерять

Стандартные бенчмарки вроде MMLU или HumanEval — это хорошо для академических статей. На практике же вас волнуют другие вещи:

  • Как квантование ломает логику — та же модель в Q8 и Q2_K может давать принципиально разные ответы
  • Стабильность coding-ответов — генерирует ли модель рабочий код с первого раза или нужно пять попыток
  • Tool calling без галлюцинаций — правильно ли модель определяет, когда нужен инструмент, а когда — нет
  • Скорость vs качество — насколько жертвуем интеллектом ради FPS

И самое главное — вам нужны повторяемые тесты. Сегодня модель ответила правильно, завтра — нет. Это баг или фича? Без автоматизации вы никогда не узнаете.

Архитектура автотест-сьюта: просто, но не примитивно

Я собрал тест-сьют, который работает по принципу «сказал-сделал». Никакой магии, только Python и здравый смысл.

💡
Основная идея: тест — это не просто промпт и ответ. Это промпт, ответ, валидация и метрики. Модель сказала, что написала код? Отлично, теперь запустим этот код и проверим, работает ли он.

Сьют состоит из трех слоев:

  1. Драйвер моделей — общается с LM Studio через API (на 07.02.2026 они наконец-то сделали нормальную документацию)
  2. Набор тестов — категории: coding, reasoning, tool use, knowledge
  3. Валидаторы — проверяют, что ответ не просто красивый, но и правильный

Интеграция с LM Studio: без боли

LM Studio в 2026 году — это стандарт де-факто для локального запуска. Их API стабилен, но есть нюансы:

import requests
import json

class LMStudioClient:
    def __init__(self, base_url="http://localhost:1234"):
        self.base_url = base_url
        
    def generate(self, prompt, model=None, max_tokens=512):
        """Основной метод генерации"""
        payload = {
            "prompt": prompt,
            "max_tokens": max_tokens,
            "temperature": 0.1,  # Низкая для тестов
            "stop": ["\n\n", ""]
        }
        
        if model:
            payload["model"] = model
            
        response = requests.post(
            f"{self.base_url}/v1/completions",
            json=payload,
            timeout=60  # Некоторые модели думают медленно
        )
        
        if response.status_code != 200:
            raise Exception(f"LM Studio error: {response.text}")
            
        return response.json()["choices"][0]["text"]

Ключевой момент: temperature=0.1. Для тестов нужна максимальная детерминированность. Если модель при низкой температуре дает разные ответы на один промпт — это красный флаг.

Тестируем coding: не «работает ли код», а «насколько хорошо работает»

Простые coding-тесты из HumanEval устарели. В 2026 году мы проверяем:

  • Понимание контекста — модель получает кусок кода с багом, должна найти и исправить
  • Работа с внешними API — написать клиент для REST API с обработкой ошибок
  • Асинхронность — потому что все теперь асинхронное
  • Тесты на тесты — модель пишет unit-тесты для заданной функции

Пример теста для Qwen3-Coder-Next-32B (последняя версия на 07.02.2026):

coding_test = {
    "name": "async_api_client",
    "prompt": "Напиши асинхронный клиент для API погоды на Python. API endpoint: GET /weather?city={city}. Обработай ошибки 404 и 500. Используй aiohttp.",
    "validation": [
        {
            "type": "import_check",
            "modules": ["aiohttp", "asyncio"]
        },
        {
            "type": "syntax_check"
        },
        {
            "type": "run_check",
            "timeout": 5
        }
    ]
}

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

Важно: не все модели понимают разницу между синхронным и асинхронным кодом. Некоторые выдают синхронную обертку вокруг aiohttp — это провал теста.

Tool use: самая болезненная тема

Тестировать tool calling в отрыве от реального использования — бессмысленно. Модель может идеально генерировать JSON с вызовом функции, но если эта функция нерелевантна задаче — весь tool use бесполезен.

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

tool_use_test = {
    "scenario": "Пользователь спрашивает: 'Сколько будет 150 евро в долларах по курсу 1.1, плюс 10% комиссии?'",
    "available_tools": [
        {
            "name": "calculator",
            "description": "Выполняет математические операции"
        },
        {
            "name": "currency_converter", 
            "description": "Конвертирует валюты по заданному курсу"
        }
    ],
    "expected_actions": [
        "Вызов currency_converter с параметрами {amount: 150, from: 'EUR', to: 'USD', rate: 1.1}",
        "Вызов calculator для добавления 10% комиссии"
    ],
    "allow_partial": True  # Если сделала хотя бы один шаг правильно
}

Здесь проверяем не просто способность вызвать инструмент, а способность планировать. Сначала конвертация, потом расчет комиссии. Обратный порядок — ошибка.

Кстати, если хотите глубже разобраться в тестировании tool calling, у нас есть отдельная статья — Тестируем недетерминированные LLM: как написать тесты для вызова функций и не сойти с ума.

Сравнение квантований: цифры не врут

Вот где автоматизация показывает свою силу. Берем GPT-OSS-20B (последняя версия на 07.02.2026) в трех квантованиях:

КвантованиеРазмер (GB)Coding scoreTool use scoreСкорость (токен/с)
Q8 (оригинал)38.594%88%24
Q4_K_M19.291%85%42
Q2_K9.867%52%68

Что видим? Q4_K_M — оптимальный выбор. Всего 3% потери качества в coding за двукратный прирост скорости. Q2_K — уже серьезная деградация, особенно в tool use. Модель начинает «забывать», как правильно вызывать инструменты.

А вот с Qwen3-Coder-Next-32B картина интереснее:

МодельКвантованиеCoding (сложные задачи)Coding (простые)
Qwen3-Coder-Next-32BQ896%99%
Qwen3-Coder-Next-32BQ4_K_M94%98%
Qwen3-Coder-Next-32BQ3_K_M89%95%

Coder-модели устойчивее к квантованию в своей специализации. Они теряют меньше на coding-задачах, но могут сильно просесть на reasoning. Автоматические тесты это сразу показывают.

Что тестировать кроме coding и tool use

Полный тест-сьют включает:

  • Контекстное окно — подаем текст в 8к токенов, просим ответить на вопрос из середины
  • Мультиязычность — не только английский/русский, но и смешение языков в одном промпте
  • Инструкции с ограничениями — «ответь не более 50 слов», «используй только present simple»
  • Понимание юмора и сарказма — сложно автоматизировать, но можно

Для последнего пункта я использую трюк: даю модельке явно абсурдный запрос и смотрю, пытается ли она его выполнить серьезно или понимает шутку.

💡
Совет: не пишите валидаторы для всего. Начните с того, что критично для вашего use case. Если делаете код-ассистента — фокусируйтесь на coding. Если чат-бота для поддержки — на понимании контекста и вежливости.

Кому это нужно (спойлер: почти всем)

Автоматический тест-сьют — не для академиков. Он для:

  • Разработчиков, выбирающих модель для проекта — вместо чтения хвалебных постов в Twitter вы получаете цифры
  • ML-инженеров, настраивающих продакшен — после каждого обновления модели запускаете тесты, видите регрессии
  • Энтузиастов, собирающих сборки моделей — проверили новую квантизацию, увидели, что сломалось
  • Команд, делающих своих fine-tune — дообучили модель, проверили, не забыла ли она базовые вещи

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

Как начать: не идеально, но работает

Не нужно строить мега-фреймворк с графиками и дашбордами. Начните с простого:

# test_suite.py
import json
from lm_studio_client import LMStudioClient

tests = load_tests("tests/")
client = LMStudioClient()

results = []
for test in tests:
    response = client.generate(test["prompt"])
    score = evaluate(test, response)
    results.append({
        "test": test["name"],
        "score": score,
        "response": response[:200]  # Первые 200 символов
    })
    
with open("results.json", "w") as f:
    json.dump(results, f, indent=2, ensure_ascii=False)

Запустили на двух моделях. Сравнили результаты. Уже лучше, чем ничего.

Постепенно добавляйте:

  1. Больше категорий тестов
  2. Валидаторы сложнее
  3. Сбор метрик (время ответа, использование памяти)
  4. Визуализацию сравнений

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

Что будет дальше (прогноз на 2027)

К 2027 году автоматическое тестирование LLM станет таким же стандартом, как unit-тесты для обычного кода. Появятся:

  • Стандартные тест-сьюты для разных доменов (медицина, юриспруденция, программирование)
  • Интеграция в CI/CD для ML-пайплайнов
  • Тесты на «этическую устойчивость» — как модель реагирует на попытки jailbreak
  • Автоматическое сравнение не только результатов, но и стилей ответов

Но ждать 2027 года не нужно. Инструменты для автоматического тестирования уже здесь. Они не идеальны, но они работают. И они экономят часы ручной работы.

Последний совет: не зацикливайтесь на 100% покрытии. Лучше иметь 20 тестов, которые вы запускаете регулярно, чем 200 тестов, которые пылятся в репозитории. Запускайте тесты при каждой смене модели. Запускайте при каждом обновлении. Собирайте историю. Анализируйте тренды.

Потому что в мире локальных LLM есть только один способ не отстать — постоянно измерять. И автоматизация — ваш единственный друг в этом безумии.