Void APIБаза знанийКак сделать Telegram-бота с нейросетью на Python
Как сделать Telegram-бота с нейросетью на Python
Telegram-бот с нейросетью — один из самых быстрых способов дать команде или клиентам доступ к ИИ. Нужны токен бота, API-ключ и несколько десятков строк на Python. Сложности начинаются потом: история диалогов, расход токенов, доступ посторонних. Соберём рабочего бота и разберём, как подготовить его к реальным пользователям.
Что понадобится
Токен бота: создайте бота через @BotFather командой /newbot и сохраните выданный токен. API-ключ Void API: создайте его в кабинете и пополните баланс. Python 3.10 или новее и две библиотеки: python-telegram-bot и openai.
Оба секрета храните в переменных окружения или файле .env, который не попадает в репозиторий. Утечка токена бота позволяет перехватить бота, утечка API-ключа — тратить ваш баланс.
pip install "python-telegram-bot>=21" openai
export TELEGRAM_TOKEN="..."
export VOID_API_KEY="..."Минимальный бот с историей диалога
Бот хранит последние сообщения каждого чата в памяти и отправляет их в модель вместе с новым вопросом. История ограничена, чтобы стоимость запроса не росла бесконечно. Команда /reset очищает контекст.
Используется асинхронный клиент: пока модель отвечает одному пользователю, бот продолжает принимать сообщения от других.
import os
from collections import defaultdict, deque
from openai import AsyncOpenAI
from telegram import Update
from telegram.constants import ChatAction
from telegram.ext import (Application, CommandHandler, ContextTypes,
MessageHandler, filters)
client = AsyncOpenAI(api_key=os.environ["VOID_API_KEY"],
base_url="https://void-api.tech/v1")
MODEL = "gpt-6-luna"
SYSTEM = "Ты полезный ассистент. Отвечай кратко и по делу на языке пользователя."
ALLOWED = {int(x) for x in os.environ.get("ALLOWED_USERS", "").split(",") if x}
history = defaultdict(lambda: deque(maxlen=12))
async def reset(update: Update, context: ContextTypes.DEFAULT_TYPE):
history[update.effective_chat.id].clear()
await update.message.reply_text("Контекст очищен.")
async def answer(update: Update, context: ContextTypes.DEFAULT_TYPE):
if ALLOWED and update.effective_user.id not in ALLOWED:
return
chat_id = update.effective_chat.id
history[chat_id].append({"role": "user", "content": update.message.text})
await context.bot.send_chat_action(chat_id, ChatAction.TYPING)
try:
response = await client.chat.completions.create(
model=MODEL,
messages=[{"role": "system", "content": SYSTEM}, *history[chat_id]],
max_tokens=1000,
)
text = response.choices[0].message.content or "Пустой ответ."
except Exception:
history[chat_id].pop()
await update.message.reply_text("Модель недоступна, попробуйте позже.")
return
history[chat_id].append({"role": "assistant", "content": text})
for start in range(0, len(text), 4000):
await update.message.reply_text(text[start:start + 4000])
app = Application.builder().token(os.environ["TELEGRAM_TOKEN"]).build()
app.add_handler(CommandHandler("reset", reset))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, answer))
app.run_polling()Что важно в этом коде
Длина сообщения в Telegram ограничена 4096 символами, поэтому длинный ответ режется на части. Разметку Markdown здесь не включаем: ответы модели часто содержат символы, которые Telegram отклоняет как некорректную разметку. Если нужно форматирование, экранируйте текст или конвертируйте его в HTML.
Список ALLOWED_USERS ограничивает доступ. Без него любой, кто найдёт бота, сможет тратить ваш баланс. Свой числовой ID можно узнать, например, временно выведя update.effective_user.id в лог.
История хранится в памяти и пропадает при перезапуске. Для продакшена используйте Redis или базу данных и храните не больше нужного: переписка пользователей — персональные данные.
Какую модель выбрать для бота
Для бота-ассистента важны скорость ответа и цена: пользователь ждёт ответа в чате, а сообщений может быть много. Начните с быстрой недорогой модели и переходите на более сильную для сложных задач: анализа документов, кода, длинных рассуждений.
Модель задаётся одной строкой MODEL, поэтому сравнить несколько вариантов просто. Можно добавить команду для переключения модели, но тогда ограничьте выбор списком, чтобы пользователи не включали самую дорогую модель по умолчанию.
Лимиты и контроль расходов
Каждое сообщение отправляет в модель всю сохранённую историю, поэтому длина истории напрямую влияет на цену. Двенадцать последних сообщений и max_tokens — простой предохранитель. Для публичного бота добавьте дневной лимит сообщений на пользователя.
Создайте для бота отдельный API-ключ: так его расход виден отдельно от других проектов, а при утечке ключ можно отозвать, не затрагивая остальные сервисы.
Запуск на сервере
Для постоянной работы подойдёт небольшой VPS. Режим polling не требует домена и HTTPS: бот сам опрашивает Telegram. Webhook экономнее при большом трафике, но требует публичного HTTPS-адреса.
Запускайте бота как службу systemd или в Docker с автоматическим перезапуском. Секреты передавайте через переменные окружения службы. Логируйте ошибки API, но не пишите в логи полный текст переписки без необходимости.
[Unit]
Description=Telegram AI bot
After=network-online.target
[Service]
WorkingDirectory=/opt/ai-bot
EnvironmentFile=/opt/ai-bot/.env
ExecStart=/opt/ai-bot/venv/bin/python bot.py
Restart=always
User=aibot
[Install]
WantedBy=multi-user.targetПопробуйте GPT и Claude через Void API
Подключайте GPT и Claude к своим приложениям, ботам и ИИ-агентам через Void API — единый OpenAI-совместимый API. Доступ из России без VPN, пополнение по СБП и оплата по фактическому использованию. Выбирайте модель под задачу, сравнивайте цены и начинайте с одного API-ключа.
Вопросы и ответы
Можно ли сделать Telegram-бота с ChatGPT из России?
Да, через OpenAI-совместимый API, доступный из России. В коде меняются только base_url и API-ключ; бот работает с моделями GPT и Claude из каталога.
Сколько стоит содержание бота с нейросетью?
Складывается из стоимости сервера и токенов. Расход токенов зависит от числа сообщений, длины истории и модели. Посчитайте среднюю стоимость сообщения по полю usage и умножьте на ожидаемое количество.
Как сделать, чтобы бот отвечал только мне или команде?
Проверяйте ID пользователя в обработчике сообщений и игнорируйте всех, кто не входит в разрешённый список, как в примере с ALLOWED_USERS.