no more forbidden things

This commit is contained in:
Pewter71 2026-05-26 23:43:07 +03:00
parent b6274f7106
commit d037834938
5 changed files with 195 additions and 210 deletions

View file

@ -1,15 +1,14 @@
# Qwen Telegram Bot
# Qwen Console App
Telegram-бот на Python с четырьмя функциями:
Консольное приложение на Python с четырьмя функциями:
- 📷 **описание изображений**присылаешь фото, бот возвращает текстовое описание через vision-модель Qwen
- 📊 **генерация графиков** — по текстовому запросу бот просит LLM написать код на matplotlib, выполняет его и отправляет PNG
- 📷 **описание изображений**указываешь путь к файлу, приложение возвращает текстовое описание через 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
@ -19,11 +18,10 @@ Telegram-бот на Python с четырьмя функциями:
- Python **3.11+**
- установленный `uv` ([инструкция](https://docs.astral.sh/uv/getting-started/installation/))
- **бинарь Graphviz** в `$PATH` (нужен для команды `/arch`):
- **бинарь 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
## Установка
@ -44,57 +42,71 @@ uv sync
cp .env.example .env
```
> ⚠️ Для функции описания изображений модель должна быть **мультимодальной (VL)**. Текстовая модель упадёт при попытке передать ей картинку.
Переменные окружения:
| Переменная | Обязательна | По умолчанию | Описание |
| --------------------- | ----------- | ----------------------------------------- | ------------------------------------------- |
| `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 bot.py
uv run src/app.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`:
| Команда | Что делает |
| ------------------------- | ------------------------------------------------------------- |
| `describe <путь>` | Описать изображение |
| `plot <описание>` | Сгенерировать matplotlib-график → сохраняется в `plot.png` |
| `arch <описание>` | Нарисовать архитектурную схему → сохраняется в `arch.png` |
| `repro <путь>` | Воспроизвести график/схему с картинки → сохраняется в `repro.png` |
| `help` | Показать справку |
| `exit` / `quit` / Ctrl+C | Выйти из приложения |
Примеры для `plot`:
```
/arch React-фронт, FastAPI-бэкенд, Postgres и Redis за nginx
/arch микросервисы: auth, orders, payments. Общаются через RabbitMQ, у каждого своя БД Postgres, Prometheus собирает метрики
/arch телеграм-бот, принимает вебхуки, складывает задачи в очередь Celery с Redis-брокером, воркеры пишут результаты в S3
>>> plot sin(x) и cos(x) на отрезке [0, 2π]
>>> plot затухающая синусоида на [0, 10]
>>> plot столбчатая диаграмма продаж по месяцам с рандомными значениями
>>> plot гистограмма нормального распределения, 1000 сэмплов
```
### Как пользоваться `/repro`
Примеры для `arch`:
Два варианта:
```
>>> arch React-фронт, FastAPI-бэкенд, Postgres и Redis за nginx
>>> arch микросервисы: auth, orders, payments. Общаются через RabbitMQ, у каждого своя БД Postgres, Prometheus собирает метрики
>>> arch телеграм-бот, принимает вебхуки, складывает задачи в очередь Celery с Redis-брокером, воркеры пишут результаты в S3
```
1. **Прикрепить фото с подписью** `/repro` — бот сразу обработает его.
2. **Ответить** `/repro` на сообщение с фото (reply-to-message).
Пример для `repro`:
Бот классифицирует изображение как график (`plot`) либо архитектурную схему (`architecture`), извлекает структуру через vision-модель, генерирует для неё matplotlib-код или DOT и отрисовывает заново. Это не попиксельная копия — это реконструкция: бот старается передать тот же тип графика/те же компоненты и связи, но стиль будет его собственный.
```
>>> repro chart.png
>>> repro /home/user/screenshots/arch_diagram.jpg
```
Результат `repro` — это не попиксельная копия, а реконструкция: приложение старается передать тот же тип графика / те же компоненты и связи, но стиль будет его собственный.
## Структура проекта
```
.
├── bot.py # основной скрипт: конфиг, LLM-клиент, хэндлеры Telegram
├── app.py # основной скрипт: конфиг, LLM-клиент, консольный цикл
├── pyproject.toml # зависимости и метаданные проекта для uv
├── uv.lock # фиксация версий (создаётся после uv sync)
├── .env.example # шаблон переменных окружения
@ -116,7 +128,7 @@ uv run <команда> # выполнить команду в окруж
Архитектурные схемы безопаснее: Graphviz парсит DOT как данные, а не исполняет его как код, поэтому инъекция через промпт там в худшем случае даст кривую или огромную картинку.
Для публичного бота стоит изолировать исполнение `/plot`, например:
Для использования в более критичной среде стоит изолировать исполнение `plot`:
- отдельный воркер-процесс с `resource.setrlimit` (CPU, память, время)
- Docker-контейнер без сети и с read-only FS
@ -125,9 +137,9 @@ uv run <команда> # выполнить команду в окруж
## Возможные улучшения
- webhook вместо polling для продакшена
- очередь задач (arq / Celery) для тяжёлого рендеринга
- история команд (readline / prompt_toolkit)
- автодополнение путей к файлам по Tab
- флаг `--open` для автоматического открытия PNG после генерации
- кэш описаний по хэшу изображения
- вывод сгенерированного кода графика в подписи к картинке (дебаг-режим)
- rate-limiting на пользователя
- вывод сгенерированного кода графика в режиме отладки (`--debug`)
- тесты для `render_plot` с фиксированными промптами