docs: полный диалог DeepSeek↔Opus по decoupling

This commit is contained in:
2026-06-28 09:16:27 +04:00
parent 15c265ecc3
commit 5fb9156e69
+135
View File
@@ -0,0 +1,135 @@
# Диалог DeepSeek ↔ Opus — Decoupling пайплайна
Дата: 28.06.2026
---
## Запрос DeepSeek (задание)
Файл: `History/opus-decoupling-plan-2026-06-28.md`
5 блоков, интерактивный режим:
1. Модульность пайплайна — контракты между стадиями
2. Интеграционное тестирование (fixture-based)
3. Деплой и синхронизация
4. Перспектива переезда на managed Flask
5. Вопросы к заказчику
---
## Ответ Opus — 5 развилок
### Вопрос 1. Граница decoupling
Варианты:
- A. Единый интерфейс пайплайна (контракт оркестратора)
- B. Изолировать только внешние зависимости (LLM, БД)
- C. И то, и другое
**Рекомендация Opus:** C
### Вопрос 2. База данных в тестах
Варианты:
- A. Абстрагировать репозиторий за интерфейсом → in-memory заглушка
- B. Реальный Postgres в Docker/testcontainers
- C. Гибрид: юнит-тесты на заглушке + интеграционные на Postgres
**Рекомендация Opus:** C
### Вопрос 3. Мокирование LLM
Варианты:
- A. DI — LLM-клиент через зависимость
- B. Мокать на уровне httpx-транспорта
- C. Record/replay — реальные ответы как фикстуры
**Рекомендация Opus:** A + C
### Вопрос 4. Тестовый фреймворк
Варианты:
- A. pytest + папка tests/ + conftest
- B. Только smoke-тесты
- C. Полное покрытие
**Рекомендация Opus:** A → C поэтапно
### Вопрос 5. Деплой
Варианты:
- A. Не трогать, отдельная задача
- B. Заодно привести sync.sh/systemd
- C. Только задокументировать
**Рекомендация Opus:** A
---
## Ответ DeepSeek
**Все 5 рекомендаций — согласен:**
- 1C, 2C, 3A+C, 4A, 5A
Запрос: жду финальный план.
---
## Ответ Opus — Финальный план (5 фаз)
### Фаза 1 — Контракты стадий (1C)
- `deploy/contracts.py` с dataclass'ами: ParseResult, ClassifyResult, GroupingResult, CompareOp
- Разделить стадии на pure-core + HTTP-adapter
- `handle_upload``parse_multipart` + `store_document`
- `parse_file` уже pure (эталон)
- `classify_batch`, `group_documents` принимают `repo` параметром
### Фаза 2 — Изоляция LLM (3A+C)
- `deploy/services/llm_client.py`: протокол `LLMClient.complete(prompt) -> str` + `HttpxLLMClient`
- `call_llm` / `_call_llm_classify` принимают `llm_client` (default `HttpxLLMClient()`)
- `FakeLLMClient` для тестов — сохранённые реальные ответы
- Зависит от Фазы 1
### Фаза 3 — Изоляция БД (2C)
- Тонкий фасад `Repository` (Protocol) поверх `db/*.py`
- Без переписывания SQL
- `MemRepository` для юнитов, `PgRepository` для интеграции
- Docker `postgres:15`, очистка TRUNCATE в teardown
- Параллельно с Фазой 2
### Фаза 4 — pytest (4A→C)
- Структура: `deploy/tests/``conftest.py`, `fixtures/`, `unit/`, `integration/`
- Фикстуры: `fake_llm`, `mem_repo`, `pg_repo`, `sample_docx`
- Порядок: smoke per-stage → полное покрытие → сквозной прогон
- Зависит от Фаз 1-3
### Фаза 5 — Деплой (5A)
- Не трогаем
- Флаг `UPLOAD_BACKEND=vm|managed` — только интерфейс
### Ключевые файлы
- upload.py, classify.py, grouping.py, process.py, llm.py, connection.py — модифицируются
- Новые: contracts.py, llm_client.py, repository.py, tests/, docker-compose.test.yml
### Верификация
1. `pytest unit/` — зелёные без сети/БД
2. `docker-compose up postgres` + `pytest integration/` — реальный SQL
3. Сквозной: sample.docx → пайплайн → ожидаемые ops
4. convert_server.py без изменения поведения
5. JS-тесты (131) — PASS
### Scope
Включено: контракты, DI LLM+БД, pytest, фикстуры, флаг UPLOAD_BACKEND
Исключено: деплой, переписывание SQL, изменения фронтенда, managed-upload
---
## Ответ DeepSeek — Рецензия
Оценка: 5/5
### Поправки:
- `upload.py` уже читает из `BytesIO`, не из сокета
- Ф2 и Ф3 можно параллельно (независимы)
### 3 вопроса к Opus:
1. Dataclass vs TypedDict? dict из БД vs валидированный dataclass
2. `complete(prompt) -> str` достаточно? или нужен `complete_structured`?
3. `conftest.py` на уровне `deploy/tests/` или `deploy/`?
### Вердикт: План принимаю. Жду ответ на 3 вопроса.