Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CODE_WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@
3. `STAGE2.md` - что именно добавил stage 2.
4. `STAGE3.md` - как backend выбирает результат и отбраковывает кандидатов.
5. Этот файл - как код устроен по папкам и строкам.
6. `DESIGN.md` - строгая целевая архитектура.
6. `DESIGN.md` - целевая архитектура и зафиксированные границы.

## 1. Главная хронология программы

Сейчас есть три основные CLI-команды:
Сейчас есть четыре основные CLI-команды и desktop UI:

```bash
python -m source.main validate-stage0
python -m source.main run-model-demo blend_normal
python -m source.main prepare --materials materials --config config/runtime.toml
python -m source.main build-state --dataset data/processed/<dataset_id> --scenario history --as-of 2025-01-15T10:00:00+03:00
python -m source.ui --smoke --scenario blend_risk
```

В хронологическом виде backend делает так:
Expand Down Expand Up @@ -89,8 +90,9 @@ README не должен быть огромным учебником. Его з

### `DESIGN.md`

Самый строгий документ. Если `README.md`, `PROJECT_GUIDE.md` или этот файл
расходятся с `DESIGN.md`, правильным считать `DESIGN.md`.
Самый строгий документ о контрактах и целевой архитектуре. Для списка реально
доступных команд приоритет у `README.md`: дизайн также содержит ещё не реализованные
цели.

### `IMPLEMENTATION_PLAN.md`

Expand Down Expand Up @@ -191,11 +193,11 @@ source_timezone = "Europe/Moscow"
время.

```toml
lims_delay_hours = 6.0
lims_delay_hours = 4.0
```

Лабораторный анализ ЛИМС не доступен мгновенно. Если он измерен в 12:00, backend
считает его доступным только в 18:00 локального времени.
считает его доступным только в 16:00 локального времени.

```toml
horizon_minutes = 60
Expand Down
45 changes: 30 additions & 15 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Технический дизайн системы рекомендаций Нефтекода

Версия контракта: **1.0**. Статус: **спецификация для реализации**.
Версия контракта: **1.0**. Статус: **частично реализованная спецификация**.

Дерево файлов, команды и тесты описывают целевую реализацию.
Документ содержит целевую архитектуру. Актуальный runtime: Stages 0–5 и Tkinter UI
для `model_demo`; исторический ML-артефакт ещё не подключён к UI.

Основания: [техническое задание](materials/ТЗ_нефтекод.docx), [материалы](materials/README.md), [поэтапный план](IMPLEMENTATION_PLAN.md). ТЗ определяет обязательные требования, этот документ — технические контракты, план — порядок реализации. При изменении контракта документ и тестовые примеры обновляются в том же PR.

Expand All @@ -11,10 +12,10 @@
| Вопрос | Решение для версии 1 |
| --- | --- |
| Команда и ресурсы | Два исполнителя (человека или агента): backend и ML; 1–2 недели; CPU; без обязательных платных API |
| Развёртывание | Одно локальное Python-приложение, Python 3.11 |
| Развёртывание | Одно локальное Python-приложение; toolchain нацелен на Python 3.11, локальный Stage-5 artifact собран в Python 3.12.3 |
| Мультиагентность | Агент качества, агент надёжности, агент оптимизации и оркестратор с явными входами и выходами |
| Взаимодействие | Синхронные вызовы Python-функций в одном процессе; структурированные результаты |
| UI | Streamlit; CLI для подготовки, обучения, оценки и воспроизведения |
| UI | Tkinter desktop UI для model-demo; CLI для `prepare`, `build-state` и demo |
| Хранение | Исходные файлы; подготовленные CSV.gz; артефакты модели; JSON/JSONL с результатами |
| Модели | Сохранение последнего значения → Ridge → HistGradientBoostingRegressor; улучшение допускается по результатам временной валидации |
| Оптимизация | Детерминированный ограниченный перебор; жёсткий фильтр перед ранжированием |
Expand Down Expand Up @@ -45,7 +46,7 @@ flowchart TD
Store --> State[Состояние на момент t]
Store --> Train[Офлайн обучение и оценка]
Train --> Model[Модель и metadata]
UI[Streamlit или CLI] --> Orch[Оркестратор]
UI[Tkinter UI или CLI] --> Orch[Оркестратор]
State --> Orch
Model --> Quality[Агент качества]
Orch --> Quality
Expand All @@ -69,7 +70,7 @@ flowchart TD
- `config.py` зависит только от контрактов и стандартного чтения TOML/JSON.
- `data/*` и `ml/features.py` не импортируют UI, оркестратор или оптимизатор.
- `ml/train.py` и `ml/evaluate.py` используются только офлайн; при открытии UI они не импортируются.
- `agents/*` используют контракты, признаки и численные модели, но не Streamlit и не журнал.
- `agents/*` используют контракты, признаки и численные модели, но не UI и не журнал.
- `constraints.py` — единственная реализация жёстких проверок; его вызывают оптимизатор и оркестратор.
- `orchestrator.py` координирует расчёт, не содержит формул обучения и смешения.
- `main.py` и `ui.py` собирают зависимости явно и вызывают общий `run_cycle`; DI-контейнер не нужен.
Expand Down Expand Up @@ -98,7 +99,7 @@ HackathonPetrolCode/
├── source/
│ ├── __init__.py
│ ├── main.py # CLI и сборка зависимостей
│ ├── ui.py # Streamlit; представление результатов
│ ├── ui.py # Tkinter; model-demo и диагностические команды
│ ├── contracts.py # Pydantic-типы обмена
│ ├── config.py # чтение и валидация настроек
│ ├── constraints.py # единый фильтр допустимости
Expand Down Expand Up @@ -430,9 +431,10 @@ sequenceDiagram

Партия — 100 т; горизонт — 60 минут. Выпуск модели — масса партии за горизонт, одинаковая для всех рецептур. Критерий риска — взвешенный индекс компонентов. Генерируются доли B от 0 до 1 с шагом 0.05; доля A равна `1-B`. Проверки доступности и качества отбрасывают неподходящие варианты. Добавляется отдельный `hold`, дубликаты рецептуры схлопываются в пользу `hold`.

- `blend_normal`: исходная рецептура A=0.9, B=0.1. Сера 8.4; верхняя граница 9.4 мг/кг. Результат — `hold`.
- `blend_risk`: A=0.7, B=0.3. Сера 13.2; верхняя граница 14.2 мг/кг. Результат — A=0.9, B=0.1: это наиболее дешёвая допустимая рецептура на данной сетке.
- `blend_missing`: исходная рецептура как у риска, но сера/граница A отсутствуют. Все потенциально пригодные рецептуры требуют A; результат — `abstain` с объяснением отсутствующих данных.
- Все demo-рецептуры рассчитывают серу и запас компонентов, но не имеют оценки T95 и
цетанового числа. Поэтому центральный цикл фиксирует кандидатов и верхнюю оценку серы,
но возвращает `abstain` без операторской рекомендации до появления обеих обязательных
оценок.

Для уставок после их подтверждения — до трёх параметров, до пяти значений каждого вокруг текущего режима, не больше 125 комбинаций плюс `hold`. При превышении бюджета запуск останавливается с понятной ошибкой, не обрезает пространство скрыто. Реальные шаги и границы фиксируются после анализа источников, без выдуманных температур и давлений в этом документе.

Expand All @@ -446,7 +448,9 @@ sequenceDiagram
| --- | --- |
| `MISSING_REQUIRED_SIGNAL`, `STALE_REQUIRED_SIGNAL` | `abstain`, список входов и их возраст |
| `SOURCE_CONFLICT`, `UNIT_UNCONFIRMED`, `TAG_UNCONFIRMED` | Блокирование зависящего расчёта; при обязательности — `abstain` |
| `UNIT_MISMATCH`, `UNASSESSED_REQUIRED_PROPERTY` | `unknown`/`abstain`; численное сравнение или операторское действие запрещено |
| `ACTION_MODEL_UNAVAILABLE`, `OUT_OF_DOMAIN` | Прогноз состояния можно показать, рекомендация изменения блокируется |
| `NON_FINITE_ACTION_FORECAST`, `ACTION_EFFECT_METRICS_NON_FINITE` | Action-кандидат или evidence отклоняется fail-closed |
| `QUALITY_LIMIT`, `CONTROL_LIMIT`, `BLEND_SUM`, `COMPONENT_STOCK` | Кандидат отклоняется с actual/limit |
| `UNCERTAINTY_UNAVAILABLE`, `RELIABILITY_UNAVAILABLE` | `unknown` по обязательной проверке |
| `NO_FEASIBLE_CANDIDATE` | `abstain` и сводка причин отбраковки |
Expand Down Expand Up @@ -489,21 +493,32 @@ Metadata обязательно содержит: `model_id`, `schema_version`,

## 12. Интерфейс и команды запуска

### Экран Streamlit
### Текущий desktop UI и целевой экран

Сейчас `source/ui.py` — локальное Tkinter-приложение. Оно запускает только
`model_demo`, отображает checks и журнал, а также вызывает `prepare` и `build-state`
как диагностические операции. Оно не загружает `ModelBundle` и не выполняет historical
forecast.

Целевой экран должен поддерживать:

1. Выбор режима, сценария, времени истории и совместимой модели; кнопка «Рассчитать».
2. Состояние: измерения, единицы, источник и возраст; отдельные блоки АВТ, гидроочистки и смеси.
3. Качество и риск: факт, прогноз, граница, применимость и конкретные предупреждения.
4. Итог: статус, текущее → рекомендуемое значение, ожидаемый эффект, проверенные ограничения.
5. Альтернативы и полный след взаимодействия агентов; возможность скачать результат.

Streamlit rerun сам по себе не запускает новый цикл и не создаёт новые журналы. Расчёт вызывается кнопкой; последний результат хранится в session state. Сохранённые модели и подготовленные данные кэшируются по идентификаторам/хешам. UI не меняет значения, выбранные оптимизатором, и не округляет числа перед проверками.
Расчёт запускается только явным действием пользователя; UI не меняет значения,
выбранные оптимизатором, и не округляет числа перед проверками. При будущей загрузке
моделей prepared data и artifacts кэшируются только по идентификаторам и хешам.

Модельный режим и неполнота проверенной спецификации всегда видны рядом с рекомендацией. Экран ошибки выполнения отличается от технологического отказа.

### Целевые команды после реализации
### Реализованные и целевые команды

Команды выполняются из корня репозитория после активации Python 3.11 окружения. Они ещё не реализованы на момент принятия дизайна.
Команды выполняются из корня репозитория после активации совместимого окружения.
Сейчас реализованы `validate-stage0`, `run-model-demo`, `prepare`, `build-state` и
`python -m source.ui`; `train`, `evaluate` и `replay` ниже остаются целевыми CLI.

```bash
python -m pip install -r requirements.txt
Expand All @@ -513,7 +528,7 @@ python -m source.main train --dataset data/processed/<dataset_id> --config confi
python -m source.main evaluate --dataset data/processed/<dataset_id> --model artifacts/models/<model_id> --split test
python -m source.main replay --dataset data/processed/<dataset_id> --model artifacts/models/<model_id> --scenario config/scenarios/history.json --at 2026-01-15T12:00:00+03:00
python -m source.main demo --scenario config/scenarios/blend_risk.json
python -m streamlit run source/ui.py
python -m source.ui
python -m pytest
python -m ruff check .
python -m ruff format --check .
Expand Down
Loading
Loading