Чтобы создать Telegram-бота с помощью ИИ, попросите кодового агента (Claude Code, Codex или похожего) написать бота на python-telegram-bot, положите токен в файл .env и сначала запустите его у себя на машине через polling. Затем добавьте команды, хранимое состояние, ответы на базе LLM и, наконец, запустите бота на сервере круглосуточно.
В руководстве мы проходим весь путь для Telegram, а затем показываем, как адаптировать того же бота для Discord. К каждому шагу приложен промпт, который можно вставить в агента.
Что мы создаём
Наш пример бота будет:
- отвечать на
/startи/help; - сохранять заметки командой
/note <text>и показывать их через/notes(хранимое состояние); - отвечать на обычные сообщения с помощью LLM, с дневным лимитом на пользователя;
- при желании общаться только с разрешёнными вами пользователями;
- работать непрерывно на сервере под systemd или в Docker.
Это хороший первый проект для vibe coding: он небольшой, результат сразу виден на телефоне, и бот действительно полезен.
Выбор стека: Python или TypeScript?
Два хороших варианта:
- Python + python-telegram-bot: зрелая, хорошо документированная асинхронная библиотека. Естественный выбор, если ваш код для ИИ, данных или автоматизации написан на Python.
- TypeScript + grammY: современная, типизированная и лёгкая библиотека, удобная для webhook на serverless-платформах. Выбирайте её, если вы уже живёте в Node.js.
Здесь я использую Python; замените название библиотеки в промптах, и те же шаги подойдут для grammY.
Подготовка:
mkdir telegram-bot && cd telegram-bot
git init
python3 -m venv .venv && source .venv/bin/activate
pip install python-telegram-bot python-dotenv anthropic
printf ".env\n.venv/\n*.db\n" >> .gitignore
В качестве примера LLM я беру Anthropic SDK; с другим провайдером замените пакет, идея та же.
Шаг 1: получите токен и положите его в .env
Токен выдаёт официальный процесс создания ботов в Telegram: вы создаёте нового бота внутри Telegram, выбираете отображаемое имя и уникальный username, оканчивающийся на «bot», и в конце получаете длинный токен. Этот токен — пароль бота; любой, у кого он есть, может отправлять сообщения от имени вашего бота.
Файл .env:
TELEGRAM_TOKEN=your-token
LLM_API_KEY=your-api-key
LLM_MODEL=the-model-you-use
ALLOWED_USER_IDS=123456789
DAILY_LLM_LIMIT=30
Не вставляйте токен и API-ключ в чат с агентом. Ему не нужны сами значения, достаточно знать, что они берутся из .env. Если токен когда-нибудь утечёт, отзовите его в том же официальном процессе и получите новый.
Шаг 2: первый промпт
Откройте агента в папке проекта и попросите самого простого работающего бота:
Set up a simple Telegram bot with python-telegram-bot (async, ApplicationBuilder).
- Read the token from .env with python-dotenv. Never open or print .env.
- Layout: bot.py (startup and handler registration), handlers.py (commands),
storage.py (SQLite later), config.py.
- Add /start and /help; /help lists all commands.
- Reply politely to unknown commands.
- Use polling. Use Python logging; never log the token.
- Add an error handler: log the error and send the user a short apology.
When done, tell me how to run it.
Запустите:
python bot.py
Найдите своего бота в Telegram и отправьте /start. Если он ответил, первый цикл готов. Если нет, вставьте ошибку из терминала агенту как есть; обычно дело в переменной окружения, которая не прочиталась.
Шаг 3: команды и хранимое состояние
Большинству ботов нужно что-то помнить: настройки пользователей, заметки, счётчики использования. Всё, что лежит в памяти, пропадает при перезапуске бота. Для небольшого бота SQLite более чем достаточно, и не нужно запускать сервер базы данных.
Add SQLite to storage.py (data/bot.db).
- notes table: id, user_id, text, created_at.
- usage table: user_id, date, llm_count.
- /note <text> saves a note, /notes lists the user's last 10 notes,
/delete <id> deletes a note only if it belongs to that user.
- All SQL must be parameterized (no string concatenation).
- Write pytest tests for the storage functions and run them.
Условие «только если заметка принадлежит этому пользователю» важно. Агенты часто пропускают такие проверки авторизации, и тогда любой, кто введёт /delete 5, сможет удалить чужую заметку.
У python-telegram-bot есть и собственные механизмы сохранения состояния, например PicklePersistence; они помогают с состоянием диалога (скажем, для многошаговых форм). Для пользовательских данных SQLite, по-моему, прозрачнее.
Шаг 4: умные ответы с LLM
Теперь то, что делает бота ИИ-ботом: отправляем обычные сообщения в LLM и пишем ответ обратно.
# llm.py
import os
from anthropic import AsyncAnthropic
client = AsyncAnthropic(api_key=os.getenv("LLM_API_KEY"))
async def reply(history: list[dict]) -> str:
resp = await client.messages.create(
model=os.getenv("LLM_MODEL"),
max_tokens=500,
system="You are a helpful Telegram assistant who answers briefly.",
messages=history[-10:], # only the last 10 messages
)
return resp.content[0].text
Промпт для агента:
Send plain text messages to reply() in llm.py.
- Keep the last 10 messages per user in memory (alternating user/assistant).
- /reset clears the conversation history.
- Enforce DAILY_LLM_LIMIT per user per day (usage table); when it's reached,
send a clear message.
- If ALLOWED_USER_IDS is not empty, only answer those users.
- Send the "typing..." action while the LLM call runs.
- Split replies longer than Telegram's message length limit.
- On API errors, send the user a short message and log the error.
Зачем лимиты? Публичный бот на LLM, который кто-то найдёт и завалит сообщениями, раздует ваш счёт. Дневной лимит, список разрешённых пользователей и короткая история — три самых простых способа удержать расходы под контролем. Чем длиннее история, тем больше токенов вы отправляете с каждым запросом.
Шаг 5: polling или webhook?
Бот может получать сообщения от Telegram двумя способами:
- Polling (long polling): бот сам постоянно спрашивает Telegram «есть что-нибудь новое?». Настройка нулевая: не нужны HTTPS-адрес, домен и открытый порт. Идеально для разработки и для небольших и средних ботов на одном сервере.
- Webhook: Telegram отправляет каждое новое обновление на указанный вами HTTPS-адрес. Ничего не ждёт в простое, а на serverless-платформах (функции, которые запускаются на каждый запрос) это единственный вариант. Взамен нужен рабочий HTTPS-endpoint, и стоит проверять, что запросы действительно приходят от Telegram, с помощью секретного пути или секретного токена.
Моё правило: начните с polling и переходите на webhook, когда он действительно нужен. Использовать оба способа для одного токена одновременно нельзя; пока установлен webhook, polling не работает.
Шаг 6: круглосуточный запуск на сервере
Когда ноутбук выключается, бот замолкает. Хватит небольшого Linux VPS, а при polling даже домен не нужен.
systemd
# /etc/systemd/system/telegram-bot.service
[Unit]
Description=Telegram bot
After=network-online.target
[Service]
User=bot
WorkingDirectory=/home/bot/telegram-bot
EnvironmentFile=/home/bot/telegram-bot/.env
ExecStart=/home/bot/telegram-bot/.venv/bin/python bot.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
journalctl -u telegram-bot -f
Docker
Попросите агента написать Dockerfile и docker-compose.yml с restart: unless-stopped, env_file: .env и томом для data/. Забудете том, и ваша база SQLite будет стираться при каждом пересоздании контейнера.
Не запускайте одного и того же бота с polling в двух местах (скажем, на ноутбуке и на сервере): Telegram отклонит это ошибкой конфликта. Для разработки заведите отдельного тестового бота с собственным токеном.
Шаг 7: адаптация под Discord
Боты Discord похожи по идее, но есть несколько важных отличий:
- Токен и приложение: вы создаёте приложение в портале разработчиков Discord, добавляете в него бота и берёте токен там. Бота на свой сервер вы добавляете по ссылке-приглашению, в которой запрошен минимум необходимых прав.
- Intents: чтобы читать содержимое сообщений, нужно включить message content intent и в портале, и в коде. Если бот не видит сообщения, почти всегда причина в этом.
- Модель соединения: боты Discord держат постоянное WebSocket-соединение с gateway, поэтому бот должен быть долгоживущим процессом; как serverless-функция он не заработает.
- Команды: современный способ — слэш-команды, и их нужно зарегистрировать в Discord.
- Библиотеки: discord.py для Python, discord.js для Node.js.
Самый чистый подход — отделить логику бота от платформы. Промпт:
Separate the bot logic from the platform:
- core/ holds platform-independent functions: handle_note, list_notes,
ask_llm. They take user_id and text and return text.
- Rewrite telegram_bot.py so its handlers call core/.
- discord_bot.py: /note, /notes and /ask slash commands with discord.py,
all calling core/. DISCORD_TOKEN comes from .env.
- Add a platform column in storage so Discord and Telegram user ids don't mix.
- Keep existing tests passing; extend the tests for core.
Теперь оба бота используют одну базу данных и одну логику LLM, а каждый занимается лишь особенностями своей платформы.
Частые ошибки: в чём ИИ обычно промахивается
- Пишет под старое API. python-telegram-bot перешёл на async в версии 20, а агенты иногда подмешивают старые синхронные примеры. Если вы столкнулись с ошибками, пусть агент проверит установленную версию (
pip show python-telegram-bot) и исправит код по документации именно этой версии. - Зашивает токен в код. Агент может захотеть положить токен в
bot.py«просто чтобы быстро проверить». Откажите. - Нет проверок авторизации. Админские команды оказываются открытыми для всех, или пользователи получают доступ к данным друг друга.
- Блокирующий код.
time.sleepили синхронный HTTP-вызов внутри async-обработчика замораживает всего бота. - Проглоченные ошибки. Без обработчика ошибок бот молча перестаёт отвечать.
- Состояние в памяти. При перезапуске всё сбрасывается.
- Длинные сообщения не разбиваются. Когда LLM пишет длинный ответ, Telegram отклоняет сообщение.
Безопасность
- Токены и API-ключи хранятся только в
.env, а.envесть в.gitignore. - Никогда не вставляйте ключи в чат, скриншот или баг-репорт.
- Читайте команды, которые агент хочет запустить, прежде чем одобрять их, особенно всё, что читает
.envили отправляет данные наружу. - Когда вы передаёте текст пользователя в LLM, исходите из того, что он может попытаться переопределить ваши инструкции (prompt injection). Не давайте боту опасных возможностей вроде запуска команд или удаления файлов.
- Сообщите пользователям, что вы храните их данные и отправляете их провайдеру LLM.
- Не запускайте бота от root на сервере; выполните
chmod 600для env-файла.
Делаем это в AgentVera
Этот проект естественно делится на две параллельные задачи: один агент пишет часть для Telegram, другой — для Discord. В AgentVera можно запустить Claude Code в одном worktree, а Codex в другом, в одной сетке. После каждого хода автоматическое code review поручает второй модели проверить легко упускаемые места, например проверки авторизации. Перед слиянием вы просматриваете изменения в панели Git и видите расход токенов агентов, пока строите функцию LLM. Когда дело доходит до сервера, SSH и SFTP переносят файлы, а менеджер Docker показывает логи контейнера локально.
Ничего из этого не обязательно; терминал и git тоже позволят закончить этого бота. Если вы ищете, чем занять своего бота, хороший пример — уведомления в Telegram из статьи торговый бот для криптовалют с помощью ИИ.
Итоги
Создать Telegram-бота с помощью ИИ — один из самых приятных способов начать vibe coding. Получите токен через официальный процесс и держите его в .env, пусть агент сначала напишет самого простого бота, а затем слой за слоем добавьте команды, состояние в SQLite и ответы LLM. Начните с polling, запустите бота на сервере через systemd или Docker и держите логику отдельно от платформы, чтобы Discord стал лёгким шагом. Проверки авторизации, которые пишет агент, и команды, которые он запускает, читайте сами; остальное агент потянет.