Microservice: ИИ-сервисы, локальные модели в бизнес-процессах

Published

June 11, 2026

WarningОграничение публичной документации

В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.

  • Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).

Начало

Создадим 4 отдельных, полностью рабочих микросервиса на Python (FastAPI), каждый в своей папке, как в проекте. Они будут общаться с Ollama и крутиться на выделенных портах Ubuntu. В каждом сервисе мы используем единый стиль логирования, анкеты Pydantic и DTO-заглушки (fallback), чтобы при перегрузке CPU или таймауте система не падала, а возвращала предсказуемый результат.

Сервис 1: ai-receipt-gateway

  • Порт: 11435
  • Модель: llama3.2-vision:11b (Мультимодальная)
  • Задача: Принять фото чека в Base64, распознать его и выдать сырой структурированный JSON продуктов.
  • github

Этот сервис принимает Base64-картинку от Go, оборачивает её в строгий системный промпт, заставляет Ollama вытащить продукты и возвращает результат в Go.

Сервис 2: ai-voice-gateway

  • Порт: 11436
  • Модель: whisper-base (Распознавание речи)
  • Задача: Принять аудиофайл в Base64, перевести его в сырой текст и вернуть текстовую строку.
  • github

Этот сервис принимает Base64-аудио от Go, отправляет его в Whisper для перевода речи в текст и возвращает чистую текстовую строку.

Сервис 3: ai-voice-parser

  • Порт: 11437
  • Модель: qwen2.5:3b (Текстовая)
  • Задача: Принять сырой текст из Whisper, вытащить продукты и провести валидацию параметров. Если порций или веса нет — выставить статус invalid и отправить на модерацию.
  • github

Этот сервис занимается только одной задачей: берет распознанный текст из Whisper, проверяет наличие названия, веса и порций. Если чего-то не хватает — бракует строку и выставляет статус invalid для модерации.

Сервис 4: ai-profanity-filter

  • Порт: 11438
  • Модель: qwen2.5:3b (Текстовая)
  • Задача: Финальный этап для чеков и валидного голоса. Заменяет мат на звездочки * и удаляет спам-позиции из массива.
  • github

Этот сервис вызывается Воркером 2 (как для чеков, так и для валидного голоса). Он проверяет финальный JSON продуктов, заменяет нецензурную лексику на звездочки * и выкидывает мусорные спам-позиции из массива.

Разница между ними в том, в каком виде данные выходят из первой фазы:

  1. Чеки (ai-receipt-gateway): На вход этого сервиса подаётся картинка, но внутри работает мультимодальная модель llama3.2-vision:11b. Она одновременно работает и как OCR (читает текст с фото), и как парсер. На выходе из этого сервиса сразу получается готовый структурированный JSON продуктов, а не сырой текст. Модели со зрением умеют делать это за один шаг. Поэтому чекам сервис ai-voice-parser не нужен. Они сразу летят на фильтрацию мата и спама (ai-profanity-filter).
  2. Голос (ai-voice-gateway): На вход подаётся аудио. Модель whisper умеет делать только одну вещь — переводить звук в текст. На выходе мы получаем сырую текстовую строку (например: “я купил две пачки молока по двести грамм”). И вот этот сырой текст мы не можем сразу отправить на фильтр мата, потому что это ещё не JSON. Нам нужно сначала превратить его в структурированные продукты. Именно для этого и нужен ai-voice-parser (на базе текстовой qwen2.5:3b). Он берёт сырую строку текста от Whisper, извлекает сущности, проверяет наличие веса/порций и собирает такой же JSON продуктов, какой чековый сервис собрал из картинки. Итоговые цепочки (пайплайны) в Кафке:

• Пайплайн ЧЕКОВ: Картинка чека ──► [ai-receipt-gateway] ──► Сырой JSON продуктов ──► [ai-profanity-filter] ──► Чистый JSON ──► [БД] • Пайплайн ГОЛОСА: Звуковой файл ──► [ai-voice-gateway] ──► Сырой текст речи ──► [ai-voice-parser] ──► Сырой JSON продуктов ──► [ai-profanity-filter] ──► Чистый JSON ──► [БД]

На этапе перед фильтром мата оба потока объединяются, потому что из ai-receipt-gateway и из ai-voice-parser выходят абсолютно одинаковые по структуре JSON-файлы.

Сценарий 1: Загрузка чека (Фотографии) и Аудио (VTT) с мобильного приложения

Эта диаграмма показывает синхронную фазу (gRPC-стриминг от мобильного приложения) и то, как Go-сервис мгновенно освобождает клиента, отправляя данные в асинхронный пайплайн.


📱 Мобилка          🟢 Go Сервис           S3 MinIO           🪪 Auth-Service         🦫 Брокер Kafka
   │                    │                     │                    │                      │
   │─── 1. gRPC Stream ─>                     │                    │                      │
   │  UploadReceipt()   │                     │                    │                      │
   │  [Metadata: token] │                     │                    │                      │
   │                    │─── 2. gRPC Call ────────────────────────>│                      │
   │                    │    ValidateToken(token) │                │                      │
   │                    │<── 3. gRPC Return ───────────────────────│                      │
   │                    │    [IsValid: true, GroupID]              │                      │
   │                    │                     │                    │                      │
   │─── 4. gRPC Stream ─>                     │                    │                      │
   │  [Send Chunks...]  │                     │                    │                      │
   │─── 5. End Stream ──>                     │                    │                      │
   │                    │── 6. PutObject() ──>│                    │                      │
   │                    │   [Save raw file]   │                    │                      │
   │                    │<─ 7. Return Path ───│                    │                      │
   │                    │                     │                    │                      │
   │                    │── 8. PublishEvent() ───────────────────────────────────────────>│
   │                    │    [receipt_id, s3_link, group_id]       │                      │  To Topic:
   │                    │                                                                 │  receipt-images-topic
   │<─ 9. gRPC Response │                                                                 │  (или receipt-audio-topic)
   │  [Status: processing, receipt_id]                                                    │

Сценарий 2: Асинхронный пайплайн обработки (Очередь Kafka & ИИ-модели)

Эта диаграмма описывает фоновую фазу, когда вы поочередно запускаете ИИ-модели на Ubuntu-машине. Обратите внимание, как аудиосообщение (VTT) проверяется на полноту данных и, в случае брака, улетает в топик модерации.


🦫 Брокер Kafka       🤖 Воркер 1/3 (Go)        S3 MinIO       🧠 ИИ (Ubuntu)       🤖 Воркер 2 (Go)       🗄 Core tracker-app
      │                       │                   │                  │                     │                    │
      │── 1. PollFetches() ──>│                   │                  │                     │                    │
      │   [New S3 Event]      │                   │                  │                     │                    │
      │                       │── 2. Download ───>│                  │                     │                    │
      │                       │   FileBytes()     │                  │                     │                    │
      │                       │<─ 3. Return Bytes │                  │                     │                    │
      │                       │                   │                  │                     │                    │
      │                       │── 4. HTTP POST (Base64/Text) ───────>│                     │                    │
      │                       │   ExtractEntities() / Recognize()    │                     │                    │
      │                       │<── 5. HTTP Return (JSON Text) ───────│                     │                    │
      │                       │                                      │                     │                    │
      │                       │ [ЕСЛИ ЭТО ГОЛОС: ХВАТАЕТ ВЕСА/ПОРЦИЙ?]                      │                    │
      │                       │───[НЕТ]───► Публикация в receipt-moderation-topic ────────> (В таблицу модерации)   │
      │                       │                                      │                     │                    │
      │                       │───[ДА]───► 6. PublishEvent() ─────────────────────────────>│                    │
      │                                    To: receipt-raw-products-topic                  │                    │
      │                                                                                    │── 7. PollFetches ─>│
      │                                                                                    │   [Raw JSON]       │
      │                                                                                    │                    │
      │                                                                                    │── 8. HTTP POST ───>│
      │                                                                                    │   FilterProfanity()│
      │                                                                                    │<─ 9. HTTP Return ──│
      │                                                                                    │   [Clean JSON]     │
      │                                                                                    │                    │
      │                                                                                    │── 10. Publish ────>│
      │                                                                                         To Topic:
      │                                                                                         receipt-clean-products-topic
      │                                                                                                             │
      │                                                                                         11. Read & Commit ──>│
      │                                                                                                              │── 12. SQL Write ──> [PostgreSQL]

Сценарий 3: B2B Интеграция с магазинами (Паттерн Request-Reply / Webhook)

Эта диаграмма детально описывает интеграцию сторонних магазинов, проверку их токенов по нашей новой receipt_processor_db, отправку чека напрямую в базу трекера и асинхронный обратный вызов (вебхук) через StoreCallbackWorker.


🏢 Магазин API       🟢 Go Сервис       🗄 Локальная БД       🦫 Брокер Kafka       🗄 Core tracker-app
      │                    │                  │                      │                    │
      │─ 1. gRPC Request ─>                   │                      │                    │
      │  RegisterStoreReceipt(store_token)    │                      │                    │
      │                    │── 2. SQL Query ─>│                      │                    │
      │                    │   GetPartnerByToken()                   │                    │
      │                    │<─ 3. SQL Return ─│                      │                    │
      │                    │   [Partner Valid, WebhookURL]           │                    │
      │                    │                  │                      │                    │
      │                    │── 4. SQL Write ─>│                      │                    │
      │                    │   CreateStoreTransaction(status: 'accepted')                 │
      │                    │                  │                      │                    │
      │                    │── 5. ProduceSync() (Прямой пуш, минуя ИИ) ──────────────────>│
      │                    │   Headers: reply_to='store-callbacks-topic'                  │  To Topic:
      │                    │   Headers: correlation_id='TX-STORE-123'                     │  receipt-clean-products-topic
      │                    │                                         │                    │
      │<─ 6. gRPC Response │                                         │                    │
      │  [Status: accepted, correlation_id]                          │                    │
      │                                                              │                    │── 7. Read Record ─>│
      │                                                              │                    │   [Commit to DB]   │
      │                                                              │                    │                    │
      │                                                              │<─ 8. Push Reply ───│
      │                                                              │   To Topic:        │
      │                                                              │   store-callbacks-topic
      │                                                              │                    │
      │                    ┌─────────────────────────────────────────┘                    │
      │                    │ 9. PollFetches() (StoreCallbackWorker)                       │
      │                    ▼                                                              │
      │              🟢 Go Сервис                                                         │
      │                    │                                                              │
      │                    │── 10. SQL Query ─>│                                          │
      │                    │   GetWebhookURLByCorrelationID()                             │
      │                    │<─ 11. SQL Return ─│                                          │
      │                    │   [WebhookURL, StoreReceiptNo]                               │
      │                    │                  │                                           │
      │─ 12. HTTP POST ────│                  │                                           │
      │  (Webhook Callback)│                  │                                           │
      │  [Chit-Status]     │                  │                                           │
      │<─ 13. HTTP 200 OK ─│                  │                                           │
      │                    │                  │                                           │
      │                    │── 14. SQL Update ──────────────────────>│                    │
      │                        UpdateTransactionStatus(status: 'processed')               │