Урок 6. Темы в боте и расширенный контекст
Содержание
Если ты много общаешься с ботом, личный чат быстро превращается в свалку: серверные дела вперемешку с заметками про поездку, кодом и личными напоминаниями. В этом уроке разберёмся, как разложить личный чат с ботом по темам — это новая фича Telegram, бот может включить её сам и сам же создавать темы. Заодно посмотрим на две команды, без которых живое общение с ботом некомфортно: /btw (быстрый побочный вопрос) и steering (вмешательство в уже идущий ответ).
Темы прямо в чате с ботом
Что это и зачем
Один и тот же 1-на-1 чат с ботом разбивается на несколько параллельных лент со своими названиями и иконками. Сверху чата появляется навигация по разделам, у каждой темы — своя история и свой контекст.
Зачем это нужно:
- Контекст одного направления не сваливается в другое. Утром обсуждал миграцию, вечером пишешь про поездку — бот не тащит серверные детали в разговор про авиабилеты.
- Каждая тема доступна одним тапом из шапки чата — не нужно скроллить ленту назад.
- В каждой теме у бота своя сессия: своя история, свой контекст, свои настройки.
- Можно завести «постоянные» темы под повторяющиеся направления (Сервер, Код, Поездки, Напоминания) и не плодить отдельных ботов.
Включаем Threaded Mode в BotFather
Темы в личном чате с ботом нужно сначала разрешить на стороне бота. Это делается в BotFather:
- Открой @BotFather → выбери своего бота → раздел Bot Settings.
- Найди пункт про Threads / Threaded Mode / разрешение на создание тем в DM. Точное название иногда меняется, ориентируйся на формулировки про threads и темы в личных чатах.
- Включи Threaded Mode.
Под ним есть второй тумблер — Disallow users to create new threads. С ним стоит разобраться отдельно, потому что он сильно меняет поведение чата.
Когда Disallow users to create new threads выключен, каждое новое сообщение, которое ты отправляешь мимо уже существующей темы, автоматически создаёт новую тему. Это удобно на этапе ознакомления — наглядно видно, как работают темы, и каждая мысль сразу получает свою «папку». Но в повседневной работе это быстро мешает: чат заваливается одноразовыми темами «привет», «а ещё», «короче», в которых лежит по одному сообщению. Поэтому в нормальном режиме этот тумблер включают — сообщения без темы идут в общую ленту, а темы заводятся осмысленно: либо тобой вручную через интерфейс Telegram, либо ботом по твоему запросу.
После включения Threaded Mode у тебя в личном чате с ботом появляется навигация по темам, а у бота — право их создавать и переименовывать.
Как OpenClaw работает с темами в DM
Внутри Telegram каждая тема в DM — это просто числовой thread ID, который автоматически прикрепляется к сообщениям в этой теме. OpenClaw на основе этого ID делает три вещи:
- Отдельная сессия на каждую тему. Сообщения из разных тем идут в разные сессии — у каждой темы своя история, свой контекст, своя память сессии.
- Сохраняет thread ID в исходящих ответах, чтобы ответ бота приходил именно в ту тему, откуда был задан вопрос.
- Прокидывает thread ID в шаблоны и логику ответа, если ты сам захочешь ветвить поведение по теме.
С точки зрения авторизации это всё ещё DM — tools.elevated.allowFrom.telegram со списком твоих ID работает в любой теме. Никаких дополнительных настроек в openclaw.json после включения тем в BotFather прописывать не нужно: OpenClaw подхватит темы автоматически.
Бот сам создаёт и поддерживает темы
Главное удобство — темы можно не придумывать вручную. У бота есть действие topic-create (под капотом — Telegram-метод createForumTopic), и оно включено по умолчанию. И самое приятное: списком направлений тоже не обязательно загружать его руками — бот уже знает, о чём вы регулярно говорите, и сам предложит разумную структуру. Достаточно написать:
Посмотри на свою память и на наши последние разговоры. Выдели направления, которые повторяются чаще всего, и заведи под них темы прямо здесь в Telegram. Названия и иконки придумай сам. Соответствие thread ID → название сохрани в TOPICS.md, чтобы дальше понимал, куда что относить.
Бот пройдётся по MEMORY.md, дневным заметкам и текущей сессии, выделит повторяющиеся направления (у каждого пользователя они получатся свои), создаст под них темы, выставит иконки и запишет соответствие thread ID → название в TOPICS.md. Дальше можно подтягивать новые темы по ходу:
Заведи отдельную тему «Wildberries API» и положи туда заметку про авторизацию.
Перенеси разговор про деплой в тему «Сервер и инфраструктура».
Каждое утро публикуй свод задач в тему «Быстрые задачи».
Зачем нужен TOPICS.md. Telegram отдаёт боту thread ID числом (3, 7, 42), а не названием. Без таблички соответствия в памяти бот не знает, что «3» — это «Код и разработка», особенно после нового запуска или сброса сессии. Файл вида:
# Темы в DM
| ID | Название |
|----|----------|
| 2 | 📺 Сервер и инфраструктура |
| 3 | ⚡ Быстрые задачи |
| 4 | 🔧 Код и разработка |
| 5 | 🧠 Память и настройки |
| 6 | 🧪 Исследования |
| 7 | 📌 Проекты |
| 8 | ✈️ Поездки и планирование |
| 9 | ⏰ Напоминания и ожидания |
— решает проблему раз и навсегда. Бот сам его обновит, когда заведёт новую тему.
Разные настройки для разных тем
Поскольку каждая тема в DM — это отдельная сессия, у неё может быть свой systemPrompt, свой набор навыков, свои правила. Конфигурируется так же, как темы форума, через channels.telegram.groups.<chatId>.topics.<threadId> — chatId здесь будет твоим Telegram user ID, потому что DM с точки зрения routing-а — это личный «канал» между ботом и тобой.
Пример: в теме «Поездки» включаем только travel-search, в теме «Код и разработка» — дев-инструменты:
{
channels: {
telegram: {
groups: {
"123456789": { // твой Telegram user ID
topics: {
"4": { // Код и разработка
skills: ["web-search-plus", "github"],
systemPrompt: "Ты дев-ассистент. Отвечай по делу, проверяй код на безопасность."
},
"8": { // Поездки
skills: ["travel-search", "web-search-plus"]
}
}
}
}
}
}
}
После правки:
openclaw gateway restart
Эта часть конфига — продвинутая и может в будущем измениться: сам факт DM-thread routing’а в OpenClaw встроен надёжно, а вот форма «развешивания» systemPrompt/skills на конкретные темы DM — менее обкатанная. Если в
openclaw doctorили логах увидишь предупреждение про неподдерживаемое поле — скинь скрин в телеграм-канал курса, разберёмся вместе.
Если хочется отдельную память и навыки для каждой темы целиком, проще пока не настраивать темы вручную, а опираться на то, что у каждой темы и так свой ключ сессии: бот в каждой теме помнит только её собственный контекст, и этого на старте достаточно.
/btw — побочный вопрос без последствий
Бывает: ты обсуждаешь с ботом большую задачу (например, миграцию). Контекст разговора уже плотный, бот в курсе, что ты делаешь. И тут хочется быстро спросить «а сколько 17 × 19?» или «какой сейчас курс доллара?» — но не хочется, чтобы этот побочный вопрос осел в истории и тащился в контекст потом.
Для этого есть /btw:
/btw сколько сейчас занимает свободного места на диске
Что происходит:
- Бот снимает снимок текущего контекста сессии (включая основной run, если он уже идёт).
- Делает отдельный одноразовый side-запрос: модель отвечает только на побочный вопрос и не продолжает основную задачу. У direct/CLI-пути инструменты обычно отключены; у Codex harness side-вопрос идёт как эфемерный дочерний thread и наследует tools и approval родительского.
- Возвращает ответ как side-result — отдельно от обычного сообщения ассистента. В Telegram это просто помеченный one-off reply (отдельного «всплывающего» side-чата у Telegram нет).
- Не пишет вопрос и ответ в историю сессии (
chat.history). После перезагрузки этого обмена не будет. Токены на side-вызов при этом тратятся.
Правило простое: /btw — это «спрошу мимоходом, в историю не клади». Если ответ нужен дальше в работе — спрашивай обычным сообщением.
Чем /btw отличается от /new:
/newначинает чистую сессию, теряя весь контекст. Хорошо для смены задачи целиком./btwоставляет текущую сессию нетронутой и не засоряет её историю. Хорошо для микро-вопросов внутри большой задачи.
Где /btw особенно полезен:
- Идёт долгий run, а ты хочешь уточнить что-то параллельно. Обычное сообщение пойдёт в очередь (
/queue);/btwне рулит основной run и отвечает отдельным side-result. - Нужно быстро посчитать или проверить факт, не засоряя историю сессии.
- Хочешь спросить «что сейчас происходит, на каком файле мы остановились» —
/btwдаст ответ и не смешает это с основной задачей.
Примеры:
/btw на каком файле мы сейчас?
/btw как называлась команда из урока 3?
/btw 17 * 19
/btw переведи рубли в доллары: 84 000 ₽
Подробности — в документации /btw.
Active-run steering — править бота на лету
Бот ушёл выполнять длинную задачу: ставит пакеты, лезет в API, разбирается с конфигом. Прошла минута, ты понимаешь, что он идёт не туда — взял не ту библиотеку или начал делать лишнее. Хочется крикнуть «стоп, не туда!» и направить.
Для этого есть steering — возможность вмешаться в уже идущий запуск. По умолчанию в OpenClaw режим steer: сообщение во время run впрыскивается в активный runtime в том же ходу, второй run сессии не стартует. Если runtime steering не принимает — OpenClaw дождётся конца текущего run и только потом обработает сообщение. Режим collect — другая стратегия: копить сообщения и отдать одной followup-пачкой после окна тишины.
Режимы очереди
OpenClaw умеет несколько стратегий обработки сообщений во время активного запуска (документация):
| Режим | Что делает |
|---|---|
steer (по умолчанию) |
Сообщение впрыскивается в текущий run после текущего tool-turn, до следующего вызова модели. История продолжается. |
followup |
Не вмешивается в текущий run. Каждое сообщение — отдельный ход после его конца. |
collect |
Не вмешивается в текущий run. Сообщения за окно тишины склеиваются в один followup-ход после конца run. |
interrupt |
Прерывает текущий run и запускает новый с самым новым сообщением. |
Steering важно понимать правильно: твоё сообщение прилетает между шагами модели. Бот сначала доделает текущий tool call (например, докачает файл), потом увидит steer, и только потом решит, что делать дальше. Уже ушедший shell-command «выключить» нельзя, но логику до следующего шага — можно. Чтобы именно оборвать run — /queue interrupt.
Debounce, cap, drop
Общие дефолты очереди: mode: "steer", debounceMs: 500 (0,5 с), cap: 20, drop: "summarize".
debounceMs — окно тишины перед сливом followup/collect-пачек (и перед batched Codex turn/steer). В режиме collect логика такая:
- Сообщение во время run или сразу после — в очередь.
- Следующие сообщения внутри debounce-окна склеиваются с ним.
- После тишины (и конца активного run, если он ещё шёл) пачка уходит одним followup.
- Новое сообщение до истечения окна сбрасывает таймер.
Если пишешь медленно или часто дробишь мысль — увеличь окно: /queue collect debounce:2s. Нужны максимально быстрые одиночные followup — debounce:0.
Рядом:
cap— максимум сообщений в очереди на сессию (дефолт 20); дальше срабатываетdrop.drop:summarize(дефолт — выбросить старые, но подложить краткую сводку),old(выбросить старые без сводки),new(отклонить новые).
Команда /queue
Режим переключается на лету, без правки конфига:
/queue steer # дефолт: вмешиваться в текущий run
/queue collect # склеивать сообщения во время run в один followup
/queue followup # каждое сообщение — отдельный followup
/queue interrupt # оборвать run и стартовать с последнего сообщения
/queue default # сбросить override сессии (/queue reset — то же)
Можно подкрутить параметры:
/queue collect debounce:2s cap:25 drop:summarize
debounce— окно тишины (принимаетms/s/m/…).cap— лимит сообщений в очереди.drop— политика при переполнении:summarize/old/new.
Постоянно прописать в ~/.openclaw/openclaw.json:
{
messages: {
queue: {
mode: "steer",
debounceMs: 500,
cap: 20,
drop: "summarize",
byChannel: {
telegram: "steer",
discord: "collect"
}
}
}
}
Что выбрать на практике
steer(дефолт) — удобен для длинных задач в Telegram: подкручиваешь ход на лету. Минус: короткая реплика «ок» / «стоп» может неожиданно свернуть run.collect— если реплики во время run хочешь копить и отдать одним followup, без вмешательства в текущий ход. Предсказуемее для «один вопрос → один ответ».followup— каждое сообщение после run’а — отдельный ход, без склейки.interrupt— когда нужно именно оборвать текущую работу и начать с последнего сообщения.
Удобный паттерн: оставить steer (он и так дефолт) и держать /btw для микро-вопросов мимо истории. Бот занят — ты подкручиваешь по ходу; побочный факт не оседает в сессии.
Если что-то пошло не так
Бот не создаёт темы. Проверь, что в группе включён режим форума и что в BotFather у бота включён Threaded Mode.
Что дальше
Бот настроен, память работает, темы разложены, steering под рукой. Осталось научиться его чинить, когда что-то пойдёт не так — и сделать так, чтобы он сам присматривал за своим здоровьем. В следующем уроке:
- Главный способ починки — отдать диагностику AI-агенту (Codex Desktop), который сам зайдёт по SSH и разберётся
- Быстрая команда
openclaw doctorдля типовых поломок без AI- Ежедневный self-check по cron: бот раз в сутки проверяет себя и состояние сервера, пишет в Telegram, если что-то отвалилось
Если что-то не получается или есть вопросы — заходи в телеграм-канал курса. Там помогут разобраться.