- Python 80.1%
- TypeScript 15%
- HTML 4.1%
- CSS 0.4%
- Dockerfile 0.1%
- Other 0.1%
| .forgejo/workflows | ||
| .opencode/rules | ||
| alembic_migrations | ||
| app | ||
| config | ||
| docs | ||
| frontend | ||
| grafana | ||
| scripts | ||
| templates | ||
| tests | ||
| tools | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| AGENTS.md | ||
| alembic.ini | ||
| ARCHITECTURE.md | ||
| ARCHITECTURE_DECISIONS.md | ||
| DEVELOPER_GUIDE.md | ||
| docker-compose.dev.yml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| Dockerfile.app | ||
| Dockerfile.bot | ||
| Dockerfile.postgres | ||
| Dockerfile.worker | ||
| FUTURE_PLANS.md | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| requirements-app.txt | ||
| requirements-bot.txt | ||
| requirements-export.txt | ||
| requirements-worker.txt | ||
| REQUIREMENTS.md | ||
| sample.csv | ||
| TECH_STACK.md | ||
Insomnia Feedback Analysis System (IFAS)
Система анализа отзывов с фестиваля анимации "Бессонница".
Возможности
- Загрузка CSV файлов — массовый импорт отзывов через админку
- Многоэтапная обработка — Stage 1 (чанкинг) + Stage 2 (детальный анализ)
- Анализ тональности и тематики — автоматическое разбиение на чанки с LLM
- Векторный поиск — pgvector HNSW индексирование для RAG
- Telegram бот — вопросы организаторов к базе отзывов
- Web-админка — управление данными, просмотр тем, вопросы пользователей
- Кэширование вопросов — семантический поиск похожих чанков
- Prometheus метрики — мониторинг LLM запросов и БД операций
- Многоэтапная обработка — конфигурируемые этапы с флагами включения
- Retry механизм — повтор второго этапа для неудачных обработок
- Безопасный вывод в Telegram — автоматическое экранирование HTML-тегов в пользовательском тексте
- Поиск чанков — гибридный поиск с фильтрами и контекстным просмотром
- Просмотр отзыва — детальная страница с мета-информацией, ответами, контекстной подсветкой чанков
Быстрый старт
Требования
- Python 3.13+
- PostgreSQL 15+ с расширением pgvector (0.8+)
- Redis
- OpenRouter API ключ
- Telegram бот токен (опционально)
Установка
- Клонировать репозиторий:
git clone <repo-url>
cd ifas
- Создать
.envфайл:
cp .env.example .env
# Отредактировать .env с вашими настройками
- Запустить dev-окружение:
# Сборка (первая — скачает модель ~1.5 ГБ для ONNX-реранкера, 2-5 мин)
make dev-build
# Запуск
make dev-up
# или: docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
- Применить миграции:
docker compose -f docker-compose.yml -f docker-compose.dev.yml exec app alembic upgrade head
Доступные сервисы
После запуска dev-окружения:
- Фронтенд (React SPA):
http://localhost:3000 - Админка (React SPA):
http://localhost:3000/admin - Backend JSON API:
http://localhost:8000/api/admin - Public JSON API:
http://localhost:8000/api - Swagger:
http://localhost:8000/docs - PostgreSQL (dev):
localhost:5433 - Redis:
localhost:6379
Production (с Traefik)
См. документацию docs/deployment/traefik.md:
cp docs/deployment/docker-compose.prod.example.yml docker-compose.prod.yml
# Отредактировать docker-compose.prod.yml — указать свой домен
make prod-up
Архитектура фронтенда
- React 19 (сборка через Vite)
- TanStack Query — управление состоянием и кэширование API
- Tailwind CSS — стилизация
- Nginx — раздача статики
- Dev:
nginx.dev.conf— проксирует/api/*на бэкенд (app:8000) - Prod:
nginx.prod.conf— только статика,/api/*проксирует Traefik
- Dev:
Страницы фронтенда
/feedbacks— список отзывов с фильтрами (год, типы чанков)/feedback/:id— детальный просмотр отзыва с чанками/search— поиск чанков по тексту с фильтрами и контекстной подсветкой- Параметр
auto_cutoff=trueдля автоматического отсечения по knee point
- Параметр
/topics— облако тем с визуализацией, фильтрами и drill-down на поиск
Запуск в режиме разработки
cd frontend
npm install
npm run dev
# Фронтенд доступен на http://localhost:5173
API фильтры
Поддерживаются множественные типы фильтров:
GET /api/feedbacks?type=personal&type=praise&type=problem
GET /api/feedbacks?year=2025&type=solution
Поддерживается фильтрация по году:
GET /api/feedbacks?year=2025
Ручная установка
- Установить зависимости:
pip install -e ".[dev]"
- Настроить базу данных:
# Создать базу данных с pgvector
psql -U postgres -c "CREATE DATABASE ifas;"
psql -U postgres -d ifas -c "CREATE EXTENSION vector;"
- Запустить миграции:
alembic upgrade head
- Запустить приложение:
# Запуск FastAPI
uvicorn app.core.main:app --host 0.0.0.0 --port 8000
# Запуск Celery worker (в отдельном терминале)
celery -A app.workers.celery worker --loglevel=info
# Запуск Telegram бота (в отдельном терминале)
python -m app.bot.main
Использование
Telegram бот
/help — показать справку
/sources — показать источники последнего ответа
/feedback_<id> — показать полный отзыв по ID
/topics — все темы с разбивкой по типам
/topic_praise — темы из похвалы с сентиментом
/topic_problems — темы из проблем с сентиментом
/topic_proposals — темы из предложений
/topic_solutions — темы из решений
/topic_personal — темы из личного
/topic <название> — детали конкретной темы
Просто задайте вопрос о отзывах — бот ответит используя RAG.
Web-админка (React SPA)
- URL:
http://localhost:3000/admin - Вход: JWT-токен из переменной
ADMIN_PASSWORDв.env - Возможности:
- Дашборд с карточками навигации
- Загрузка CSV файлов с отзывами
- Просмотр и удаление отзывов с чанками
- Переразбиение чанков (
/api/admin/feedbacks/{id}/rechunk) - Повтор второго этапа (
/api/admin/feedbacks/{id}/retry-stage2) - Статистика по батчам и LLM-запросам
- Просмотр тем с фильтрацией по типу
- Управление вопросами пользователей
- Live Prometheus метрики (авто-обновление каждые 10 с)
REST API (для фронтенда)
- URL:
http://localhost:8000/api - Эндпоинты:
GET /api/feedbacks— список отзывов (пагинация, фильтры по year, type)GET /api/feedbacks/{id}— детали отзыва с ответами и чанкамиGET /api/topics/cloud— данные для облака тем
- Примеры:
# Список отзывов с пагинацией GET /api/feedbacks?page=1&per_page=10 # Фильтр по году GET /api/feedbacks?year=2025 # Множественные типы GET /api/feedbacks?type=personal&type=praise # Детали отзыва GET /api/feedbacks/123
Многоэтапная обработка отзывов
Система использует два этапа обработки отзывов:
Этап 1: Базовое чанкирование
- Модель:
deepseek/deepseek-v4-flash - Задачи:
- Разбиение ответов на смысловые чанки
- Определение тональности каждого чанка
- Извлечение тем (до 3 на чанк)
- Определение
is_detailedдля каждого ответа
Этап 2: Детальный анализ
- Модель:
deepseek/deepseek-v4-flash - Задачи (только для ответов с
is_detailed=true):- Создание заголовков для развёрнутых ответов
- Извлечение подробно раскрытых тем
- Определение главных тем всего отзыва
- Определение стиля написания
- Общая тональность отзыва
Конфигурация этапов
В config/settings.yaml:
processing:
stage1_enabled: true
stage2_enabled: true
stage1_model: "deepseek/deepseek-v4-flash"
stage2_model: "deepseek/deepseek-v4-flash"
stage1_temperature: 0.3
stage2_temperature: 0.5
Флаги позволяют отключать этапы для экономии токенов при отладке.
Отслеживание состояния
Поле processing_stage в таблице feedbacks:
stage1— первый этап выполненstage2— второй этап выполненcompleted— обработка завершена
Retry механизм
Если второй этап не выполнился, можно запустить его повторно:
curl -X POST http://localhost:8000/api/admin/feedbacks/123/retry-stage2
Это запустит Stage 2 напрямую (без сброса на Stage 1).
Debug режим
При включенном LLM_DEBUG=true сохраняются все промпты и ответы LLM:
debug/
├── stage1/
│ ├── prompt_0001_*.json
│ ├── response_0001_*.json
│ ├── reasoning_0001_*.json
│ └── full_0001_*.json
├── stage2/
│ └── ...
└── stats_*.json
Структура проекта
ifas/
├── app/
│ ├── api/ # FastAPI эндпоинты (admin_api, admin [legacy], metrics, feedback)
│ ├── bot/ # Telegram бот (aiogram 3.x)
│ ├── core/ # Конфигурация, логирование, main
│ ├── db/ # Модели, репозитории, миграции
│ ├── events/ # Domain events для async embeddings
│ ├── llm/ # LLM провайдеры (OpenRouter/DeepSeek)
│ ├── services/ # Бизнес-логика (chunking, rag, embeddings, reranker)
│ ├── utils/ # Утилиты (retry, colors, llm)
│ └── workers/ # Celery задачи
├── config/ # YAML конфигурации
│ ├── settings.yaml
│ ├── prompts.yaml
│ └── error_messages.yaml
├── frontend/ # React приложение
│ ├── src/
│ │ ├── components/ # FeedbackCard, FeedbackList
│ │ └── pages/ # Home, Detail
│ ├── nginx.conf # Проксирование /api на бэкенд
│ └── Dockerfile # Многостадийная сборка
├── templates/ # Jinja2 шаблоны (legacy — не используются)
├── tests/ # Тесты (590+ unit тестов)
├── alembic_migrations/ # Миграции БД
├── docker-compose.yml
└── pyproject.toml
Разработка
Инструменты сравнения поиска
Скрипт tools/compare_search_methods.py позволяет сравнивать качество и скорость различных методов поиска:
vector_only— только векторный поиск (pgvector)bm25_only— только полнотекстовый поиск (BM25)hybrid— гибридный поиск с RRF (Reciprocal Rank Fusion)hybrid_rerank— гибридный поиск + реранкинг (Qwen3Reranker)
Пример использования:
python tools/compare_search_methods.py --query "атмосфера на фестивале" --methods vector_only,bm25_only
Подробное описание см. в .opencode/rules/tools.md.
Тесты
# Все тесты
pytest tests/ -v
# С покрытием
pytest --cov=app --cov-report=term-missing
Linting
# Ruff - проверка
ruff check app/ tests/
# Ruff - форматирование
ruff format .
# MyPy
mypy app/
# Конкретная команда запуска тестов (без external, без integration):
python -m pytest tests/unit/ --ignore=tests/unit/test_compare_search_methods.py -v --tb=short -m "not external"
Pre-commit
pre-commit install
pre-commit run --all-files
Мониторинг
Prometheus метрики
/metrics— эндпоинт для Prometheusifas_llm_requests_total— счётчик LLM запросов (с лейбломtype: stage1/stage2/chat/embedding)ifas_llm_request_duration_seconds— гистограмма длительности LLM запросовifas_llm_tokens_prompt_total/ifas_llm_tokens_completion_total— счётчики токеновifas_llm_tokens_reasoning_total— reasoning токены (R1 модели)ifas_llm_cost_total— стоимость LLM запросов в USDifas_celery_task_total— счётчик задач Celery (с лейбламиtask_name,status)ifas_database_query_duration_seconds— гистограмма запросов к БДifas_app_info— информация о приложении (версия)ifas_feedbacks_processed_total— всего обработано отзывовifas_chunks_created_total— всего создано чанковifas_topics_total— количество уникальных темifas_rag_requests_total— всего RAG запросовifas_rag_request_duration_seconds— гистограмма длительности RAG запросовifas_database_errors_total— ошибки БДifas_errors_total— общее количество ошибокifas_celery_queue_length— длина очереди Celery (gauge)ifas_db_pool_active_connections— активные соединения БД (gauge)ifas_batch_buffer_size— размер буфера батчей (gauge)
Live JSON-метрики для дашборда: GET /api/admin/metrics (JWT-авторизация).
Health check
/health— проверка состояния приложения и БД
Лицензия
MIT