14 KiB
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 руками.
Примерно так:
{
"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_messagenormalized_query_v2_xresolved_fragmentsretrieval_resultsfallback statesession context
8.2. Что он должен делать
Собирать один связный user-facing ответ.
Если один fragment
Отвечать прямо по вопросу.
Если несколько fragments
Собирать один ответ с понятной структурой:
- сначала общий вывод;
- потом блоки по подзадачам;
- без ощущения, что это 5 несвязанных кусков.
Если часть вопроса не выполнима
Отвечать по доступной части и мягко пояснять ограничения.
8.3. Ответ должен быть на русском
Жёсткое требование:
- никакого транслита;
- никаких англоязычных route names в тексте;
- никаких внутренних служебных формулировок.
8.4. Ответ не должен быть “сухой отладкой”
Нельзя выводить пользователю:
planned routestracestore canonical selectedfallback_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
{
"session_id": "...",
"message": "...",
"mode": "assistant",
"period_hint": "...",
"business_context": "..."
}
Response
{
"ok": true,
"assistant_reply": "человекочитаемый ответ",
"reply_type": "factual | clarification | out_of_scope | partial | empty | error",
"debug": {
"trace_id": "...",
"fragments": [...],
"routes": [...],
"retrieval_status": [...]
}
}
13. Что логировать
Для каждого сообщения логировать:
session_idmessage_iduser_messagenormalizer_outputexecution_planretrieval_callsretrieval_results_rawretrieval_results_normalizedassistant_replyreply_typetrace_id
Это пригодится потом для field-based hardening.
14. Минимальный MVP этого этапа
Чтобы не расползтись, можно сделать MVP так:
Этап MVP-1
Сделать хотя бы 2 полноценных route executor:
hybrid_store_plus_livestore_feature_risk
И уже через них показать нормальный user-facing reply.
Этап MVP-2
Добавить:
batch_refresh_then_storestore_canonical
Этап MVP-3
Дополировать:
- partial replies
- better formatting
- richer debug drawer
15. Формат ответа ассистента
Ответ должен быть:
- на русском;
- коротким, но содержательным;
- с понятной привязкой к вопросу;
- без внутренних названий маршрутов.
Пример плохого ответа
Planned routes: store canonical. Sandbox mode. Trace...
Пример допустимого ответа
По текущему запросу найдены проблемные хвосты по нескольким поставщикам. Основные расхождения связаны с оплатами без корректного закрытия и неполной связкой документов. Ниже показаны контрагенты и проблемные цепочки.
16. Что НЕ делать на этом этапе
Не надо сейчас:
- строить суперсложную агентную систему;
- делать память на долгий диалог;
- пытаться решить все типы route сразу идеально;
- снова уходить в synthetic eval hardening;
- показывать пользователю внутреннюю кухню как основной результат.
17. Критерии приёмки
Этап считается принятым, если:
-
Assistant Mode возвращает русский человекочитаемый ответ, а не route plan;
-
debug остаётся доступен, но вынесен отдельно;
-
хотя бы для 2 route’ов работает полный factual loop:
- question → retrieval → factual reply;
-
out-of-scope / clarification / partial fallback корректно отображаются в чате;
-
decomposition mode не сломан;
-
транслит и технический мусор исчезли из основного ответа.
18. Артефакты, которые должен выдать Codex
docs/assistant_mode_vnext_spec.mddocs/route_executor_contracts.mddocs/final_answer_composer_spec.md- backend endpoint для assistant reply
- unified retrieval result schema
- GUI update для user-facing reply + debug drawer
docs/known_limits_current_routes.md
19. Короткий итог
Следующий шаг — это уже не normalizer, а:
сделать так, чтобы ассистент после нормализации реально ходил за фактами и отвечал человеку по сути, а не показывал внутренний план работы.
Если хочешь, я следующим сообщением сделаю ещё короткую жёсткую версию этого ТЗ для вставки в Codex.