452 lines
16 KiB
Markdown
452 lines
16 KiB
Markdown
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 без пояснений.
|