Initial import NDC_1C

This commit is contained in:
2026-03-26 10:38:25 +03:00
commit a162d77ef7
2943 changed files with 3615871 additions and 0 deletions
+467
View File
@@ -0,0 +1,467 @@
TZ_LLM_Normalizer_v2.0.2.md
Ниже даю **ТЗ на новый вариант — `Normalizer v2.0.2`**.
Это уже не про “ещё лучше понять бухгалтерию”, а про **доводку устойчивости исполнения** после последнего жирного прогона.
---
# ТЗ: `Normalizer v2.0.2`
## Stability / No-Route / Schema Hardening
---
## 1. Контекст этапа
После перехода на `v2.0.1` система показала правильный вектор:
* `schema_validation_pass_rate = 96.15`
* `scope_in_scope_rate = 92.31`
* `clarification_required_rate = 15.38`
* `out_of_scope` отрабатывается
* нормальные in-scope вопросы в большинстве случаев проходят без лишнего clarification
Комментарий:
Это уже лучше, чем бесконечный prompt-tuning `v1.x`, потому что новая схема стала:
* устойчивее к новым формулировкам;
* лучше разделять допустимый/недопустимый контур;
* меньше душить нормальные вопросы уточнениями.
Но после жирного прогона видны три конкретные проблемы:
1. `schema_validation_pass_rate` упала с 100 до 96.15
2. `no_route_fragment_rate = 20.69` — слишком много
3. часть внутренних состояний (`fallback_type`, `execution_readiness`, `soft_assumptions`) согласованы неидеально
---
## 2. Цель этапа
Довести `v2.0.1` до более устойчивой рабочей версии `v2.0.2`, не меняя базовую архитектуру.
Цели:
* вернуть `schema_validation_pass_rate` к `100`
* разобраться с природой `no_route`
* сделать внутреннюю policy-логику согласованной
* не сломать уже хорошие свойства:
* scope gating
* out-of-scope filtering
* умеренный clarification rate
* decomposition-first подход
---
## 3. Главный принцип этапа
На этом этапе **не надо**:
* снова тюнить под конкретные 26 вопросов;
* переписывать всю prompt-логику;
* возвращаться к `v1.x`;
* пытаться “угадать всё лучше через ещё один prompt”.
Нужно:
* сделать систему **строже и честнее на уровне исполнения**;
* понять, где `no_route` правильный, а где это недонастроенный mapping;
* сделать output pipeline согласованным и стабильным.
Комментарий:
Это уже этап **операционной жёсткости**, а не “семантической магии”.
---
# 4. Что именно надо чинить
---
## 4.1. Проблема A: schema validation не 100
### Симптом
В последнем прогоне:
* `schema_validation_pass_rate = 96.15`
* кейс `BQ-001` не прошёл валидацию
* был retry (`request_count_for_case = 2`)
### Требование
Нужно вернуть:
* `schema_validation_pass_rate = 100`
### Что сделать
1. Разобрать `BQ-001` целиком:
* raw question
* raw model output
* parsed object
* validation error
* retry output
2. Выявить точную причину:
* field missing
* wrong enum
* wrong nested type
* prompt overflow / malformed json
* parser inconsistency
3. Исправить причину на системном уровне, а не точечно под кейс.
### Ожидаемый артефакт
Файл:
`docs/v2_0_2_schema_forensic.md`
Комментарий:
Schema loss даже в одном кейсе — это нельзя игнорировать.
Это технический риск уровня “сломается в проде в неожиданный момент”.
---
## 4.2. Проблема B: слишком много `no_route`
### Симптом
* `no_route_fragment_rate = 20.69`
* `route_distribution.no_route = 6`
### Требование
Разделить все `no_route` случаи на две категории:
### A. Legit no-route
Когда реально нельзя безопасно отправить дальше:
* fragment out-of-scope;
* fragment слишком неопределённый;
* fragment требует clarification;
* fragment семантически распознан, но не относится к исполняемому бухгалтерскому действию.
### B. Missing route mapping
Когда fragment уже in-scope и достаточно понятен, но код не умеет подобрать маршрут.
### Что сделать
1. Выгрузить все fragments с `no_route`
2. Для каждого сделать ручную классификацию:
* `legit_no_route`
* `missing_mapping`
3. Если это `missing_mapping`, добавить deterministic mapping rule
4. Если это `legit_no_route`, зафиксировать policy явно
### Ожидаемый артефакт
Файл:
`docs/v2_0_2_no_route_audit.md`
Комментарий:
Сейчас `no_route` — это ещё слишком “чёрный ящик”.
Нужно сделать так, чтобы каждый такой случай был объясним.
---
## 4.3. Проблема C: несогласованность execution state
### Симптом
Есть кейсы, где:
* `fallback_type = none`
* `predicted_clarification_required = false`
* но `executable_with_soft_assumptions_fragments = 0`
Например:
* `BQ-007`
* `BQ-024`
### Что это значит
Внутренняя state machine не полностью согласована.
### Требование
Согласовать следующие статусы между собой:
* `domain_relevance`
* `execution_readiness`
* `predicted_clarification_required`
* `fallback_type`
* `route_decision`
* `soft_assumption_used`
### Целевая логика
Если fragment:
* in-scope
* не clarification
* не out-of-scope
* и route выбран
то должно быть явно видно:
* либо `execution_readiness = executable`
* либо `execution_readiness = executable_with_soft_assumptions`
Не должно быть “исполняем, но readiness не поднят”.
### Ожидаемый артефакт
Файл:
`docs/v2_0_2_execution_state_machine.md`
---
# 5. Что изменить в схеме
## 5.1. Явно ввести `execution_readiness`
Если ещё не введено как обязательное поле — сделать обязательным.
```json id="mgbtkn"
{
"execution_readiness": "executable | executable_with_soft_assumptions | needs_clarification | no_route"
}
```
## 5.2. Явно ввести `route_status`
```json id="6sdd3j"
{
"route_status": "routed | no_route"
}
```
## 5.3. Явно ввести `no_route_reason`
Если `route_status = no_route`, обязателен reason:
```json id="y0eqbg"
{
"no_route_reason": "out_of_scope | insufficient_specificity | missing_mapping | unsupported_fragment_type"
}
```
Комментарий:
Это очень важно.
Без этого вы будете бесконечно смотреть на `no_route` как на аморфную массу.
---
# 6. Что изменить в коде
---
## 6.1. Добавить post-normalization state resolver
Сделать отдельный кодовый слой после ответа LLM:
```text id="kcynfd"
resolve_fragment_execution_state(fragment, session_context) -> resolved_fragment
```
Он должен:
1. нормализовать readiness;
2. нормализовать route_status;
3. ставить `no_route_reason`;
4. приводить `fallback_type` в согласованное состояние.
---
## 6.2. Ввести deterministic `no_route` policy
Если fragment:
* in-scope
* и не clarification
* и есть достаточно route-critical flags
то `no_route` запрещён.
В таком случае должен выбираться маршрут.
`no_route` разрешён только если:
* fragment реально вне контура;
* fragment реально недостаточно определён;
* fragment unsupported by current route map.
---
## 6.3. Добавить trace completeness check
Сейчас у вас раньше был кейс с пустым trace view.
Нужно проверить, что для каждого run сохраняется:
* raw input
* raw model output
* parsed fragments
* resolved execution state
* final route per fragment
Если trace неполный — логировать это как системную ошибку.
---
# 7. Что изменить в prompt’ах
На этом этапе prompt менять минимально.
Нужно только:
* добавить требование, чтобы fragment-level output был полным и непротиворечивым;
* не трогать общий semantic слой без нужды.
### Добавить в developer prompt
```text id="xlg5ut"
Every in-scope fragment must produce a consistent execution state.
If a fragment is routable, mark it as executable or executable_with_soft_assumptions.
Do not leave routable fragments in an unresolved execution state.
If a fragment cannot be routed, provide an explicit no_route_reason.
```
Комментарий:
Это не semantic tuning, а дисциплина output’а.
---
# 8. Новый eval для `v2.0.2`
Нужен уже не просто набор “сложных вопросов”, а **размеченный eval по policy**.
## 8.1. Состав eval
Собрать 20 кейсов:
### Блок A — routable in-scope
8 кейсов
Ожидание:
* in-scope
* no clarification
* route selected
* no `no_route`
### Блок B — legit clarification
4 кейса
Ожидание:
* in-scope
* clarification needed
### Блок C — out-of-scope
4 кейса
Ожидание:
* out-of-scope
* no route
* fallback out_of_scope
### Блок D — borderline / soft assumptions
4 кейса
Ожидание:
* in-scope
* executable_with_soft_assumptions
* route selected
---
## 8.2. Новые метрики
Обязательно считать:
* `schema_validation_pass_rate`
* `scope_detection_accuracy`
* `route_resolution_accuracy`
* `no_route_precision`
* `false_no_route_rate`
* `execution_state_consistency_rate`
* `clarification_precision`
* `clarification_recall`
---
# 9. Целевые показатели
Минимально приемлемо:
* `schema_validation_pass_rate = 100`
* `execution_state_consistency_rate >= 95`
* `false_no_route_rate <= 10`
* `route_resolution_accuracy` заметно выше текущего
* `clarification_required_rate` не выше текущего на in-scope одноходовых кейсах
Хорошо:
* `false_no_route_rate <= 5`
* `execution_state_consistency_rate = 100`
---
# 10. Что нельзя делать
Codex запрещено:
1. снова возвращать один главный `intent_class` как основу всего;
2. снова лечить всё через few-shot под эти 26 вопросов;
3. занижать `no_route` искусственно, просто проставляя маршрут куда угодно;
4. выключать fallback/out-of-scope;
5. игнорировать единичный schema fail как “неважный”.
---
# 11. Артефакты
Codex должен выдать:
1. `docs/v2_0_2_schema_forensic.md`
2. `docs/v2_0_2_no_route_audit.md`
3. `docs/v2_0_2_execution_state_machine.md`
4. `schemas/normalized_query_v2_0_2.json`
5. `prompts/developer/normalizer_v2_0_2.txt`
6. `reports/v2_0_2_eval_plan.md`
---
# 12. Короткий смысл этапа
`v2.0.2` — это версия не про “лучше понимать язык”, а про:
* **не ломать схему**
* **не терять route без объяснения**
* **сделать внутренние состояния честными и жёсткими**
* **перестать иметь серые зоны между clarification / no-route / executable**
---
# 13. Практический итог
После `v2.0.2` вы должны получить систему, где для каждого fragment всегда понятно:
* он в контуре или нет;
* он исполним или нет;
* если не исполним — почему;
* если исполним — с какими допущениями;
* какой route выбран;
* если route не выбран — по какой строго указанной причине.
Это уже будет нормальный инженерный фундамент, а не “LLM что-то там решила”.
---