Initial import NDC_1C
This commit is contained in:
@@ -0,0 +1,541 @@
|
||||
TZ_Assistant_Mode_vNext.md
|
||||
|
||||
## Переход от route-plan ответа к нормальному диалоговому ответу по данным базы
|
||||
|
||||
---
|
||||
|
||||
## 1. Цель этапа
|
||||
|
||||
Превратить текущий Assistant Mode из технического интерфейса, который показывает:
|
||||
|
||||
* decomposition,
|
||||
* route plan,
|
||||
* trace,
|
||||
* sandbox-пояснения,
|
||||
|
||||
в рабочий диалоговый режим, который:
|
||||
|
||||
* принимает вопрос пользователя;
|
||||
* прогоняет его через normalizer/decomposition;
|
||||
* выполняет реальный retrieval/query по маршруту;
|
||||
* получает фактические данные;
|
||||
* собирает **человекочитаемый ответ на русском языке**;
|
||||
* показывает debug только как дополнительный раскрываемый слой.
|
||||
|
||||
---
|
||||
|
||||
## 2. Текущее состояние
|
||||
|
||||
Сейчас Assistant Mode работает как **planner/debug shell**:
|
||||
|
||||
**что уже есть:**
|
||||
|
||||
* ввод вопроса;
|
||||
* decomposition / route selection;
|
||||
* trace id;
|
||||
* debug drawer;
|
||||
* session-based диалоговая оболочка.
|
||||
|
||||
**что отсутствует:**
|
||||
|
||||
* реальный factual retrieval по данным базы;
|
||||
* route-specific execution с возвратом нормальных данных;
|
||||
* финальный answer composition по результатам retrieval;
|
||||
* русскоязычный user-facing reply policy;
|
||||
* разделение user-answer и technical-debug.
|
||||
|
||||
Комментарий:
|
||||
Сейчас пользователь получает “planned routes / sandbox retrieval mode / trace”,
|
||||
а должен получать ответ по сути вопроса.
|
||||
|
||||
---
|
||||
|
||||
## 3. Новая целевая архитектура
|
||||
|
||||
Нужен полный контур:
|
||||
|
||||
**User message → Normalizer → Execution Planner → Route-specific Retrieval → Result Normalization → Final Answer Composer → Assistant Reply**
|
||||
|
||||
---
|
||||
|
||||
## 4. Что должно происходить после сообщения пользователя
|
||||
|
||||
## 4.1. Шаг 1 — Normalization
|
||||
|
||||
Оставляем текущий `normalizer_v2.x`:
|
||||
|
||||
* scope filter;
|
||||
* fragments;
|
||||
* execution readiness;
|
||||
* route status;
|
||||
* clarification/out-of-scope detection.
|
||||
|
||||
## 4.2. Шаг 2 — Execution planning
|
||||
|
||||
Для каждого исполнимого fragment:
|
||||
|
||||
* определить маршрут;
|
||||
* собрать execution plan;
|
||||
* передать fragment в route-specific executor.
|
||||
|
||||
## 4.3. Шаг 3 — Real retrieval / query
|
||||
|
||||
Вместо sandbox plan нужно выполнять **реальный вызов backend data layer**:
|
||||
|
||||
* к 1С / хранилищу / API / query handlers;
|
||||
* получать фактические данные;
|
||||
* нормализовать их в общий result schema.
|
||||
|
||||
## 4.4. Шаг 4 — Final answer composition
|
||||
|
||||
На основе:
|
||||
|
||||
* user message,
|
||||
* fragments,
|
||||
* data results,
|
||||
* fallback state
|
||||
|
||||
нужно собрать **один нормальный ответ для пользователя**.
|
||||
|
||||
---
|
||||
|
||||
# 5. Главный принцип нового режима
|
||||
|
||||
## Пользователь не должен видеть:
|
||||
|
||||
* planned routes;
|
||||
* store canonical selected;
|
||||
* sandbox retrieval mode;
|
||||
* raw trace explanation;
|
||||
* транслит;
|
||||
* служебные внутренние названия маршрутов.
|
||||
|
||||
## Пользователь должен видеть:
|
||||
|
||||
* нормальный русский ответ;
|
||||
* если данных нет — понятное объяснение;
|
||||
* если нужен clarification — уточняющий вопрос;
|
||||
* если часть вопроса вне контура — вежливое ограничение;
|
||||
* при желании — кнопку “Показать технический разбор”.
|
||||
|
||||
---
|
||||
|
||||
# 6. Новый слой: Route-specific factual retrieval
|
||||
|
||||
---
|
||||
|
||||
## 6.1. Для каждого route нужен executor
|
||||
|
||||
Нужно реализовать route executors как отдельные backend handlers.
|
||||
|
||||
### A. `hybrid_store_plus_live`
|
||||
|
||||
Для causal / cross-entity / chain queries:
|
||||
|
||||
* искать связанные сущности;
|
||||
* возвращать:
|
||||
|
||||
* контрагент/объект,
|
||||
* документы,
|
||||
* оплаты,
|
||||
* проводки,
|
||||
* подтверждающие связи,
|
||||
* признаки разрыва цепочки.
|
||||
|
||||
### B. `store_feature_risk`
|
||||
|
||||
Для anomaly / rule-check / suspicious scan:
|
||||
|
||||
* искать проблемные объекты/записи;
|
||||
* возвращать:
|
||||
|
||||
* сущность,
|
||||
* причина попадания,
|
||||
* риск-признак,
|
||||
* релевантные поля.
|
||||
|
||||
### C. `batch_refresh_then_store`
|
||||
|
||||
Для overview / ranking / top / period risk:
|
||||
|
||||
* возвращать агрегаты;
|
||||
* топы;
|
||||
* summary blocks;
|
||||
* приоритеты проверки;
|
||||
* зоны риска.
|
||||
|
||||
### D. `store_canonical`
|
||||
|
||||
Для canonical factual path:
|
||||
|
||||
* выдавать прямую фактическую информацию по каноническому учётному представлению.
|
||||
|
||||
### E. `live_mcp_drilldown` (если уже подключён)
|
||||
|
||||
Для точечного drilldown:
|
||||
|
||||
* конкретный документ;
|
||||
* конкретная проводка;
|
||||
* конкретный объект;
|
||||
* source-of-record.
|
||||
|
||||
---
|
||||
|
||||
## 6.2. Все executors должны возвращать unified result schema
|
||||
|
||||
Нужен единый формат результата, чтобы answer composer не зависел от route руками.
|
||||
|
||||
Примерно так:
|
||||
|
||||
```json
|
||||
{
|
||||
"fragment_id": "F1",
|
||||
"route": "hybrid_store_plus_live",
|
||||
"status": "ok | empty | partial | error",
|
||||
"result_type": "list | summary | object | chain | ranking",
|
||||
"items": [],
|
||||
"summary": {},
|
||||
"evidence": [],
|
||||
"errors": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 7. Новый слой: Result normalization
|
||||
|
||||
Перед финальной генерацией ответа retrieval-результаты нужно привести в нормализованный вид.
|
||||
|
||||
Нужен слой:
|
||||
|
||||
* `normalize_retrieval_result(fragment, raw_backend_result)`
|
||||
|
||||
Задача:
|
||||
|
||||
* привести все маршруты к общему формату;
|
||||
* отдать composer понятный и предсказуемый payload.
|
||||
|
||||
---
|
||||
|
||||
# 8. Новый слой: Final Answer Composer
|
||||
|
||||
Это ключевой этап.
|
||||
|
||||
## 8.1. Что он получает
|
||||
|
||||
На вход:
|
||||
|
||||
* `user_message`
|
||||
* `normalized_query_v2_x`
|
||||
* `resolved_fragments`
|
||||
* `retrieval_results`
|
||||
* `fallback state`
|
||||
* `session context`
|
||||
|
||||
## 8.2. Что он должен делать
|
||||
|
||||
Собирать **один связный user-facing ответ**.
|
||||
|
||||
### Если один fragment
|
||||
|
||||
Отвечать прямо по вопросу.
|
||||
|
||||
### Если несколько fragments
|
||||
|
||||
Собирать один ответ с понятной структурой:
|
||||
|
||||
* сначала общий вывод;
|
||||
* потом блоки по подзадачам;
|
||||
* без ощущения, что это 5 несвязанных кусков.
|
||||
|
||||
### Если часть вопроса не выполнима
|
||||
|
||||
Отвечать по доступной части и мягко пояснять ограничения.
|
||||
|
||||
---
|
||||
|
||||
## 8.3. Ответ должен быть на русском
|
||||
|
||||
Жёсткое требование:
|
||||
|
||||
* никакого транслита;
|
||||
* никаких англоязычных route names в тексте;
|
||||
* никаких внутренних служебных формулировок.
|
||||
|
||||
---
|
||||
|
||||
## 8.4. Ответ не должен быть “сухой отладкой”
|
||||
|
||||
Нельзя выводить пользователю:
|
||||
|
||||
* `planned routes`
|
||||
* `trace`
|
||||
* `store canonical selected`
|
||||
* `fallback_type=...`
|
||||
|
||||
Это всё — только в debug drawer.
|
||||
|
||||
---
|
||||
|
||||
# 9. Типы user-facing ответов
|
||||
|
||||
---
|
||||
|
||||
## 9.1. Normal factual reply
|
||||
|
||||
Когда данные найдены.
|
||||
|
||||
Пример:
|
||||
|
||||
* перечисление поставщиков с хвостами;
|
||||
* список проблемных объектов;
|
||||
* summary по рискам;
|
||||
* ranking.
|
||||
|
||||
## 9.2. Empty result reply
|
||||
|
||||
Когда запрос корректен, но ничего не найдено.
|
||||
|
||||
Пример:
|
||||
|
||||
> По текущим данным явных проблемных записей по этому условию не найдено.
|
||||
|
||||
## 9.3. Partial reply
|
||||
|
||||
Когда по части вопроса данные найдены, по части — нет.
|
||||
|
||||
## 9.4. Clarification reply
|
||||
|
||||
Когда нужно уточнение.
|
||||
|
||||
## 9.5. Out-of-scope reply
|
||||
|
||||
Когда вопрос не про базу компании.
|
||||
|
||||
## 9.6. Backend error reply
|
||||
|
||||
Когда retrieval сломался технически.
|
||||
|
||||
Пример:
|
||||
|
||||
> Не удалось получить данные из контура. Попробуйте повторить запрос или уточнить формулировку.
|
||||
|
||||
---
|
||||
|
||||
# 10. Нужно разделить два уровня ответа
|
||||
|
||||
---
|
||||
|
||||
## 10.1. User Reply
|
||||
|
||||
То, что человек видит в чате.
|
||||
|
||||
## 10.2. Debug Payload
|
||||
|
||||
То, что раскрывается по кнопке:
|
||||
|
||||
* fragments
|
||||
* execution readiness
|
||||
* route status
|
||||
* no_route_reason
|
||||
* retrieval status
|
||||
* trace id
|
||||
|
||||
Это должно жить отдельно.
|
||||
|
||||
---
|
||||
|
||||
# 11. Что изменить в GUI
|
||||
|
||||
---
|
||||
|
||||
## 11.1. Assistant message bubble
|
||||
|
||||
В ответе ассистента должен отображаться:
|
||||
|
||||
* нормальный текст;
|
||||
* опционально таблица/список результатов, если уместно;
|
||||
* без технического мусора.
|
||||
|
||||
## 11.2. Debug toggle
|
||||
|
||||
Кнопка:
|
||||
|
||||
* `Показать разбор`
|
||||
или
|
||||
* `Технические детали`
|
||||
|
||||
Внутри:
|
||||
|
||||
* decomposition;
|
||||
* routes;
|
||||
* fragments;
|
||||
* trace id;
|
||||
* backend status;
|
||||
* fallback state.
|
||||
|
||||
## 11.3. Loading states
|
||||
|
||||
Во время выполнения:
|
||||
|
||||
* `Разбираю запрос`
|
||||
* `Ищу данные`
|
||||
* `Собираю ответ`
|
||||
|
||||
---
|
||||
|
||||
# 12. Что изменить в backend API
|
||||
|
||||
Нужен нормальный assistant endpoint, который возвращает уже готовый user reply.
|
||||
|
||||
## Пример
|
||||
|
||||
`POST /api/assistant/message`
|
||||
|
||||
### Request
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "...",
|
||||
"message": "...",
|
||||
"mode": "assistant",
|
||||
"period_hint": "...",
|
||||
"business_context": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"assistant_reply": "человекочитаемый ответ",
|
||||
"reply_type": "factual | clarification | out_of_scope | partial | empty | error",
|
||||
"debug": {
|
||||
"trace_id": "...",
|
||||
"fragments": [...],
|
||||
"routes": [...],
|
||||
"retrieval_status": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 13. Что логировать
|
||||
|
||||
Для каждого сообщения логировать:
|
||||
|
||||
* `session_id`
|
||||
* `message_id`
|
||||
* `user_message`
|
||||
* `normalizer_output`
|
||||
* `execution_plan`
|
||||
* `retrieval_calls`
|
||||
* `retrieval_results_raw`
|
||||
* `retrieval_results_normalized`
|
||||
* `assistant_reply`
|
||||
* `reply_type`
|
||||
* `trace_id`
|
||||
|
||||
Это пригодится потом для field-based hardening.
|
||||
|
||||
---
|
||||
|
||||
# 14. Минимальный MVP этого этапа
|
||||
|
||||
Чтобы не расползтись, можно сделать MVP так:
|
||||
|
||||
### Этап MVP-1
|
||||
|
||||
Сделать хотя бы 2 полноценных route executor:
|
||||
|
||||
* `hybrid_store_plus_live`
|
||||
* `store_feature_risk`
|
||||
|
||||
И уже через них показать нормальный user-facing reply.
|
||||
|
||||
### Этап MVP-2
|
||||
|
||||
Добавить:
|
||||
|
||||
* `batch_refresh_then_store`
|
||||
* `store_canonical`
|
||||
|
||||
### Этап MVP-3
|
||||
|
||||
Дополировать:
|
||||
|
||||
* partial replies
|
||||
* better formatting
|
||||
* richer debug drawer
|
||||
|
||||
---
|
||||
|
||||
# 15. Формат ответа ассистента
|
||||
|
||||
Ответ должен быть:
|
||||
|
||||
* на русском;
|
||||
* коротким, но содержательным;
|
||||
* с понятной привязкой к вопросу;
|
||||
* без внутренних названий маршрутов.
|
||||
|
||||
### Пример плохого ответа
|
||||
|
||||
> Planned routes: store canonical. Sandbox mode. Trace...
|
||||
|
||||
### Пример допустимого ответа
|
||||
|
||||
> По текущему запросу найдены проблемные хвосты по нескольким поставщикам.
|
||||
> Основные расхождения связаны с оплатами без корректного закрытия и неполной связкой документов.
|
||||
> Ниже показаны контрагенты и проблемные цепочки.
|
||||
|
||||
---
|
||||
|
||||
# 16. Что НЕ делать на этом этапе
|
||||
|
||||
Не надо сейчас:
|
||||
|
||||
* строить суперсложную агентную систему;
|
||||
* делать память на долгий диалог;
|
||||
* пытаться решить все типы route сразу идеально;
|
||||
* снова уходить в synthetic eval hardening;
|
||||
* показывать пользователю внутреннюю кухню как основной результат.
|
||||
|
||||
---
|
||||
|
||||
# 17. Критерии приёмки
|
||||
|
||||
Этап считается принятым, если:
|
||||
|
||||
1. Assistant Mode возвращает **русский человекочитаемый ответ**, а не route plan;
|
||||
2. debug остаётся доступен, но вынесен отдельно;
|
||||
3. хотя бы для 2 route’ов работает полный factual loop:
|
||||
|
||||
* question → retrieval → factual reply;
|
||||
4. out-of-scope / clarification / partial fallback корректно отображаются в чате;
|
||||
5. decomposition mode не сломан;
|
||||
6. транслит и технический мусор исчезли из основного ответа.
|
||||
|
||||
---
|
||||
|
||||
# 18. Артефакты, которые должен выдать Codex
|
||||
|
||||
1. `docs/assistant_mode_vnext_spec.md`
|
||||
2. `docs/route_executor_contracts.md`
|
||||
3. `docs/final_answer_composer_spec.md`
|
||||
4. backend endpoint для assistant reply
|
||||
5. unified retrieval result schema
|
||||
6. GUI update для user-facing reply + debug drawer
|
||||
7. `docs/known_limits_current_routes.md`
|
||||
|
||||
---
|
||||
|
||||
# 19. Короткий итог
|
||||
|
||||
Следующий шаг — это уже **не normalizer**, а:
|
||||
|
||||
**сделать так, чтобы ассистент после нормализации реально ходил за фактами и отвечал человеку по сути, а не показывал внутренний план работы.**
|
||||
|
||||
Если хочешь, я следующим сообщением сделаю ещё **короткую жёсткую версию этого ТЗ для вставки в Codex**.
|
||||
Reference in New Issue
Block a user