Гайд · TNWS AI
Как протестировать инструмент агента Pydantic AI без вызова LLM через TestModel
Локальный тест инструмента с TestModel и override: какие свойства можно проверить без LLM, почему нельзя оценивать так качество настоящих ответов.
Что решаем и кому подходит
Поисковый вопрос: «как тестировать агента Pydantic AI без платных вызовов TestModel». Проверить ветку Python-инструмента без подключения платной или недоступной модели. Официальная документация рекомендует TestModel, Agent.override и запрет реальных запросов в тестовом окружении. TestModel является процедурной подменой, а не нейросетью: он по умолчанию может вызвать все инструменты и сформировать данные по схемам. Поэтому его результат нельзя считать оценкой точности вашей настоящей модели. Инструкция опирается на актуальную официальную документацию Pydantic AI, проверенную 20 сентября 2026 года. Примеры предназначены для Python 3.10+ с пакетом pydantic-ai. Используйте модель и учётные данные, доступные именно вашему аккаунту; пример идентификатора из документации не является обещанием доступа. Демонстрационные коды, статусы и суммы вымышлены.
Порядок действий
- Сделайте чистый читающий инструмент с измеримым побочным эффектом — увеличением счётчика вызовов в памяти теста.
- Создайте агента с обычным идентификатором модели, но для локального теста временно подмените модель через
agent.override(model=TestModel()). - Запустите тест без реального ключа и проверьте, что инструмент вызван, а формат результата подходит программе.
- Отдельно подготовьте регрессионный набор реальных содержательных вопросов: его TestModel не заменяет.
До сетевого запуска установите pydantic-ai и настройте ключ провайдера предусмотренным им способом. Примеры не содержат действующих секретов. Для воспроизводимого теста зафиксируйте версии Python, пакета и выбранной модели; после обновления снова выполните как удачный, так и отрицательный сценарий. Вызов run_sync использован для наглядного скрипта вне уже работающего асинхронного цикла. Там, где проект асинхронный, применяйте документированный await agent.run(...) и управляйте ресурсами на стороне приложения.
Готовый шаблон для запуска
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel
hits = []
agent = Agent("openai:gpt-5.2")
@agent.tool_plain
def read_label() -> str:
"""Прочитать тестовую метку из памяти."""
hits.append("read_label")
return "учебная метка R-7"
with agent.override(model=TestModel()):
result = agent.run_sync("Покажи метку")
assert hits == ["read_label"]
print(result.output)
Конкретный вход и ожидаемый результат
Вход «Покажи метку», фиктивное значение инструмента — «учебная метка R-7». Ожидаемый проверяемый результат в этой программе: список hits содержит ровно один вызов read_label. Текст результата TestModel может быть техническим и не обязан быть красивым ответом на русском. Второй тест должен запускать настоящую модель в контролируемом окружении и проверять, умеет ли она выбрать инструмент на вопросе пользователя; смешивать эти два критерия нельзя.
Почему этот способ работает
TestModel полезен для проверки интеграции: зарегистрировался ли инструмент, правильно ли выполнен код, не попала ли запись во внешнюю БД, корректно ли обработана ошибка. Но этот имитатор пытается удовлетворить схеме и вызвать доступные инструменты, а не понимает смысл русского вопроса. Поэтому тест «показал ли агент правильный день недели» должен использовать отдельный эталон и реальную модель либо заранее определённую функцию подмены поведения. Для безопасности в тестовом окружении документация упоминает ALLOW_MODEL_REQUESTS=False; применять глобальный флаг нужно осмысленно и изолированно, чтобы не вмешаться в чужие параллельные процессы.
Пограничный случай и предметная проверка
При тестировании инструментов записи обеспечьте изолированную тестовую БД или подмену зависимости, поскольку TestModel способен вызвать инструмент и совершить его реальные побочные действия. На один тест назначайте конкретное ожидаемое событие и проверяйте состояние до и после. Когда вы добавите второй инструмент, прежнее предположение о числе вызовов может измениться — такой тест должен сообщить об этом явно. Для проверки запрета сетевых вызовов создайте отдельный тестовый процесс с соответствующей настройкой среды. В конце тестового пакета оставьте хотя бы один интеграционный сценарий с реальной моделью, если продукт зависит от способности модели выбирать инструмент.
Если инструмент принимает сложные аргументы, TestModel сгенерирует значения по схеме, а не по смыслу человеческого вопроса. Поэтому отдельно проверяйте, что обработка произвольного допустимого аргумента безопасна и не вызывает запись куда-либо вне тестовой среды. Для точной симуляции выбранного аргумента документация предлагает FunctionModel, но это другая методика; не приписывайте TestModel заранее запрограммированный русский смысл. Отдельный тест интеграции с реальной моделью должен иметь собственный ограниченный бюджет.
Критерии приёмки
- Тест проходит без внешнего ключа API и без обращения к настоящей модели.
- Счётчик
hitsподтверждает выполнение ровно нужной функции. - Отчёт тестов отдельно помечает, что смысловое качество LLM этим прогоном не проверялось.
Проверка успешного выполнения Python-программы не равна проверке верности ответа нейросети. Сопоставьте результат с входом и с доверенным источником данных, затем повторите тест на отрицательном примере. Формулировка текста может отличаться от образца; условия приёмки описывают наблюдаемое поведение, которое действительно нужно пользователю. Если один критерий не соблюдён, не скрывайте сбой повтором без ограничения: сохраните минимальный безопасный воспроизводимый пример и исправьте соответствующий слой — данные, схему, инструмент, инструкцию или обработку ошибки.
Частые ошибки и чего не делать
- Не выдавайте искусственный текст TestModel за показатель качества русского ответа.
- Не запускайте все инструменты на реальных данных, если TestModel автоматически пробует их вызывать.
- Не оставляйте
overrideна обычном продуктивном пути после локального теста.
Вопросы и ответы
Использует ли TestModel настоящую нейросеть?
Нет, это процедурная тестовая модель.
Можно ли тестировать структурный вывод?
Да, но правдоподобие значений TestModel не гарантируется.
Зачем override?
Он временно заменяет модель в данном контексте теста.
Официальные источники
Частые вопросы
Использует ли TestModel настоящую нейросеть?
Нет, это процедурная тестовая модель.
Можно ли тестировать структурный вывод?
Да, но правдоподобие значений TestModel не гарантируется.
Зачем override?
Он временно заменяет модель в данном контексте теста.
Читайте также
Как дать агенту Pydantic AI инструмент чтения справки без права записи
Инструмент tool_plain для чтения вымышленной справки: минимальные полномочия, пример вопроса, проверка вызова и защита от ложных ответов.
Как извлечь поля заявки из русского письма через Pydantic AI и output_type
Пошаговое извлечение темы и номера заявки в Pydantic AI: схема BaseModel, конкретное письмо, проверка полей и ошибки, которые не исправит одна валидация.
Как ограничить число обращений агента Pydantic AI к модели через request_limit
Ограничение числа модельных шагов Pydantic AI: UsageLimits(request_limit), обработка исключения и тест на цикл инструмента.
Комментарии
Пока тихо. Скажите первое слово