АДРЕСНЫЙ РЕЖИМ -Step-5 - feat(assistant): стабилизация свободного LLM-роутинга, прическа маршрутов chat/address, прототип прогноза НДС
This commit is contained in:
+2210
-315
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,15 @@
|
||||
- domain live-gate: `docs/ADDRESS/runs/2026-04-08_Address_Batch2_Lifecycle_FullGate_PhaseC_PostFix2/run_summary.json` (`strict 36/36`)
|
||||
- targeted code gate: `addressQueryRuntimeM23.test.ts + assistantAddressFollowupContext.test.ts = 223/223`, `build=PASS`
|
||||
- global non-regression: `docs/ADDRESS/runs/2026-04-08_Address_Nightly_Regression_2026-04-08_13-19-24/nightly_summary.json` (`stress 102/102`, `followup 25/25`, comparator PASS)
|
||||
- Принят `domain scope freeze`: новые домены временно не расширяем; фокус смещен на Step-5 (архитектура + UX + качество ответов).
|
||||
- Step-5 bootstrap (2026-04-08):
|
||||
- UX compose first-line direct-answer patch внедрен;
|
||||
- targeted tests: `220/220 + 3/3`;
|
||||
- live smoke: `docs/ADDRESS/runs/2026-04-08_Address_Step5_UX_Smoke_v2/run_summary.json` (`strict 6/6`).
|
||||
- Step-5 living router increment (2026-04-08):
|
||||
- added `FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1` (default `true`);
|
||||
- added chat mode (`chat`) for non-data conversational messages with safe fallback to deep pipeline;
|
||||
- added OpenAI-compatible `chat()` in `OpenAIResponsesClient` (with local `/responses` -> `/chat/completions` fallback).
|
||||
- Финальный stress-pack: `102/102`
|
||||
`docs/ADDRESS/runs/2026-04-02_Address_Slang_Live_Stress_2026-04-02_12-57-27/run_summary.json`
|
||||
- Финальный follow-up pack: `25/25`
|
||||
@@ -37,7 +46,7 @@
|
||||
`docs/ADDRESS/runs/2026-04-08_Address_Nightly_Regression_2026-04-08_13-19-24/nightly_summary.json`
|
||||
- Task Scheduler: `NDC_ADDRESS_Nightly_Regression` временно `Disabled` (ручной режим до стабилизации infra-канала).
|
||||
- Текущий production-контур: `question_mode=address_query`, live-first через MCP.
|
||||
- Следующий этап: `Step-4` domain expansion по рельсовой модели Step-0.
|
||||
- Следующий этап: `Step-5` Architecture + UX Quality (LLM-first валидация входа, улучшение пользовательского ответа, без расширения domain scope).
|
||||
|
||||
## Что реально реализовано в коде (срез 2026-04-08)
|
||||
|
||||
@@ -83,6 +92,7 @@
|
||||
- `step0_preprod_rail_plan_v1.md` - обязательный pre-prod рельсовый этап перед массовым расширением доменов.
|
||||
- `step0_closeout_2026-04-02.md` - факт закрытия Step-0 с артефактами и gate-подтверждением.
|
||||
- `domain_expansion_implementation_plan_v1.md` - план `Step-4`.
|
||||
- `step5_architecture_ux_quality_plan_v1_2026-04-08.md` - план `Step-5` (LLM-first input validation, UX, качество ответов).
|
||||
- `general_domain_questions_analysis_plan_v1_2026-04-02.md` - глубокий разбор общего домена (40 вопросов), route-модель и batch-план внедрения.
|
||||
- `management_route_probe_report_g1_2026-04-02.md` - live Batch-0 probe по первой группе общего домена (Q1–Q5) с route-верификацией через MCP/1С.
|
||||
- `complex_questions_status_and_reuse_map_2026-04-02.md` - сверка кода/доков по "сложным вопросам": что реализовано, что detection-only, и как переиспользовать в продуктовом плане.
|
||||
@@ -133,3 +143,11 @@
|
||||
- `docs/ADDRESS/runs/2026-04-02_Address_Followup_Context_Chains_2026-04-02_19-15-Run5/`
|
||||
- `docs/ADDRESS/runs/2026-04-02_Address_Domain_ContractsOpenItems_Reference_Acceptance_2026-04-02_17-00-22/`
|
||||
- `docs/ADDRESS/runs/2026-04-02_Address_Nightly_Regression_2026-04-02_17-35-00/`
|
||||
- Step-5 follow-up hardening (2026-04-08):
|
||||
- `address_dialog_continuation_contract_v2` for context continuation/switching.
|
||||
- Safe retry on retryable limited outcomes (`missing_anchor` / `empty_match`) using raw user message + preserved context.
|
||||
- Regression confirmation: `246/246` PASS (`assistantAddressFollowupContext`, `addressQueryRuntimeM23`, `assistantAddressLlmPredecompose`).
|
||||
- Step-5 living router validation (2026-04-08):
|
||||
- `assistantLivingRouter.test.ts`: `4/4` PASS
|
||||
- `assistantLivingChatMode.test.ts`: `1/1` PASS
|
||||
- build: PASS
|
||||
|
||||
@@ -4,6 +4,17 @@
|
||||
Контур: `question_mode=address_query` (live-first, MCP)
|
||||
Стартовая база качества: закрытый этап стабилизации (`102/102` stress, `25/25` follow-up).
|
||||
|
||||
## 0. Status Update (2026-04-08)
|
||||
|
||||
План Step-4 остается референсом, но на текущем этапе введен `domain scope freeze`:
|
||||
|
||||
- новые домены временно не расширяем;
|
||||
- текущий охват (Batch-1/Batch-2/Batch-3) зафиксирован как рабочий baseline;
|
||||
- приоритет смещен на Step-5: архитектура, LLM-first валидация пользовательских запросов и качество ответов.
|
||||
|
||||
Рабочий документ следующего этапа:
|
||||
`docs/ADDRESS/address_query/step5_architecture_ux_quality_plan_v1_2026-04-08.md`.
|
||||
|
||||
## 1. Цель и рамки
|
||||
|
||||
Цель этапа: расширять покрытие доменов/интентов без деградации уже стабильного ядра.
|
||||
|
||||
@@ -14,8 +14,8 @@ flowchart LR
|
||||
E["Auto-nightly Incident<br/>2026-04-08 09:52<br/>MCP fetch failed"]
|
||||
F["Targeted Fix<br/>S019 predecompose anchor drift"]
|
||||
G["Manual Control Nightly Recheck<br/>2026-04-08 13:19<br/>102/102 + 25/25 PASS"]
|
||||
H["CURRENT STATE<br/>BATCH2_PHASE_C_CLOSED"]
|
||||
I["NEXT STEP<br/>Batch-4/5 domain scoping<br/>Debt/Aging/Risk"]
|
||||
H["CURRENT STATE<br/>STEP5_PHASE_B_BOOTSTRAP_ACTIVE"]
|
||||
I["NEXT STEP<br/>Step-5 core hardening<br/>LLM-first validation + clarification UX"]
|
||||
K["Batch-2 Gate Closed<br/>36/36 + Global PASS"]
|
||||
J["Operational Rail<br/>Scheduler: Disabled<br/>Manual nightly only"]
|
||||
|
||||
@@ -37,6 +37,10 @@ flowchart LR
|
||||
`docs/ADDRESS/runs/2026-04-08_Address_Batch2_Lifecycle_FullGate_PhaseC_PostFix2/run_summary.json`
|
||||
- Master checker (entry to Batch-2):
|
||||
`docs/ADDRESS/address_query/step4_wave1_batch1_master_checker_v1.md`
|
||||
- Step-5 plan (current focus):
|
||||
`docs/ADDRESS/address_query/step5_architecture_ux_quality_plan_v1_2026-04-08.md`
|
||||
- Step-5 UX smoke (bootstrap):
|
||||
`docs/ADDRESS/runs/2026-04-08_Address_Step5_UX_Smoke_v2/run_summary.json`
|
||||
- Batch-2 Phase-A artifacts:
|
||||
- `docs/ADDRESS/address_query/domain_general_batch2_lifecycle_card_v1.md`
|
||||
- `docs/ADDRESS/question_sets/domain_general_batch2_lifecycle_acceptance_2026-04-08_phaseA.json`
|
||||
@@ -50,4 +54,14 @@ flowchart LR
|
||||
- Функциональные гейты закрыты.
|
||||
- Точечный flake `S019` закрыт.
|
||||
- Batch-2 lifecycle закрыт до `Phase C`: domain gate `36/36`, global regression `102/102 + 25/25`, comparator PASS.
|
||||
- Следующий практический шаг: стартовать scoping Batch-4/Batch-5 (`debt/aging/risk`) как отдельную доменную волну.
|
||||
- Step-5 запущен: UX bootstrap-патч в `composeStage` и targeted smoke `6/6`.
|
||||
- Следующий практический шаг: core hardening Step-5 (LLM-first validation + clarification UX), при domain scope freeze.
|
||||
|
||||
## Step-5 Increment Update (2026-04-08)
|
||||
|
||||
- Added `address_dialog_continuation_contract_v2` in runtime follow-up flow (`new_topic` / `continue_previous` / `switch_to_suggested`).
|
||||
- Added safe retry for retryable limited answers (`limited_reason_category: missing_anchor | empty_match`) with retry on raw user message and preserved follow-up context.
|
||||
- Added low-quality pseudo-anchor guard for referential follow-ups (`кроме этого ...`) with stable anchor carryover.
|
||||
- Added debug/log audit fields: `dialog_continuation_contract_v2`, `address_retry_audit`.
|
||||
- Targeted regression after hardening: `246/246` PASS (`assistantAddressFollowupContext`, `addressQueryRuntimeM23`, `assistantAddressLlmPredecompose`).
|
||||
- Living router increment: conversational `chat` mode added for non-data messages with safe fallback to deep pipeline (`assistantLivingRouter 4/4`, `assistantLivingChatMode 1/1`, build PASS).
|
||||
|
||||
@@ -51,7 +51,7 @@ Batch-1 можно переводить в runtime только после за
|
||||
- [x] Phase B.1 (Batch-1 prep): реализованы `period_coverage_profile`, `document_type_and_account_section_profile`, `counterparty_population_and_roles`, `contract_usage_overview` (unit/build green).
|
||||
- [x] Phase B.2 (Batch-3 value prep): реализованы `customer_revenue_and_payments`, `supplier_payouts_profile`, `contract_usage_and_value`; стандарт ранжирования `top-20`; routing усилен для сленга/опечаток.
|
||||
- [x] Targeted live-check Batch-1 next pack (`Q6/Q7/Q28`) выполнен: `strict factual 9/9`.
|
||||
- [x] Targeted code gate по расширенному management/value слою: `addressQueryRuntimeM23.test.ts = 200/200`, `assistantAddressLlmPredecompose.test.ts = PASS`, `build=PASS`.
|
||||
- [x] Targeted code gate по расширенному management/value слою: `addressQueryRuntimeM23.test.ts + assistantAddressFollowupContext.test.ts = 223/223`, `build=PASS`.
|
||||
- [x] Phase C (Batch-1 domain pack) прогнан: `domain_general_batch1_acceptance_2026-04-02_phaseA.json` -> `strict 28/28`
|
||||
run: `docs/ADDRESS/runs/2026-04-03_Address_Domain_General_B1_PhaseC_LiveGate_R3/`
|
||||
- [x] Batch-3 value live-gate прогнан: `temp_batch3_value_top20_2026-04-02.json` -> `strict 33/33`
|
||||
@@ -59,8 +59,8 @@ Batch-1 можно переводить в runtime только после за
|
||||
- [x] Global non-regression + comparator к baseline: `PASS`
|
||||
run: `docs/ADDRESS/runs/2026-04-03_Address_Nightly_Regression_Post_AnchorHardening_R6/nightly_summary.json`
|
||||
детали: `overall_ok=true`, `stress_102=102/102`, `followup_25=25/25`, comparator PASS.
|
||||
- [x] Контрольный nightly recheck (`2026-04-08 10:51`) закрыт в `PASS`
|
||||
run: `docs/ADDRESS/runs/2026-04-08_Address_Nightly_Regression_2026-04-08_10-51-20/nightly_summary.json`
|
||||
- [x] Контрольный nightly recheck (`2026-04-08 13:19`) закрыт в `PASS`
|
||||
run: `docs/ADDRESS/runs/2026-04-08_Address_Nightly_Regression_2026-04-08_13-19-24/nightly_summary.json`
|
||||
детали: `stress_102=102/102`, `followup_25=25/25`, comparator PASS.
|
||||
- [x] Batch-2 lifecycle Phase A стартован:
|
||||
- `domain_general_batch2_lifecycle_card_v1.md`
|
||||
@@ -69,13 +69,13 @@ Batch-1 можно переводить в runtime только после за
|
||||
- `step4_wave1_batch2_phaseA_backlog_v1.md`
|
||||
- [x] Batch-2 Phase-B progress:
|
||||
- resolver drift по `Q12/Q13/Q26/Q27/Q31/Q32` закрыт
|
||||
- `addressQueryRuntimeM23.test.ts = 210/210`, `build=PASS`
|
||||
- `addressQueryRuntimeM23.test.ts + assistantAddressFollowupContext.test.ts = 223/223`, `build=PASS`
|
||||
- live hotpass `wave1_batch2_phaseB_resolver_hotpass_2026-04-08.md` (`route match 6/6`)
|
||||
- [x] Phase B закрыт.
|
||||
- [x] Phase C закрыт.
|
||||
|
||||
## 4. Решение на сейчас
|
||||
|
||||
1. Начинать можно, но строго по фазам выше.
|
||||
2. Прямое включение Batch-1 intents в production-path без Phase B/C — запрещено.
|
||||
3. Точка входа в работу: Batch-2 уже в `Phase A active`; следующий шаг — выполнить Batch-2 Phase B и закрыть domain gate/глобальный comparator.
|
||||
1. Wave-1 domain-расширение (Batch-1/Batch-2/Batch-3) зафиксировано как закрытое.
|
||||
2. Новые домены временно не запускаем (`domain scope freeze`).
|
||||
3. Следующая точка входа в работу: Step-5 (`Architecture + UX + Answer Quality`), с приоритетом LLM-first валидации пользовательского запроса и качества ответа.
|
||||
|
||||
@@ -79,8 +79,9 @@ Scope: `Q8..Q13 + Q26 + Q27 + Q31 + Q32`
|
||||
## 4. Текущий приоритет (следующий кодовый шаг)
|
||||
|
||||
1. Перевести Batch-2 из wave backlog в master checker как `closed`.
|
||||
2. Подготовить Batch-4/Batch-5 scope (debt/aging/risk) отдельной доменной карточкой.
|
||||
3. Держать nightly regression в green-контуре как release guardrail.
|
||||
2. Ввести `domain scope freeze` на текущем объеме доменов.
|
||||
3. Перейти к Step-5 (`Architecture + UX + Answer Quality`) без запуска новых доменных волн.
|
||||
4. Держать nightly regression в green-контуре как release guardrail.
|
||||
|
||||
## 5. Фактические артефакты закрытия
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
# Step-5 Architecture + UX Quality Plan V1
|
||||
|
||||
Дата: 2026-04-08
|
||||
Статус: `active` (Phase B bootstrap started)
|
||||
Контур: `question_mode=address_query` (live-first, MCP)
|
||||
|
||||
## 1. Что фиксируем сейчас
|
||||
|
||||
1. Текущий объем доменов фиксируем (`domain scope freeze`).
|
||||
2. Новые домены временно не добавляем.
|
||||
3. Фокус переносим на качество архитектуры и пользовательского ответа.
|
||||
|
||||
## 2. Цель Step-5 (простыми словами)
|
||||
|
||||
Сделать ассистента менее “механическим” и более полезным:
|
||||
|
||||
1. меньше ручной словарной рутины;
|
||||
2. больше смысловой обработки через LLM;
|
||||
3. ответ по делу, в человеческом формате, с четкой конкретикой и аккуратными рекомендациями.
|
||||
|
||||
## 3. Принципы этапа
|
||||
|
||||
1. LLM отвечает за понимание смысла и валидацию формулировки пользователя.
|
||||
2. Runtime отвечает за безопасность маршрута (`intent -> filters -> recipe -> MCP`).
|
||||
3. LLM не генерирует свободные запросы к 1С/БД.
|
||||
4. Company-specific словари/хардкод не добавляем.
|
||||
|
||||
## 4. Целевая схема (LLM-first, но безопасно)
|
||||
|
||||
1. `LLM Semantic Contract`:
|
||||
- на входе формируем каноническое представление запроса;
|
||||
- фиксируем `intent`, `entities`, `period`, `user_goal`, `confidence`, `ambiguity`.
|
||||
2. `Route Validator`:
|
||||
- проверяем, что intent поддержан и фильтры допустимы;
|
||||
- при конфликте/нехватке данных выдаем корректный clarification, а не псевдо-factual.
|
||||
3. `Execution`:
|
||||
- только whitelist recipes и текущий MCP-контур.
|
||||
4. `Answer Composer`:
|
||||
- сначала прямой ответ на вопрос;
|
||||
- затем короткое обоснование (по данным);
|
||||
- затем опционально рекомендации (если уместно и подтверждено данными).
|
||||
|
||||
## 5. Рабочие пакеты
|
||||
|
||||
### WP-1. Уход от словарной рутины
|
||||
|
||||
1. Зафиксировать “словарный freeze”: новые slang-слова не добавляем как основной путь.
|
||||
2. Расширять покрытие через LLM-contract + regression-набор перефразировок.
|
||||
3. Ввести метрику доли запросов, обработанных через LLM canonical path без словарного патча.
|
||||
|
||||
### WP-2. LLM-first валидация запроса
|
||||
|
||||
1. Добавить обязательную проверку качества canonical-контракта:
|
||||
- intent consistency;
|
||||
- entity consistency;
|
||||
- period consistency.
|
||||
2. Если confidence низкий, задавать 1 целевой уточняющий вопрос (без “простыни”).
|
||||
3. Убрать токсичный UX fallback вида “что сломано / ограничения” там, где вопрос обычный и решаемый.
|
||||
|
||||
### WP-3. Качество ответа для пользователя
|
||||
|
||||
1. Формат ответа по умолчанию:
|
||||
- `короткий прямой ответ`;
|
||||
- `ключевые цифры/факты`;
|
||||
- `опционально: что это значит для бизнеса`.
|
||||
2. Для ranking/summary ответов:
|
||||
- не смешивать несколько разных вопросов в один ответ;
|
||||
- явно писать период и сущность (контрагент/договор/документ).
|
||||
3. Для рекомендаций:
|
||||
- только мягкие и grounded (на основе текущих данных);
|
||||
- без выдуманных советов “из воздуха”.
|
||||
|
||||
### WP-4. UX и follow-up
|
||||
|
||||
1. Стабилизировать follow-up цепочки (короткие реплики, местоимения, “а теперь за 21”).
|
||||
2. Держать контекст предыдущего успешного address-ответа.
|
||||
3. Не терять контекст после промежуточного clarification.
|
||||
|
||||
## 6. Gate и метрики Step-5
|
||||
|
||||
Обязательные:
|
||||
|
||||
1. не просесть ниже baseline:
|
||||
- stress `102/102`;
|
||||
- follow-up `25/25`;
|
||||
- comparator `PASS`.
|
||||
2. `false_factual_rate = 0`.
|
||||
3. `execution_error_rate = 0`.
|
||||
|
||||
Новые UX-метрики:
|
||||
|
||||
1. `clarification_rate` на целевом UX-наборе снижается.
|
||||
2. `direct_answer_rate` растет (ответ начинается с сути, а не с шаблонного fallback).
|
||||
3. `mixed_answer_rate` (слипание ответов на разные вопросы) снижается к 0.
|
||||
|
||||
## 7. Фазы выполнения
|
||||
|
||||
1. **Phase A — Contract/UX Design**
|
||||
описать v2 контракт и формат “человеческого” ответа.
|
||||
2. **Phase B — Runtime Implementation**
|
||||
внедрить LLM-first validation + composer improvements.
|
||||
3. **Phase C — Live UX Gate**
|
||||
прогон targeted UX-набора + контроль global non-regression.
|
||||
|
||||
## 8. Критерий завершения Step-5
|
||||
|
||||
Step-5 считается закрытым, когда одновременно:
|
||||
|
||||
1. baseline quality gates остаются зелеными;
|
||||
2. на UX-наборе заметно меньше ненужных clarification/fallback ответов;
|
||||
3. ответы стабильно конкретные, по вопросу, без механического шаблона;
|
||||
4. новые domain-расширения можно запускать уже на более зрелой архитектуре.
|
||||
|
||||
## 9. Прогресс на 2026-04-08
|
||||
|
||||
Сделано (первый рабочий инкремент):
|
||||
|
||||
1. UX-ответы в `composeStage` переведены в формат “суть первой строкой”:
|
||||
- для management/ranking/counterparty/document/bank intents первая строка теперь дает прямой ответ (количество/итог/top-заголовок);
|
||||
- служебные строки вида “собран профиль…” оставлены как supporting block.
|
||||
2. Исправлен role-focus для фраз типа `скока поставщиков в базе`:
|
||||
- при явном supplier/customer/mixed-сигнале приоритет отдается роли, даже если LLM-канонизация добавила общий `контрагент` контекст.
|
||||
3. Regression tests green:
|
||||
- `addressQueryRuntimeM23.test.ts` -> `220/220`;
|
||||
- `assistantAddressFollowupContext.test.ts` -> `3/3`.
|
||||
4. Live UX smoke (targeted) green:
|
||||
- набор: `docs/ADDRESS/question_sets/step5_ux_smoke_2026-04-08.json`;
|
||||
- run v2: `docs/ADDRESS/runs/2026-04-08_Address_Step5_UX_Smoke_v2/run_summary.json`;
|
||||
- результат: `strict 6/6`.
|
||||
|
||||
Наблюдение:
|
||||
|
||||
1. На targeted smoke ответы стали короче и конкретнее в первой строке (например: `Поставщиков ...: 79`, `Активные заказчики в 2020 году: 13`, `Найдено документов ...: 12`).
|
||||
|
||||
## 10. Increment 2026-04-08 (Anchor Clarification UX)
|
||||
|
||||
1. Hardened `partial_coverage` for anchor mismatch in `addressQueryService`.
|
||||
2. If mismatch reason is `counterparty_anchor_not_matched` or `contract_anchor_not_matched`, runtime now returns targeted clarification (anchor-first), instead of generic period-first suggestion.
|
||||
3. For counterparty/contract mismatch, next step keeps recognized period window and asks for exact entity anchor.
|
||||
4. Added regression assertion in `addressQueryRuntimeM23.test.ts` for counterparty mismatch clarification wording.
|
||||
5. Validation:
|
||||
- `addressQueryRuntimeM23.test.ts` -> PASS (220/220)
|
||||
- `assistantAddressFollowupContext.test.ts` -> PASS (3/3)
|
||||
- `npm run build` -> PASS.
|
||||
|
||||
## 11. Increment 2026-04-08 (Dialog Continuation v2 + Safe Retry)
|
||||
|
||||
1. В `assistantService` добавлен `address_dialog_continuation_contract_v2`:
|
||||
- решения `new_topic` / `continue_previous` / `switch_to_suggested`;
|
||||
- явная фиксация `previous_intent`, `target_intent`, `reasons`.
|
||||
2. Расширены follow-up сигналы для референсных реплик:
|
||||
- формы вида `этого/этом/эту/эти...`, `кроме этого...`, `помимо этого...`, `есть еще...`.
|
||||
3. Добавлен `safe retry` для address-lane:
|
||||
- если первый ответ ограниченный (`limited_reason_category in missing_anchor|empty_match`) и есть риск деградации после rewrite;
|
||||
- runtime делает повторный проход по raw user message с сохранением контекста предыдущего успешного ответа.
|
||||
4. Для follow-up запросов типа `кроме этого документа...` добавлена защита от псевдо-якорей:
|
||||
- low-quality anchor заменяется на устойчивый якорь из follow-up контекста.
|
||||
5. В debug/log добавлены поля аудита:
|
||||
- `dialog_continuation_contract_v2`;
|
||||
- `address_retry_audit`.
|
||||
|
||||
Validation (targeted regression, 2026-04-08):
|
||||
|
||||
1. `assistantAddressFollowupContext.test.ts` -> PASS (`7/7`)
|
||||
2. `addressQueryRuntimeM23.test.ts` -> PASS (`223/223`)
|
||||
3. `assistantAddressLlmPredecompose.test.ts` -> PASS (`16/16`)
|
||||
4. Total targeted pack -> PASS (`246/246`)
|
||||
|
||||
## 12. Increment 2026-04-08 (Living Assistant Router v1)
|
||||
|
||||
1. Added a lightweight living router in `assistantService`:
|
||||
- `address_data` when address lane is triggered;
|
||||
- `chat` for non-data conversational messages;
|
||||
- `deep_analysis` fallback for data-like or uncertain cases.
|
||||
2. Added new runtime flag:
|
||||
- `FEATURE_ASSISTANT_LIVING_CHAT_ROUTER_V1` (default: `true`).
|
||||
3. Added live chat generation path via `OpenAIResponsesClient.chat(...)`:
|
||||
- OpenAI-compatible local provider support (`/responses` with fallback to `/chat/completions`);
|
||||
- safe fallback to existing deep pipeline if chat call fails.
|
||||
4. Safety behavior:
|
||||
- in `useMock=true` mode, router keeps deep pipeline (no network in tests);
|
||||
- no changes to address rails and follow-up context logic.
|
||||
5. Validation:
|
||||
- `assistantLivingRouter.test.ts` -> PASS (`4/4`);
|
||||
- `assistantLivingChatMode.test.ts` -> PASS (`1/1`);
|
||||
- targeted regression pack with address follow-up/predecompose tests -> PASS (`28/28`);
|
||||
- `npm run build` -> PASS.
|
||||
|
||||
## 13. Increment 2026-04-08 (ToolGate hardening for casual chat)
|
||||
|
||||
1. Fixed address tool gate over-trigger:
|
||||
- `llm_canonical_candidate_detected` no longer auto-runs address lane when predecompose contract is `mode=unsupported` or `intent=unknown` with low confidence.
|
||||
2. Result:
|
||||
- short casual messages (`йо`, `привет`) no longer fall into clarification-heavy deep/accounting pipeline.
|
||||
- they are handled by living chat mode.
|
||||
3. Validation:
|
||||
- extended `assistantLivingChatMode.test.ts` with repro-case `йо` + rewritten canonical candidate.
|
||||
- PASS (`2/2`) with assertion that `addressQueryService.tryHandle` is not called.
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{"id":"UX001","text":"какие клиенты самые доходные"},
|
||||
{"id":"UX002","text":"скока поставщиков в базе"},
|
||||
{"id":"UX003","text":"какие заказчики работали с нами в 2020 году"},
|
||||
{"id":"UX004","text":"какие договоры давно не использовались"},
|
||||
{"id":"UX005","text":"покажи документы по нортону"},
|
||||
{"id":"UX006","text":"покажи операции по договору 19/15"}
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# 2026-04-08_Address_Step5_UX_Smoke_v1
|
||||
|
||||
Generated at: 2026-04-08T13:53:34
|
||||
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\step5_ux_smoke_2026-04-08.json
|
||||
Backend URL: http://127.0.0.1:8787/api/assistant/message
|
||||
LLM: local / qwen2.5-14b-instruct-1m @ http://127.0.0.1:1234
|
||||
Strict policy: route
|
||||
|
||||
## Totals
|
||||
- questions_total: 6
|
||||
- ok_200_count: 6
|
||||
- semantic_pass_count: 6
|
||||
- semantic_pass_rate: 1.0
|
||||
- route_pass_count: 6
|
||||
- route_pass_rate: 1.0
|
||||
- strict_pass_count: 6
|
||||
- strict_pass_rate: 1.0
|
||||
- factual_count: 6
|
||||
- partial_coverage_count: 0
|
||||
- clarification_required_count: 0
|
||||
- http_error_count: 0
|
||||
- llm_decomposition_attempted_count: 6
|
||||
- llm_decomposition_applied_count: 4
|
||||
- llm_fallback_count: 0
|
||||
- llm_fallback_rate: 0.0
|
||||
- tool_gate_blocked_count: 0
|
||||
- tool_gate_blocked_rate: 0.0
|
||||
- avg_elapsed_ms: 5562.2
|
||||
|
||||
## Files
|
||||
- run_summary.json
|
||||
- full_live_results.json
|
||||
- failures_only.json
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
# Response Audit: 2026-04-08_Address_Step5_UX_Smoke_v1
|
||||
|
||||
| id | strict | route_health | reply_type | intent | limited_reason | question | assistant_first_line |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| UX001 | True | ok_or_factual | factual | customer_revenue_and_payments | None | какие клиенты самые доходные | Топ-5 заказчиков по сумме поступлений: |
|
||||
| UX002 | True | ok_or_factual | factual | counterparty_population_and_roles | None | скока поставщиков в базе | Всего уникальных контрагентов в базе: 139. |
|
||||
| UX003 | True | ok_or_factual | factual | counterparty_activity_lifecycle | None | какие заказчики работали с нами в 2020 году | Активные заказчики в 2020 году: 13. |
|
||||
| UX004 | True | ok_or_factual | factual | contract_usage_overview | None | какие договоры давно не использовались | Использованных договоров: 291 из 394 (73.9%). |
|
||||
| UX005 | True | ok_or_factual | factual | list_documents_by_counterparty | None | покажи документы по нортону | Найдено документов по контрагенту: 12. |
|
||||
| UX006 | True | ok_or_factual | factual | bank_operations_by_contract | None | покажи операции по договору 19/15 | Найдено банковских операций по договору: 1. |
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"run_id": "2026-04-08_Address_Step5_UX_Smoke_v1",
|
||||
"generated_at": "2026-04-08T13:53:34",
|
||||
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\step5_ux_smoke_2026-04-08.json",
|
||||
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
|
||||
"llm_provider": "local",
|
||||
"llm_model": "qwen2.5-14b-instruct-1m",
|
||||
"llm_base_url": "http://127.0.0.1:1234",
|
||||
"strict_policy": "route",
|
||||
"totals": {
|
||||
"questions_total": 6,
|
||||
"ok_200_count": 6,
|
||||
"semantic_pass_count": 6,
|
||||
"semantic_pass_rate": 1.0,
|
||||
"route_pass_count": 6,
|
||||
"route_pass_rate": 1.0,
|
||||
"strict_pass_count": 6,
|
||||
"strict_pass_rate": 1.0,
|
||||
"factual_count": 6,
|
||||
"partial_coverage_count": 0,
|
||||
"clarification_required_count": 0,
|
||||
"http_error_count": 0,
|
||||
"llm_decomposition_attempted_count": 6,
|
||||
"llm_decomposition_applied_count": 4,
|
||||
"llm_fallback_count": 0,
|
||||
"llm_fallback_rate": 0.0,
|
||||
"tool_gate_blocked_count": 0,
|
||||
"tool_gate_blocked_rate": 0.0,
|
||||
"avg_elapsed_ms": 5562.2
|
||||
},
|
||||
"distributions": {
|
||||
"reply_type": {
|
||||
"factual": 6
|
||||
},
|
||||
"actual_intent": {
|
||||
"customer_revenue_and_payments": 1,
|
||||
"counterparty_population_and_roles": 1,
|
||||
"counterparty_activity_lifecycle": 1,
|
||||
"contract_usage_overview": 1,
|
||||
"list_documents_by_counterparty": 1,
|
||||
"bank_operations_by_contract": 1
|
||||
},
|
||||
"actual_mode": {
|
||||
"address_query": 6
|
||||
},
|
||||
"mcp_call_status": {
|
||||
"matched_non_empty": 6
|
||||
},
|
||||
"limited_reason_category": {},
|
||||
"route_health": {
|
||||
"ok_or_factual": 6
|
||||
},
|
||||
"tool_gate_decision": {
|
||||
"run_address_lane": 6
|
||||
},
|
||||
"tool_gate_reason": {
|
||||
"address_mode_classifier_detected": 6
|
||||
}
|
||||
},
|
||||
"address_llm_predecompose_metrics": {
|
||||
"overall": {
|
||||
"llm_attempted": 6,
|
||||
"llm_applied": 4,
|
||||
"fallback_used": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"tool_gate_blocked": 0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"by_intent": {
|
||||
"customer_revenue_and_payments": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 0,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"counterparty_population_and_roles": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"counterparty_activity_lifecycle": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"contract_usage_overview": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 0,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"list_documents_by_counterparty": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"bank_operations_by_contract": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# 2026-04-08_Address_Step5_UX_Smoke_v2
|
||||
|
||||
Generated at: 2026-04-08T13:55:47
|
||||
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\step5_ux_smoke_2026-04-08.json
|
||||
Backend URL: http://127.0.0.1:8787/api/assistant/message
|
||||
LLM: local / qwen2.5-14b-instruct-1m @ http://127.0.0.1:1234
|
||||
Strict policy: route
|
||||
|
||||
## Totals
|
||||
- questions_total: 6
|
||||
- ok_200_count: 6
|
||||
- semantic_pass_count: 6
|
||||
- semantic_pass_rate: 1.0
|
||||
- route_pass_count: 6
|
||||
- route_pass_rate: 1.0
|
||||
- strict_pass_count: 6
|
||||
- strict_pass_rate: 1.0
|
||||
- factual_count: 6
|
||||
- partial_coverage_count: 0
|
||||
- clarification_required_count: 0
|
||||
- http_error_count: 0
|
||||
- llm_decomposition_attempted_count: 6
|
||||
- llm_decomposition_applied_count: 4
|
||||
- llm_fallback_count: 0
|
||||
- llm_fallback_rate: 0.0
|
||||
- tool_gate_blocked_count: 0
|
||||
- tool_gate_blocked_rate: 0.0
|
||||
- avg_elapsed_ms: 5551.5
|
||||
|
||||
## Files
|
||||
- run_summary.json
|
||||
- full_live_results.json
|
||||
- failures_only.json
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
# Response Audit: 2026-04-08_Address_Step5_UX_Smoke_v2
|
||||
|
||||
| id | strict | route_health | reply_type | intent | limited_reason | question | assistant_first_line |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| UX001 | True | ok_or_factual | factual | customer_revenue_and_payments | None | какие клиенты самые доходные | Топ-5 заказчиков по сумме поступлений: |
|
||||
| UX002 | True | ok_or_factual | factual | counterparty_population_and_roles | None | скока поставщиков в базе | Поставщиков (только supplier-роль): 79. |
|
||||
| UX003 | True | ok_or_factual | factual | counterparty_activity_lifecycle | None | какие заказчики работали с нами в 2020 году | Активные заказчики в 2020 году: 13. |
|
||||
| UX004 | True | ok_or_factual | factual | contract_usage_overview | None | какие договоры давно не использовались | Использованных договоров: 291 из 394 (73.9%). |
|
||||
| UX005 | True | ok_or_factual | factual | list_documents_by_counterparty | None | покажи документы по нортону | Найдено документов по контрагенту: 12. |
|
||||
| UX006 | True | ok_or_factual | factual | bank_operations_by_contract | None | покажи операции по договору 19/15 | Найдено банковских операций по договору: 1. |
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"run_id": "2026-04-08_Address_Step5_UX_Smoke_v2",
|
||||
"generated_at": "2026-04-08T13:55:47",
|
||||
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\step5_ux_smoke_2026-04-08.json",
|
||||
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
|
||||
"llm_provider": "local",
|
||||
"llm_model": "qwen2.5-14b-instruct-1m",
|
||||
"llm_base_url": "http://127.0.0.1:1234",
|
||||
"strict_policy": "route",
|
||||
"totals": {
|
||||
"questions_total": 6,
|
||||
"ok_200_count": 6,
|
||||
"semantic_pass_count": 6,
|
||||
"semantic_pass_rate": 1.0,
|
||||
"route_pass_count": 6,
|
||||
"route_pass_rate": 1.0,
|
||||
"strict_pass_count": 6,
|
||||
"strict_pass_rate": 1.0,
|
||||
"factual_count": 6,
|
||||
"partial_coverage_count": 0,
|
||||
"clarification_required_count": 0,
|
||||
"http_error_count": 0,
|
||||
"llm_decomposition_attempted_count": 6,
|
||||
"llm_decomposition_applied_count": 4,
|
||||
"llm_fallback_count": 0,
|
||||
"llm_fallback_rate": 0.0,
|
||||
"tool_gate_blocked_count": 0,
|
||||
"tool_gate_blocked_rate": 0.0,
|
||||
"avg_elapsed_ms": 5551.5
|
||||
},
|
||||
"distributions": {
|
||||
"reply_type": {
|
||||
"factual": 6
|
||||
},
|
||||
"actual_intent": {
|
||||
"customer_revenue_and_payments": 1,
|
||||
"counterparty_population_and_roles": 1,
|
||||
"counterparty_activity_lifecycle": 1,
|
||||
"contract_usage_overview": 1,
|
||||
"list_documents_by_counterparty": 1,
|
||||
"bank_operations_by_contract": 1
|
||||
},
|
||||
"actual_mode": {
|
||||
"address_query": 6
|
||||
},
|
||||
"mcp_call_status": {
|
||||
"matched_non_empty": 6
|
||||
},
|
||||
"limited_reason_category": {},
|
||||
"route_health": {
|
||||
"ok_or_factual": 6
|
||||
},
|
||||
"tool_gate_decision": {
|
||||
"run_address_lane": 6
|
||||
},
|
||||
"tool_gate_reason": {
|
||||
"address_mode_classifier_detected": 6
|
||||
}
|
||||
},
|
||||
"address_llm_predecompose_metrics": {
|
||||
"overall": {
|
||||
"llm_attempted": 6,
|
||||
"llm_applied": 4,
|
||||
"fallback_used": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"tool_gate_blocked": 0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"by_intent": {
|
||||
"customer_revenue_and_payments": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 0,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"counterparty_population_and_roles": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"counterparty_activity_lifecycle": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"contract_usage_overview": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 0,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"list_documents_by_counterparty": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
},
|
||||
"bank_operations_by_contract": {
|
||||
"total": 1,
|
||||
"llm_attempted": 1,
|
||||
"llm_applied": 1,
|
||||
"fallback_used": 0,
|
||||
"tool_gate_blocked": 0,
|
||||
"fallback_rate": 0.0,
|
||||
"gate_block_rate": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user