Каждый, кто делал бота поддержки или автоматизацию на языковых моделях, знает эту боль. Вы отправляете текст клиента в облачный API, ждёте, пока запрос долетит до дата-центра, отстоит очередь и вернётся, а потом ещё разбираете вежливый абзац, чтобы понять: так это жалоба или вопрос о доставке? Платите за каждый вызов. И молитесь, чтобы интернет не моргнул.
Cortiq Mobile делает то же самое иначе. Модель решений лежит в памяти вашего телефона, отвечает одним JSON и не тратит время на дорогу: на реальном Android-смартфоне нативное решение занимает 13–22 миллисекунды (Jev1.3 при хорошей связи 350-900мс). Это не чат, который что-то «пишет». Это классификатор с честным «не знаю», доступный по HTTP любой программе в вашей сети.

Решение принято прямо на телефоне: вариант card_arrival, уверенность 99,8 %. Ниже на экране — время, которое ушло на ответ.
Приложение: Google Play · исходный код: infosave2007/cmfmobile · документация Decision API: docs/mobile-decision.md
Что такое модель решений
Обычная языковая модель генерирует текст токен за токеном. Модель решений не генерирует ничего. У неё есть навыки — наборы меток. Например, навык banking77 знает 77 типов банковских запросов, clinc150 — 150 бытовых намерений, massive — команды голосового ассистента. Получив текст, модель оценивает, какая метка описывает его лучше всего, и возвращает её вместе с уверенностью. Если уверенности мало, она отказывается — и это штатный ответ, а не ошибка.
Для кода это меняет всё. Вместо «попросить модель ответить в JSON и надеяться» вы получаете контракт: три поля, которые всегда на месте.
{"accepted": true, "choice": "card_arrival", "confidence": 0.998}
Правило одно: действуете при accepted: true и непустом choice. Пришло accepted: false и choice: null — отдаёте задачу человеку или уходите в безопасную ветку. Никаких регулярок по свободному тексту.
Запуск за пять минут
Установите Cortiq Mobile на Android из Google Play (на iPhone — через TestFlight).
Скачайте модель решений. Модели → Hugging Face → Готовые →
infosave/cmf-decision. Нажмите «Скачать», затем «Загрузить в движок». Первая вкладка приложения станет «Решения» — там можно сразу проверить модель вручную: выбрать навык, нажать «Подставить пример» и «Принять решение».Запустите сервер. Вкладка «Сервер» → включите «Требовать bearer-токен» → «Запустить сервер». На экране появятся адрес телефона, токен и QR-код. Порт по умолчанию — 8080.
Всё. Телефон стал сервером принятия решений для вашей локальной сети.
Первый запрос
# PHONE_TOKEN возьмите с экрана «Сервер»; не храните его в исходниках. curl "http://PHONE_IP:8080/v1/decide" \ -H "Authorization: Bearer $PHONE_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"skill":"banking77","text":"Where is my card?","profile":"balanced"}'
Ответ придёт с полями accepted, choice, confidence, а также с таймингами: timings_us.total — полное время работы модели, resonance — только этап сравнения с метками. Поле profile задаёт политику уверенности: balanced для большинства задач, quality-first, когда ложное срабатывание дороже отказа, cost-saver, когда важнее принять решение.
Тот же вызов из Python:
import requests PHONE = "http://PHONE_IP:8080" HEADERS = {"Authorization": f"Bearer {PHONE_TOKEN}"} def decide(skill: str, text: str) -> str | None: r = requests.post(f"{PHONE}/v1/decide", headers=HEADERS, json={"skill": skill, "text": text, "profile": "balanced"}, timeout=5) r.raise_for_status() d = r.json() return d["choice"] if d["accepted"] and d["choice"] else None label = decide("banking77", "I still have not received my new card") if label == "card_arrival": open_card_delivery_ticket() elif label is None: escalate_to_human()
Какие навыки есть и что они умеют
Не нужно держать список меток в голове — спросите у телефона:
curl -H "Authorization: Bearer $PHONE_TOKEN" http://PHONE_IP:8080/v1/skills curl -H "Authorization: Bearer $PHONE_TOKEN" http://PHONE_IP:8080/v1/skills/banking77
Первый запрос возвращает доступные навыки, второй — полное описание: все метки и рубрику, то есть правила, по которым модель выбирает. Рубрику стоит прочитать до интеграции: она объясняет, что считается каждой меткой, и избавляет от сюрпризов.
Для сложных сценариев есть типизированный маршрут POST /v1/decisions: вы передаёте состояние (state) и список вопросов (questions), а получаете ответ на каждый. Это тот же контракт Cortiq, что и в настольной версии, так что код переносится между телефоном и сервером без изменений.
Насколько быстро и сколько клиентов выдержит
Мы проверяли на Xiaomi с Android 14 по обычному домашнему Wi-Fi, клиент — ноутбук. Нативное решение внутри телефона — 13–22 мс. Полный HTTP-запрос с сетью, разбором JSON и очередью:
Клиентов одновременно |
Решений в секунду |
Задержка p50 / p95 |
|---|---|---|
1 |
13,6 |
63 / 137 мс |
4 |
27,4 |
135 / 209 мс |
При 16 параллельных клиентах телефон не копит бесконечную очередь, а честно отвечает 429 «подождите» лишним запросам, обрабатывая остальные с той же скоростью. Для интеграций оптимально 1–4 клиента: этого хватает на десятки решений в секунду. Все 22 проверки контракта прошли, включая корректные коды ошибок: 400 на битый JSON, 401 без токена, 404 на неизвестный навык. Полный протокол — в репозитории.
Для сравнения масштаба: 63 миллисекунды — это полный круг по Wi-Fi до телефона и обратно, включая само решение. Облачному API за это время обычно хватает лишь на то, чтобы установить соединение.
Когда модель не уверена: оракул по вашему желанию
Отказ модели — не тупик. В приложении есть оракул: при отказе локальной модели вы можете одним нажатием отправить запрос внешнему HTTPS-провайдеру с вашим собственным ключом (по умолчанию предлагается MiMo через OpenRouter, но подойдёт любой OpenAI-совместимый). Оракул выключен по умолчанию, включается в «Настройки → Оракул», каждый внешний вызов требует подтверждения, а ключ лежит в защищённом хранилище телефона. Через API телефона ключ потратить невозможно: удалённый клиент получает только локальные решения.

Оракул выключен по умолчанию и включается только вручную.
Получается двухуровневая схема: быстрые и бесплатные решения на телефоне для подавляющего большинства запросов, а редкие сложные случаи — наверх, под вашим контролем.
Два совета напоследок
Включайте токен до запуска сервера и держите телефон в домашней или офисной сети: локальный API работает по HTTP и рассчитан на доверенное окружение. Одна модель в памяти — пока загружена модель решений, чат-маршруты отвечают 409; это нормально, так телефон защищает вас от путаницы между двумя разными API.
Итог
Классификация намерений, маршрутизация заявок, фильтрация команд для умного дома, первая линия поддержки — всё это задачи, где нужен не текст, а решение. Cortiq Mobile даёт для них API, который живёт в телефоне, отвечает за десятки миллисекунд, не требует подписки и умеет честно сказать «не знаю». Загрузите модель, запустите сервер, сделайте первый curl — дальше это просто ещё один сервис в вашей сети. Только быстрее и ваш.
JBFW
Предполагаю внутри подобие rag-системы: ищет нечто релевантное, вместо текста отдает Y/N...