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. ---