К основному содержимому

AI Telegram-бот на VDS с LangChain и Ollama

AI-агенты на VDS · 19.04.2026 · 3 мин чтения
Иллюстрация к статье «AI Telegram-бот на VDS с LangChain и Ollama»

Обзор

Создадим Telegram-бота с AI-возможностями: он будет помнить контекст разговора, использовать локальную LLM через Ollama и отвечать на вопросы по вашим документам.

Установка зависимостей

pip install python-telegram-bot langchain langchain-ollama
pip install python-dotenv

Структура проекта

tg-ai-bot/
├── bot.py
├── .env
└── requirements.txt

Код бота

>import os
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes
from langchain_ollama import OllamaLLM
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, AIMessage

llm = OllamaLLM(model="llama3.2")
history = {}

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    user_text = update.message.text
    if chat_id not in history:
        history[chat_id] = []
    history[chat_id].append(HumanMessage(content=user_text))
    if len(history[chat_id]) > 20:
        history[chat_id] = history[chat_id][-20:]
    messages = [("system", "Ты полезный ассистент.")]
    for msg in history[chat_id]:
        role = "user" if isinstance(msg, HumanMessage) else "assistant"
        messages.append((role, msg.content))
    prompt = ChatPromptTemplate.from_messages(messages)
    chain = prompt | llm
    response = chain.invoke({})
    history[chat_id].append(AIMessage(content=response))
    await update.message.reply_text(response)

app = Application.builder().token(os.getenv("BOT_TOKEN")).build()
app.add_handler(MessageHandler(filters.TEXT, handle_message))
app.run_polling()

Файл .env

BOT_TOKEN=your_telegram_bot_token_here

Запуск как системная служба

>[Unit]
Description=AI Telegram Bot
After=network.target

[Service]
WorkingDirectory=/home/user/tg-ai-bot
EnvironmentFile=/home/user/tg-ai-bot/.env
ExecStart=/home/user/tg-ai-bot/venv/bin/python bot.py
Restart=always

[Install]
WantedBy=multi-user.target
Получите BOT_TOKEN у @BotFather в Telegram. Создайте нового бота командой /newbot и скопируйте токен.

Частые ошибки

Большинство сбоев Telegram-ботов на python-telegram-bot связано не с LLM, а с самим механизмом получения обновлений от Telegram.

telegram.error.Conflict: terminated by other getUpdates request

Эта ошибка означает, что два экземпляра бота одновременно опрашивают Telegram с одним и тем же токеном — например, старый systemd-процесс не остановился перед запуском нового. Проверьте systemctl status и список процессов (ps aux | grep bot.py) перед повторным запуском.

telegram.error.InvalidToken

Токен из .env не подходит: либо файл не загрузился (проверьте, что python-dotenv действительно вызывается до чтения переменной), либо токен скопирован с лишним пробелом или обрезан. Проверьте значение прямо перед стартом бота, выведя его длину, а не сам токен, в лог.

Long polling против webhook

Параметр Long polling Webhook
Нужен публичный домен с HTTPS Нет Да
Задержка ответа Обычно доли секунды Минимальная, Telegram сам стучится к вам
Сложность настройки на VDS Низкая, достаточно запустить процесс Выше, нужен reverse proxy и сертификат
Подходит для Небольших и средних ботов Высоконагруженных ботов, много обновлений

Когда такой подход не подходит

  • Ожидается высокая нагрузка с тысячами сообщений в минуту — long polling из примера не масштабируется горизонтально без доработки хранения истории.
  • История диалога должна переживать перезапуск процесса — текущая реализация хранит её только в памяти словаря history.
  • Нужна многопользовательская изоляция с разными системными промптами — потребуется отдельное хранилище настроек на chat_id, а не общий системный промпт.
  • Требуется гарантированная доставка сообщений даже при падении процесса — для этого нужна очередь заданий, а не прямой вызов внутри обработчика.

Проверка, что бот отвечает

systemctl status ai-telegram-bot --no-pager
journalctl -u ai-telegram-bot -n 50 --no-pager

Убедитесь, что служба в статусе active (running), а в логе нет повторяющихся ошибок подключения к Ollama. Отправьте боту тестовое сообщение и проверьте, что в логе появляется факт получения апдейта — если апдейт не приходит вовсе, проблема на стороне Telegram API или сетевого доступа с сервера, а не в коде бота.

Стоит также предусмотреть ограничение на длину истории и частоту запросов от одного пользователя: без rate limiting один активный пользователь может отправлять сообщения быстрее, чем локальная модель успевает на них отвечать, и очередь необработанных обновлений будет расти. Простейшая защита — ограничить число одновременных запросов к LLM на один chat_id и вернуть сообщение "подождите предыдущий ответ", если лимит превышен.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке