Как изолировать ИИ-сервис на Python от .NET
Автор описывает схему, при которой остановка Python-сервиса с моделью машинного обучения не роняет .NET API: запросы получают HTTP 503 и восстанавливаются без перезапуска основного приложения. Подход позволяет локализовать отказ ИИ в рамках отдельной функции.
В рамках проекта Enterprise GenAI Platform был проведён эксперимент: при остановке Python-сервиса, отвечающего за вычисления ИИ, основной API на .NET 10 продолжил работу. Запрос на семантическое сравнение текстов в этот момент вернул HTTP 503, а после пересоздания контейнера Python тот же запрос снова завершился успешно с HTTP 200 — без перезапуска .NET-приложения.
Архитектура платформы построена как модульный монолит на .NET: в нём сосредоточены публичные маршруты, проверка запросов, прикладная логика и доступ к PostgreSQL. Модули Chats и AI пока не вынесены в отдельные процессы. А вот вычисления ИИ требуют иного жизненного цикла: загрузка весов модели, зависимости PyTorch и работа с памятью плохо сочетаются с обработкой обычных запросов.
Автор отмечает, что модель можно было бы запускать и в .NET через ONNX Runtime, но платформа рассчитана на развитие обработки текстов, а Python даёт прямой доступ к нужным инструментам без переноса зависимостей в Core API. Поэтому отдельно развёрнут только вычислительный компонент, а не каждый прикладной модуль. Взаимодействие между .NET и Python организовано по HTTP: для интерактивного сравнения двух фраз очередь сообщений лишь усложнила бы систему.
Для проверки выбранной схемы использовалась модель sentence-transformers/all-MiniLM-L6-v2, работающая локально на CPU. Она преобразует текст в 384-мерный эмбеддинг, после чего вычисляется косинусное сходство. В FastAPI модель загружается один раз при старте через lifespan, а HTTP-обработчик объявлен синхронной функцией, которую FastAPI выполняет в пуле потоков, чтобы не блокировать цикл событий.
Сетевые сбои обрабатываются отдельно: в AiOrchestratorClient исключения переводятся в типизированные ошибки, а HTTP 500 от Python классифицируется как ошибка ответа, а не потеря соединения. Специальный обработчик превращает их в ответы ProblemDetails, не раскрывая клиенту внутренние сообщения. Core API фиксирует статус, категорию и идентификатор запроса для сопоставления журналов.
Автор подчёркивает, что эксперимент не доказывает отказоустойчивость всей платформы: конкретная AI-функция во время сбоя была недоступна. Однако цель достигнута — отказ вычислительной зависимости остаётся понятной ошибкой отдельной операции, а не превращается в сбой основного сервера. При этом независимое масштабирование остаётся архитектурной возможностью, а не обязательной необходимостью.
Отдельно отмечается ограничение модели: all-MiniLM-L6-v2 ориентирована прежде всего на английский язык, поэтому для русскоязычных корпоративных документов модель и пороги близости придётся подбирать по отдельным проверочным данным. Вычислительный сервис возвращает показатель сходства, но решение о его достаточности остаётся за прикладной системой.
Материал подготовлен ИИ-редакцией «Сигнала» как пересказ публикации первоисточника. Фактическую точность и подробности проверяйте по оригиналу.