Это руководство для администратора и оператора: за что отвечает каждый раздел интерфейса,
как устроена интеграция с мессенджерами и ИИ-агентами, и по какой логике всё это работает вместе.
Документ лежит прямо на сервере по адресу /howto.html — можно открывать в любой момент,
без входа в систему.
RT Desk — это рабочее место поддержки и продаж в одном приложении: канбан-доска задач, недельный календарь, CRM по клиентам и единый почтовый ящик входящих сообщений из мессенджеров (сейчас — Telegram), который умеет отвечать клиентам автоматически с помощью ИИ-агента, при необходимости опираясь на базу знаний компании.
Сервис состоит из трёх независимых программ (контейнеров), которые работают вместе, но не ломают друг друга при сбое:
(связи между ними подробно показаны в разделе 10)
Главное, что нужно понимать: вся информация и вся логика «что говорить клиенту» хранится и настраивается в самом rt-desk, во вкладке Настройки. Агенты-контейнеры ничего не хранят сами — они просто выполняют то, что там написано, и могут быть перезапущены или обновлены в любой момент без потери данных.
Главная страница (/). Обычная канбан-доска: колонки — это «треки» (например, направления работы
или проекты), внутри каждого трека — четыре фиксированные дорожки: К выполнению → В работе → На проверке → Выполнено.
Страница /calendar — недельный календарь в стиле доски: вместо треков колонками идут
дни недели с понедельника по воскресенье, а записи — это карточки внутри дня. По умолчанию всегда
открывается текущая неделя, сегодняшний день выделен рамкой.
/calendar?week=2026-11-09), поэтому ссылку на неё
можно переслать коллеге.Страница /clients — простая CRM: карточка на каждого клиента со статусом, контактами,
заметками и списком привязанных задач с доски.
| Статус | Что значит |
|---|---|
| Потенциальный | Потенциальный клиент, сделки ещё не было |
| Активный | Текущий, работающий клиент |
| Приостановлен | Временно не ведём работу (например, ждём ответа) |
| В архиве | Клиент закрыт/неактуален, но история сохранена |
Страница /dialogs — единый «почтовый ящик» переписки с клиентами из всех подключённых
мессенджеров. Один диалог = одна продолжающаяся переписка с одним чатом.
У каждого диалога есть переключатель «агент включён / выключен» прямо в карточке переписки. Как только человек вручную отправляет сообщение из этого интерфейса, агент для этого диалога автоматически выключается — чтобы бот и оператор не писали клиенту одновременно. Включить агента обратно можно тем же переключателем.
Раздел Настройки → Мессенджеры → Telegram подключает бота, который принимает и отправляет сообщения для вкладки «Диалоги». Архитектура сделана так, что добавление нового мессенджера (MAX, Instagram, WhatsApp — сейчас в интерфейсе они отмечены как «Скоро») не потребует переделывать «Диалоги» или CRM — это просто отдельный «адаптер».
@BotFather и получить токен вида 123456:ABC-DEF….| Режим | Как работает | Когда выбрать |
|---|---|---|
| Опрос | rt-desk сам периодически спрашивает у Telegram «есть новые сообщения?» | Сервер за NAT, без публичного домена/HTTPS, тестовый запуск, localhost |
| Вебхук | Telegram сам присылает сообщение на публичный HTTPS-адрес сервера, как только оно приходит | Продуктивный сервер с доменом и HTTPS — быстрее, без задержки опроса |
Для Вебхук есть кнопка «Подключить через вебхук» — она в один клик берёт текущий домен страницы (тот, через который вы сейчас открыли /settings) и регистрирует его в Telegram. Ручное поле «Публичный адрес сервера» нужно только для нестандартного адреса.
Статус-индикатор под полем токена показывает реальное состояние: серая точка — выключено, зелёная — подключено и работает, красная — есть ошибка (текст ошибки выводится рядом).
TELEGRAM_BOT_TOKEN в .env используется только один раз,
при самом первом старте «с нуля», чтобы не вводить токен вручную — после этого источником истины всегда
являются Настройки.
client-agent — отдельная программа (контейнер), которая каждые 10–15 секунд спрашивает у
rt-desk: «есть диалоги, на которые никто не ответил?», забирает один диалог, обрабатывает его и отправляет
ответ клиенту через тот же канал (Telegram и т.д.). Она намеренно вынесена из основного rt-desk: её логика
меняется часто, и её сбой или обновление никогда не может повредить данные — диалог просто подождёт
чуть дольше.
Всё, что агент говорит и когда он передаёт диалог человеку, управляется только настройками ниже — в коде контейнера нет захардкоженного поведения.
Шаг 5 при отклонении возвращает ответ на шаг 4 с комментарием судьи — так происходит до лимита повторов, заданного в настройках; после лимита диалог автоматически уходит оператору, а не отправляется клиенту без проверки.
| Поле | Назначение |
|---|---|
| Включён | Общий выключатель. Выключено — диалоги копятся только в очереди оператора, бот ничего не пишет. |
| Ключ API OpenAI | Ключ OpenAI, которым агент обращается к модели. Этот же ключ переиспользуется Базой знаний — вводить второй раз не нужно. |
| Основная модель | «Запасная» модель — используется, если классификатор выключен или категория не найдена в таблице маршрутизации. |
| Максимум шагов на сообщение | Сколько внутренних шагов (вызовов инструментов) агент может сделать на одно сообщение, прежде чем принудительно эскалировать — защита от зацикливания. |
| Служебный токен | Общий секрет, которым контейнер client-agent подтверждает rt-desk, что запрос действительно от него. Генерируется автоматически; копируется в AGENT_SERVICE_TOKEN контейнера. |
| Сценарий | Главное поле: сценарий-инструкция на обычном языке — кто агент, как приветствует, что предлагает, когда обязан передать человеку. Это единственное место, определяющее тон и содержание ответов. |
| Классификатор | Быстрая/дешёвая модель, которая присваивает сообщению метку категории для таблицы маршрутизации. Выключен — всё идёт на Основная модель. |
| Маршрутизация (маршрутизация) | Таблица «категория → модель», например complex → gpt-5, simple_faq → gpt-4o-mini. |
| Проверяющая модель (проверка) | Вторая модель, проверяющая черновик ответа перед отправкой клиенту — главный предохранитель от «отклонения от сценария». |
| Максимум повторов | Сколько раз черновик может быть отклонён судьёй, прежде чем диалог уйдёт человеку. 0 — эскалация после первого же отказа. |
| Доступ к базе знаний | Разрешает агенту во время диалога задавать вопрос базе знаний вместо того, чтобы гадать или строго держаться текста сценария. |
AGENT_SERVICE_TOKEN файла .env рядом с docker-compose.yml.docker compose up -d --build — всё остальное (ключ OpenAI, промпты, модели) настраивается только через интерфейс, без переменных окружения.
Страница /knowledgebase — загрузка документов компании (инструкции, тарифы, FAQ и т.п.) плюс
тестовый чат, где можно сразу проверить, что на них ответит ИИ.
Документы хранятся внутри самого rt-desk: каждый загруженный текст разбивается на кусочки ~1200 символов, для каждого кусочка строится embedding (через OpenAI) и сохраняется. Поиск по базе — это поиск «похожих по смыслу» кусочков, а не поиск по ключевым словам.
На странице База знаний документ можно добавить двумя способами: кнопкой
⇪ Загрузить .md — загрузить готовый markdown-файл (название берётся из имени файла, текст читается
прямо в браузере) — или кнопкой + Добавить — вставить текст вручную. Оба пути ведут в одну и ту же
форму перед сохранением, так что текст из файла можно поправить до того, как он уйдёт на эмбеддинг.
Список документов слева разбит на две группы — Загруженные файлы (📄, с именем исходного файла) и Ручные записи (✍️) — чтобы сразу было видно, что пришло из файла, а что ввели руками. Большой документ автоматически режется на несколько кусочков (чанков); все они привязаны к одному документу, и при удалении документа удаляются сразу все его кусочки — «осиротевших» эмбеддингов в базе не остаётся.
Внизу страницы — панель Векторное пространство: 2D-проекция (PCA) эмбеддингов всех кусочков базы. Точки,
расположенные рядом на графике, семантически близки по смыслу; цвет точки соответствует документу, которому
принадлежит кусочек, а наведение на точку показывает текст кусочка и его номер. Это быстрый способ увидеть,
не дублируют ли документы друг друга и насколько плотно/разрозненно покрыта тема базой. Кнопка
↻ Refresh пересчитывает проекцию заново — полезно после добавления или удаления документов.
Если судья много раз отклоняет черновик — последний вариант всё равно возвращается, но помечается как «не одобрен судьёй» (проверка не пройдена), а не скрывается.
| Поле | Назначение |
|---|---|
| Включён | Без этого тестовый чат и инструмент поиска у Агент поддержки вернут ошибку. |
| Адрес агента | Внутренний адрес контейнера knowledgebase-agent, например http://knowledgebase-agent:8091 из поставляемого docker-compose.yml — обычно трогать не нужно. |
| Модель | Модель, которая формулирует ответ по найденным кусочкам. |
| Фрагментов на вопрос (лучшие K) | Сколько кусочков документов подавать модели на один вопрос. |
| Системная инструкция | Необязательная инструкция тону/формату ответа; по умолчанию — «отвечать только по контексту, иначе сказать "не знаю"». |
| Проверяющая модель | Модель-проверяющий + лимит повторов, та же логика предохранителя, что у Агент поддержки. |
Запуск на проде — тем же способом, что и Агент поддержки: контейнер уже прописан в docker-compose.yml,
ему нужен тот же AGENT_SERVICE_TOKEN в .env.
Раздел Настройки → Команда → Пользователи. Два уровня доступа:
| Роль | Что видит и может |
|---|---|
| Администратор | Всё: Доска, Календарь, Клиенты, Диалоги, База знаний и Настройки (каналы, агенты, пользователи) |
| Обычный пользователь | Доска, Календарь, Клиенты, Диалоги, База знаний — без доступа к Настройки |
При первом запуске, если пользователей ещё нет, автоматически создаётся администратор из переменных
ADMIN_USER / ADMIN_PASSWORD (по умолчанию — admin / admin,
обязательно сменить перед публикацией сервиса куда-либо, кроме локального теста).
Все созданные здесь пользователи сразу появляются в списке «Ответственный» (ответственный) у задач на доске и записей в календаре — отдельно ничего настраивать не нужно. Если пользователя удалить, его задачи и записи просто станут «без ответственного».
Новый пароль нужно сообщить пользователю напрямую — рассылки на почту сервис не делает.
Полная схема данных и вызовов между тремя контейнерами:
Клиент пишет в Telegram
│
▼
┌───────────────────┐ long polling / webhook
│ Telegram Bot API │◄──────────────────────────────┐
└───────────────────┘ │
│ новое сообщение │
▼ │
┌─────────────────────────────────────────────────────────────┐
│ rt-desk │
│ src/channels/telegram → dialogs.js → clients.js │
│ (создаёт/обновляет диалог и клиента, кладёт в очередь) │
│ │
│ Настройки ──────────────────────────────┐ │
│ (сценарий, модели, токены, правила) │ читает конфиг │
└─────────────────────┬──────────────────────┼─────────────────┘
GET /api/agent/dialogs/pending │
POST /api/agent/dialogs/:id/claim │
POST /api/agent/dialogs/:id/reply │
│ │
▼ │
┌───────────────────┐ │
│ client-agent │◄─────────────┘
│ (опрашивает каждые │ POST /api/agent/kb/ask
│ 10–15 секунд) │──────────────┐
└───────────────────┘ │
▼
┌─────────────────────┐
rt-desk POST /api/knowledgebase/chat ──►│ │
(тестовый чат на странице KB) │ knowledgebase-agent │
│ (поиск + ответ + judge) │
└─────────────────────┘
▲
POST /api/agent/kb/search
ищет похожие кусочки в данных rt-desk
Ключевые идеи этой схемы:
DATA_DIR). Агенты — «безголовые» исполнители, у них нет своей базы данных.client-agent и
knowledgebase-agent к rt-desk проверяются заголовком X-Service-Token, который
сравнивается с токеном из Настроек — обновили токен в интерфейсе, он сразу действует на все новые запросы.knowledgebase-agent — ответ клиенту
в Telegram гарантированно совпадает с тем, что видит админ при проверке.cp .env.example .env # задать ADMIN_PASSWORD и остальные переменные docker compose up -d --build
Поднимаются три сервиса: rt-desk (порт задаётся HOST_PORT, по умолчанию 8090),
client-agent и knowledgebase-agent.
git pull docker compose up -d --build
Данные (диалоги, клиенты, документы базы знаний, настройки) хранятся в отдельном docker-томе
rtdesk-data, подключённом к /app/data — они переживают пересборку и обновление образа.
| Переменная | Назначение |
|---|---|
ADMIN_USER / ADMIN_PASSWORD | Логин/пароль администратора, создаваемого при самом первом старте (пустой базе пользователей) |
HOST_PORT | На каком порту хоста слушать rt-desk (по умолчанию 8090) |
COOKIE_SECURE | Включить Secure-флаг для cookie сессии — поставить true, если сервис работает за HTTPS |
TELEGRAM_BOT_TOKEN | Нужен только при первом запуске «с нуля», дальше управляется из Настроек |
AGENT_SERVICE_TOKEN | Общий секрет для client-agent и knowledgebase-agent — должен совпадать со значением «Служебный токен» в Настройках rt-desk |
SENTRY_DSN | Если задан — ошибки всех трёх сервисов уходят в Sentry для мониторинга |
Всё состояние — это один JSON-файл внутри тома rtdesk-data (плюс папка с голосовыми
сообщениями). Достаточно периодически копировать содержимое этого тома:
docker run --rm -v rtdesk-data:/data -v $(pwd):/backup alpine \ tar czf /backup/rtdesk-backup-$(date +%F).tar.gz -C /data .
docker compose logs -f client-agent / knowledgebase-agent — текст ошибки,
плюс она же, скорее всего, уже прилетела в Sentry, если он настроен.restart: unless-stopped в docker-compose перезапустит его автоматически).src/channels/ по образцу Telegram —
сами «Диалоги» и CRM менять не придётся, они не привязаны к конкретному мессенджеру.