image_recognition/README.md

133 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Qwen Telegram Bot
Telegram-бот на Python с четырьмя функциями:
- 📷 **описание изображений** — присылаешь фото, бот возвращает текстовое описание через vision-модель Qwen
- 📊 **генерация графиков** — по текстовому запросу бот просит LLM написать код на matplotlib, выполняет его и отправляет PNG
- 🏛 **архитектурные схемы** — по описанию системы LLM генерирует DOT, Graphviz рендерит это в PNG
- ♻️ **воспроизведение с фото** — кидаешь фото графика или архитектурной схемы, бот распознаёт тип, извлекает структуру и отрисовывает заново в своём стиле
## Стек
- [python-telegram-bot](https://docs.python-telegram-bot.org/) — асинхронный клиент Telegram Bot API
- [openai](https://github.com/openai/openai-python) SDK — работа с любым OpenAI-совместимым провайдером (OpenRouter, DashScope, vLLM и др.)
- [matplotlib](https://matplotlib.org/) + numpy — рендеринг графиков
- [Graphviz](https://graphviz.org/) + [python-graphviz](https://github.com/xflr6/graphviz) — рендеринг архитектурных схем из DOT
- [uv](https://docs.astral.sh/uv/) — менеджер пакетов и виртуальных окружений
## Требования
- Python **3.11+**
- установленный `uv` ([инструкция](https://docs.astral.sh/uv/getting-started/installation/))
- **бинарь Graphviz** в `$PATH` (нужен для команды `/arch`):
- Linux: `sudo apt install graphviz`
- macOS: `brew install graphviz`
- Windows: [скачать с graphviz.org](https://graphviz.org/download/)
- токен Telegram-бота от [@BotFather](https://t.me/BotFather)
- API-ключ провайдера, поддерживающего мультимодальную модель Qwen
## Установка
```bash
git clone <https://git.lambda.coredump.ru/BtoB_team/image_recognition.git>
cd image_recognition
# создаёт .venv и ставит зависимости из pyproject.toml + uv.lock
uv sync
```
## Конфигурация
Скопируй шаблон и впиши свои ключи:
```bash
cp .env.example .env
```
> ⚠️ Для функции описания изображений модель должна быть **мультимодальной (VL)**. Текстовая модель упадёт при попытке передать ей картинку.
## Запуск
```bash
uv run bot.py
```
Бот запускается в режиме long-polling и пишет лог в stdout.
## Использование
| Действие | Что делает бот |
| ------------------------------------ | ----------------------------------------------------------- |
| `/start` или `/help` | Показать справку |
| Отправить фото (без подписи-команды) | Вернуть описание изображения |
| `/plot <описание>` | Сгенерировать и прислать matplotlib-график |
| `/arch <описание>` | Нарисовать архитектурную схему через Graphviz |
| `/repro` + фото | Распознать график/схему и отрисовать её заново |
Примеры запросов к `/plot`:
```
/plot sin(x) и cos(x) на отрезке [0, 2π]
/plot затухающая синусоида на [0, 10]
/plot столбчатая диаграмма продаж по месяцам с рандомными значениями
/plot гистограмма нормального распределения, 1000 сэмплов
```
Примеры запросов к `/arch`:
```
/arch React-фронт, FastAPI-бэкенд, Postgres и Redis за nginx
/arch микросервисы: auth, orders, payments. Общаются через RabbitMQ, у каждого своя БД Postgres, Prometheus собирает метрики
/arch телеграм-бот, принимает вебхуки, складывает задачи в очередь Celery с Redis-брокером, воркеры пишут результаты в S3
```
### Как пользоваться `/repro`
Два варианта:
1. **Прикрепить фото с подписью** `/repro` — бот сразу обработает его.
2. **Ответить** `/repro` на сообщение с фото (reply-to-message).
Бот классифицирует изображение как график (`plot`) либо архитектурную схему (`architecture`), извлекает структуру через vision-модель, генерирует для неё matplotlib-код или DOT и отрисовывает заново. Это не попиксельная копия — это реконструкция: бот старается передать тот же тип графика/те же компоненты и связи, но стиль будет его собственный.
## Структура проекта
```
.
├── bot.py # основной скрипт: конфиг, LLM-клиент, хэндлеры Telegram
├── pyproject.toml # зависимости и метаданные проекта для uv
├── uv.lock # фиксация версий (создаётся после uv sync)
├── .env.example # шаблон переменных окружения
└── .env # реальные ключи (в git не коммитить!)
```
## Работа с зависимостями
```bash
uv add <пакет> # добавить зависимость
uv remove <пакет> # убрать зависимость
uv sync # синхронизировать .venv с lock-файлом
uv run <команда> # выполнить команду в окружении проекта
```
## ⚠️ Безопасность
Код для построения графиков **генерируется LLM и исполняется через `exec`** в урезанном неймспейсе (без `import`, без `open`, с ограниченным набором builtins). Этого достаточно для локального использования и dev-стенда, но **это не песочница**.
Архитектурные схемы безопаснее: Graphviz парсит DOT как данные, а не исполняет его как код, поэтому инъекция через промпт там в худшем случае даст кривую или огромную картинку.
Для публичного бота стоит изолировать исполнение `/plot`, например:
- отдельный воркер-процесс с `resource.setrlimit` (CPU, память, время)
- Docker-контейнер без сети и с read-only FS
- [nsjail](https://github.com/google/nsjail) / [firejail](https://firejail.wordpress.com/)
- вместо `exec` — разобрать запрос в ограниченный DSL, а уже его превратить в matplotlib-вызовы детерминированным кодом
## Возможные улучшения
- webhook вместо polling для продакшена
- очередь задач (arq / Celery) для тяжёлого рендеринга
- кэш описаний по хэшу изображения
- вывод сгенерированного кода графика в подписи к картинке (дебаг-режим)
- rate-limiting на пользователя
- тесты для `render_plot` с фиксированными промптами