AI-ассистент в Telegram на локальной LLM: архитектура и подводные камни
Как сделать корпоративного AI-бота в Telegram на self-hosted LLM (Llama / Qwen / DeepSeek). Архитектура, выбор библиотеки, изоляция тенантов, безопасность, цены.
Telegram — самый простой канал для AI-ассистента в российском бизнесе: сотрудники уже там, не надо учить новый интерфейс, есть мобильная версия. Если делать на self-hosted LLM — данные не уходят к OpenAI / Anthropic / Яндексу, что важно для 152-ФЗ и просто здравого смысла.
Эта статья — архитектура production-grade Telegram-бота на Llama/Qwen/DeepSeek, с изоляцией пользователей, RAG по корпоративной базе и понятными ценами.
Зачем вообще Telegram, а не веб-интерфейс
Веб-чат сделать проще, но Telegram даёт:
- Push-уведомления — пользователь видит ответ сразу, не нужно держать вкладку
- Мобильность из коробки — без отдельного приложения
- Аутентификация — можно через
tg_user_idбез логин/пароль - Низкий барьер для команд 30+ — все уже умеют пользоваться
Минусы:
- Telegram — внешний сервис, метаданные диалогов идут через серверы Telegram (но не контент сообщений если бот в группе, и весь контент если 1-на-1)
- Лимиты API (30 сообщений/сек на бота)
- Без официальных enterprise-фич: SSO, audit log, retention policies
Для внутреннего AI-помощника команды 30–200 человек — обычно достаточно.
Архитектура
[Пользователь TG]
↕ (Bot API)
[Telegram Bot Server (aiogram)]
↕
[Очередь задач (Redis / RabbitMQ)]
↕
[Worker → LLM-сервис (vLLM / llama.cpp)]
↕
[Vector DB (Qdrant) + Метаданные (Postgres)]
Компоненты:
- Bot frontend — принимает сообщения, обрабатывает команды (
/start,/help,/reset), складывает запросы в очередь - Очередь — нужна потому что LLM-инференс долгий (5–30 секунд), нельзя блокировать webhook
- Worker — забирает задачу, вызывает LLM, опционально RAG, возвращает ответ
- LLM-сервис — vLLM или llama.cpp с открытым OpenAI-совместимым API
- Vector DB — Qdrant для RAG-поиска по корпусу
- Postgres — пользователи, история диалогов, права доступа
Выбор библиотеки для бота
В 2026 в Python три основных варианта:
| Библиотека | Когда брать |
|---|---|
| aiogram 3 | Дефолт. Async, поддерживает все актуальные методы Bot API, активно поддерживается. |
| python-telegram-bot | Если уже на ней проект. Тяжелее, async/sync mix. |
| telebot (pyTelegramBotAPI) | Максимально простая, для прототипов. В production не масштабируется. |
Дефолт для AGmind — aiogram 3 + FastAPI (для webhook-режима).
Минимальный пример (псевдокод)
# bot.py — aiogram 3 + Redis-очередь + worker отдельно
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from redis.asyncio import Redis
import asyncio, json, uuid
bot = Bot(token=TG_TOKEN)
dp = Dispatcher()
redis = Redis.from_url("redis://localhost:6379")
@dp.message(Command("start"))
async def cmd_start(msg: types.Message):
await msg.answer("Привет. Задавайте вопросы по нашим документам — отвечу за 5–30 секунд.")
@dp.message()
async def handle_msg(msg: types.Message):
user_id = msg.from_user.id
if not await is_user_allowed(user_id):
return await msg.answer("Доступ ограничен. Обратитесь к администратору.")
job_id = str(uuid.uuid4())
await redis.lpush("llm_jobs", json.dumps({
"job_id": job_id,
"user_id": user_id,
"chat_id": msg.chat.id,
"text": msg.text,
"history_window": 10,
}))
await msg.answer("⏳ Думаю...")
# worker.py — забирает задачи, дёргает LLM, отправляет ответ
import httpx, asyncio
from redis.asyncio import Redis
async def worker():
redis = Redis.from_url("redis://localhost:6379")
bot = Bot(token=TG_TOKEN)
while True:
_, raw = await redis.brpop("llm_jobs")
job = json.loads(raw)
history = await get_history(job["user_id"])
rag_chunks = await retrieve(job["text"], top_k=5)
prompt = build_prompt(job["text"], history, rag_chunks)
async with httpx.AsyncClient(timeout=60) as client:
r = await client.post("http://vllm:8000/v1/chat/completions", json={
"model": "qwen3-32b-instruct",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.3,
})
answer = r.json()["choices"][0]["message"]["content"]
await save_history(job["user_id"], job["text"], answer)
await bot.send_message(job["chat_id"], answer)
asyncio.run(worker())
Это упрощено — production-код добавит retry, error handling, метрики, health-checks.
RAG по корпусу
Чтобы бот отвечал по вашим документам (регламенты, инструкции, договоры), а не из базовых знаний LLM, нужен RAG-слой:
- Индексация: документы → парсинг (vision LLM для PDF) → чанки → эмбеддинги (BGE-M3 / E5 для русского) → Qdrant
- Retrieval: вопрос пользователя → эмбеддинг → top-K похожих чанков из Qdrant
- Reranking: bge-reranker-v2-m3 сортирует top-K по релевантности
- Generation: LLM получает вопрос + top-3 чанка как контекст, генерирует ответ
Подробно про архитектуру: AI-помощник на корпоративной базе знаний, RAG простыми словами.
Изоляция тенантов и прав доступа
Часто у разных сотрудников разные права на разные документы. HR не должен видеть финдиректорские документы. В боте это реализуется через:
1. Per-user filtering на retrieval. В Qdrant у каждого чанка проставлен acl_tag (например, “hr-public”, “fin-restricted”, “all”). При запросе фильтр acl_tag IN [user_tags] отсекает то что нельзя.
2. ACL в Postgres. Связка tg_user_id → user_email → groups → allowed_acl_tags.
3. Audit-log каждого запроса. Куда LLM сходил, какие чанки получил, что ответил. Хранить минимум 90 дней.
Что НЕЛЬЗЯ делать: доверять LLM фильтрацию («не показывай это пользователю») через промпт. Промпт-инъекция обходит за минуту. Фильтр на уровне retrieval, до LLM.
Безопасность бота
Дополнительные меры специфично для Telegram:
1. Whitelist пользователей. В корпоративном боте регистрируемся через /start CODE где CODE выдаётся HR через корп-чат. Иначе посторонние из контактов сотрудника утекут в бот.
2. Rate-limit per user. 10 запросов в минуту, 100 в час. Защита от прок-атаки и от того что сотрудник по ошибке зацикливает запросы.
3. Пин-нить версию модели. Если сегодня перешли на новую версию Qwen 3 — пользователи увидят разное поведение, могут пожаловаться. Релизьте через A/B группы.
4. Удаление по запросу. Право пользователя стереть свою историю диалогов (152-ФЗ + просто здравый смысл).
5. Не логировать контент сообщений в общий лог. ID и метаданные — да, тексты — отдельный шифрованный store или ничего вовсе.
Какую LLM выбрать для Telegram-бота?
Зависит от задач и железа:
| Модель | Память | Подходит для |
|---|---|---|
| Qwen 3 8B Instruct | 16 GB VRAM | Простые Q&A, FAQ-бот |
| Qwen 3 32B Instruct | 40 GB VRAM | Универсальный корпоративный бот |
| Llama 3.3 70B | 80 GB VRAM (Q4) | Тяжёлая аналитика, длинный контекст |
| DeepSeek R1 671B | 400+ GB unified memory | Топовое качество reasoning |
| GigaChat Pro / YandexGPT 4 | API only | Если нужна российская SaaS-LLM (но без локального хостинга) |
Сравнение для русского: DeepSeek vs Qwen vs Llama benchmark, GigaChat vs YandexGPT vs Llama self-hosted.
Дефолт для команды 30–100 человек: Qwen 3 32B на одной H100 80GB или Llama 3.3 70B на 2× RTX 4090 или DGX Spark / Mac Studio M3 Ultra.
Цены
Минимальный bot-сервер (Qwen 3 8B + RAG для команды 20 человек):
- 1× RTX 3090 / 4090, 64 GB RAM, 1 TB SSD: 200–350 тыс. ₽
- Внедрение: 400–700 тыс. ₽
- TCO: 30–50 тыс. ₽ / месяц
- Окупается ~12 месяцев против ChatGPT Enterprise на той же команде
Production bot (Qwen 3 32B + RAG для команды 50–100):
- DGX Spark / Mac Studio M3 Ultra: 600 тыс. – 1.4 млн ₽
- Внедрение: 1–2 млн ₽
- TCO: 80–150 тыс. ₽ / месяц
- Окупается 9–14 месяцев
Связано: сколько стоит свой ChatGPT на 30 человек, сколько стоит AI-сервер.
Подводные камни
1. Длинный ответ vs Telegram-лимит. Сообщение в Telegram — 4096 символов. Если LLM генерит длинно — нужно автоматически разбивать на части.
2. Markdown в Telegram. Telegram парсит Markdown по своим правилам (MarkdownV2). LLM генерит стандартный — ломается. Решение: post-processing или parse_mode=None.
3. Эмодзи в кириллице. Старые библиотеки иногда ломают эмодзи или кириллицу — проверьте на тестах.
4. Webhook vs long polling. Production — webhook (TLS-сертификат, домен). Long polling — для прототипа, не масштабируется.
5. Истории диалогов растут. Если хранить контекст за месяц — попадает в LLM 50k токенов и больше. Резюмируйте старые сообщения, держите окно 10–20 последних.
6. «Бот не отвечает» в чатах. Если бот добавлен в группу — Telegram по умолчанию шлёт ему только сообщения с @username. Включается через BotFather → Group Privacy.
Когда Telegram-бот не ваш ответ
- Нужны сложные UI-компоненты (формы, таблицы) — Telegram это плохо умеет, лучше веб
- Есть compliance-требования к SSO, audit log, retention — Telegram не enterprise-канал
- Аудитория за пределами РФ + нет аналогов — там WhatsApp / Discord / Slack
- Аудитория не использует Telegram (госкомпании, некоторые банки, школы) — будет принудительная установка
Итог
AI-ассистент в Telegram на локальной LLM в 2026 — рабочая архитектура для команд 20–200 человек, особенно где данные нельзя в облако. Простой setup за 4–8 недель, окупается 9–14 месяцев против SaaS.
Главные подводные камни — изоляция тенантов (на retrieval, не в промпте) и устойчивость к нагрузке (очередь обязательна).
В AGmind мы делаем такие боты как часть базовой стандартной поставки — Qwen 3 / Llama / DeepSeek + Qdrant RAG + aiogram + изоляция через ACL. Если задача «корпоративный AI в Telegram без облака» — позвоните на 30-минутный аудит.
Telegram-бот — один из каналов доставки. Читайте корпоративный ИИ-помощник целиком — pillar чтобы понять как Telegram-интерфейс сочетается с RAG, интеграциями и другими каналами в единой системе.
Связанные тексты: AI-агенты для бизнеса, архитектура AI-помощника на базе знаний, DGX Spark setup.