recognition + graphs + schemes

This commit is contained in:
Еленкин Петр 2026-04-22 01:29:23 +03:00
parent f7cf147e86
commit b6274f7106
6 changed files with 1680 additions and 2 deletions

134
README.md
View file

@ -1,3 +1,133 @@
# image_recognition
# 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` с фиксированными промптами