ДОМЕНЫ - ВОПРОСЫ - Этап 4: точный маршрут confirmed payables на дату без эвристического фолбэка

This commit is contained in:
2026-04-12 14:14:03 +03:00
parent 1b2ee93176
commit fbd156e58e
19 changed files with 1303 additions and 162 deletions
+529
View File
@@ -0,0 +1,529 @@
Да, так двигаться **можно**, но не в виде «сейчас добьём все сложные вопросы, а потом когда-нибудь займёмся длинным диалогом».
Правильнее так:
**сейчас добивать сложные вычислительные вопросы — да,
но уже сейчас заложить минимальный каркас длинного диалога, чтобы потом не пришлось ломать всё заново.**
То есть ответ не «сначала одно, потом другое», а:
**основной фокус — на сложных доказуемых вопросах,
но с обязательной тонкой прослойкой state/navigation уже сейчас.**
---
## Почему так
У тебя сейчас по сути есть **три разных задачи**, и их нельзя смешивать:
### 1. Доказательный вычислительный контур
Это вопросы типа:
* кому должны;
* кто должен нам;
* остатки;
* задолженность;
* обязательства на дату;
* НДС;
* обороты;
* сверки;
* причины расхождения.
Тут нужен не “умный ассистент”, а **строгий финансовый движок ответа**.
LLM тут только:
* понимает запрос,
* канонизирует,
* упаковывает ответ.
### 2. Диалоговая навигация по результатам
Это уже история:
* покажи должников;
* открой первого;
* покажи документы по нему;
* открой вот этот документ;
* вернись к списку;
* теперь покажи только крупных;
* а теперь снова общий список.
Это вообще другая задача. Это не про бухгалтерский расчёт, а про **сессионное состояние, ссылки на объекты и навигацию**.
### 3. Разговорный слой
Это:
* как красиво формулируется ответ;
* как держится контекст;
* как не врёт;
* как не теряет тему;
* как уточняет.
Если не разделить эти три задачи, начнётся каша:
* вычислительные баги будете лечить промптом;
* диалоговые провалы — данными;
* архитектурные проблемы — текстом ответа.
---
## Что у вас уже сделано правильно
Судя по описанию, вы уже сделали важную правильную вещь:
вы ушли от «говно-MVP на if-ах» к более нормальной оркестрации и явным контрактам.
Это правильно.
Потому что без этого дальше было бы бессмысленно развивать сложные вопросы.
---
## Где сейчас опасность
Опасность у вас не в том, что вы пошли в сложные вопросы.
Опасность в другом:
**вы можете начать чинить сложные кейсы так, что они размоют рабочие простые кейсы.**
Это самая частая проблема.
То есть:
* новый route ради сложного кейса начинает перехватывать старые запросы;
* новая нормализация ломает короткие вопросы;
* новый orchestration layer делает хуже там, где раньше всё было стабильно;
* deep/fallback начинает срабатывать там, где раньше был простой exact answer.
Поэтому тебе сейчас нельзя работать по принципу:
> “ну сейчас доделаем тяжёлые вопросы, а там посмотрим”
Нужен другой режим:
> **сложные кейсы добавляются как отдельный слой, не ломая работающий baseline.**
---
## Самый правильный способ двигаться сейчас
### Главный принцип:
**не делать “общую умность”, а делать “изолированные доказательные capability-маршруты”.**
То есть не надо пытаться “в целом сделать ассистент умнее”.
Надо делать конкретные capability-блоки:
* confirmed_payables_as_of_date
* confirmed_receivables_as_of_date
* vat_obligation_breakdown
* account_balance_as_of_date
* document_chain_explainer
* debtor_detail_drilldown
* settlement_reconciliation_trace
И каждый из них:
* имеет входной контракт,
* имеет data-route,
* имеет свой evidence model,
* имеет свои acceptance tests.
Это намного стабильнее, чем пытаться “допилить общий интеллект”.
---
## Можно ли сейчас фокусироваться на сложных вопросах, а длинные цепочки делать потом
**Да, но только частично.**
Правильный ответ такой:
### Что можно отложить
Можно отложить:
* полноценную богатую conversational UX-историю;
* красивые возвращения по веткам;
* умные эллипсисы типа “тот же документ, что мы обсуждали раньше”;
* сложные нелинейные прыжки по истории.
### Что нельзя откладывать
Нельзя откладывать:
* **модель состояния результата**;
* **идентификаторы result set’ов**;
* **идентификаторы выбранных объектов**;
* **контекст фокуса**;
* **операции drilldown / back / reopen / refine**.
Потому что если этого не заложить сейчас, потом всё придётся перепахивать.
---
## Очень важная мысль
Длинный диалог в вашем кейсе — это **не “LLM держит контекст”**.
Это вообще не об этом.
Это должно быть не:
* “модель помнит, о чём говорили”,
а:
* “система хранит конкретный объектный state разговора”.
Например:
### После запроса “покажи должников”
создаётся объект:
* `result_set_id = debtors_2020_05_v1`
* тип: `receivables_list`
* дата среза
* фильтры
* сортировка
* список entity_id
### Потом “открой второго”
создаётся:
* `focus_object = counterparty:gamma_mebel`
* `parent_result_set = debtors_2020_05_v1`
### Потом “покажи документы по нему”
создаётся:
* `result_set_id = docs_for_gamma_mebel_2020_05_v1`
* тип: `document_list`
* parent focus: `counterparty:gamma_mebel`
### Потом “вернись к списку должников”
это не магия модели, а явное:
* restore `result_set_id = debtors_2020_05_v1`
Вот тогда это работает как система.
А не как “LLM вроде бы держит мысль”.
---
## Поэтому правильная стратегия у вас должна быть двухконтурной
## Контур А — основной: сложные доказательные вопросы
Это ваш главный приоритет прямо сейчас.
Потому что если ассистент не умеет честно отвечать на:
* кому должны,
* кто должен нам,
* сколько НДС,
* какие обязательства открыты,
* почему расхождение,
то всё остальное рано или поздно бессмысленно.
Здесь надо добивать **exact analytical routes**.
## Контур Б — минимальный state/navigation framework
Не весь длинный диалог целиком, а минимальный каркас.
То есть прямо сейчас нужно ввести хотя бы:
* `conversation_state`
* `current_focus`
* `result_sets`
* `drilldown_history`
* `resolvable references`
типа “этот контрагент”, “первый”, “тот документ”, “верни прошлый список”
Без этого потом многоуровневые кейсы будут собираться заново криво.
---
## Как бы я выстроил разработку по этапам
## Этап 1. Заморозить baseline
Перед любыми тяжёлыми доработками нужно зафиксировать текущий рабочий контур:
* список простых запросов, которые уже работают;
* их эталонные ответы;
* их route expectations;
* их допустимые форматы;
* их accuracy baseline.
Иначе вы не заметите, как сложные доработки сожрут простые кейсы.
То есть нужен **golden baseline suite**.
Прям обязательно:
* 30–50 простых сценариев;
* 1020 средних;
* 510 сложных.
И для каждого:
* intent;
* expected route;
* required evidence;
* must_not_happen;
* acceptance criteria.
---
## Этап 2. Выделить отдельный слой exact analytical capabilities
Не один “универсальный роут”, а capability registry.
Например:
* `confirmed_payables_as_of_date`
* `confirmed_receivables_as_of_date`
* `account_balance_as_of_date`
* `tax_obligation_snapshot`
* `document_trace_chain`
* `counterparty_reconciliation_detail`
И каждый capability должен быть:
* изолирован,
* версионирован,
* под rollout flag,
* с собственным eval suite.
Это защитит простые кейсы.
---
## Этап 3. Для сложных вопросов делать не prompt-tuning, а data-route design
Вот тут очень важно.
На текущем этапе вам не нужно “допилить LLM, чтобы она лучше поняла вопрос”.
Вам нужно:
* описать доказательный объект ответа;
* понять, какие сущности для него нужны;
* понять, где эти поля лежат;
* понять, как строится формула;
* понять, как выглядит traceability.
То есть сложный вопрос нужно разбирать не как “сложный prompt”, а как:
**какой exact business computation за ним стоит?**
Например, вопрос:
> кому должны на май 2020
разбирается как:
* дата среза,
* открытые обязательства,
* группировка по контрагенту,
* классификация обязательств,
* исключение закрытых,
* доказательная цепочка.
Вот это правильный уровень.
---
## Этап 4. Уже сейчас ввести минимальный state model для диалога
Не надо пока делать “идеальный длинный разговор”.
Но нужно завести базовые сущности:
### `session_context`
* active_result_set_id
* active_focus_object
* last_confirmed_route
* date_scope
* organization_scope
### `result_set`
* id
* type
* route_id
* filters
* sort
* entity_refs[]
* source_refs[]
* created_from_turn
### `focus_object`
* object_type
* object_id
* label
* provenance_result_set_id
### `navigation_event`
* action: open / refine / back / compare / reset
* source_result_set_id
* target_object_id
* derived_result_set_id
Тогда потом длинный диалог нарастает нормально.
---
## Этап 5. Сделать 2–3 эталонные длинные цепочки, а не весь “длинный диалог”
Вот это важный баланс.
Не надо сейчас пытаться закрыть **все** длинные диалоги.
Нужно взять 2–3 ключевые цепочки и довести их как вертикальные срезы.
Например:
### Цепочка 1
* покажи должников на дату
* открой крупнейшего
* покажи документы по нему
* открой документ
* покажи, чем закрывался
* вернись к списку
### Цепочка 2
* кому должны на дату
* оставь только поставщиков
* покажи по конкретному контрагенту
* покажи основание долга
* покажи связанные оплаты
* верни сводку
### Цепочка 3
* покажи НДС за период
* объясни расхождение
* открой документы-источники
* покажи корректировки
* вернись к агрегату
Этого уже хватит, чтобы не строить всё вслепую.
---
## На что я бы не тратил время сейчас
Сейчас я бы **не** делал ставку на:
* “сделаем модель ещё умнее, и она сама вытянет”;
* бесконечную шлифовку prose-ответов;
* тонкую косметику fallback-логики;
* попытку одной общей оркестрацией покрыть всё;
* богатую свободную болталку.
Это всё вторично по сравнению с:
* exact routes,
* state model,
* regression harness,
* evidence model.
---
## Как не сломать простые кейсы
Вот тут прям практический совет.
### 1. Все новые маршруты — только за флагами
Новый exact-route не должен сразу заменять старый baseline.
Сначала:
* old route remains default
* new route runs in shadow mode
* сравниваете ответы
* смотрите deltas
* только потом переводите на prod path
### 2. Для каждого кейса фиксируйте expected route
Например:
* “остаток по счету” не должен внезапно уйти в deep-analysis;
* “кому должны” должен идти только в confirmed payables route;
* “покажи документы по этому контрагенту” — только в drilldown route.
### 3. Отдельно меряйте регрессии
Не только answer correctness, но и:
* route correctness;
* evidence completeness;
* fallback frequency;
* overconfident wrong answers;
* broken referential follow-ups.
---
## Самый правильный способ мыслить про ваш продукт сейчас
Не как про “LLM-ассистента по бухгалтерии”, а как про:
**доказательный финансовый query engine + conversational navigator поверх него**
Вот это, по-моему, самая точная рамка.
Потому что если мыслить “ассистентом”, вас всё время будет тянуть лечить вычислительные проблемы через LLM.
А если мыслить “доказательным query engine”, тогда всё встаёт на место:
* LLM — вход и объяснение;
* engine — расчёт;
* state layer — навигация;
* evidence layer — доверие.
---
## Мой прямой совет по порядку работ
Я бы делал так:
### Сейчас
1. Зафиксировать baseline простых рабочих кейсов.
2. Выбрать 5–7 самых важных сложных управленческих вопросов.
3. Для каждого сделать exact business route.
4. Одновременно заложить минимальный result/state/navigation layer.
5. Прогнать 2–3 длинные эталонные цепочки.
### Не сейчас
* не пытаться закрыть весь длинный диалог целиком;
* не делать глобальную магическую “универсальную” оркестрацию;
* не лечить сложные кейсы только prompt engineering’ом.
---
## Короткий ответ на твой главный вопрос
**Да, фокус на сложных вопросах сейчас — правильный.**
Но **полностью откладывать длинные цепочки нельзя**. Их нужно не “доделывать потом”, а **заложить сейчас в виде минимальной объектной модели состояния и 2–3 эталонных навигационных сценариев**.
То есть:
**сначала не “сложные вопросы vs длинные диалоги”,
а “exact routes first, state skeleton in parallel, rich dialog later”.**
Это, на мой взгляд, для вас сейчас самый здоровый путь.
Могу дальше сразу разложить это в виде **конкретного roadmap-а по спринтам / этапам**, чтобы это можно было отдать в работу.