ДОМЕНЫ - ВОПРОСЫ - Этап 4: точный маршрут confirmed payables на дату без эвристического фолбэка
This commit is contained in:
@@ -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 простых сценариев;
|
||||
* 10–20 средних;
|
||||
* 5–10 сложных.
|
||||
|
||||
И для каждого:
|
||||
|
||||
* 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-а по спринтам / этапам**, чтобы это можно было отдать в работу.
|
||||
Reference in New Issue
Block a user