NODEDC_1C/docs/ARCH/5 - assistant_mode_architec...

13 KiB
Raw Blame History

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.ts
  • llm_normalizer/backend/src/services/assistantService.ts
  • llm_normalizer/backend/src/services/answerComposer.ts
  • llm_normalizer/backend/src/services/assistantSessionStore.ts
  • llm_normalizer/backend/src/types/assistant.ts
  • llm_normalizer/backend/src/services/routeHintAdapter.ts (общий deterministic routing)
  • llm_normalizer/backend/src/services/normalizerService.ts (общий normalizer pipeline)

Подключение в сервер:

  • llm_normalizer/backend/src/server.ts
  • llm_normalizer/backend/src/serverContext.ts

2.2 Frontend

Ключевые узлы:

  • llm_normalizer/frontend/src/App.tsx (mode switch + orchestration)
  • llm_normalizer/frontend/src/components/AssistantPanel.tsx
  • llm_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

Ключевые сущности:

  • AssistantMessageRequestPayload
  • AssistantDebugPayload
  • AssistantConversationItem
  • AssistantMessageResponsePayload

fallback_type (жестко зафиксированный набор):

  • none
  • out_of_scope
  • clarification
  • partial
  • unknown

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

Порядок выполнения:

  1. ensureSession -> получаем/создаем session_id.
  2. Сохраняем user message как conversation item (role=user).
  3. Формируем NormalizeRequestPayload с:
    • promptVersion по умолчанию normalizer_v2_0_2,
    • connection/prompt/context/useMock из запроса.
  4. Вызываем normalizerService.normalize(...).
  5. По route_hint_summary строим retrieval plan (buildRetrievalPlan).
  6. Передаем данные в composeAssistantAnswer(...).
  7. Формируем debug payload:
    • trace_id,
    • route_summary,
    • fragments,
    • retrieval,
    • normalized.
  8. Сохраняем assistant message как conversation item (role=assistant).
  9. Логируем structured event assistant_message_processed.
  10. Возвращаем:
  • assistant_reply,
  • conversation_item,
  • debug,
  • conversation.

3.5 Routing rules (общий deterministic v2 engine)

Основные правила маршрутизации берутся из:

  • llm_normalizer/backend/src/services/routeHintAdapter.ts

Правила выбора маршрута:

  1. live_mcp_drilldown
    • если asks_for_exact_object_trace = true.
  2. batch_refresh_then_store
    • если asks_for_ranking_or_top = true или asks_for_period_summary = true.
  3. hybrid_store_plus_live
    • если has_multi_entity_scope = true и asks_for_chain_explanation = true.
  4. store_feature_risk
    • если asks_for_rule_check = true и не chain;
    • также anomaly path: asks_for_anomaly_scan = true без ranking и без multi-entity chain.
  5. store_canonical
    • default routed путь для in-scope, если нет более сильного сигнала.
  6. 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

Логика:

  1. out_of_scope
    • вежливый boundary response (работа только по company-specific accounting contour).
  2. clarification
    • конкретный уточняющий ответ: период/счет/документ/контрагент.
  3. partial
    • сообщает, что обработана только часть запроса;
    • выводит routed части;
    • явно фиксирует sandbox retrieval mode.
  4. none
    • human-readable summary с перечислением planned routes.
  5. 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_id
  • message_id
  • user_message
  • normalizer_output
  • resolved_execution_state
  • routes
  • fallback_type
  • retrieval_payloads
  • assistant_reply
  • trace_id

Это дает базу для будущего field-eval hardening.


4. Frontend: функциональная архитектура

4.1 Режимы UI

Реализовано в:

  • llm_normalizer/frontend/src/App.tsx

Есть явный переключатель:

  • Assistant
  • Decomposition

Поведение:

  • backend pipeline общий;
  • UI-представление разное;
  • decomposition stack не ломается и остается доступным.

4.2 Assistant Mode UI состав

Реализовано в:

  • llm_normalizer/frontend/src/components/AssistantPanel.tsx

Элементы:

  1. Chat timeline:
    • user/assistant messages,
    • timestamp,
    • trace id для assistant сообщений.
  2. Input зона:
    • поле сообщения,
    • send,
    • reset session.
  3. Контекст:
    • periodHint
    • businessContext
  4. Toggle:
    • useMock.
  5. Debug drawer:
    • раскрывается per assistant message,
    • показывает raw debug JSON (trace/fragments/routes/fallback/retrieval/normalized).

4.3 Pipeline progress UX

Во время обработки показывается этапный status ticker:

  1. Razbirayu zapros
  2. Proveryayu kontur
  3. Opredelyayu marshrut
  4. Ishchu dannye
  5. Sobirayu otvet

Цель: убрать ощущение “зависло” и визуализировать pipeline.


4.4 Frontend state flow

Ключевые state переменные:

  • uiMode
  • assistantSessionId
  • assistantConversation
  • assistantInput
  • assistantBusy
  • assistantStatus
  • assistantError

Flow отправки:

  1. optimistic append user message в chat;
  2. запуск status ticker;
  3. вызов apiClient.sendAssistantMessage(...);
  4. обновление session_id и полной conversation с backend;
  5. остановка ticker + финальный статус.

4.5 API client для Assistant

Реализовано в:

  • llm_normalizer/frontend/src/api/client.ts

Добавлены методы:

  • sendAssistantMessage(...) -> POST /api/assistant/message
  • loadAssistantSession(sessionId) -> GET /api/assistant/session/:id

5. Что сделано по требованиям ТЗ (mapping)

  1. docs/assistant_mode_spec.md — выполнено
  2. GUI с переключателем Assistant / Decomposition — выполнено
  3. backend endpoint assistant loop — выполнено
  4. answer_composer слой — выполнено
  5. session-based chat history — выполнено (in-memory)
  6. debug drawer/expandable technical view — выполнено
  7. docs/assistant_mode_flow.md — выполнено
  8. docs/known_limits_before_field_eval.md — выполнено

6. Критические ограничения текущей реализации

  1. retrieval sandbox/stubbed
    • assistant выдает план/маршрут, не full factual extraction по всем route.
  2. session memory volatile
    • хранится только в памяти backend процесса.
  3. нет production hardening
    • auth/tenancy/persistence/SLO не включены.
  4. 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

  1. Переключить mode -> Assistant.
  2. Ввести сообщение в чат.
  3. Нажать Send.
  4. Проверить:
    • появился 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,
  • сбор 3040 реальных полевых запросов,
  • policy hardening по traces (clarification/no-route/partial quality).