Разработка LLM-агентов часто сталкивается с проблемой нестабильности на стыке вывода модели и приложения. Изначально простые промпты со временем требуют сложной обработки: регулярных выражений, ручных проверок и повторных запросов, так как модель может добавлять пояснительный текст или менять формат JSON. Фреймворк Pydantic AI от команды разработчиков библиотеки валидации предлагает решение через модели типов, где агент описывается функцией с аннотациями, а ответ строго типизируется. Установка начинается с добавления пакета через uv или pip, после чего создается провайдер и модель. В примере используется OpenAI-совместимый шлюз BotHub с моделью GPT-6-Luna, где ключ API и базовый URL задаются в провайдере, а сама модель инициализируется указанием имени модели на шлюзе. Для работы с асинхронностью используется ядро asyncio, но для скриптов доступна синхронная обертка run_sync, а для интеграции в FastAPI — обычный await.
Описание инструментов для LLM в Pydantic AI упрощено до использования декораторов, которые автоматически генерируют JSON-схемы аргументов и передают docstring модели. Пример агента поддержки демонстрирует два типа инструментов: @agent.tool для функций, требующих контекст зависимостей (RunContext), и @agent.tool_plain для простых функций. Зависимости, такие как HTTP-клиент, описываются через dataclass и передаются в конструктор агента через параметр deps_type, что позволяет статическим анализаторам проверять контракты и упрощает написание тестов. При ошибке в аргументах инструмента можно抛出 исключение ModelRetry, чтобы модель попыталась исправить запрос, либо ValidationError, который также обрабатывается как повод для ретрая. Лимит повторных попыток настраивается глобально или точечно для каждого инструмента.
Структурированный вывод обеспечивается параметром output_type, принимающим Pydantic-модель, dataclass или TypedDict, что гарантирует получение данных в строгом формате и позволяет IDE подсказывать поля. Для бизнес-логики поверх схемы можно добавить @agent.output_validator, который проверяет содержимое ответа и может вызвать ModelRetry, если данные не соответствуют правилам, например, лимиту суммы возврата. Если модель не может заполнить все поля, агент может вернуть объединение типов, включая обычный текст для уточняющих вопросов. Поддержка стриминга позволяет отдавать промежуточные валидированные снапшоты ответа по мере генерации, что удобно для чат-интерфейсов. Тестирование агентов осуществляется путем полной подмены модели на TestModel или FunctionModel, что позволяет детерминированно проверять логику вызова инструментов и работу с зависимостями без реальных запросов к API, исключая случайные сбои от поведения нейросети.