ITUZOV LAB
← Все статьи
Практический гайд

Алиса с нормальным ИИ: свой навык для Станции

Учим Яндекс Станцию отвечать как настоящий ИИ: Grok, Claude или GPT вместо шаблонных фраз. Без кода, по кнопкам в двух панелях, за вечер.

26 минНачальный29 сентября 2026 г.

Что получится

Обычная Яндекс Станция после этого гайда начнёт отвечать по-человечески. Не «я пока не умею такого», а нормальный разговор: продиктует рецепт коктейля, поругает за пропущенный зал, проведёт код-ревью в роли строгого тимлида. Отвечать будет Grok, Claude, GPT или любая другая модель на твой выбор.

Вот ответы из моей колонки, я их сократил:

Как это звучит вживую

«Как сделать коктейль Май Тай?»

«Май Тай делается так: в шейкере со льдом смешай шестьдесят миллилитров светлого рома, тридцать сока лайма, пятнадцать апельсинового ликёра и пятнадцать миндального сиропа оржа. Хорошо встряхни, перелей в бокал со льдом и сверху аккуратно налей немного тёмного рома. Укрась мятой и долькой лайма.»

«Проведи код-ревью как строгий тимлид: я назвал переменную data2»

«data2 это не имя, а капитуляция. Из названия не ясно, что внутри, откуда взялось и чем отличается от data. Переименуй по смыслу, иначе на ревью не пропущу.»

Кода писать не придётся: программу я уже написал и выложил, её нужно только подключить. Точнее, писал её не совсем я: диктовал агенту, проверял и правил (этому учу в курсе «ChatGPT и Codex с нуля»). Всё остальное это кнопки в двух панелях и один спокойный вечер.

Как это устроено

Своего ИИ в колонку не засунуть, она просто микрофон с динамиком. Зато у Алисы есть навыки: маленькие программы, которые она запускает по просьбе.

Ты говоришь «Алиса, запусти умника». Всё, что ты скажешь дальше, Алиса переводит в текст и отправляет на твою программу в интернете. Программа пересылает вопрос нейросети, получает ответ и возвращает его Алисе. Алиса читает его вслух.

Путь вопроса из четырёх звеньев: колонка, Алиса, навык, нейросеть
Обратно ответ едет той же дорогой: навык отдаёт текст Алисе, Алиса читает его вслух

Значит, нужны три вещи: доступ к нейросети, программа-посредник и навык в Алисе, который знает адрес этой программы. Ровно этим и займёмся, по одному шагу.

Главная особенность: три секунды

Алиса ждёт ответ навыка около трёх секунд, дальше сдаётся. Программа держит запас поменьше, чтобы успеть ответить до этого срока. Умные модели столько думают далеко не всегда, поэтому в программу заложен приём: если модель не успела, колонка говорит «Секунду, думаю, скажи „дальше“». Говоришь «дальше», и она читает готовый ответ.

Это не поломка: так программа обходит ограничение платформы. С моделью по умолчанию «дальше» приходится говорить часто: она отвечает за две-три секунды и в лимит попадает не всегда. Если это мешает, в конце гайда есть раздел про быстрые модели, с ними пауз меньше.

Развилка: быстрый ответ сразу и медленный ответ по слову «дальше»
Две дороги одного вопроса: модель успела за три секунды или не успела

Что понадобится

  • Яндекс Станция, подойдёт любая,
  • аккаунт Яндекса, тот самый, к которому она привязана,
  • аккаунт в Timeweb Cloud, оттуда мы возьмём и доступ к нейросети, и место для программы.

По времени: час-полтора, если всё пойдёт гладко. Дольше всего ждёшь не себя, а машины: сборка приложения несколько минут и модерация навыка ещё пара.

Про деньги честно: на сентябрь 2026 программа, запущенная в Timeweb, стоит 510 ₽ в месяц, но списывается по часам, по 0,7 ₽. То есть вечер проб обойдётся в пару рублей, сутки в семнадцать, а если не понравится, приложение удаляется и начисления прекращаются (как это сделать, написано в конце). Ключ к нейросети стоит 1 ₽ в месяц, сами вопросы идут отдельно и стоят копейки.

Шаг 1. Берём доступ к нейросети

Напрямую подписка на Claude или ChatGPT тут не подойдёт: программе нужен не сайт, а ключ, такой длинный пароль для доступа к модели.

Брать его будем в Timeweb. Там в одном месте лежат десятки моделей (Claude, GPT, Grok, DeepSeek), переключаться между ними можно одной строчкой настроек, и платить получится российской картой.

Вторая причина важнее: в соседнем разделе той же панели запускается и сама программа. Не нужно арендовать сервер, подключаться к нему по ssh и настраивать руками, достаточно подключить репозиторий и нажать кнопку. Получается, что и доступ к нейросети, и запуск программы живут в одном аккаунте и оплачиваются с одного баланса.

  1. 01

    Заходим в панель

    Регистрируемся в Timeweb Cloud и пополняем баланс. Пятисот рублей хватит на месяц работы навыка со всеми разговорами, меньшей суммой тоже можно обойтись, списание почасовое.

  2. 02

    Открываем AI Gateway

    В левом меню находим «ИИ-сервисы», внутри «AI Gateway». Это единая точка доступа ко всем моделям сразу.

    Кнопка «Создать ключ» на баннере раздела
    Раздел AI Gateway в панели Timeweb Cloud, кнопка «Создать ключ» обведена
  3. 03

    Создаём ключ

    Откроется форма нового ключа. Название придумай любое, срок действия оставь бессрочным (там же есть варианты на 30, 60, 90 дней и год), проект подойдёт общий. Дальше «Создать». Сам ключ стоит 1 ₽ в месяц, токены считаются отдельно.

  4. 04

    Сохраняем ключ

    Ключ показывается один раз. Скопируй его в заметки, он понадобится на следующем шаге.

Боишься потратить лишнее: ставим потолок расходовРазвернуть

Вернись на вкладку «API-ключи» и открой свой ключ, там сверху будет «Управление». В форме создания лимита нет, поэтому шаг легко пропустить, а он единственный, который делает случайный перерасход невозможным.

Пока лимита нет, написано «Не установлен»
Вкладка «Управление» у ключа AI Gateway, кнопка «Установить лимиты» обведена

В открывшемся окне два переключателя: общий лимит на все модели и лимит по каждой модели отдельно. Для навыка хватает общего, дальше «Сохранить».

Лимит считается по сумме входящих и исходящих токенов
Окно «Лимиты потребления токенов» с переключателями общего лимита и лимита по моделям
Ключ это деньги

Ключ это длинная строка из букв и цифр, и относиться к нему надо как к паролю от кошелька: любой, у кого он есть, тратит твой баланс. Не выкладывай его в интернет и не показывай в скриншотах. Если утёк, удали ключ в панели и создай новый, старый сразу перестанет работать, а потолок расходов из блока выше не даст увести больше лимита.

Шаг 2. Запускаем программу-посредник

Программу писать не надо, она готова и лежит открыто: github.com/ituzov/ituzovlab-alice. Мы просто скажем Timeweb: возьми код по этой ссылке и запусти его у себя. Сервис для этого называется App Platform, он сам разбирается, что за программа и как её включить.

  1. 01

    Создаём приложение

    В левом меню панели Timeweb Cloud открываем App Platform и жмём «Создать».

    App Platform живёт в том же меню, что и AI Gateway
    Раздел App Platform в панели Timeweb Cloud, кнопка «Создать» обведена
  2. 02

    Выбираем подключение по ссылке

    Откроется экран «Добавить App» с плитками GitHub, GitLab и остальных. Они нам не нужны, потому что заводить аккаунт и давать доступ к своему репозиторию не придётся: под плитками есть неприметная строчка «Подключите git-репозиторий по URL», нажимаем её.

    Плитки провайдеров пропускаем, нам нужна строчка под ними
    Экран «Добавить App», ссылка «Подключите git-репозиторий по URL» под плитками обведена
  3. 03

    Вставляем ссылку на программу

    В поле «URL репозитория» вставляем адрес целиком. Имя пользователя и пароль не заполняем, репозиторий открытый. Дальше «Подключить».

    Ссылка на репозиторий
    https://github.com/ituzov/ituzovlab-alice.git
    Адрес начинается с https:// и заканчивается на .git, иначе панель его не примет
    Окно «Подключите git-репозиторий по URL» с заполненным полем адреса
  4. 04

    Проверяем, что панель всё поняла

    После подключения репозитория панель сама разберётся, что внутри: подставит ветку main, фреймворк Express и версию Node.js. Проверь, что стоит именно 22: программа работает и на 24, но у меня на ней сборка однажды зависла и упала на середине, а на 22 прошла спокойно.

    Всё определилось само, версия Node.js подставлена автоматически
    Экран добавления приложения: ветка main, фреймворк Express и выбранная версия Node.js 22
  5. 05

    Выбираем конфигурацию подешевле

    Ниже список конфигураций, и по умолчанию отмечена вторая строка, за 810 ₽ в месяц. Навыку столько не нужно, выбирай первую: 1 CPU, 1 ГБ памяти, 510 ₽ в месяц. Регион оставь какой есть.

    Там же, под списком, нажми «Показать расширенные настройки», без них дальше не пройти. Заодно в самом низу, в поле «Название», можно поменять придуманное панелью имя на своё: из него получится адрес приложения.

    Цена пересчитывается справа: 0,7 ₽ в час вместо 1,11 ₽
    Список конфигураций приложения, выбрана первая строка за 510 рублей, ниже ссылка «Показать расширенные настройки»
  6. 06

    Вписываем путь проверки и открываем переменные

    В расширенных настройках найди «Путь проверки состояния» и впиши /health, по нему Timeweb понимает, что программа жива. Команда запуска npm start уже стоит, её не трогаем. Дальше жми «Добавить» напротив переменных.

    Команда запуска уже подставлена, её не трогаем
    Расширенные настройки приложения: поле «Путь проверки состояния» со значением /health и кнопка «Добавить» у переменных
  7. 07

    Вставляем настройки одной пачкой

    Откроется окно добавления переменных. В подсказке сверху сказано, что скопированный список можно вставить целиком в поле «Название» обычной вставкой (Ctrl+V на Windows, ⌘+V на Mac), и панель сама разложит его по строкам. Вот эти четыре строки, копируй их целиком:

    Настройки приложения
    API_KEY=paste_your_key_here
    BASE_URL=https://api.timeweb.ai/v1
    MODEL=xai/grok-4.7
    REASONING_EFFORT=low

    После вставки открой строку API_KEY и замени paste_your_key_here на ключ из шага 1. Дальше «Сохранить».

    Что тут что: API_KEY это твой ключ, BASE_URL адрес Timeweb AI Gateway (его не меняем), MODEL выбор нейросети (по умолчанию Grok, потому что он весёлый), REASONING_EFFORT=low просьба не размышлять слишком долго, иначе Алиса не дождётся ответа.

    Эти настройки лежат не в коде, а рядом с ним: так твой ключ не попадает в открытый репозиторий, а модель меняется без правки программы. Позже к ним добавятся ещё две: ALICE_SKILL_ID на шаге 3, он закроет программу от чужих, и SYSTEM_PROMPT в конце гайда, если захочешь сменить характер ассистента.

    Значение ключа на скриншоте замазано, у тебя там будет длинная строка
    Окно «Добавить переменные» с подсказкой про массовую вставку и заполненными строками API_KEY, BASE_URL, MODEL
  8. 08

    Проверяем список и выключаем лишнее

    В расширенных настройках должно появиться четыре строки: API_KEY, BASE_URL, MODEL и REASONING_EFFORT. Значения панель прячет, это нормально.

    Ниже два переключателя, сертификаты Минцифры и ТЦИ, по умолчанию включённые. Навыку они не нужны: он ходит только к нейросети по обычному защищённому соединению. Выключи оба, сборка будет чуть короче.

    Сертификаты нужны для сайтов госуслуг, нашему навыку они ни к чему
    Список добавленных переменных из четырёх строк и выключенные переключатели сертификатов
  9. 09

    Заказываем приложение

    Справа в блоке «Цена» ещё раз посмотри итог и жми «Заказать».

    Оплата почасовая, поэтому проба стоит копейки
    Блок «Цена» с итогом 0,7 рубля в час и кнопка «Заказать»
  10. 10

    Ждём сборку

    Начнётся деплой: Timeweb скачает код, поставит зависимости, соберёт образ и запустит программу. Это несколько минут, а ход видно в логах. Дожидаемся строчки «Deploy succeeded», перед ней должно быть «App is healthy»: это Timeweb постучался по нашему /health и получил ответ.

    Если вместо успеха «failed», причина будет в этих же логах
    Логи деплоя со строками «App is healthy» и «Deploy succeeded»
  11. 11

    Забираем адрес приложения

    Открой вкладку «Дашборд»: справа, в карточке с репозиторием, лежит домен вида my-alice-1a2b.twc1.net. Это и есть адрес программы, его надо скопировать, он понадобится на следующем шаге.

    Заодно проверь, что программа жива: открой этот адрес в браузере целиком, с https:// в начале. Должна открыться страница с одним словом ok, больше она ничего не умеет.

    Вот он, домен приложения. Публичный IP замазан, он не понадобится
    Дашборд приложения: статус «В сети», карточка с репозиторием и доменом
Если сборка тянется или падает

Сборка образа занимает минуты, и это нормально: платформа каждый раз печёт полноценный контейнер, а не просто копирует файлы. Но если она висит совсем долго или обрывается, а в логах ничего понятного нет, стоит пересоздать приложение в другом регионе: список открывается в блоке «Регион». Между российскими площадками цена одинаковая, так что Москву можно свободно менять на Петербург и наоборот. Зарубежные (Амстердам, Франкфурт) стоят заметно дороже, а навыку они ничего не дают: колонка всё равно в России.

Берём российскую площадку, зарубежные дороже без всякой пользы
Выпадающий список регионов: Санкт-Петербург, Москва, Амстердам, Франкфурт
Как потом менять настройки: передеплой

Дальше в гайде пару раз встретится слово «передеплоить». Это значит: зайти в приложение на App Platform, открыть вкладку «Настройки», нажать «Редактировать» у настроек деплоя, поменять что нужно и нажать «Сохранить данные». Новая сборка запустится сама, признак готовности всё тот же, «Deploy succeeded».

Важно: пока сборка не прошла, приложение живёт со старыми настройками. И если я выложу в репозиторий новую версию программы, к тебе она приедет только со следующей сборкой: у репозитория, подключённого по ссылке, автодеплоя нет.

Если умеешь читать код: разбор навыка по кускамРазвернуть

Кнопки уже нажаты, программа работает, и для результата это знать не нужно. А если код тебе не чужой, вот её главные места. Всего около 230 строк на Express, четыре файла, по одной задаче на файл, единственная зависимость это сам Express.

Модель никто не торопит, её просто перестают ждать. Файл alice.js запускает запрос и таймер одновременно, а дальше забирает то, что сработало первым:

// Ждём ответ, но не дольше ms миллисекунд. Не дождались: вернём null
function waitAtMost(promise, ms) {
  const timer = new Promise((resolve) => setTimeout(() => resolve(null), ms));
  return Promise.race([promise, timer]);
}

Запрос к модели при этом никуда не девается. Таймер выиграл гонку, Алиса получила «Секунду, думаю», а модель дописывает ответ в фоне, и он лежит до того момента, пока ты не скажешь «дальше»:

async function deliver(dialog, answerPromise, waitText) {
  const answer = await waitAtMost(answerPromise, config.waitForAnswerMs);
  if (!answer) {
    return say(waitText); // не успели: попросим сказать «дальше»
  }
  ...
  return say(answer);
}

Порог waitForAnswerMs стоит на 2,4 секунды, хотя Алиса ждёт около трёх. Запас нужен на дорогу: пока ответ летит от приложения до колонки, время тоже идёт.

Отдельный случай, когда новый вопрос задан, пока модель думает над старым. В первой версии он молча терялся, и это была самая противная ошибка из всех: вживую она выглядела как «колонка меня не слышит». Лечится одной строкой, новый запрос не начинается сам по себе, а пристраивается в очередь за недоделанным.

// Обычный вопрос. Если модель ещё думает над прошлым, встаём в очередь за ним
const previous = dialog.pendingAnswer || Promise.resolve();
dialog.pendingAnswer = previous.then(() => askAndRemember(dialog, userText));

Память разговора устроена бесхитростно. Никакой базы данных нет, история лежит в обычном Map в памяти процесса, по ключу сеанса Алисы. Каждый вопрос и ответ дописываются в массив, а старое отрезается, чтобы запросы не разрастались и не дорожали:

dialog.history.push({ role: 'assistant', content: answer });
 
// Храним только последние реплики, чтобы запросы не разрастались
if (dialog.history.length > config.maxHistory) {
  dialog.history = dialog.history.slice(-config.maxHistory);
}

Отсюда и её повадки: память живёт, пока живёт процесс, поэтому пропадает после деплоя. Для голосового навыка это нормально, разговор всё равно короткий. Сколько реплик помнить, задаёт maxHistory в config.js, но чтобы его поменять, придётся форкнуть репозиторий: приложение подключено к моему, а чужой код не правится.

Отдельно пришлось воевать с markdown. Модели его любят, а колонка читает текст буквально, со всеми «звёздочка звёздочка». Инструкция в промпте помогает не всегда, поэтому ответ ещё и чистится руками, в llm.js:

function cleanForSpeech(text) {
  return text
    .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // [текст](ссылка) → текст
    .replace(/[*_`#>]/g, '')                // markdown-символы
    .replace(/^\s*[-•]\s+/gm, '')           // маркеры списков
    .trim();
}

Своих программа отличает по skill_id. Вебхук открыт всему интернету, поэтому server.js первым делом сверяет, от твоего ли навыка пришёл запрос, а чужим вешает трубку:

// Чужой навык? Не отвечаем (защита от тех, кто найдёт адрес туннеля)
if (config.skillId && alice.session.skill_id !== config.skillId) {
  return res.sendStatus(403);
}

Обрати внимание на config.skillId &&: пока переменная не задана, проверки нет вообще. Сделано, чтобы навык заработал сразу, до того как ты узнаешь свой skill_id, но именно поэтому шаг с этой переменной и нельзя пропускать.

По мелочи там ещё несколько поправок на голос. Ответ обрезается до 1024 символов, потому что больше Алиса не читает. Команды перед сравнением приводятся к простому виду, поэтому «Алиса, дальше!» и «дальше» это одно и то же. И на слово ping навык отвечает pong, так Яндекс иногда проверяет, жив ли он.

Весь код открыт: github.com/ituzov/ituzovlab-alice, лицензия MIT.

Шаг 3. Создаём навык в Алисе

Теперь надо познакомить Алису с нашей программой. Делается это в Яндекс Диалогах, там же, где разработчики выпускают навыки в магазин. Наш навык будет приватным: он работает только на твоих колонках и в каталоге не показывается.

  1. 01

    Создаём навык

    Идём на dialogs.yandex.ru/developer под тем же аккаунтом Яндекса, к которому привязана колонка. Сверху выбираем «Навыки в Алисе» и жмём «Создать навык Алисы».

    Соседние вкладки про ТВ и умный дом нам не нужны
    Главная Яндекс Диалогов с плиткой «Создать навык Алисы»
  2. 02

    Заполняем карточку

    Откроется длинная форма, и половина полей обязательна. Название навыка это фраза, которой ты будешь его звать: возьми что-нибудь редкое из двух слов, у меня «Умник лаборатории». На простом имени колонка запустит чужой навык с похожим названием, у меня так и было, по «режиму умника» открывался чей-то чужой, из которого даже выйти не получалось.

    Активационные имена можно не трогать, туда подставится название. В примеры запросов добавь одну строку вида «Запусти навык» плюс твоё имя. Описание годится любое, хоть «личный навык». Голос выбери на свой вкус, им навык будет говорить.

    Навык приватный, так что карточку увидишь только ты
    Заполненная карточка навыка: название, активационные имена, примеры запросов, описание
  3. 03

    Указываем адрес программы и закрываем доступ

    В блоке Backend оставь «Webhook URL» и вставь адрес приложения из шага 2. Обязательно целиком, вместе с https:// в начале: без него Яндекс адрес не примет.

    Ниже переключи тип доступа на «Приватный». Это важно вдвойне: навык не попадёт в общий каталог, и проверять его будут не люди, а автомат, то есть быстро.

    Категорию и имя разработчика тоже надо заполнить, содержание неважно
    Поле Webhook URL с адресом приложения и переключатель типа доступа в положении «Приватный»
  4. 04

    Ставим иконку

    Иконка обязательна, без неё форма не сохранится. Подойдёт любая картинка в png или jpeg.

    Доступные поверхности ниже оставляем как есть, Станция там уже отмечена
    Поле загрузки иконки навыка с подсказкой про формат и размер
  5. 05

    Сохраняем и отправляем на модерацию

    Жмём «Сохранить», потом «Отправить на модерацию». Появится окно с комментарием для модератора, его можно оставить пустым и подтвердить.

    Шапка навыка с кнопками «Сохранить» и «Отправить на модерацию»
  6. 06

    Публикуем

    У приватного навыка проверка автоматическая, у меня заняла пару минут. Когда в шапке появится «модерация пройдена», жми «Опубликовать»: без этого шага колонка навык не увидит.

    Дальше статус сменится на «запрос на публикацию», это нормально
    Шапка навыка с отметкой «модерация пройдена» и кнопкой «Опубликовать»
  7. 07

    Проверяем связку

    Открой слева вкладку «Тестирование» и напиши там любой вопрос. Ответ придёт от нейросети, а если модель задумается, увидишь то самое «Секунду, думаю. Скажи „дальше“»: напиши «дальше», и ответ подтянется. Работает тут всё ровно так же, как будет на колонке, только текстом.

    Справа видно сырой запрос от Алисы, он нам сейчас пригодится
    Вкладка «Тестирование»: вопрос, ответ «Секунду, думаю», слово «дальше» и ответ нейросети
  8. 08

    Забираем skill_id

    Справа, в блоке «Последний запрос», найди строку skill_id внутри session. Это набор букв и цифр через дефисы, скопируй его без кавычек.

    Значение на скриншоте замазано, у тебя там будет свой идентификатор
    Данные запроса на вкладке «Тестирование», строка skill_id выделена
  9. 09

    Открываем настройки приложения

    Вернись в App Platform, зайди в приложение и открой вкладку «Настройки». Первая строка «Настройки деплоя», жми «Редактировать».

    Вкладка «Настройки» приложения, строка «Настройки деплоя» с кнопкой «Редактировать»
  10. 10

    Добавляем переменную

    Откроется та же форма, что при создании приложения. У переменных жми «Добавить», в название впиши ALICE_SKILL_ID, в значение вставь скопированный идентификатор и сохрани окно.

    Значение замазано, у тебя будет свой skill_id
    Окно добавления переменной ALICE_SKILL_ID со вставленным значением
  11. 11

    Сохраняем настройки

    Главное не забыть: внизу формы нажать «Сохранить данные». Новая сборка после этого запустится сама, отдельно ничего нажимать не надо. Когда она закончится, программа начнёт отвечать только твоему навыку, а всех остальных игнорировать.

    Теперь переменных пять, а не четыре
    Форма настроек деплоя с переменными и кнопкой «Сохранить данные» внизу
Почему адрес надо закрывать

Адрес твоей программы открыт всему интернету, а Яндекс свои запросы никак не подписывает. Пока ALICE_SKILL_ID не прописан, любой, кто узнает адрес, может задавать вопросы за твой счёт. Шаг с skill_id не пропускай, он занимает минуту.

Шаг 4. Говорим с колонкой

Скажи колонке «Алиса, запусти лунного умника», подставив своё название, и дальше говори обычными словами: слушает Алиса, отвечает нейросеть.

Проверь сразу что-нибудь, на чём обычная Алиса спотыкается. Я сказал «поругай меня за то, что я опять не пошёл в зал» и получил: «Ну ты даёшь. Опять диван победил зал, да? Завтра без отговорок, кроссовки в руки и пошёл.» После пяти лет «я пока не умею такого» это было сильно.

Команд всего две: «дальше» забирает ответ, если колонка сказала «Секунду, думаю», «хватит» закрывает навык. Синонимы тоже понимает: «ну что там», «продолжай», «давай», «стоп», «выход», «пока».

Разговор навык помнит: спроси «кто такой Толстой», потом «что он написал», и модель поймёт, про кого речь. Держит двадцать последних реплик, после выхода всё с чистого листа.

Какую модель выбрать

По умолчанию стоит Grok: отвечает за две-три секунды и шутит. В трёхсекундный лимит Алисы он попадает не всегда, отсюда и частое «дальше». Хочешь меньше пауз, поставь модель побыстрее.

Мои замеры первого ответа:

  • yandex/aliceai-llm-latest, 0,9 секунды: самая быстрая, но хуже слушает инструкции, мне диктовала списки вслух,
  • timeweb/gpt-oss-120b, 1,4 секунды,
  • deepseek/deepseek-v4-flash, 1,5 секунды,
  • anthropic/claude-haiku-4-5, от 1,8 до 3,4 секунды,
  • xai/grok-4.7 с REASONING_EFFORT=low, от 2 до 3 секунд.

Claude Sonnet 5, Gemini 3.8 Flash и Qwen 3.8 Max в лимит не укладываются, с ними «дальше» придётся говорить почти всегда. Цифры плавают от вопроса к вопросу, у тебя выйдет немного иначе.

Чтобы сменить модель, впиши её ID в переменную MODEL и сохрани настройки деплоя. Сам ID берётся в панели: AI Gateway → вкладка «Подключение» → выбрать модель.

Если после смены модели сломалось

Настройку REASONING_EFFORT понимают не все модели, и та, которая не понимает, отвечает ошибкой. Если навык вдруг начал говорить «Не получилось достучаться до модели», удали эту переменную и передеплой.

Если что-то не работает

Колонка говорит «Такого навыка нет»

Проверь, что навык прошёл модерацию, и что ты зовёшь его тем названием, которое указано в Диалогах. Ещё колонка должна быть привязана к тому же аккаунту Яндекса, под которым создан навык.

Колонка открывает чужой навык

Название слишком простое, и Алиса выбрала похожий публичный навык. Смени название на редкое, из двух слов, и отправь на модерацию заново.

В «Тестировании» ответ не приходит

Открой адрес приложения в браузере. Если там нет ok, дело в приложении: посмотри логи деплоя на App Platform. Если ok есть, проверь, что в Webhook URL вставлен полный адрес вместе с https://, без лишнего пробела в конце.

Навык отвечает «Не получилось достучаться до модели»

Обычные причины: закончились деньги на балансе Timeweb, исчерпан лимит токенов на ключе, у ключа вышел срок действия или в MODEL указан ID несуществующей модели. Ещё так бывает, когда модель не понимает REASONING_EFFORT, тогда эту переменную надо убрать.

В логах ошибка про ByteString и character at index 7

Значит, в API_KEY осталась заглушка paste_your_key_here или в ключ затесались русские буквы. Программа не может отправить такой ключ в заголовке запроса и падает ещё до обращения к модели. Открой переменную, вставь настоящий ключ из шага 1 и передеплой.

После добавления ALICE_SKILL_ID навык замолчал

Значит, программа считает твой навык чужим. Почти всегда причина в значении переменной: лишний пробел, кавычки по краям или скопирован не тот идентификатор. Сравни значение с тем, что показывает «Тестирование», поправь и передеплой. Крайний случай: удали переменную, убедись, что навык ожил, и добавь заново.

Колонка постоянно просит сказать «дальше»

Так и должно быть с медленной моделью: Алиса ждёт три секунды, а модель думает дольше. Поставь в MODEL модель побыстрее из списка выше.

Навык забыл, о чём мы говорили

Память живёт, пока идёт разговор. Она обнуляется, когда ты сказал «хватит», когда Алиса сама закрыла навык после долгой паузы и после каждого нового деплоя приложения.

Что можно докрутить

Кроме модели, кнопками меняется и характер ассистента. По умолчанию он обычный помощник: отвечает коротко, без списков и эмодзи, потому что текст зачитывается вслух. Добавь в настройки приложения переменную SYSTEM_PROMPT, и вместо помощника получится кто угодно, например строгий коуч или вечно недовольный кот.

SYSTEM_PROMPT=Ты вечно недовольный кот. Отвечай ворчливо, одной-двумя фразами, по-русски. Без списков и эмодзи, текст читается вслух.
Шестая переменная рядом с остальными пятью
Окно добавления переменной SYSTEM_PROMPT с промптом про недовольного кота

Две тонкости. Писать надо одной строкой: перевод строки в поле переменной не вставить. И про чтение вслух в своём тексте лучше упомянуть, иначе модель начнёт диктовать колонке списки и звёздочки разметки. Дальше как обычно, сохраняешь настройки, ждёшь сборку, и характер сменился.

Если не понравилось

Приложение платное, поэтому удалять его лучше сразу, а не «потом разберусь». Открой App Platform, зайди в приложение и удали его: начисления прекратятся, потому что оплата почасовая. Навык в Диалогах можно оставить, он бесплатный, но без приложения работать не будет, так что его тоже стоит удалить. Ключ AI Gateway удаляется в панели там же, где создавался.

Код открыт, лицензия MIT: github.com/ituzov/ituzovlab-alice. Забирай и переделывай под себя.

Что дальше

Эту программу писал не я вручную, а агент под мою диктовку, и это отдельный навык: ставить задачу, проверять результат и не тонуть в чужом коде. Про него у меня есть курс «ChatGPT и Codex с нуля»: там то же самое, но на своих задачах, а не на готовом репозитории.

Если по ходу гайда понравилось возиться с сервером и захотелось полного контроля, посмотри разбор «Первый сайт на сервере»: там всё руками, через ssh, без App Platform.

Что дальше

Такие разборы выходят регулярно

Короткие мысли и находки я публикую в телеграм-канале, а глубокие разборы, курсы и сообщество, где растут инженеры, живут здесь, в Lab.

Заведи аккаунт в ITUZOV LAB

Зарегистрироваться