545 lines
18 KiB
Markdown
545 lines
18 KiB
Markdown
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.
|
||
|
||
---
|
||
|
||
|