439 lines
20 KiB
Markdown
439 lines
20 KiB
Markdown
TZ_Assistant_Mode_vNext2.md
|
||
|
||
Да, даю уже в формате **жёсткой вставки в ТЗ**.
|
||
|
||
Ниже блок, который логично добавлять как отдельный раздел после текущего `Final Answer Composer / answer policy`, потому что в текущем контуре уже есть правильная базовая архитектура, но composer пока остаётся operational, retrieval — sandbox/stubbed, а пользовательский ответ не обязан доказывать основание отбора и полноту покрытия вопроса. Это прямо следует из текущего vNext ТЗ и архитектурного отчёта.
|
||
|
||
---
|
||
|
||
# Дополнение к ТЗ: explainable answer layer и контроль полноты декомпозиции
|
||
|
||
## 1. Цель дополнения
|
||
|
||
Закрыть два критических продуктовых дефекта Assistant Mode:
|
||
|
||
1. ассистент выдаёт формально человекочитаемый, но смыслово пустой ответ без объяснения, почему именно эти объекты, записи или цепочки были отобраны;
|
||
2. ассистент теряет части многосоставного пользовательского запроса на этапе decomposition/routing и отвечает только на отдельный фрагмент, создавая ложное ощущение, что задача решена.
|
||
|
||
Цель этого этапа — сделать так, чтобы Assistant Mode:
|
||
|
||
* отвечал **по смыслу бухгалтерского вопроса**;
|
||
* объяснял **основания отбора и вывода**;
|
||
* гарантировал **покрытие всех существенных частей запроса**;
|
||
* не подменял пользовательский вопрос ближайшим технически доступным маршрутом.
|
||
|
||
---
|
||
|
||
## 2. Что фиксируем как обязательный продуктовый контракт
|
||
|
||
Считать ответ ассистента корректным можно только тогда, когда одновременно выполнены четыре условия:
|
||
|
||
1. ответ относится именно к предмету вопроса пользователя, а не к соседнему маршруту;
|
||
2. ответ объясняет, **почему** найденные записи/объекты/контрагенты попали в результат;
|
||
3. ответ показывает, **на каких признаках и фактах** основан вывод;
|
||
4. ответ закрывает **все существенные части** многосоставного запроса либо явно помечает, что часть вопроса не покрыта.
|
||
|
||
Если хотя бы одно из этих условий не выполнено, ответ считается непригодным даже при технически успешном pipeline.
|
||
|
||
---
|
||
|
||
## 3. Новый обязательный слой: Explainable Answer Layer
|
||
|
||
После `Result Normalization` и до финального `Assistant Reply` должен быть отдельный обязательный слой:
|
||
|
||
**Explainable Answer Layer**
|
||
|
||
Новый полный контур:
|
||
|
||
**User message → Normalizer → Requirement Extraction → Execution Planning → Route-specific Retrieval → Result Normalization → Explainable Answer Layer → Final Answer Composer → Assistant Reply**
|
||
|
||
Задача этого слоя:
|
||
|
||
* восстановить пользовательское намерение в нормальной человекочитаемой форме;
|
||
* проверить полноту покрытия вопроса;
|
||
* проверить предметную релевантность ответа;
|
||
* собрать не просто summary, а **объяснимый вывод**.
|
||
|
||
---
|
||
|
||
## 4. Новый обязательный контракт декомпозиции
|
||
|
||
### 4.1. Декомпозиция должна выделять не только fragments, но и requirements
|
||
|
||
Нужно разделить два уровня:
|
||
|
||
### A. `requirements`
|
||
|
||
Смысловые требования пользователя.
|
||
|
||
Примеры:
|
||
|
||
* найти поставщиков с хвостами;
|
||
* объяснить, почему они считаются проблемными;
|
||
* показать, где именно разрыв по цепочке;
|
||
* отделить аномалии по риску от аномалий по сумме.
|
||
|
||
### B. `execution_fragments`
|
||
|
||
Технические единицы исполнения, которые маршрутизируются по route.
|
||
|
||
Важно:
|
||
один `requirement` может порождать несколько `execution_fragments`;
|
||
несколько fragments могут обслуживать один requirement.
|
||
|
||
Без этого разделения многосоставные вопросы будут и дальше схлопываться в один ближайший route.
|
||
|
||
---
|
||
|
||
### 4.2. Для каждого пользовательского сообщения нужен coverage report
|
||
|
||
После decomposition система обязана формировать объект:
|
||
|
||
```json
|
||
{
|
||
"requirements_total": 0,
|
||
"requirements_covered": 0,
|
||
"requirements_uncovered": [],
|
||
"requirements_partially_covered": [],
|
||
"clarification_needed_for": [],
|
||
"out_of_scope_requirements": []
|
||
}
|
||
```
|
||
|
||
Это внутренний контракт pipeline.
|
||
|
||
Без него нельзя считать, что система поняла вопрос.
|
||
|
||
---
|
||
|
||
### 4.3. Запрещён silent loss of intent
|
||
|
||
Если в исходном сообщении было несколько требований, а в execution plan попала только часть, система не имеет права:
|
||
|
||
* молча проигнорировать остальные части;
|
||
* выдавать ответ так, будто задача полностью выполнена;
|
||
* считать вопрос закрытым.
|
||
|
||
В этом случае допустимы только три режима:
|
||
|
||
1. **полный ответ** — если покрыто всё;
|
||
2. **partial answer** — если покрыта только часть и это явно сказано;
|
||
3. **clarification** — если без уточнения нельзя корректно закрыть все требования.
|
||
|
||
---
|
||
|
||
## 5. Новый обязательный контракт retrieval result
|
||
|
||
Текущий unified result schema нужно расширить. Сейчас в нём есть хороший базовый каркас, но для объяснимого ответа его недостаточно.
|
||
|
||
Каждый route executor должен возвращать не только данные, но и признаки, объясняющие включение объекта в ответ.
|
||
|
||
### Обязательные поля результата
|
||
|
||
```json
|
||
{
|
||
"fragment_id": "F1",
|
||
"requirement_ids": ["R1"],
|
||
"route": "store_feature_risk",
|
||
"status": "ok | empty | partial | error",
|
||
"result_type": "list | summary | object | chain | ranking",
|
||
"items": [],
|
||
"summary": {},
|
||
"evidence": [],
|
||
"why_included": [],
|
||
"selection_reason": [],
|
||
"risk_factors": [],
|
||
"business_interpretation": [],
|
||
"confidence": "high | medium | low",
|
||
"limitations": [],
|
||
"errors": []
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5.1. Смысл новых полей
|
||
|
||
`why_included`
|
||
Почему объект вообще попал в выборку.
|
||
|
||
`selection_reason`
|
||
По каким конкретным правилам, фильтрам, признакам или сопоставлениям он был отобран.
|
||
|
||
`risk_factors`
|
||
Какие именно признаки риска, расхождения, аномалии или разрыва цепочки обнаружены.
|
||
|
||
`business_interpretation`
|
||
Как это интерпретируется в бухгалтерском или операционном смысле.
|
||
|
||
`confidence`
|
||
Оценка уверенности результата.
|
||
|
||
`limitations`
|
||
Что система не смогла подтвердить или где данные неполны.
|
||
|
||
---
|
||
|
||
## 6. Новый обязательный слой: Answer Grounding Check
|
||
|
||
Перед выдачей финального ответа должен выполняться `Answer Grounding Check`.
|
||
|
||
### Его задача:
|
||
|
||
проверить, что итоговый ответ действительно опирается на retrieval results и не съехал по предметной области.
|
||
|
||
### Проверяемые условия:
|
||
|
||
1. ключевые сущности ответа присутствуют в retrieval results;
|
||
2. ключевые выводы ответа подтверждены `evidence` и `selection_reason`;
|
||
3. предмет ответа совпадает с предметом вопроса;
|
||
4. если пользователь спрашивал про ОС, ответ не может быть собран по НДС;
|
||
5. если пользователь спрашивал про 97 счёт, ответ не может уйти в общий рейтинг контрагентов без объяснения связи;
|
||
6. если пользователь спрашивал про аномалию, ответ обязан назвать признак аномалии.
|
||
|
||
Если проверка не проходит, ответ не отправляется в user-facing канал и должен перейти в один из fallback-режимов:
|
||
|
||
* clarification;
|
||
* partial with limitation;
|
||
* technical error;
|
||
* no-grounded-answer.
|
||
|
||
---
|
||
|
||
## 7. Новый обязательный стандарт user-facing ответа
|
||
|
||
Каждый нормальный factual answer должен содержать не просто summary, а следующие смысловые элементы:
|
||
|
||
### 7.1. Итоговый вывод
|
||
|
||
Короткий ответ на главный вопрос.
|
||
|
||
### 7.2. Основание отбора
|
||
|
||
Почему именно эти объекты попали в ответ.
|
||
|
||
### 7.3. Подтверждающие признаки
|
||
|
||
Какие факты, поля, несоответствия, связи или разрывы обнаружены.
|
||
|
||
### 7.4. Практический смысл
|
||
|
||
Что это означает для бухгалтера или что именно здесь выглядит проблемным.
|
||
|
||
### 7.5. Ограничения
|
||
|
||
Что не удалось проверить полностью, если такое есть.
|
||
|
||
### 7.6. Следующее действие
|
||
|
||
Что стоит посмотреть или проверить дальше.
|
||
|
||
---
|
||
|
||
### 7.2. Требование к стилю ответа
|
||
|
||
Ответ должен быть:
|
||
|
||
* на русском;
|
||
* коротким, но содержательным;
|
||
* предметным;
|
||
* без route names;
|
||
* без debug-лексики;
|
||
* без пустых формулировок типа “по запросу найдены данные”;
|
||
* без перечисления ссылок без пояснения, зачем они показаны.
|
||
|
||
---
|
||
|
||
## 8. Обязательные шаблоны смысловой структуры ответа
|
||
|
||
### 8.1. Для anomaly / risk / suspicious scan
|
||
|
||
Ответ обязан содержать:
|
||
|
||
* что именно признано аномалией;
|
||
* по каким признакам это признано аномалией;
|
||
* чем запись отличается от нормального поведения;
|
||
* какие объекты наиболее рискованные;
|
||
* в чём риск состоит практически.
|
||
|
||
### 8.2. Для chain / causal / cross-entity explanation
|
||
|
||
Ответ обязан содержать:
|
||
|
||
* какую цепочку система проверяла;
|
||
* где именно найден разрыв или конфликт;
|
||
* какие сущности участвуют в цепочке;
|
||
* почему это считается хвостом, разрывом или зависшей ситуацией.
|
||
|
||
### 8.3. Для ranking / overview / top
|
||
|
||
Ответ обязан содержать:
|
||
|
||
* принцип ранжирования;
|
||
* почему верхние позиции оказались наверху;
|
||
* какие признаки сильнее всего влияли на приоритет.
|
||
|
||
### 8.4. Для canonical factual reply
|
||
|
||
Ответ обязан содержать:
|
||
|
||
* прямой ответ по объекту;
|
||
* источник/основание;
|
||
* при необходимости — уточнение статуса, периода, документа, связанной записи.
|
||
|
||
---
|
||
|
||
## 9. Новый обязательный формат partial answer
|
||
|
||
Если закрыта не вся задача, partial reply обязан быть структурирован так:
|
||
|
||
1. что удалось проверить;
|
||
2. что именно не покрыто;
|
||
3. почему не покрыто;
|
||
4. нужно ли уточнение;
|
||
5. можно ли продолжить по оставшейся части.
|
||
|
||
Недопустимо:
|
||
выдать ответ по одному фрагменту без явной маркировки того, что другие части вопроса потеряны.
|
||
|
||
---
|
||
|
||
## 10. Новые reply types
|
||
|
||
К текущему набору reply/fallback типов нужно добавить или закрепить отдельно:
|
||
|
||
* `factual`
|
||
* `factual_with_explanation`
|
||
* `partial_coverage`
|
||
* `clarification_required`
|
||
* `empty_but_valid`
|
||
* `no_grounded_answer`
|
||
* `route_mismatch_blocked`
|
||
* `backend_error`
|
||
|
||
Это нужно, чтобы различать:
|
||
просто технически успешный ответ и
|
||
семантически валидный ответ с объяснимым основанием.
|
||
|
||
---
|
||
|
||
## 11. Что нужно изменить в логировании
|
||
|
||
К уже существующим логам надо добавить поля, которые позволят анализировать именно смысловую пригодность ответа, а не только route/fallback. Сейчас логирование уже есть, но его надо расширить для field hardening.
|
||
|
||
### Добавить в structured log:
|
||
|
||
* `requirements_extracted`
|
||
* `requirements_total`
|
||
* `requirements_covered`
|
||
* `requirements_uncovered`
|
||
* `coverage_status`
|
||
* `answer_grounding_status`
|
||
* `reply_semantic_type`
|
||
* `why_included_summary`
|
||
* `selection_reason_summary`
|
||
* `route_subject_match`
|
||
* `clarification_target`
|
||
* `dropped_intent_segments`
|
||
|
||
---
|
||
|
||
## 12. Что нужно изменить в UI
|
||
|
||
Debug drawer остаётся, но в основном ответе надо показывать не только итог, а и короткий explainable summary.
|
||
|
||
### В bubble ответа ассистента показывать:
|
||
|
||
* краткий вывод;
|
||
* короткий блок “почему это попало в ответ”;
|
||
* по необходимости — список объектов;
|
||
* по необходимости — блок “что проверить дальше”.
|
||
|
||
### В debug drawer переносить:
|
||
|
||
* raw fragments;
|
||
* route selection;
|
||
* trace id;
|
||
* fallback state;
|
||
* raw retrieval payloads;
|
||
* coverage report;
|
||
* grounding check result.
|
||
|
||
---
|
||
|
||
## 13. Новые критерии приёмки этапа
|
||
|
||
Этап считается принятым только если выполнены все условия:
|
||
|
||
1. ассистент отвечает по предмету вопроса, а не по ближайшему соседнему route;
|
||
2. каждый factual answer содержит объяснение, почему объект/запись/контрагент попал в ответ;
|
||
3. для каждого многосоставного вопроса система фиксирует coverage report;
|
||
4. система не теряет части вопроса молча;
|
||
5. если покрыта только часть — это явно отмечено в ответе;
|
||
6. если предмет ответа съехал — ответ блокируется как `route_mismatch_blocked` или `no_grounded_answer`;
|
||
7. anomaly-ответы объясняют признак аномалии, а не только выводят список сущностей;
|
||
8. chain-ответы объясняют разрыв цепочки, а не только перечисляют документы;
|
||
9. в основном ответе нет route names, trace, sandbox wording и другого внутреннего мусора;
|
||
10. debug остаётся доступен отдельно и не ломает основной UX.
|
||
|
||
---
|
||
|
||
## 14. Минимальный MVP этого дополнения
|
||
|
||
### MVP-1
|
||
|
||
Внедрить:
|
||
|
||
* `requirements` + `coverage report`;
|
||
* расширенный unified result schema;
|
||
* `Answer Grounding Check`;
|
||
* explainable answer contract хотя бы для:
|
||
|
||
* `store_feature_risk`
|
||
* `hybrid_store_plus_live`
|
||
|
||
### MVP-2
|
||
|
||
Добавить explainable templates для:
|
||
|
||
* `batch_refresh_then_store`
|
||
* `store_canonical`
|
||
|
||
### MVP-3
|
||
|
||
Дополировать:
|
||
|
||
* richer explanation formatting;
|
||
* confidence/limitations;
|
||
* better partial answer behavior;
|
||
* трассировку semantic failures.
|
||
|
||
---
|
||
|
||
## 15. Что считать провалом этапа
|
||
|
||
Этап не считается выполненным, если сохраняется хотя бы один из сценариев:
|
||
|
||
* пользователь спросил про аномалию, а получил список без признаков аномальности;
|
||
* пользователь задал многосоставной вопрос, а ассистент ответил только на один фрагмент без явной маркировки;
|
||
* ответ предметно съехал в другой участок учёта;
|
||
* ответ содержит ссылки, route names, trace или sandbox-пояснения вместо нормального объяснения;
|
||
* ассистент дал формально связный, но необоснованный вывод без основания отбора.
|
||
|
||
---
|
||
|
||
## 16. Короткий итог для разработчика
|
||
|
||
Задача следующего этапа — не просто улучшить текст ответа.
|
||
|
||
Задача этапа:
|
||
|
||
* сделать декомпозицию **полной**, а не частичной;
|
||
* сделать ответ **объяснимым**, а не декоративно-человекочитаемым;
|
||
* заставить ассистента **доказывать**, почему он выбрал именно эти записи;
|
||
* запретить выдачу ответа, если система не может подтвердить предметную релевантность и полноту покрытия вопроса.
|
||
|
||
---
|
||
|
||
Если хочешь, следующим сообщением я сразу соберу ещё и **сверхкороткую версию для Codex/разработчика на 1 экран**, без пояснений, только требования и acceptance criteria.
|