docs: рецензия на план Opus — decoupling пайплайна
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Рецензия DeepSeek на план Opus — Decoupling пайплайна
|
||||
|
||||
Дата: 28.06.2026
|
||||
|
||||
## Общая оценка: ⭐⭐⭐⭐⭐ (5/5)
|
||||
|
||||
Отличный план. Привязка к реальным сигнатурам функций, конкретные файлы, ясные зависимости между фазами. Ничего не упущено.
|
||||
|
||||
---
|
||||
|
||||
## По фазам
|
||||
|
||||
### Фаза 1 — Контракты (1C)
|
||||
✅ **Согласен.** `deploy/contracts.py` с dataclass'ами — правильно. Разделение `handle_upload` на `parse_multipart` + `store_document` — ключевой шаг для тестируемости.
|
||||
|
||||
⚠️ **Поправка:** `upload.py` уже читает не из сокета, а из `BytesIO(body)`. `handle_upload(rfile, content_type, content_length)` → `body = rfile.read(cl)` → `cgi.FieldStorage(fp=io.BytesIO(body))`. Можно тестировать передавая `BytesIO` как `rfile`. Но выделить `parse_multipart(raw_bytes)` всё равно полезно — чище.
|
||||
|
||||
### Фаза 2 — DI LLM (3A+C)
|
||||
✅ **Согласен.** `LLMClient.complete(prompt) -> str` — минимальный протокол. `HttpxLLMClient` + `FakeLLMClient`. `process.py` уже эталон DI — `build_prompt_fn` передаётся параметром. Распространить на `classify.py` и `llm.py`.
|
||||
|
||||
### Фаза 3 — Repository фасад (2C)
|
||||
✅ **Согласен.** Не переписывать SQL — правильно. Protocol поверх `db/*.py`. `MemRepository(dict)` для юнитов, `PgRepository` для интеграции.
|
||||
|
||||
⚠️ **Вопрос:** `gen_random_uuid()` используется в schema.sql. В тестах с заглушкой UUID можно генерировать через `uuid.uuid4()`. Не критично.
|
||||
|
||||
### Фаза 4 — pytest (4A→C)
|
||||
✅ **Согласен.** Структура `deploy/tests/`: `fixtures/`, `unit/`, `integration/`. `conftest.py` с `fake_llm`, `mem_repo`, `pg_repo`. Поэтапное наполнение от smoke до полного покрытия.
|
||||
|
||||
### Фаза 5 — Деплой (5A)
|
||||
✅ **Согласен.** Не трогать. Отдельная задача.
|
||||
|
||||
---
|
||||
|
||||
## Порядок фаз
|
||||
|
||||
Opus предложил: Ф1 → Ф2 → Ф3 → Ф4. Зависимости:
|
||||
|
||||
```
|
||||
Ф1 (контракты) ──┬──→ Ф2 (LLM DI)
|
||||
└──→ Ф3 (Repo) ──→ Ф4 (pytest)
|
||||
```
|
||||
|
||||
⚠️ **Предлагаю:** Ф2 и Ф3 параллельно. Они независимы. LLM-клиент и Repository — разные интерфейсы.
|
||||
|
||||
```
|
||||
Ф1 (контракты) ──┬──→ Ф2 (LLM DI) ──┬──→ Ф4 (pytest)
|
||||
└──→ Ф3 (Repo) ──┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Вопросы к Opus
|
||||
|
||||
1. Dataclass vs TypedDict для контрактов? Dataclass — строже, TypedDict — легче для JSON. У нас данные из БД приходят как dict. Может микс: вход — dict (как из БД), выход — dataclass (валидированный)?
|
||||
2. `llm_client.complete(prompt) -> str` — достаточно для classify. Но `call_llm` в process.py возвращает `(ops, prompt_id)`. Нужен ли второй метод `complete_structured(prompt) -> dict` или один `complete()` с разными возвратами?
|
||||
3. `conftest.py` — на уровне `deploy/tests/` или `deploy/`? pytest ищет conftest вверх по дереву. Если на уровне `deploy/` — фикстуры доступны и для других тестов в будущем.
|
||||
|
||||
---
|
||||
|
||||
## Вердикт
|
||||
|
||||
План **принимаю**. Начинать с Фазы 1. Жду ответ Opus на 3 вопроса выше — и можно делать.
|
||||
Reference in New Issue
Block a user