TZ_LLM_Normalizer_v1.1.1.md

Да, ты правильно понимаешь.

Сейчас у вас набор **типизированный и управляемый**:

* кейсы уже разложены по классам;
* видно, где именно остаточные промахи;
* промахи уже не системные, а **пограничные**;
* значит, текущий этап — это именно **шлифовка на известных типах**, а не поиск всей правды о мире.

Именно поэтому сейчас есть смысл делать **v1.1.1 polish**:
не большой новый этап, а аккуратную доводку по 3–5 остаточным паттернам, с минимальным риском деградации и минимальным бюджетом.

---

# Главное про риск деградации

Риск деградации тут **есть**, но он уже локальный, не катастрофический.

## Откуда риск

Сейчас normalizer уже хорошо держит:

* schema,
* route,
* causal semantics,
* cross-entity.

Если начать слишком агрессивно править prompt’ы, можно:

* случайно сломать уже хорошие `cross_entity`;
* ухудшить `route_hint_accuracy`;
* вернуть лишние переэскалации;
* попортить confidence-policy.

## Поэтому правильный режим такой

Нужно делать не “ещё один большой тюнинг”, а:

* **не трогать то, что уже даёт 100%**
* править только:

  * `period_close_risk` vs `heavy_analytical`
  * `drilldown_explain` vs лишний `needs_cross_entity_join`
  * `anomaly_probe` vs лишний `batch_refresh_then_store`

То есть это именно **surgical patch**, а не новая версия всего normalizer’а.

---

# ТЗ для Codex: Normalizer v1.1.1 Polish

## 1. Цель этапа

Провести точечную доводку `normalizer_v1_1` до `normalizer_v1_1_1`, чтобы улучшить остаточные показатели **без деградации уже работающих классов** и без дорогих повторных прогонов.

Цели:

* убрать оставшиеся пограничные mismatch’и;
* улучшить согласованность `intent_class` и `requires`;
* уменьшить лишнюю route escalation;
* сохранить текущие сильные результаты:

  * `schema_validation_pass_rate = 100`
  * `route_hint_accuracy = 96.67`
  * `cross_entity = 100%`
  * `high_confidence_error_rate = 0`

---

## 2. Scope этапа

### В scope входит

* точечный forensic-аудит остаточных mismatch’ов;
* минимальная правка taxonomy logic;
* минимальная правка few-shot и developer prompt;
* контрольный микро-прогон на узком наборе кейсов;
* оценка риска деградации относительно v1.1.

### В scope не входит

* новый большой eval на 30+ новых кейсах;
* переписывание всей схемы;
* переписывание всего prompt manager;
* новая архитектура normalizer;
* массовый prompt sweep;
* расширение доменного словаря во все стороны.

---

## 3. Что именно надо чинить

## Паттерн 1. `period_close_risk` уезжает в `heavy_analytical`

### Симптом

Вопросы про предзакрытие/конец периода/что взорвётся в последний день:

* понимаются по route правильно;
* но получают `intent_class = heavy_analytical` вместо `period_close_risk`.

### Что нужно сделать

Уточнить taxonomy:

Если вопрос содержит смысл:

* предзакрытие,
* конец периода,
* перед сдачей отчетности,
* в последний день,
* что взорвётся,
* что критично перед закрытием,
* где опасные хвосты перед закрытием,

то primary intent должен быть:

* `period_close_risk`

Даже если при этом:

* нужен обзор,
* нужна приоритизация,
* нужен batch route.

### Важно

`period_close_risk` не должен исчезать внутрь `heavy_analytical`.
`heavy_analytical` — это обзорный/рейтинговый класс.
`period_close_risk` — это специальный предметный класс с периодной угрозой.

---

## Паттерн 2. В точечном drilldown лишне поднимается `needs_cross_entity_join = true`

### Симптом

Для вопросов вида:

* “покажи документ №... и связанную проводку”
* “покажи карточку конкретной операции и связанную проводку”

маршрут правильный:

* `live_mcp_drilldown`

intent тоже правильный:

* `drilldown_explain`

Но в `requires` появляется лишнее:

* `needs_cross_entity_join = true`

### Что нужно сделать

Уточнить правило:

Если вопрос:

* про **один конкретный объект**
* и у него есть идентификатор / номер / ref / карточка / конкретная операция / конкретный документ,
* и задача — точечно показать source-of-record / связанную проводку / один связанный объект,

то:

* `needs_exact_object_trace = true`
* `needs_runtime_truth = true`
* `needs_cross_entity_join = false`

Даже если в вопросе упоминается “связанная проводка”.

### Логика

Связанный объект в точечном drilldown — это ещё не multi-entity join в смысле causal report.

---

## Паттерн 3. `anomaly_probe` местами переэскалирует в `batch_refresh_then_store`

### Симптом

Есть вопрос уровня:

* “где по июню выглядит подозрительно, но без точечного документа, просто дай зоны риска”

Ожидание:

* `anomaly_probe`
* `store_feature_risk`

Факт:

* `anomaly_probe`
* но route уходит в `batch_refresh_then_store`

### Что нужно сделать

Уточнить правило route hint:

Если:

* вопрос аномальный / риск-ориентированный,
* не требует ranking,
* не требует whole-company overview,
* не требует full prioritized review,
* не требует batch-scale summary,

то:

* route должен оставаться `store_feature_risk`

Даже если:

* есть `needs_period_cut = true`
* есть общая риск-лексика.

### Логика

Сам по себе “июнь” или “зоны риска” не должен автоматически толкать всё в batch.

---

## 4. Что надо поменять в prompt’ах

## 4.1 Developer prompt

Нужно добавить 3 точечных блока правил:

### Блок A. `period_close_risk`

```text
Если вопрос явно относится к предзакрытию, закрытию периода, сдаче отчетности, концу месяца или рискам последнего дня, primary intent_class должен быть period_close_risk, а не heavy_analytical, даже если требуется обзор или приоритизация.
```

### Блок B. exact drilldown

```text
Если вопрос относится к одному конкретному документу, операции, номеру, ref или объекту и просит показать связанную проводку или источник, это exact object trace. В таком случае needs_cross_entity_join не поднимается, если не требуется анализ множества сущностей или нескольких кейсов.
```

### Блок C. anomaly without heavy batch

```text
Если вопрос просит показать зоны риска, подозрительные случаи или аномалии без рейтинга, без full overview и без company-wide aggregation, route_hint должен быть store_feature_risk, а не batch_refresh_then_store.
```

---

## 4.2 Few-shot

Добавить **ровно 3 новых few-shot**:

### Few-shot 1

`period_close_risk` vs `heavy_analytical`

Пример:

* “Перед закрытием периода что у нас может взорваться в последний день?”
  Ожидание:
* `intent_class = period_close_risk`
* `route_hint = batch_refresh_then_store`

### Few-shot 2

точечный drilldown без `needs_cross_entity_join`

Пример:

* “Покажи документ №TRX-88 и связанную проводку по 51”
  Ожидание:
* `intent_class = drilldown_explain`
* `needs_exact_object_trace = true`
* `needs_cross_entity_join = false`
* `route_hint = live_mcp_drilldown`

### Few-shot 3

anomaly without batch escalation

Пример:

* “Где по июню выглядит подозрительно, просто дай зоны риска без детального разбора”
  Ожидание:
* `intent_class = anomaly_probe`
* `route_hint = store_feature_risk`

---

## 5. Что нельзя трогать

Codex запрещено:

* ухудшать cross-entity rules;
* переписывать causal language interpretation;
* менять schema;
* трогать confidence logic, если это не требуется точечно;
* добавлять много новых few-shot;
* делать большие перестройки domain prompt.

Сильные зоны v1.1:

* `cross_entity`
* `heavy_analytical`
* `rule_based_account_control`
* общий `route_hint`
  Их надо **сохранять**, а не “переосмыслять”.

---

## 6. Прогоны и бюджет

### Режим

Только **микро-проверка**, очень экономно.

### Лимит

* максимум **5 API-вызовов** на весь этап polish;
* один кейс = один запрос;
* без повторов, кроме технического fail;
* `temperature = 0`

### Контрольный набор

Проверить только эти кейсы:

1. `NQ-008`
2. `V11-DD-005`
3. `V11-OT-003`
4. `V11-OT-004`
5. `V11-OT-005`

### Зачем именно они

Они покрывают все три остаточных паттерна:

* drilldown overspecification,
* taxonomy drift,
* route over-escalation.

---

## 7. Что должен выдать Codex

### Артефакты

1. `docs/normalizer_v1_1_1_patch_notes.md`
2. обновлённый:

   * `prompts/developer/normalizer_v1_1_1.txt`
   * `prompts/fewshot/normalizer_fewshot_v1_1_1.txt`
3. `reports/normalizer_v1_1_1_micro_eval.json`
4. `reports/normalizer_v1_1_1_micro_eval.md`

### В patch notes обязательно указать

* что именно было изменено;
* какие 3 паттерна лечили;
* почему изменения безопасны;
* сколько API-вызовов реально потрачено;
* были ли ретраи;
* что улучшилось;
* что осталось как есть.

---

## 8. Критерии приёмки

Этап считается принятым, если:

1. не превышен лимит в 5 запросов;
2. schema validation остаётся 100;
3. `NQ-008` и `V11-DD-005` больше не поднимают лишний `needs_cross_entity_join`;
4. `V11-OT-003` и `V11-OT-005` получают `intent_class = period_close_risk`;
5. `V11-OT-004` получает `route_hint = store_feature_risk`;
6. не возникает деградации на уже сильных классах;
7. patch описан прозрачно и без “магических” неясных изменений.

---

## 9. Честная цель этапа

Не надо ставить задачу “добить всё до 99”.

Правильная цель этого этапа:

* подчистить остаточные пограничные ошибки,
* не поломать working core,
* зафиксировать устойчивую v1.1.1,
* после этого уже собирать **новую пачку других кейсов** на следующем этапе.

То есть сейчас:
**не расширение мира, а полировка известной карты.**

---

## 10. Короткая версия для Codex

Сделать v1.1.1 patch:

* точечно поправить `period_close_risk` vs `heavy_analytical`,
* убрать лишний `needs_cross_entity_join` в точечном drilldown,
* убрать лишнюю batch-эскалацию для мягкого anomaly-probe,
* добавить 3 few-shot,
* сделать микро-прогон на 5 кейсах,
* не потратить больше 5 запросов,
* не трогать сильные части модели.


