NODEDC_1C/IN/TZ_LLM_Normalizer_v1.1.2.md

452 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

TZ_LLM_Normalizer_v1.1.2.md
Ниже даю **ТЗ на `normalizer_v1.1.2`** с комментариями — так, чтобы его можно было и отдать Codex, и потом нормально архивировать как понятный инженерный документ.
---
# ТЗ: `normalizer_v1.1.2`
## Точечная доводка границы `heavy_analytical` ↔ `period_close_risk`
---
## 1. Контекст этапа
На версии `normalizer_v1.1.1` удалось очень сильно улучшить рабочие свойства normalizerа как предроутерного слоя:
* `schema_validation_pass_rate = 100`
* `route_hint_accuracy = 100`
* `causal_flag_accuracy = 100`
* `cross_entity = 100%`
* `drilldown_explain = 100%`
* `rule_based_account_control = 100%`
* `period_close_risk = 100%`
Однако при этом появился побочный перекос в taxonomy:
* `intent_class_accuracy = 90` вместо `93.33` на `v1.1`
* `heavy_analytical = 40%`
* `high_confidence_error_rate = 3.33` вместо `0`
Комментарий:
Это означает, что версия `v1.1.1` **улучшила поведение normalizerа как route/cause normalizer**, но при этом **слишком агрессивно начала относить heavy обзорные вопросы к `period_close_risk`**, если в формулировке есть слова про закрытие периода, отчётность или предзакрытие.
---
## 2. Что именно произошло
Проблема локализована и понятна.
### Текущий корневой дефект
В `developer prompt v1.1.1` есть правило, которое слишком жёстко задаёт:
> если вопрос относится к предзакрытию, закрытию периода, сдаче отчётности, концу месяца или рискам последнего дня, primary intent должен быть `period_close_risk`, даже если требуется обзор или приоритизация.
Комментарий:
Это правило было добавлено, чтобы вылечить потерю `period_close_risk` внутри `heavy_analytical`.
Но в текущем виде оно **перетянуло слишком много heavy overview вопросов в `period_close_risk`**.
### Дополнительный фактор
В few-shot наборе есть пример на `period_close_risk`, но **нет достаточного симметричного набора примеров**, который бы показывал модели:
* когда вопрос остаётся `heavy_analytical`,
* даже если он сформулирован “перед закрытием периода” или “перед сдачей отчётности”.
Комментарий:
То есть у модели появился сильный positive-trigger на `period_close_risk`, но нет хорошего отрицательного противовеса.
---
## 3. Цель `v1.1.2`
Сделать **узкий и безопасный patch**, который:
1. сохранит:
* `route_hint_accuracy = 100`
* `causal_flag_accuracy = 100`
* `schema_validation_pass_rate = 100`
* сильные результаты по `cross_entity`, `drilldown_explain`, `rule_based_account_control`
2. исправит:
* taxonomy drift между `heavy_analytical` и `period_close_risk`
* лишнюю high-confidence оценку на пограничных кейсах
3. не приведёт к деградации уже сильных зон.
Комментарий:
Это **не новый большой этап**, а именно **surgical patch**.
Менять нужно **только границу intent-class**, а не общую архитектуру normalizerа.
---
## 4. Scope этапа
### В scope входит
* корректировка одного участка `developer prompt`;
* добавление 2 симметричных few-shot примеров для `heavy_analytical`;
* добавление 1 confidence-rule для пограничных кейсов;
* очень короткий контрольный прогон на 5 кейсах.
### В scope не входит
* изменение schema;
* изменение route logic;
* изменение cross-entity правил;
* изменение drilldown правил;
* изменение anomaly patch;
* новый большой eval-run на 30+ кейсов;
* новые данные/срезы/онтология.
Комментарий:
Данные и база сейчас не нужны.
Проблема находится **целиком в prompt/taxonomy layer**.
---
## 5. Что именно нужно исправить
---
## 5.1. Паттерн A: `heavy_analytical` ошибочно уходит в `period_close_risk`
### Симптом
На `v1.1.1` следующие кейсы получили неправильный `intent_class`:
* `NQ-002`
* `NQ-007`
* `V11-HA-004`
Во всех этих кейсах:
* route правильный: `batch_refresh_then_store`
* causal/requires нормальные
* ошибка только в том, что `intent_class` стал `period_close_risk` вместо `heavy_analytical`
### Природа ошибки
Вопросы содержат:
* контекст закрытия периода,
* июнь / предзакрытие / отчётность,
но по сути просят:
* обзор,
* рейтинг,
* summary,
* общую картину,
* концентрацию ошибок,
* приоритизацию.
Такие вопросы должны оставаться `heavy_analytical`.
Комментарий:
`period_close_risk` — это не “любой вопрос про период”, а **специальный класс про угрозу срыва закрытия**.
Если в центре вопроса **обзор / рейтинг / агрегированный срез**, это должен быть `heavy_analytical`.
---
## 5.2. Паттерн B: high confidence на пограничном кейсе
### Симптом
В кейсе `NQ-002`:
* intent ошибочный,
* route правильный,
* confidence = `high`
### Природа ошибки
Пограничные вопросы между:
* `heavy_analytical`
* `period_close_risk`
не должны получать `high confidence`, если модель не различает класс уверенно.
Комментарий:
Даже если route совпадает, **ошибочно высокая уверенность на спорном intent — это риск для последующего управления качеством**.
Эту часть нужно приглушить.
---
# 6. Конкретные изменения для Codex
---
## 6.1. Изменить `developer prompt`
### Файл
`prompts/developer/normalizer_v1_1_2.txt`
### Что сделать
Переписать правило про `period_close_risk`.
### Текущее проблемное правило
Смысл текущего правила:
> если вопрос относится к предзакрытию/закрытию/отчётности/последнему дню, primary intent = `period_close_risk`, даже если нужен обзор или приоритизация.
### Новая правильная формулировка
Вставить вместо него такой блок:
```text
If a question is explicitly about period close risk, pre-close danger, last-day closing failure, reporting deadline risk, or threats that can break the close process itself, use `period_close_risk` as the primary intent_class.
However, if the main purpose of the question is:
- ranking,
- top issues,
- overview,
- concentration of errors,
- summary,
- prioritized review list,
- company-wide analytical review,
then the primary intent_class should remain `heavy_analytical`, even if the question is phrased in the context of month-end close or reporting preparation.
```
### Дополнительное уточнение
Добавить ещё один отдельный блок:
```text
`heavy_analytical` has priority over `period_close_risk` when the question asks for:
- ranking,
- top-N,
- overview,
- summary,
- company-wide picture,
- prioritized analytical review,
even if the wording mentions closing period, reporting, or pre-close context.
Use `period_close_risk` only when the core of the question is the risk of failing or destabilizing the close process itself.
```
Комментарий:
Это главное исправление всей версии `v1.1.2`.
Ничего сильнее менять не надо.
---
## 6.2. Добавить 2 симметричных few-shot примера
### Файл
`prompts/fewshot/normalizer_fewshot_v1_1_2.txt`
### Что сделать
Оставить existing few-shot на `period_close_risk`, но добавить **два примера-контрвеса**.
---
### Few-shot 1 — heavy remains heavy
```text
Q: Сделай рейтинг самых рисковых хвостов перед закрытием периода за июнь.
Expected:
{
"intent_class": "heavy_analytical",
"requires": {
"needs_cross_entity_join": false,
"needs_causal_chain": false,
"needs_exact_object_trace": false,
"needs_ranking": true,
"needs_anomaly_summary": false,
"needs_runtime_truth": false,
"needs_period_cut": true,
"needs_evidence": false
},
"expected_output_shape": "ranked_list",
"route_hint": "batch_refresh_then_store"
}
```
### Few-shot 2 — overview remains heavy
```text
Q: Дай обзорный риск-срез перед сдачей отчетности: где максимальная концентрация ошибок.
Expected:
{
"intent_class": "heavy_analytical",
"requires": {
"needs_cross_entity_join": false,
"needs_causal_chain": false,
"needs_exact_object_trace": false,
"needs_ranking": true,
"needs_anomaly_summary": true,
"needs_runtime_truth": false,
"needs_period_cut": true,
"needs_evidence": false
},
"expected_output_shape": "anomaly_summary",
"route_hint": "batch_refresh_then_store"
}
```
### Existing few-shot to keep
Оставить пример:
```text
Q: Перед закрытием периода что у нас может взорваться в последний день?
Expected intent_class: period_close_risk
```
Комментарий:
Эти два новых примера нужны не потому, что модель “тупая”, а потому, что в `v1.1.1` у неё был сильный пример только в одну сторону.
`v1.1.2` должен сделать границу симметричной.
---
## 6.3. Добавить confidence-ограничение
### Файл
`prompts/developer/normalizer_v1_1_2.txt`
### Что сделать
Добавить явное правило:
```text
If a question is plausibly on the boundary between `heavy_analytical` and `period_close_risk`, do not assign `confidence.overall = high`.
Use `medium` unless the wording strongly and unambiguously centers on close-process failure risk rather than analytical overview.
```
Комментарий:
Это страховка от кейса `NQ-002`, где route был правильный, но модель слишком самоуверенно выбрала спорный intent.
---
# 7. Что нельзя менять
Codex **запрещено**:
1. менять schema;
2. менять route rules;
3. трогать cross-entity prompt logic;
4. трогать drilldown prompt logic;
5. трогать anomaly/store_feature_risk patch;
6. добавлять много новых few-shot;
7. переписывать весь domain prompt;
8. делать большие prompt sweepы;
9. делать повторные API-запросы без необходимости.
Комментарий:
`v1.1.1` очень хорош по route/cause behavior.
Наша задача — **не поломать working core ради косметики taxonomy**.
---
# 8. Контрольный прогон
## Режим
Только микро-прогон.
## Лимит
* максимум **5 API-вызовов**
* один кейс = один запрос
* без повторов
* `temperature = 0`
## Проверить только эти кейсы
1. `NQ-002`
2. `NQ-007`
3. `V11-HA-004`
4. `V11-OT-003`
5. `V11-OT-005`
Комментарий:
Этого достаточно.
Три кейса проверяют boundary heavy/period-close.
Два кейса проверяют, что `period_close_risk` мы не сломали обратно.
---
# 9. Ожидаемый результат
## Минимально acceptable
* `NQ-002``heavy_analytical`
* `NQ-007``heavy_analytical`
* `V11-HA-004``heavy_analytical`
* `V11-OT-003` остаётся `period_close_risk`
* `V11-OT-005` остаётся `period_close_risk`
## Дополнительно желательно
* на пограничных кейсах confidence не `high`, а `medium`
Комментарий:
Если эти 5 кейсов проходят, значит `v1.1.2` делает ровно то, что нужно, и не требует нового полного 30-case eval прямо сейчас.
---
# 10. Артефакты, которые должен выдать Codex
1. `docs/normalizer_v1_1_2_patch_notes.md`
2. `prompts/developer/normalizer_v1_1_2.txt`
3. `prompts/fewshot/normalizer_fewshot_v1_1_2.txt`
4. `reports/normalizer_v1_1_2_micro_eval.json`
5. `reports/normalizer_v1_1_2_micro_eval.md`
---
# 11. Что должно быть в patch notes
В `normalizer_v1_1_2_patch_notes.md` обязательно описать:
* какая именно проблема была в `v1.1.1`;
* почему она возникла;
* какие prompt changes внесены;
* какие few-shot added;
* почему изменения безопасны;
* сколько API-вызовов потрачено;
* были ли ретраи;
* результаты микро-прогона;
* что осталось на будущее.
Комментарий:
Это нужно именно для архива и последующего контроля версий, чтобы потом было понятно, **почему `v1.1.2` вообще появился**.
---
# 12. Приёмка этапа
Этап считается принятым, если:
1. не превышен лимит в 5 API-вызовов;
2. `NQ-002`, `NQ-007`, `V11-HA-004` получают `intent_class = heavy_analytical`;
3. `V11-OT-003` и `V11-OT-005` остаются `period_close_risk`;
4. не возвращается лишний `high confidence` на пограничные heavy/period-close кейсы;
5. изменения зафиксированы прозрачно;
6. не сломаны уже сильные route/cause части normalizerа.
---
# 13. Короткий смысл этапа
`v1.1.2` — это **не улучшение всей системы**, а **локальная шлифовка последнего taxonomy-boundary**.
По сути задача одна:
> Сохранить идеальное route/cause поведение `v1.1.1`,
> но вернуть правильное именование там, где heavy overview был ошибочно засосан в period_close_risk.
---
Если хочешь, я следующим сообщением сделаю ещё **ультра-короткую версию этого ТЗ для прямой вставки в Codex**, буквально как job prompt без пояснений.