13 KiB
5 - Assistant Mode Architecture Report (2026-03-24)
1. Статус этапа
Дата фиксации: 24 марта 2026.
На текущем этапе реализован рабочий Assistant Mode поверх существующего Decomposition контура:
- decomposition/debug режим сохранен и не удален;
- добавлен отдельный backend endpoint для assistant-loop;
- добавлен слой
answer_composer(human-readable ответ); - добавлена session-scoped история диалога (in-memory);
- добавлен debug drawer в GUI по каждому assistant ответу;
- единый pipeline нормализации/маршрутизации используется для обоих режимов.
2. Что входит в текущую архитектуру
2.1 Backend
Ключевые узлы:
llm_normalizer/backend/src/routes/assistant.tsllm_normalizer/backend/src/services/assistantService.tsllm_normalizer/backend/src/services/answerComposer.tsllm_normalizer/backend/src/services/assistantSessionStore.tsllm_normalizer/backend/src/types/assistant.tsllm_normalizer/backend/src/services/routeHintAdapter.ts(общий deterministic routing)llm_normalizer/backend/src/services/normalizerService.ts(общий normalizer pipeline)
Подключение в сервер:
llm_normalizer/backend/src/server.tsllm_normalizer/backend/src/serverContext.ts
2.2 Frontend
Ключевые узлы:
llm_normalizer/frontend/src/App.tsx(mode switch + orchestration)llm_normalizer/frontend/src/components/AssistantPanel.tsxllm_normalizer/frontend/src/api/client.ts(assistant API methods)llm_normalizer/frontend/src/state/types.ts(assistant типы состояния)llm_normalizer/frontend/src/styles.css(assistant/mode switch UI стиль)
3. Backend: функциональная архитектура
3.1 Endpoint’ы
3.1.1 POST /api/assistant/message
Назначение:
- принять user message;
- прогнать через normalizer pipeline;
- определить route/fallback;
- собрать human-readable assistant reply;
- вернуть reply + debug + session conversation snapshot.
Проверки:
user_messageобязателен;- при пустом сообщении возвращается
INVALID_ASSISTANT_MESSAGE(HTTP 400).
3.1.2 GET /api/assistant/session/:session_id
Назначение:
- вернуть текущую историю сессии из in-memory store.
Поведение:
- если сессия отсутствует:
ASSISTANT_SESSION_NOT_FOUND(HTTP 404).
3.2 Контракт данных Assistant Mode
Типы заданы в:
llm_normalizer/backend/src/types/assistant.ts
Ключевые сущности:
AssistantMessageRequestPayloadAssistantDebugPayloadAssistantConversationItemAssistantMessageResponsePayload
fallback_type (жестко зафиксированный набор):
noneout_of_scopeclarificationpartialunknown
3.3 Session memory
Реализовано в:
llm_normalizer/backend/src/services/assistantSessionStore.ts
Характеристики:
- хранилище: in-memory
Map<session_id, session_state>; - auto-create сессии при первом сообщении;
- ограничение длины:
MAX_ITEMS_PER_SESSION = 200; - хранение только в рамках текущего backend процесса;
- при рестарте backend память очищается.
Это deliberate решение текущего этапа (sandbox/stage), без persistent storage.
3.4 Assistant pipeline (внутренний flow)
Реализовано в:
llm_normalizer/backend/src/services/assistantService.ts
Порядок выполнения:
ensureSession-> получаем/создаемsession_id.- Сохраняем user message как conversation item (
role=user). - Формируем
NormalizeRequestPayloadс:promptVersionпо умолчаниюnormalizer_v2_0_2,- connection/prompt/context/useMock из запроса.
- Вызываем
normalizerService.normalize(...). - По
route_hint_summaryстроим retrieval plan (buildRetrievalPlan). - Передаем данные в
composeAssistantAnswer(...). - Формируем
debugpayload:trace_id,route_summary,fragments,retrieval,normalized.
- Сохраняем assistant message как conversation item (
role=assistant). - Логируем structured event
assistant_message_processed. - Возвращаем:
assistant_reply,conversation_item,debug,conversation.
3.5 Routing rules (общий deterministic v2 engine)
Основные правила маршрутизации берутся из:
llm_normalizer/backend/src/services/routeHintAdapter.ts
Правила выбора маршрута:
live_mcp_drilldown- если
asks_for_exact_object_trace = true.
- если
batch_refresh_then_store- если
asks_for_ranking_or_top = trueилиasks_for_period_summary = true.
- если
hybrid_store_plus_live- если
has_multi_entity_scope = trueиasks_for_chain_explanation = true.
- если
store_feature_risk- если
asks_for_rule_check = trueи не chain; - также anomaly path:
asks_for_anomaly_scan = trueбез ranking и без multi-entity chain.
- если
store_canonical- default routed путь для in-scope, если нет более сильного сигнала.
no_route- если fragment out-of-scope / insufficient specificity / missing mapping / unsupported fragment type.
Fallback type в summary:
out_of_scope— сообщение вне контура;clarification— нет routable in-scope fragment’ов из-за недоспецификации;partial— часть in-scope/routed, часть no-route/out-of-scope;none— все ок для текущего контура.
3.6 Answer composer rules
Реализовано в:
llm_normalizer/backend/src/services/answerComposer.ts
Логика:
out_of_scope- вежливый boundary response (работа только по company-specific accounting contour).
clarification- конкретный уточняющий ответ: период/счет/документ/контрагент.
partial- сообщает, что обработана только часть запроса;
- выводит routed части;
- явно фиксирует sandbox retrieval mode.
none- human-readable summary с перечислением planned routes.
unknown- защитный fallback, если routed items не сформированы.
Важно:
- на этом этапе composer формирует человеко-читаемый operational ответ;
- это не финальный production-grade semantic answer over full live retrieval.
3.7 Retrieval слой (текущий статус)
Текущее состояние: stubbed / sandbox retrieval plan.
Что есть:
- генерация плана “что и по какому route исполнять”;
- диагностический payload по fragment’ам.
Чего пока нет:
- боевой deep retrieval из 1С по всем route;
- гарантированного factual grounding для каждого ответа assistant mode.
3.8 Логирование и трассировка
В assistantService пишется structured log c событием:
assistant_message_processed
Поля:
session_idmessage_iduser_messagenormalizer_outputresolved_execution_stateroutesfallback_typeretrieval_payloadsassistant_replytrace_id
Это дает базу для будущего field-eval hardening.
4. Frontend: функциональная архитектура
4.1 Режимы UI
Реализовано в:
llm_normalizer/frontend/src/App.tsx
Есть явный переключатель:
AssistantDecomposition
Поведение:
- backend pipeline общий;
- UI-представление разное;
- decomposition stack не ломается и остается доступным.
4.2 Assistant Mode UI состав
Реализовано в:
llm_normalizer/frontend/src/components/AssistantPanel.tsx
Элементы:
- Chat timeline:
- user/assistant messages,
- timestamp,
- trace id для assistant сообщений.
- Input зона:
- поле сообщения,
- send,
- reset session.
- Контекст:
periodHintbusinessContext
- Toggle:
useMock.
- Debug drawer:
- раскрывается per assistant message,
- показывает raw debug JSON (
trace/fragments/routes/fallback/retrieval/normalized).
4.3 Pipeline progress UX
Во время обработки показывается этапный status ticker:
Razbirayu zaprosProveryayu konturOpredelyayu marshrutIshchu dannyeSobirayu otvet
Цель: убрать ощущение “зависло” и визуализировать pipeline.
4.4 Frontend state flow
Ключевые state переменные:
uiModeassistantSessionIdassistantConversationassistantInputassistantBusyassistantStatusassistantError
Flow отправки:
- optimistic append user message в chat;
- запуск status ticker;
- вызов
apiClient.sendAssistantMessage(...); - обновление
session_idи полной conversation с backend; - остановка ticker + финальный статус.
4.5 API client для Assistant
Реализовано в:
llm_normalizer/frontend/src/api/client.ts
Добавлены методы:
sendAssistantMessage(...)->POST /api/assistant/messageloadAssistantSession(sessionId)->GET /api/assistant/session/:id
5. Что сделано по требованиям ТЗ (mapping)
docs/assistant_mode_spec.md— выполнено- GUI с переключателем
Assistant/Decomposition— выполнено - backend endpoint assistant loop — выполнено
answer_composerслой — выполнено- session-based chat history — выполнено (in-memory)
- debug drawer/expandable technical view — выполнено
docs/assistant_mode_flow.md— выполненоdocs/known_limits_before_field_eval.md— выполнено
6. Критические ограничения текущей реализации
- retrieval sandbox/stubbed
- assistant выдает план/маршрут, не full factual extraction по всем route.
- session memory volatile
- хранится только в памяти backend процесса.
- нет production hardening
- auth/tenancy/persistence/SLO не включены.
- composer базовый
- достаточен для MVP loop, но не финальный policy-grade layer.
7. Запуск и проверка на новой машине (текущий этап)
7.1 Backend
cd X:\1C\NDC_1C\llm_normalizer\backend
npm install
npm run dev
7.2 Frontend
cd X:\1C\NDC_1C\llm_normalizer\frontend
npm install
npm run dev
7.3 Открыть GUI
http://localhost:5174
7.4 Smoke test Assistant Mode
- Переключить mode ->
Assistant. - Ввести сообщение в чат.
- Нажать
Send. - Проверить:
- появился assistant reply;
- появился trace id;
- открывается debug drawer;
- session сохраняет историю.
8. Тестовый статус к моменту фиксации
Проверки выполнены 24.03.2026:
- backend tests:
npm test-> 21 passed - backend build:
npm run build-> OK - frontend build:
npm run build-> OK
Также добавлен endpoint test:
llm_normalizer/backend/tests/assistantEndpoint.test.ts
Покрывает:
- успешный
POST /api/assistant/message; - session continuity;
GET /api/assistant/session/:session_id.
9. Архитектурный итог этапа
Текущий Assistant Mode — это уже usable dialog loop:
- user-friendly вход (чат),
- deterministic decomposition/routing ядро,
- единый backend pipeline,
- прозрачная debug-плоскость для инженерной диагностики,
- session-based continuity в рамках процесса.
Для перехода в следующий уровень (field-hardened assistant) нужен следующий блок:
- подключение route-specific factual retrieval,
- сбор 30–40 реальных полевых запросов,
- policy hardening по traces (clarification/no-route/partial quality).