АДРЕСНЫЙ РЕЖИМ - M2.3b тюнинг account-scope и диагностика стадий адресного рантайма
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
# Этап 4 — Архитектурный аудит под MCP-first адресные запросы
|
||||
|
||||
Дата: 2026-03-29
|
||||
Контур: `X:\1C\NDC_1C`
|
||||
|
||||
## 1) Цель аудита
|
||||
|
||||
Понять, в каком состоянии проект перед переходом на новый класс задач:
|
||||
|
||||
- "покажи незакрытые договоры";
|
||||
- "найди, кому мы должны";
|
||||
- "найди, кто должен нам";
|
||||
- "покажи остаток по счету".
|
||||
|
||||
И зафиксировать, что нужно поменять в рантайме, чтобы это работало как **LLM-интерфейс к живой 1С через MCP**.
|
||||
|
||||
## 2) Подтвержденные факты (as-is)
|
||||
|
||||
### 2.1 Assistant runtime сейчас snapshot-first
|
||||
|
||||
Текущий `AssistantDataLayer` поднимает данные из фиксированного набора JSON-файлов из `docs/ARCH/2020экспорт`, а не из полного корпуса:
|
||||
|
||||
- `llm_normalizer/backend/src/services/assistantDataLayer.ts:3379-3386`
|
||||
- `llm_normalizer/backend/src/services/assistantDataLayer.ts:3401`
|
||||
|
||||
Размер подключенного snapshot-пакета:
|
||||
|
||||
- `docs/ARCH/2020экспорт` = **1.82 MB** (10 файлов).
|
||||
|
||||
### 2.2 Полный monthly-корпус есть, но в assistant runtime не используется
|
||||
|
||||
Объем полного корпуса:
|
||||
|
||||
- `docs/ARCH/2020_monthly_company_asof_full/_tmp_ndjson` = **6732 MB** (12 файлов),
|
||||
- средний файл ≈ **561 MB**.
|
||||
|
||||
Итог: по текущему коду assistant работает по сильно урезанному слою данных относительно доступного объема.
|
||||
|
||||
### 2.3 MCP/live есть, но как overlay и только на части маршрутов
|
||||
|
||||
Live-путь в assistant включается только если:
|
||||
|
||||
- `FEATURE_ASSISTANT_MCP_RUNTIME_V1=true`
|
||||
(`llm_normalizer/backend/src/config.ts:90-100`)
|
||||
|
||||
и только для маршрутов:
|
||||
|
||||
- `hybrid_store_plus_live`
|
||||
- `live_mcp_drilldown`
|
||||
(`llm_normalizer/backend/src/services/assistantDataLayer.ts:2863`)
|
||||
|
||||
Для `store_canonical` live не используется.
|
||||
|
||||
### 2.4 Claim-bound live план в `assistantDataLayer` ориентирован на 3 семейства
|
||||
|
||||
`buildLiveMcpCallPlan(...)` имеет claim-ветки:
|
||||
|
||||
- `prove_fixed_asset_amortization_coverage` (`assistantDataLayer.ts:348`)
|
||||
- `prove_vat_chain_completeness` (`assistantDataLayer.ts:396`)
|
||||
- `prove_rbp_tail_state` (`assistantDataLayer.ts:460`)
|
||||
|
||||
Остальное уходит в `claim_type: null` + generic live probe (`assistantDataLayer.ts:444`).
|
||||
|
||||
Это не покрывает "простые адресные запросы" как отдельный runtime-класс.
|
||||
|
||||
### 2.5 Route-дисциплина сейчас заточена под Stage 4 глубинные цепочки
|
||||
|
||||
В `routeHintAdapter` есть жесткие query-class rules:
|
||||
|
||||
- `exact_object_trace -> live_mcp_drilldown` (`routeHintAdapter.ts:86-87`)
|
||||
- `canonical_fact_lookup -> store_canonical` (`routeHintAdapter.ts:149-150`)
|
||||
|
||||
В результате простые lookup-вопросы по умолчанию тяготеют к `store_canonical` (snapshot), а не к MCP-first.
|
||||
|
||||
### 2.6 Postgres в assistant runtime фактически не активен
|
||||
|
||||
По проекту:
|
||||
|
||||
- в `.env.example` дефолт `CANONICAL_DB_URL=sqlite:///...`
|
||||
(`.env.example:18`, `README.md:89`)
|
||||
- `canonical_layer/store.py` поддерживает и SQLite, и Postgres через SQLAlchemy
|
||||
(`canonical_layer/store.py:55`, `canonical_layer/store.py:59`)
|
||||
|
||||
На момент аудита:
|
||||
|
||||
- локально есть `data/canonical_store.db` (SQLite);
|
||||
- активного процесса `postgres` не обнаружено.
|
||||
|
||||
Важно: текущий `llm_normalizer/backend` **не использует** `canonical_layer` store напрямую в assistant execution path.
|
||||
|
||||
## 3) Главный технический вывод
|
||||
|
||||
Зафиксирован статус:
|
||||
|
||||
**SNAPSHOT_PRIMARY_WITH_OPTIONAL_LIVE_OVERLAY_CONFIRMED**
|
||||
|
||||
То есть:
|
||||
|
||||
- live-инфраструктура есть;
|
||||
- но архитектурно основной путь ассистента по-прежнему snapshot-first;
|
||||
- адресные "быстрые" бизнес-запросы как отдельный MCP-first runtime-класс пока не оформлены.
|
||||
|
||||
## 4) Что точно не бьется с новой задачей
|
||||
|
||||
1. `store_canonical` = snapshot path, а нам нужен live-first для адресных запросов.
|
||||
2. Нет отдельного address-intent и address-query planner.
|
||||
3. Нет acceptance-метрик для "быстрого доступа к сущностям" (не reasoning-heavy).
|
||||
4. Нет отдельного answer contract под tabular/list-ответы для live lookup.
|
||||
|
||||
## 5) Рамка изменения (без слома Stage 4 deep path)
|
||||
|
||||
Меняем не всю архитектуру, а добавляем новый lane:
|
||||
|
||||
- `address_query_runtime` как отдельный класс в существующем assistant pipeline;
|
||||
- приоритет источника для этого класса: `live_mcp` (mandatory), snapshot только как явно маркированный fallback;
|
||||
- Stage 4 deep chain path оставляем как есть.
|
||||
|
||||
## 6) Финальный verdict аудита
|
||||
|
||||
**MCP_INFRA_EXISTS_BUT_ADDRESS_RUNTIME_NOT_IMPLEMENTED**
|
||||
|
||||
Новый функционал реализуем через отдельный MCP-first address lane, без тотального рефакторинга текущего Stage 4 chain runtime.
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
# Target Architecture — MCP-first Address Queries (Stage 4)
|
||||
|
||||
Дата: 2026-03-29
|
||||
|
||||
## 1) Что вводим
|
||||
|
||||
Добавляем в текущий assistant runtime новый режим:
|
||||
|
||||
- `question_mode = address_query`
|
||||
|
||||
Это не замена deep-chain логики Stage 4, а параллельный "быстрый" lane для адресных вопросов.
|
||||
|
||||
## 2) Типы вопросов для первого релиза (Address V1)
|
||||
|
||||
Минимальный набор:
|
||||
|
||||
1. `list_open_contracts`
|
||||
2. `list_payables_counterparties` (кому мы должны)
|
||||
3. `list_receivables_counterparties` (кто должен нам)
|
||||
4. `account_balance_snapshot` (остатки по счету / счетам)
|
||||
5. `open_items_by_counterparty_or_contract` (незакрытые хвосты по контрагенту/договору)
|
||||
|
||||
## 3) Принцип источников данных
|
||||
|
||||
Для `address_query`:
|
||||
|
||||
- primary source: `MCP/live` (обязательно);
|
||||
- snapshot-source: только fallback с явной маркировкой;
|
||||
- запрещено молча подменять live на snapshot.
|
||||
|
||||
Правило ответа:
|
||||
|
||||
- если live недоступен: честный `DATA_UNAVAILABLE_LIVE`;
|
||||
- если live доступен, но пусто: честный `NO_MATCH_FOR_FILTERS`;
|
||||
- если live дал строки: `FACTUAL_LIST`/`FACTUAL_SUMMARY`.
|
||||
|
||||
## 4) Pipeline (встраивание в текущую архитектуру)
|
||||
|
||||
Новая ветка поверх текущего пайплайна:
|
||||
|
||||
1. `Normalizer` -> определяет `question_mode=address_query` и `address_intent`.
|
||||
2. `AddressIntentResolver` -> фиксирует intent + обязательные фильтры (period/account/counterparty/contract).
|
||||
3. `AddressQueryPlanner` -> выбирает MCP recipe (query template + params).
|
||||
4. `McpExecutor` -> исполняет 1..N live-вызовов.
|
||||
5. `AddressResultMaterializer` -> нормализует строки в табличный вид + totals.
|
||||
6. `AddressAnswerComposer` -> короткий ответ + список + ограничения.
|
||||
|
||||
## 5) MCP query recipes (контракт)
|
||||
|
||||
Для каждого intent хранится recipe:
|
||||
|
||||
- `recipe_id`
|
||||
- `purpose`
|
||||
- `query_template`
|
||||
- `required_params`
|
||||
- `optional_params`
|
||||
- `output_schema`
|
||||
- `sort/default_limit`
|
||||
|
||||
Примеры базовых рецептов:
|
||||
|
||||
- `address.open_contracts.by_period`
|
||||
- `address.payables.counterparty_totals`
|
||||
- `address.receivables.counterparty_totals`
|
||||
- `address.balance.by_account`
|
||||
- `address.open_items.by_counterparty_contract`
|
||||
|
||||
## 6) Контракт ответа (Address mode)
|
||||
|
||||
Форматы:
|
||||
|
||||
1. `FACTUAL_LIST`
|
||||
Короткий вывод + список строк (N top) + totals.
|
||||
|
||||
2. `FACTUAL_SUMMARY`
|
||||
Если строк много: агрегат + top контрагенты + рекомендация уточнить фильтры.
|
||||
|
||||
3. `LIMITED_WITH_REASON`
|
||||
Если live недоступен/ошибка/нехватка фильтров.
|
||||
|
||||
Обязательные поля debug:
|
||||
|
||||
- `question_mode`
|
||||
- `address_intent`
|
||||
- `recipe_id`
|
||||
- `required_filters`
|
||||
- `resolved_filters`
|
||||
- `mcp_calls[]`
|
||||
- `rows_fetched`
|
||||
- `rows_matched`
|
||||
- `result_mode`
|
||||
|
||||
## 7) Совместимость с текущим Stage 4
|
||||
|
||||
Не ломаем текущие chain-ветки:
|
||||
|
||||
- `settlements_60_62`, `vat_document_register_book`, `month_close_costs_20_44`, `fixed_asset_amortization` остаются.
|
||||
- `address_query` включается только при явном address-intent.
|
||||
|
||||
Приоритет:
|
||||
|
||||
- если вопрос "why/how/prove/chain" -> текущий deep path;
|
||||
- если вопрос "show/list/find/open/balance" -> address path.
|
||||
|
||||
## 8) Границы (что не делаем)
|
||||
|
||||
1. Не вводим новый proof engine.
|
||||
2. Не расширяем домены beyond P0/P1 для V1.
|
||||
3. Не делаем большой redesign routing.
|
||||
4. Не зависим от Postgres как обязательного prereq для Address V1.
|
||||
|
||||
## 9) Техническое решение по Postgres
|
||||
|
||||
Коротко:
|
||||
|
||||
- Postgres оставляем как optional storage path для canonical layer;
|
||||
- Address V1 делаем MCP-first без блокировки на миграцию в Postgres;
|
||||
- отдельный migration pack можно делать потом, когда будет нужна materialized аналитика/кеши.
|
||||
|
||||
## 10) Архитектурный verdict
|
||||
|
||||
**ADDRESS_LANE_MCP_FIRST_IS_COMPATIBLE_WITH_CURRENT_STAGE4_RUNTIME**
|
||||
|
||||
То есть новый функционал можно внедрить итеративно, не вынося проект в тяжелый рефактор.
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
# Execution Plan — Address Runtime (Wave A..D)
|
||||
|
||||
Дата: 2026-03-29
|
||||
Фокус: быстрый LLM-интерфейс к 1С сущностям через MCP/live.
|
||||
|
||||
## Общий подход
|
||||
|
||||
Делаем отдельный пакет, без большого неразмеченного рефакторинга:
|
||||
|
||||
- Wave A: baseline + contracts
|
||||
- Wave B: runtime lane + planner
|
||||
- Wave C: recipes + answer contract
|
||||
- Wave D: live rerun + acceptance
|
||||
|
||||
## Wave A — Baseline & Contracts
|
||||
|
||||
### Цель
|
||||
|
||||
Зафиксировать source-of-truth и контракты перед кодом.
|
||||
|
||||
### Что делаем
|
||||
|
||||
1. Вводим `question_mode=address_query`.
|
||||
2. Фиксируем V1 intents (5 штук).
|
||||
3. Фиксируем `address_query_recipe` контракт.
|
||||
4. Фиксируем обязательные debug поля и run-артефакты.
|
||||
|
||||
### Артефакты
|
||||
|
||||
- `docs/ADDRESS/runs/<run_id>/README.md`
|
||||
- `run_summary.json`
|
||||
- `address_intent_contract.md`
|
||||
- `address_recipe_contract.md`
|
||||
|
||||
## Wave B — Runtime Lane
|
||||
|
||||
### Цель
|
||||
|
||||
Встроить новый lane в текущий assistant pipeline.
|
||||
|
||||
### Что делаем
|
||||
|
||||
1. Добавляем `AddressIntentResolver`.
|
||||
2. Добавляем `AddressQueryPlanner`.
|
||||
3. Добавляем source policy:
|
||||
- `address_query => live_required=true`
|
||||
- fallback на snapshot только явно и с limitation.
|
||||
4. Разводим маршруты:
|
||||
- deep reasoning path не трогаем;
|
||||
- address path идет отдельной веткой.
|
||||
|
||||
### Acceptance
|
||||
|
||||
- Address intent корректно выделяется на контрольном наборе.
|
||||
- Для address-intent не происходит тихого ухода в snapshot-first.
|
||||
|
||||
## Wave C — Query Recipes & Answer Contract
|
||||
|
||||
### Цель
|
||||
|
||||
Сделать рабочие адресные ответы по MCP.
|
||||
|
||||
### Что делаем
|
||||
|
||||
1. Реализуем минимум 5 MCP recipes (по intent V1).
|
||||
2. Делаем materializer:
|
||||
- rows -> normalized list,
|
||||
- totals,
|
||||
- stable output schema.
|
||||
3. Добавляем `AddressAnswerComposer`:
|
||||
- `FACTUAL_LIST`,
|
||||
- `FACTUAL_SUMMARY`,
|
||||
- `LIMITED_WITH_REASON`.
|
||||
|
||||
### Acceptance
|
||||
|
||||
- На expected-positive вопросах есть непустой factual output.
|
||||
- Ошибки live не маскируются, false factual = 0.
|
||||
|
||||
## Wave D — Live Replay & Acceptance
|
||||
|
||||
### Цель
|
||||
|
||||
Проверить live-сценарии на реальных адресных вопросах.
|
||||
|
||||
### Контрольный набор (минимум)
|
||||
|
||||
1. Покажи незакрытые договоры.
|
||||
2. Кому мы должны денег.
|
||||
3. Кто должен нам денег.
|
||||
4. Остатки по счету 60 (или 62) на текущую дату.
|
||||
5. Незакрытые позиции по конкретному контрагенту.
|
||||
|
||||
### Метрики
|
||||
|
||||
1. `address_intent_resolution_rate >= 0.95`
|
||||
2. `address_live_call_success_rate >= 0.95`
|
||||
3. `address_non_empty_result_rate > 0` на positive-кейсах
|
||||
4. `address_false_factual_rate = 0`
|
||||
5. `address_snapshot_fallback_rate` (должна быть низкой и явной)
|
||||
|
||||
### Обязательные артефакты
|
||||
|
||||
- `chat_export_address_live.md`
|
||||
- `debug_payloads/`
|
||||
- `live_call_inventory.json`
|
||||
- `address_result_matrix.md`
|
||||
- `address_failure_breakdown.json`
|
||||
|
||||
## Run-структура (обязательно)
|
||||
|
||||
Все прогоны только сюда:
|
||||
|
||||
- `docs/ADDRESS/runs/<YYYY-MM-DD>_<PackName>/`
|
||||
|
||||
## Риски и анти-риски
|
||||
|
||||
Риск:
|
||||
|
||||
- смешение deep-chain и address-lane в одном вопросе.
|
||||
|
||||
Контрмера:
|
||||
|
||||
- rule-based switch по `question_mode` + explicit fallback в mixed-mode.
|
||||
|
||||
Риск:
|
||||
|
||||
- деградация в silent snapshot.
|
||||
|
||||
Контрмера:
|
||||
|
||||
- mandatory debug flag `live_required_for_mode=true`,
|
||||
- limitation если live недоступен.
|
||||
|
||||
## Финальный критерий пакета
|
||||
|
||||
Пакет считается принятым, когда:
|
||||
|
||||
1. Address intent стабильно маршрутизируется в MCP-first lane.
|
||||
2. На части live-кейсов система дает быстрый factual ответ.
|
||||
3. Нет ложной "доказанности" и нет молчаливой подмены источника.
|
||||
|
||||
Verdict:
|
||||
|
||||
- `ADDRESS_RUNTIME_V1_READY`
|
||||
- или `ADDRESS_RUNTIME_V1_READY_WITH_LIMITATIONS`
|
||||
- или `ADDRESS_RUNTIME_V1_NOT_READY`
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# ADDRESS Track (MCP-first)
|
||||
|
||||
Этот раздел фиксирует разворот Stage 4 в сторону "адресных" пользовательских запросов:
|
||||
|
||||
- быстро найти сущности;
|
||||
- показать список и статус (есть/нет, закрыто/не закрыто);
|
||||
- получить остатки/долги/контрагентов по текущему состоянию базы.
|
||||
|
||||
Ключевой принцип трека: **MCP/live-first**, а не snapshot-first.
|
||||
|
||||
## Документы
|
||||
|
||||
1. `1 - architecture_audit_mcp_first_address_runtime_2026-03-29.md`
|
||||
Технический аудит текущего состояния и ограничений.
|
||||
|
||||
2. `2 - target_architecture_mcp_first_address_queries_stage4_2026-03-29.md`
|
||||
Целевая архитектура под адресные запросы.
|
||||
|
||||
3. `3 - execution_plan_address_runtime_waveA_waveD_2026-03-29.md`
|
||||
Пошаговый план реализации без большого рефакторинга.
|
||||
|
||||
## Раны и артефакты
|
||||
|
||||
Все новые прогоны и доказательные артефакты складываются в:
|
||||
|
||||
- `docs/ADDRESS/runs/`
|
||||
|
||||
Базовый аудитный run:
|
||||
|
||||
- `docs/ADDRESS/runs/2026-03-29_Address_Runtime_Pivot_Baseline/`
|
||||
|
||||
Reference in New Issue
Block a user