145 lines
8.7 KiB
Markdown
145 lines
8.7 KiB
Markdown
# Qwen Console App
|
||
|
||
Консольное приложение на Python с четырьмя функциями:
|
||
|
||
- 📷 **описание изображений** — указываешь путь к файлу, приложение возвращает текстовое описание через vision-модель Qwen
|
||
- 📊 **генерация графиков** — по текстовому запросу LLM пишет код на matplotlib, приложение выполняет его и сохраняет PNG
|
||
- 🏛 **архитектурные схемы** — по описанию системы LLM генерирует DOT, Graphviz рендерит это в PNG
|
||
- ♻️ **воспроизведение с фото** — указываешь путь к фото графика или схемы, приложение распознаёт тип и отрисовывает заново
|
||
|
||
## Стек
|
||
|
||
- [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/)
|
||
- 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
|
||
```
|
||
|
||
Переменные окружения:
|
||
|
||
| Переменная | Обязательна | По умолчанию | Описание |
|
||
| --------------------- | ----------- | ----------------------------------------- | ------------------------------------------- |
|
||
| `LLM_API_KEY` | ✅ | — | API-ключ провайдера |
|
||
| `LLM_BASE_URL` | ❌ | `https://llm.lambda.coredump.ru/v1` | Base URL OpenAI-совместимого API |
|
||
| `LLM_MODEL` | ❌ | `qwen3.5-122b` | Имя модели |
|
||
| `LLM_DISABLE_THINKING`| ❌ | `false` | Отключить reasoning (для Qwen3/DeepSeek-R1) |
|
||
|
||
> ⚠️ Для команды `describe` и `repro` модель должна быть **мультимодальной (VL)**. Текстовая модель упадёт при попытке передать ей картинку.
|
||
|
||
## Запуск
|
||
|
||
```bash
|
||
uv run src/app.py
|
||
```
|
||
|
||
Приложение запускается в интерактивном режиме и ждёт команд.
|
||
|
||
## Использование
|
||
|
||
```
|
||
>>> <команда> <аргумент>
|
||
```
|
||
|
||
| Команда | Что делает |
|
||
| ------------------------- | ------------------------------------------------------------- |
|
||
| `describe <путь>` | Описать изображение |
|
||
| `plot <описание>` | Сгенерировать matplotlib-график → сохраняется в `plot.png` |
|
||
| `arch <описание>` | Нарисовать архитектурную схему → сохраняется в `arch.png` |
|
||
| `repro <путь>` | Воспроизвести график/схему с картинки → сохраняется в `repro.png` |
|
||
| `help` | Показать справку |
|
||
| `exit` / `quit` / Ctrl+C | Выйти из приложения |
|
||
|
||
Примеры для `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`:
|
||
|
||
```
|
||
>>> repro chart.png
|
||
>>> repro /home/user/screenshots/arch_diagram.jpg
|
||
```
|
||
|
||
Результат `repro` — это не попиксельная копия, а реконструкция: приложение старается передать тот же тип графика / те же компоненты и связи, но стиль будет его собственный.
|
||
|
||
## Структура проекта
|
||
|
||
```
|
||
.
|
||
├── app.py # основной скрипт: конфиг, LLM-клиент, консольный цикл
|
||
├── 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-вызовы детерминированным кодом
|
||
|
||
## Возможные улучшения
|
||
|
||
- история команд (readline / prompt_toolkit)
|
||
- автодополнение путей к файлам по Tab
|
||
- флаг `--open` для автоматического открытия PNG после генерации
|
||
- кэш описаний по хэшу изображения
|
||
- вывод сгенерированного кода графика в режиме отладки (`--debug`)
|
||
- тесты для `render_plot` с фиксированными промптами
|