| # Пакетне тестування генерації правових позицій | |
| ## Опис функціоналу | |
| Нова закладка "📊 Пакетне тестування" дозволяє проводити масове тестування генерації правових позицій із текстів судових рішень, завантажених з CSV файлу. | |
| ## Як користуватися | |
| ### 1. Підготовка CSV файлу | |
| CSV файл повинен містити обов'язкову колонку `text` з текстами судових рішень: | |
| ```csv | |
| id_lp,text | |
| 1,"Текст судового рішення 1..." | |
| 2,"Текст судового рішення 2..." | |
| 3,"Текст судового рішення 3..." | |
| ``` | |
| **Приклади тестових файлів:** | |
| - `test_docs/test_sample.csv` - простий приклад для демонстрації | |
| - `test_docs/df_lp_part_cd_test_29_result.csv` - повний набір тестових даних | |
| ### 2. Використання інтерфейсу | |
| 1. **Відкрийте закладку "📊 Пакетне тестування"** | |
| 2. **Виберіть провайдера та модель LLM:** | |
| - Провайдер AI: OpenAI, Anthropic, Gemini, DeepSeek | |
| - Модель генерації: відповідна модель обраного провайдера | |
| 3. **Налаштуйте паузу між запитами:** | |
| - Використовуйте слайдер "⏱️ Пауза між запитами (секунди)" | |
| - Діапазон: від 0 до 10 секунд | |
| - За замовчуванням: 1 секунда | |
| - Крок: 0.5 секунди | |
| - **Рекомендації:** | |
| - 0-1 сек: для швидкої обробки малих обсягів | |
| - 1-2 сек: оптимально для більшості випадків | |
| - 3-5 сек: для уникнення rate limits при великих обсягах | |
| - 5-10 сек: для консервативної обробки або при обмеженнях API | |
| 4. **Завантажте CSV файл:** | |
| - Натисніть "📁 Завантажте CSV файл з тестовими даними" | |
| - Виберіть ваш CSV файл | |
| - Натисніть "📂 Завантажити CSV файл" | |
| - Перевірте попередній перегляд завантажених даних | |
| 5. **Запустіть пакетне тестування:** | |
| - Натисніть "▶️ Запустити пакетне тестування" | |
| - Слідкуйте за прогресом обробки | |
| - Дочекайтеся завершення | |
| 6. **Завантажте результати:** | |
| - Після завершення з'явиться кнопка "📥 Завантажити результати" | |
| - Файл буде збережено у папці `test_results/` | |
| - Назва файлу містить назву моделі та мітку часу | |
| ### 3. Формат результатів | |
| Результуючий CSV файл містить: | |
| - Всі оригінальні колонки з вхідного файлу | |
| - Нова колонка з назвою моделі (наприклад, `gemini-3.0-flash`, `gpt-4o-mini`, `claude-3-5-sonnet-20241022`) | |
| - У новій колонці - **повний JSON об'єкт** з усіма полями правової позиції | |
| **Приклад результату:** | |
| ```csv | |
| id_lp,text,gemini-3.0-flash | |
| 1,"Текст судового рішення 1...","{""title"": ""Заголовок позиції"", ""text"": ""Текст правової позиції"", ""proceeding"": ""Кримінальне судочинство"", ""category"": ""Категорія""}" | |
| 2,"Текст судового рішення 2...","{""title"": ""Заголовок позиції 2"", ""text"": ""Текст правової позиції 2"", ""proceeding"": ""Цивільне судочинство"", ""category"": ""Категорія 2""}" | |
| ``` | |
| **Структура JSON об'єкту:** | |
| ```json | |
| { | |
| "title": "Заголовок судового рішення", | |
| "text": "Текст короткого змісту позиції суду", | |
| "proceeding": "Тип судочинства", | |
| "category": "Категорія судового рішення" | |
| } | |
| ``` | |
| **Приклад реального результату:** | |
| ```json | |
| { | |
| "title": "Обчислення розміру відшкодування шкоди, заподіяної внаслідок незаконного добування (збирання) або знищення цінних видів водних біоресурсів", | |
| "text": "Обчислення розміру відшкодування шкоди, заподіяної внаслідок незаконного добування (збирання) або знищення цінних видів водних біоресурсів, можливо здійснювати на підставі Такс, затверджених постановою КМУ від 21.11.2011 № 1209, без проведення експертизи.", | |
| "proceeding": "Кримінальне судочинство", | |
| "category": "Встановлення розміру шкоди (стаття 135)" | |
| } | |
| ``` | |
| ### 4. Обробка результатів | |
| Після завантаження CSV файлу з результатами, ви можете: | |
| 1. **Парсити JSON у Python:** | |
| ```python | |
| import pandas as pd | |
| import json | |
| # Завантажити результати | |
| df = pd.read_csv('test_results/batch_test_results_gemini-3.0-flash_20260103_120000.csv') | |
| # Парсити JSON з колонки моделі | |
| df['parsed'] = df['gemini-3.0-flash'].apply(json.loads) | |
| # Витягти окремі поля | |
| df['title'] = df['parsed'].apply(lambda x: x['title']) | |
| df['text'] = df['parsed'].apply(lambda x: x['text']) | |
| df['proceeding'] = df['parsed'].apply(lambda x: x['proceeding']) | |
| df['category'] = df['parsed'].apply(lambda x: x['category']) | |
| ``` | |
| 2. **Експортувати у зручний формат:** | |
| ```python | |
| # Розгорнути JSON в окремі колонки | |
| df_expanded = pd.concat([df.drop(['gemini-3.0-flash', 'parsed'], axis=1), | |
| pd.json_normalize(df['parsed'])], axis=1) | |
| # Зберегти у новий CSV з розгорнутими полями | |
| df_expanded.to_csv('results_expanded.csv', index=False) | |
| ``` | |
| ## Алгоритм роботи | |
| 1. **Завантаження CSV файлу** - система зчитує файл та перевіряє наявність колонки `text` | |
| 2. **Валідація** - перевірка формату та коректності даних | |
| 3. **Пакетна генерація** - для кожного рядка: | |
| - Зчитується текст з колонки `text` | |
| - Виконується генерація правової позиції з використанням `LEGAL_POSITION_PROMPT` | |
| - Повний JSON результат (з усіма полями: title, text, proceeding, category) записується в нову колонку | |
| 4. **Збереження** - результати зберігаються у файл з міткою часу | |
| ## Технічні деталі | |
| ### Використовувані файли та функції | |
| **Основні файли:** | |
| - `interface.py` - інтерфейс користувача (нова закладка) | |
| - `prompts.py` - промпт `LEGAL_POSITION_PROMPT` для генерації | |
| - `main.py` - функція `generate_legal_position()` для генерації | |
| **Нові функції в interface.py:** | |
| ```python | |
| async def load_csv_file(file) -> Tuple[str, Optional[pd.DataFrame]] | |
| """Завантаження та валідація CSV файлу""" | |
| async def process_batch_testing( | |
| df: pd.DataFrame, | |
| provider: str, | |
| model_name: str, | |
| progress=gr.Progress() | |
| ) -> Tuple[str, Optional[str]] | |
| """Пакетна обробка тестових даних""" | |
| ``` | |
| ### Структура директорій | |
| ``` | |
| Legal_Position_2/ | |
| ├── test_docs/ # Тестові CSV файли | |
| │ ├── test_sample.csv | |
| │ └── df_lp_part_cd_test_29_result.csv | |
| ├── test_results/ # Результати пакетного тестування | |
| │ └── batch_test_results_<model>_<timestamp>.csv | |
| ├── interface.py # Інтерфейс з новою закладкою | |
| ├── prompts.py # Промпти для генерації | |
| └── main.py # Основна логіка генерації | |
| ``` | |
| ## Обробка помилок | |
| Система обробляє наступні випадки: | |
| - Відсутність колонки `text` у CSV файлі | |
| - Помилки кодування (підтримується UTF-8 та CP1251) | |
| - Помилки генерації для окремих рядків (записується текст помилки) | |
| - Помилки збереження результатів | |
| ## Продуктивність | |
| - **Прогрес-бар** - показує поточний стан обробки | |
| - **Послідовна обробка** - рядки обробляються один за одним | |
| - **Пауза між запитами** - налаштовується для уникнення rate limits | |
| - **Час виконання** - залежить від: | |
| - Кількості рядків у CSV файлі | |
| - Швидкості відповіді API провайдера | |
| - Налаштованої паузи між запитами | |
| **Приклад розрахунку часу:** | |
| - 100 рядків × (3 сек на запит + 1 сек пауза) = ~400 секунд (~6.7 хвилин) | |
| - 100 рядків × (3 сек на запит + 0 сек пауза) = ~300 секунд (~5 хвилин) | |
| - 10 рядків × (3 сек на запит + 1 сек пауза) = ~40 секунд | |
| ## Підтримувані провайдери та моделі | |
| - **OpenAI**: GPT-4o, GPT-4o-mini, GPT-4-turbo та інші | |
| - **Anthropic**: Claude 3.5 Sonnet, Claude 3 Opus та інші | |
| - **Gemini**: Gemini 3.0 Flash, Gemini 2.0 Flash та інші | |
| - **DeepSeek**: DeepSeek Chat та інші | |
| ## Приклади використання | |
| ### Приклад 1: Тестування з GPT-4o-mini | |
| 1. Виберіть провайдера: OpenAI | |
| 2. Виберіть модель: gpt-4o-mini | |
| 3. Завантажте файл: `test_docs/test_sample.csv` | |
| 4. Запустіть тестування | |
| 5. Результат: `test_results/batch_test_results_gpt-4o-mini_20260103_115530.csv` | |
| ### Приклад 2: Порівняння моделей | |
| 1. Запустіть тестування з GPT-4o-mini | |
| 2. Завантажте той самий CSV знову | |
| 3. Запустіть тестування з Claude 3.5 Sonnet | |
| 4. Порівняйте результати в обох файлах | |
| ## Rate Limits та рекомендації | |
| ### Обмеження API провайдерів | |
| Різні провайдери мають різні обмеження на кількість запитів: | |
| - **OpenAI:** | |
| - Free tier: ~3 RPM (requests per minute) | |
| - Paid tier: 60-500 RPM залежно від плану | |
| - **Anthropic:** | |
| - Free tier: обмежено | |
| - Paid tier: залежить від підписки | |
| - **Gemini:** | |
| - Free tier: 15 RPM | |
| - Paid tier: вищі ліміти | |
| - **DeepSeek:** | |
| - Залежить від підписки | |
| ### Рекомендовані налаштування паузи | |
| | Кількість рядків | Рекомендована пауза | Причина | | |
| |------------------|---------------------|---------| | |
| | 1-10 | 0.5-1 сек | Швидка обробка, мінімальний ризик | | |
| | 10-50 | 1-2 сек | Баланс між швидкістю та надійністю | | |
| | 50-100 | 2-3 сек | Уникнення rate limits | | |
| | 100+ | 3-5 сек | Консервативний підхід | | |
| **Порада:** Якщо ви отримуєте помилки про перевищення ліміту запитів (rate limit errors), збільште паузу на 1-2 секунди. | |
| ## Додаткова інформація | |
| - Результати не впливають на інші закладки додатку | |
| - Кожен запуск створює новий файл результатів | |
| - Результати зберігаються локально у папці `test_results/` | |
| - Папка `test_results/` додана в `.gitignore` | |
| - Пауза застосовується між запитами, але не після останнього | |
| - При помилці в одному рядку обробка продовжується для наступних | |