Добавил бота в группу — он классифицирует каждое сообщение, отвечает по базе знаний в твоём стиле и эскалирует горячих лидов тебе в личку. На сложном — молчит и пишет черновик.
SQLite · Claude Haiku 4.5 · grammy long-polling · базa знаний — knowledge_base.md
Claude Haiku 4.5 с tool-use выдаёт класс + confidence. Decision engine превращает это в действие. При уверенности ниже 0.7 действие downgrade'ится до DRAFT_FOR_OWNER — ты увидишь черновик в DM и решишь сам.
negative залипает.Никаких внешних админок, ни Supabase, ни OpenAI. Один процесс, одна SQLite-БД, один docker-compose на твоём сервере.
Один диалог с @BotFather: /newbot → токен. Обязательно /setprivacy → Disable, иначе бот в группе будет видеть только команды и упоминания, а нам нужны все сообщения.
Один markdown-файл knowledge_base.md с секциями Продукты и цены, FAQ, Возражения, Кейсы, Правила. Бот не имеет права выходить за пределы — если факта нет, честно говорит «уточню».
Заполни .env (токен, Anthropic-ключ, owner id, ALLOWED_CHAT_IDS, пароль админки) → docker compose up -d. Добавь бота в группы из whitelist — он сразу в работе.
Каждый файл — отдельный слой, всё читаемо за вечер. Никаких vendor-локов: захочешь — поменяешь responder на свой LLM или классификатор на правила.
Claude Haiku 4.5 + tool-use. На выходе строгий JSON: class + confidence 0–1. 10 классов, никакой свободной формы — никаких сюрпризов в downstream.
Чистая функция: класс + confidence → одно из IGNORE / REPLY / REPLY_SOFT / REPLY_AND_NOTIFY / NOTIFY_ONLY / DRAFT_FOR_OWNER. Никакого LLM в этом слое — детерминизм.
Claude + tone-of-voice + база знаний. У каждого класса своя стратегия ответа. Не вылезает за пределы базы — если факта нет, говорит «уточню», а не выдумывает.
Админка на :8080: список чатов, у каждого — последние сообщения, юзеры, статусы. По клику открывается полная переписка. auto_reply переключается тоггером.
Статус на (chat_id, user_id): new → cold → warm → hot → buyer. Односторонняя — назад не падает. negative залипает, SUPPORT_REQUEST → support.
На REPLY_AND_NOTIFY / NOTIFY_ONLY / DRAFT_FOR_OWNER — DM владельцу с триаж-блоком: кто, в каком чате, что сказал, какое действие. Чтобы DM работал — один раз /start у бота.
Один тоггл в админке: auto_reply: OFF. Бот всё ещё классифицирует и пишет в БД, но молчит и не дёргает владельца. Полезно когда сам ведёшь диалог и не хочешь, чтобы бот лез.
Никакого Postgres, Redis или внешних сервисов. Весь state — tg-agent.db в docker volume. Бэкап = sqlite3 .backup в крон. Схема накатывается при старте, миграций руками нет.
ALLOWED_CHAT_IDS в .env — единственный источник того, где бот работает. Добавили в чужой чат? Бот молча проигнорирует. Без whitelist'а вообще не стартует.
Бот не просит вас выбирать статус. Он смотрит на класс сообщения и продвигает (chat, user) вверх по лестнице. Назад не падает — раз стал buyer, остался buyer.
Ничего нового или экзотического. TypeScript + grammy + Hono + better-sqlite3 + Anthropic SDK. Один Docker-образ, multi-stage build, native-deps собраны заранее.
@BotFather выключить privacy mode: /setprivacy → выбрать бота → Disable. В дефолтном privacy mode боты в группах видят только команды (/...) и упоминания (@bot). Без Disable вся идея не работает — classifier не получит сообщения для разметки.
ALLOWED_CHAT_IDS в .env — whitelist. Сообщения из чатов вне списка проходят через handler, но decision engine принудительно ставит IGNORE. Никакого ответа, никакого классификатора, никакого расхода токенов на чужие чаты.
confidence < CONFIDENCE_THRESHOLD (0.7 по умолчанию) любое не-IGNORE действие downgrade'ится до DRAFT_FOR_OWNER. Ты получаешь в DM: класс, confidence, оригинал сообщения, предлагаемый ответ. Решаешь — отправить, отредактировать или просто посмотреть.
auto_reply. OFF — бот всё ещё классифицирует и пишет в БД, но молчит и не дёргает тебя. ON — снова в бою. Изменение мгновенное, рестарт не нужен.
tg-agent-data. Три таблицы: tg_chats (чат + auto_reply), tg_users (лестница лида), tg_messages (полный лог). Бэкап — sqlite3 .backup в крон, ничего больше. Никаких облачных БД.
classifier.ts и responder.ts изолированы за функциями classify() и respond(). Меняй внутренности — остальное не заметит. Decision engine, CRM и админка — pure logic, без LLM.
DRAFT_FOR_OWNER кнопками в DM — пока ты просто видишь черновик и пишешь сам. Не работает в личных чатах с клиентами (DM) — заточен под групповые. И базовая авторизация админки — только HTTP basic, поэтому перед публикой обязателен TLS-терминатор (Caddy / Cloudflare).
Один docker-compose, твой сервер, твоя база знаний. Никакой облачной БД, никаких API-ключей, кроме твоих собственных.
Сейчас живёт на одной машине · admin under tg.46-62-215-11.nip.io