Деплой AI-агента в продакшен через Telegram. Пользователь пишет задачу → агент выполняет в Docker-песочнице → присылает результат.
╔══════════════════════════════════════════════════════╗ ║ 📱 Telegram → 🌐 Webhook → 🚀 FastAPI ║ ║ ↓ ║ ║ 🐳 Docker Sandbox (агент) ║ ║ ↓ ║ ║ 📤 Ответ пользователю ║ ╚══════════════════════════════════════════════════════╝ # Поток запроса: # 1. Пользователь пишет задачу в Telegram # 2. Telegram отправляет webhook на наш FastAPI сервер # 3. FastAPI извлекает задачу → запускает Docker контейнер # 4. Код агента выполняется в изолированной песочнице # 5. Результат возвращается через Telegram API
# Установка зависимостей pip install python-telegram-bot fastapi uvicorn from telegram import Update from telegram.ext import Application, CommandHandler, MessageHandler, filters # 1. Регистрация бота через @BotFather → получаем токен TOKEN = "YOUR_BOT_TOKEN" async def start(update: Update, context): await update.message.reply_text( "🤖 Привет! Я AI-агент. Отправь мне задачу, и я выполню её в песочнице." ) async def handle_message(update: Update, context): task = update.message.text user_id = update.effective_user.id await update.message.reply_text( f"🔄 Выполняю задачу: {task[:100]}...") # Здесь будет вызов агента в Docker result = await execute_in_sandbox(task, user_id) await update.message.reply_text(f"✅ Результат:\n{result}") # Сборка приложения app = Application.builder().token(TOKEN).build() app.add_handler(CommandHandler("start", start)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
# Dockerfile для песочницы агента FROM python:3.12-slim # Безопасность: непривилегированный пользователь RUN useradd -m -s /bin/bash sandbox WORKDIR /workspace # Предустановленные инструменты (опционально) RUN pip install --no-cache-dir requests httpx pandas COPY agent_script.py /workspace/run.py USER sandbox CMD ["python", "/workspace/run.py"]
# Python SDK для управления Docker sandbox pip install docker import docker import os client = docker.from_env() async def execute_in_sandbox(task: str, user_id: int) -> str: """Запуск задачи в Docker-контейнере.""" try: container = client.containers.run( image="agent-sandbox:latest", command=["python", "-c", task], mem_limit="512m", # ограничение памяти network_disabled=True, # без сети (безопасность) read_only=True, # read-only файловая система remove=True, # автоудаление после завершения stdout=True, stderr=True, timeout=60 # таймаут 60 сек ) return container.decode('utf-8').strip() or "(нет вывода)" except docker.errors.ContainerError as e: return f"❌ Ошибка выполнения:\n{e.stderr.decode('utf-8')}" except Exception as e: return f"❌ Ошибка: {str(e)}"
# Полный цикл: от получения задачи до ответа async def handle_agent_task(update: Update, context): task = update.message.text user_id = update.effective_user.id # 1. Отправляем статус "печатает" await context.bot.send_chat_action( chat_id=update.effective_chat.id, action="typing" ) # 2. Проверяем лимиты и blacklist if not rate_limiter.is_allowed(user_id): await update.message.reply_text("⏳ Слишком много запросов. Подождите.") return # 3. Запускаем в Docker sandbox result = await execute_in_sandbox(task, user_id) # 4. Обрезаем результат если слишком длинный if len(result) > 4000: result = result[:4000] + "\n... (обрезано)" # 5. Отправляем результат await update.message.reply_text( f"📋 Задача:\n{task}\n\n📤 Результат:\n{result}" )
import time from collections import defaultdict class RateLimiter: """Rate limiting: максимум 5 запросов в минуту.""" def __init__(self, max_requests=5, window=60): self.max_requests = max_requests self.window = window self.history = defaultdict(list) def is_allowed(self, user_id): now = time.time() window_start = now - self.window self.history[user_id] = [ t for t in self.history[user_id] if t > window_start] if len(self.history[user_id]) >= self.max_requests: return False self.history[user_id].append(now) return True # Blacklist опасных паттернов BLOCKED_PATTERNS = [ r"os\.system", r"subprocess", r"eval\s*\(", r"exec\s*\(", r"__import__", r"open\s*\(", r"shutil", r"socket", r"requests\.post", ] def is_safe(code: str) -> bool: import re for pattern in BLOCKED_PATTERNS: if re.search(pattern, code): return False return True
# /etc/systemd/system/telegram-agent.service [Unit] Description=Telegram AI Agent Bot After=docker.service network.target [Service] Type=simple User=agent WorkingDirectory=/opt/telegram-agent ExecStart=/opt/telegram-agent/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
# Запуск и включение сервиса sudo systemctl daemon-reload sudo systemctl enable telegram-agent sudo systemctl start telegram-agent # nginx reverse proxy + SSL sudo apt install nginx certbot python3-certbot-nginx sudo certbot --nginx -d your-domain.com # /etc/nginx/sites-available/telegram-agent server { listen 443 ssl; server_name your-domain.com; location /webhook { proxy_pass http://127.0.0.1:8000/webhook; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } # Установка webhook в Telegram curl -X POST https://api.telegram.org/bot{TOKEN}/setWebhook \ -d "url=https://your-domain.com/webhook"