TZ_LLM_Normalizer_v1.md

Ниже даю **жёсткое ТЗ для Codex** на точечную доводку LLM-normalizer с очень экономным режимом прогонов.

---

# ТЗ для Codex: точечная доводка LLM Normalizer v1 → v1.1

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

Довести текущий LLM-normalizer до более стабильного качества на реальных бухгалтерских человеческих запросах, **не раздувая бюджет на API-прогоны**.

Главная цель этапа:

* поднять качество нормализации;
* убрать текущие semantic-промахи по `intent_class`, `route_hint` и `causal flags`;
* сохранить 100% schema validation;
* сделать это **через точечные изменения prompt/few-shot/eval**, без массовых дорогих прогонов.

---

## 2. Текущий статус

Текущий eval дал:

* `schema_validation_pass_rate = 100`
* `intent_class_accuracy = 72.73`
* `route_hint_accuracy = 90.91`
* `causal_flag_accuracy = 81.82`
* `high_confidence_error_rate = 9.09`

Проблемные кейсы:

* `NQ-004`
* `NQ-008`
* `NQ-009`

Тип проблемы:

* schema уже держится хорошо;
* route_hint уже близок к рабочему;
* основное слабое место — `intent_class`;
* часть ошибок связана с неправильной трактовкой causal/cross-entity языка;
* минимум один кейс даёт ошибку route при при этом пойманной causal-семантике.

---

## 3. Главный принцип этапа

### Очень важно

Не делать дорогую “перестрелку запросами”.

Нельзя:

* гонять большие автоматические sweep’ы;
* отправлять много повторов на один и тот же кейс;
* делать temperature-sampling по 10–20 вариантов;
* прогонять сотни запросов на каждую мелкую правку.

Нужно:

* сделать **точечную forensic-доработку**;
* разобрать 3 проблемных кейса;
* внести минимальные, но сильные изменения;
* прогнать **ровно один запрос на кейс** в контрольном eval-наборе;
* максимум 30 запросов на финальный контроль.

---

## 4. Budget constraints / лимиты на прогоны

Codex обязан соблюдать жёсткий лимит.

### Допустимый лимит API-вызовов на этот этап

* до **10** вызовов на forensic/ручную проверку;
* до **30** вызовов на финальный eval-run;
* итого целевой потолок: **не более 40 внешних LLM-запросов** на весь этап.

### Правила

1. Один кейс = один запрос.
2. Не делать повторные запросы на тот же кейс без явной необходимости.
3. Ретраи разрешены только:

   * при техническом fail,
   * при невалидном JSON,
   * не более 1 повтора на кейс.
4. Не делать random sampling.
5. `temperature = 0` на всех eval-запусках.
6. Не делать “прогоны для красоты” после достижения приемлемого результата.

---

## 5. Что нужно сделать по шагам

## Этап A. Forensic-аудит проблемных кейсов

### Задача A1

Разобрать вручную кейсы:

* `NQ-004`
* `NQ-008`
* `NQ-009`

### Что нужно собрать по каждому кейсу

Для каждого кейса составить мини-таблицу:

* `case_id`
* `raw_question`
* `expected.intent_class`
* `actual.intent_class`
* `expected.route_hint`
* `actual.route_hint`
* `expected.requires`
* `actual.requires`
* `какие признаки модель не увидела`
* `какие признаки модель увидела лишние`
* `предполагаемая причина ошибки`
* `какая минимальная правка должна это исправить`

### Ожидаемый результат

Файл:
`docs/normalizer_forensic_audit_v1_1.md`

### Ограничение по вызовам

Новые API-вызовы для этого этапа делать только если не хватает уже существующих trace/result-данных.
Цель: по возможности **0 новых запросов**, максимум **3**.

---

## Этап B. Точечная доработка taxonomy и route logic в prompt-слое

### Задача B1

Уточнить `developer prompt` так, чтобы он:

* жёстче различал:

  * `cross_entity`
  * `anomaly_probe`
  * `rule_based_account_control`
  * `drilldown_explain`
  * `ambiguous_human_query`
* не сваливал causal cross-entity в соседние классы.

### Задача B2

Добавить/исправить правила приоритетов:

#### Приоритет 1

Если вопрос требует связать:

* документы,
* оплаты,
* проводки,
* закрывающие,
* договоры,
* регистры,
* даты,
* подтверждение цепочки,

то это **не** `simple_factual` и обычно **не** `store_feature_risk`,
а causal multi-entity scenario.

#### Приоритет 2

Если вопрос про множество кейсов, даже если просит “объяснить”, это не `needs_exact_object_trace`, если нет одного конкретного документа/проводки/объекта.

#### Приоритет 3

Если в вопросе есть риск/аномалия-лексика, но одновременно есть document/payment/posting chain, то приоритет у causal cross-entity semantics, а не у risk-bucket.

#### Приоритет 4

`ambiguous_human_query` использовать только когда вопрос действительно не раскладывается в конкретный intent-class, а не как ленивый fallback.

### Задача B3

Уточнить `domain prompt`:

* расширить словарь фраз:

  * “не бьётся”
  * “не сходится”
  * “не видно”
  * “не собралось”
  * “повисло”
  * “хвост”
  * “разложи по документам / оплатам / закрывающим”
  * “чем подтверждается”
  * “где ошибка в цепочке”
  * “что пошло криво”
* привязать их к causal semantics.

### Ожидаемый результат

Обновить:

* `prompts/developer/normalizer_v1_1.txt`
* `prompts/domain/normalizer_domain_v1_1.txt`

---

## Этап C. Few-shot patch вместо большого переписывания

### Задача C1

Не переписывать весь prompt заново.
Добавить **только 5–7 новых few-shot примеров**, которые закрывают пограничные случаи.

### Обязательные типы новых few-shot

Нужно минимум по одному примеру на каждый паттерн:

1. `cross_entity` vs `anomaly_probe`
2. `cross_entity` vs `rule_based_account_control`
3. `cross_entity multiple explain` vs `drilldown_explain`
4. `causal human language` + `risk words`
5. `ambiguous human wording`, которое всё равно надо класть в нормальный intent-class
6. `rule-based control` без causal chain
7. `heavy overview` без точечного explain

### Требование

Few-shot должны быть короткими.
Не делать огромные простыни.

### Ожидаемый результат

Обновить:

* `prompts/fewshot/normalizer_fewshot_v1_1.txt`

---

## Этап D. Ужесточить confidence policy

### Задача D1

Снизить долю high-confidence ошибок.

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

Добавить в developer prompt правило:

Модель не должна ставить:

* `confidence.overall = high`
* `confidence.route_hint = high`

если одновременно:

* есть ambiguity,
* route зависит от тонкого различия между соседними классами,
* вопрос длинный и многослойный,
* модель не уверена в period scope,
* causal semantics частично восстановлена, но не полностью.

### Цель

Снизить `high_confidence_error_rate`.

### Ожидаемый результат

Правка внутри:

* `developer prompt`
* опционально: post-validation rule на backend, который помечает suspicious confidence

---

## Этап E. Подготовить экономный eval-набор из 30 кейсов

### Задача E1

Собрать один контрольный eval-набор:
`eval_cases/normalizer_eval_v1_1_30cases.json`

### Размер

Ровно **30 кейсов**, не больше.

### Ограничение

Один кейс = один запрос.

### Состав набора

Сделать сбалансированно:

* `cross_entity` — 10 кейсов
* `heavy_analytical` — 5 кейсов
* `drilldown_explain` — 5 кейсов
* `rule_based_account_control` — 5 кейсов
* `anomaly_probe / ambiguous_human_query / period_close_risk` — 5 кейсов

### Обязательные условия

* включить `NQ-004`, `NQ-008`, `NQ-009` в переработанном виде или их исходные кейсы;
* включить минимум 5 человеческих формулировок из creative-stress стиля;
* не делать дубли почти одинаковых вопросов.

---

## Этап F. Сделать один контрольный прогон

### Задача F1

Запустить **один** eval-run по 30 кейсам.

### Правила прогона

* `temperature = 0`
* один запрос на кейс
* без multi-sampling
* без повторов, кроме:

  * технического fail
  * invalid JSON
* максимум 1 retry на кейс

### Ожидаемый файл отчёта

`reports/normalizer_eval_v1_1_run.md`

### Ожидаемый JSON

`reports/normalizer_eval_v1_1_run.json`

---

## 6. Что нужно измерять в финальном отчёте

В отчёт обязательно вывести:

* `cases_total`
* `schema_validation_pass_rate`
* `intent_class_accuracy`
* `route_hint_accuracy`
* `causal_flag_accuracy`
* `high_confidence_error_rate`

Дополнительно:

* accuracy по каждому классу:

  * `cross_entity`
  * `heavy_analytical`
  * `drilldown_explain`
  * `rule_based_account_control`
  * `anomaly_probe`
* список всех mismatch’ов
* короткий комментарий по каждому mismatch’у
* сравнение **до / после** относительно текущих baseline-метрик

---

## 7. Целевые метрики этапа

Ниже не “идеальный мир”, а реальные целевые ориентиры.

### Минимально приемлемо

* `schema_validation_pass_rate >= 95`
* `intent_class_accuracy >= 85`
* `route_hint_accuracy >= 92`
* `causal_flag_accuracy >= 88`
* `high_confidence_error_rate <= 7`

### Хороший результат

* `schema_validation_pass_rate >= 98`
* `intent_class_accuracy >= 88`
* `route_hint_accuracy >= 94`
* `causal_flag_accuracy >= 90`
* `high_confidence_error_rate <= 5`

### Отличный результат

* `schema_validation_pass_rate = 100`
* `intent_class_accuracy >= 90`
* `route_hint_accuracy >= 95`
* `causal_flag_accuracy >= 92`
* `high_confidence_error_rate <= 3`

### Важно

Цель “95+ везде” можно держать как aspirational target, но Codex не должен ради этого устраивать дорогую перестрелку запросами. Сначала нужен максимально дешёвый и умный рост качества.

---

## 8. Что нельзя делать

Codex **запрещено**:

1. Делать массовый prompt sweep.
2. Прогонять десятки вариантов одного и того же кейса.
3. Использовать temperature > 0 для eval.
4. Делать скрытые повторные запросы “на всякий случай”.
5. Увеличивать eval set выше 30 кейсов без явной необходимости.
6. Пытаться лечить всё переписыванием backend-логики, если проблема решается prompt/few-shot таксономией.
7. Ломать уже рабочую schema validation ради intent tuning.

---

## 9. Что нужно поправить в коде

Codex должен проверить и при необходимости обновить:

### A. Prompt manager

* версионирование prompt’ов:

  * `normalizer_v1`
  * `normalizer_v1_1`
* возможность быстро переключать presets

### B. Eval runner

* добавить режим:

  * `single-pass-strict`
* который гарантирует:

  * один запрос на кейс,
  * без повторов,
  * лог явных retries

### C. Report generator

* добавить сравнение baseline vs current
* отдельно выводить mismatch table
* отдельно выводить bad confidence cases

### D. Storage / trace

* сохранить привязку:

  * `case_id`
  * `trace_id`
  * `prompt_version`
  * `schema_version`
  * `model`
  * `request_count_for_case`

Это нужно, чтобы контролировать бюджет реально.

---

## 10. Какие артефакты должен выдать Codex

Codex обязан выдать:

1. `docs/normalizer_forensic_audit_v1_1.md`
2. обновлённые prompt-файлы:

   * `prompts/developer/normalizer_v1_1.txt`
   * `prompts/domain/normalizer_domain_v1_1.txt`
   * `prompts/fewshot/normalizer_fewshot_v1_1.txt`
3. новый eval-набор:

   * `eval_cases/normalizer_eval_v1_1_30cases.json`
4. обновлённый экономный eval runner
5. отчёты:

   * `reports/normalizer_eval_v1_1_run.md`
   * `reports/normalizer_eval_v1_1_run.json`
6. краткий changelog:

   * `docs/normalizer_v1_1_changes.md`

---

## 11. Формат changelog

В changelog обязательно указать:

* что именно было изменено в prompt’ах;
* какие linguistic patterns добавлены;
* какие few-shot кейсы добавлены;
* какие кейсы были проблемными в baseline;
* сколько API-вызовов было потрачено на этап;
* итоговые метрики до/после;
* что осталось проблемным после тюнинга.

---

## 12. Приёмка этапа

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

1. Не превышен лимит внешних API-вызовов:

   * желательно до 40,
   * жёсткий потолок 45 только при техфейлах.
2. Есть forensic-аудит 3 проблемных baseline-кейсов.
3. Есть обновлённые prompt/few-shot файлы.
4. Есть новый eval-набор из 30 кейсов.
5. Есть один финальный eval-run.
6. Schema validation не просела.
7. `route_hint_accuracy` не стала хуже baseline.
8. `intent_class_accuracy` выросла заметно относительно baseline.
9. `high_confidence_error_rate` не вырос, а лучше — снизился.
10. В отчёте есть честный список оставшихся mismatch’ов.

---

## 13. Короткий practical summary для Codex

Что делать по сути:

1. Разобрать 3 плохих кейса.
2. Точечно усилить taxonomy и causal-language interpretation.
3. Добавить 5–7 сильных few-shot примеров.
4. Не трогать лишнего.
5. Собрать 30-кейсовый eval set.
6. Прогнать его **одним проходом**.
7. Сравнить с baseline.
8. Выдать отчёт и changelog.
9. Не жечь бюджет.

---

## 14. Самый важный акцент

Главная задача Codex сейчас — **не сделать “идеальную исследовательскую систему”**, а сделать **дешёвую и умную доводку** уже рабочего normalizer’а.

То есть нужно:

* чинить только то, что реально болит;
* не трогать то, что уже работает;
* не плодить дорогие прогоны;
* улучшать качество через forensic + prompt/few-shot patching.

---


