АДРЕСНЫЙ РЕЖИМ - ADDRESS: стабилизация интерпретации сленга и mixed RU/EN, расширение intent/mode-роутинга, регресс-тесты и live stress 102/102

This commit is contained in:
dctouch 2026-04-02 11:01:28 +03:00
parent 7dd6607ded
commit da8a4eb872
68 changed files with 29777 additions and 3220 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
[
{ "id": "S001", "text": "свк доки за 2020 покаж пж", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S002", "text": "покеж все доки по свк за 20 год", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S003", "text": "дай список документов по свк за 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S004", "text": "какие у свк есть доки за 2020?", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S005", "text": "че по свк по докам за 2020 год", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S006", "text": "ёпт покажи доки по свк за 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S007", "text": "бля, доки свк 2020 вывали", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S008", "text": "svk docs for 2020 please", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S009", "text": "docs by counterparty svk year 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S010", "text": "по контрагенту свк покаж документы за 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S011", "text": "плс доки по свк 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S012", "text": "свк док за 2020 гони", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "S013", "text": "по свк банковские операции за 2020 покаж", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S014", "text": "свк выписка банка 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S015", "text": "платежи по свк за 2020 выведи", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S016", "text": "оплаты по свк за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S017", "text": "свк банк опер за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S018", "text": "че у свк по банку за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S019", "text": "свк списания/поступления за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S020", "text": "bank ops by svk for 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S021", "text": "transactions by counterparty svk 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S022", "text": "бля, по свк банковские платежки 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "S023", "text": "сальдо по счету 60.01 на дату 2020-07-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S024", "text": "остаток по счету 60.01 на 2020.05", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S025", "text": "покажи остаток по 60.01 за май 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S026", "text": "счет 60 остаток на май 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S027", "text": "баланс account 60.01 as of 2020-07-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S028", "text": "60.01 saldo на 31.07.2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S029", "text": "сколько на счете 60 на конец 2020-05", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S030", "text": "дай остаток 60.02 на 2020-12-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S031", "text": "епт, сальдо по счету 62.01 на 2020-12-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S032", "text": "плс остаток по счету 51 на 2020-06-30", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S033", "text": "как там по счету 60.01 на 2020.07?", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S034", "text": "сальдо 60 на 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "S035", "text": "какие документы формируют остаток по счету 60.01 на 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S036", "text": "из чего состоит остаток по счету 60 на 2020.05", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S037", "text": "раскрой остаток 60.01 по документам на конец июля 2020", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S038", "text": "доки под остатком 60.01 на 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S039", "text": "documents forming balance for account 60.01 as of 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S040", "text": "бля, какие доки формируют остаток 60.01 на 2020-05-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S041", "text": "по счету 62.01 раскрой остаток документами на 2020-12-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S042", "text": "из чего остаток по счету 51 на 2020-06-30", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "S043", "text": "покажи документы по договору 15/24 за 2020", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S044", "text": "доки по дог. 15/24 за 2020", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S045", "text": "какие документы по контракту 15/24", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S046", "text": "docs by contract 15/24 year 2020", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S047", "text": "бля, покажи по договору 15/24 доки", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S048", "text": "договор 15/24 документы", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S049", "text": "плс документы договор №15/24", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S050", "text": "покеж документы по 15/24", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "S051", "text": "банковские операции по договору 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S052", "text": "платежи по договору 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S053", "text": "выписка по договору 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S054", "text": "bank ops by contract 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S055", "text": "ёпт, покажи банк операции по дог 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S056", "text": "по контракту 15/24 платежки", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "S057", "text": "покажи сальдо по счету 60 за 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60" },
{ "id": "S058", "text": "а теперь только май 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60" },
{ "id": "S059", "text": "ок, теперь 2020.05", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60" },
{ "id": "S060", "text": "теперь на 2020-07-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60" }
]

View File

@ -0,0 +1,50 @@
[
{ "id": "X001", "text": "свк доки кинь за 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X002", "text": "по свк все документы за 20й год", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X003", "text": "пж вывали доки контрагент свк 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X004", "text": "svk poka docy za 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X005", "text": "какие доки по компании свк за 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X006", "text": "бля покаж свк документы 2020", "expected_intent": "list_documents_by_counterparty", "expected_mode": "address_query" },
{ "id": "X007", "text": "свк банк операции за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X008", "text": "по свк выписку банка за 2020 выведи", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X009", "text": "свк платежки за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X010", "text": "bank ops svk 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X011", "text": "транзакции по свк за 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X012", "text": "ёпт по свк че по банку 2020", "expected_intent": "bank_operations_by_counterparty", "expected_mode": "address_query" },
{ "id": "X013", "text": "остаток по 60.01 на 2020-07-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X014", "text": "сальдо 60.01 на 31.07.2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X015", "text": "что на счете 60 на 2020.05", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X016", "text": "дай остаток 62.01 на 2020 май", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X017", "text": "saldo account 60 as of 2020-12-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X018", "text": "плиз остаток по счету 51 на 2020-06-30", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X019", "text": "скока по 60.02 на конец 2020-12", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X020", "text": "бля сальдо 60.01 на 2020-05-31", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query" },
{ "id": "X021", "text": "раскрой остаток 60.01 по документам на конец июля 2020", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X022", "text": "доки под остатком 60.01 на 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X023", "text": "из чего остаток 60.01 на 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X024", "text": "какие документы формируют остаток по 60.01 на 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X025", "text": "docs forming balance 60.01 as of 2020-07-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X026", "text": "раскидай остаток 62.01 по докам на 2020-12-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X027", "text": "по счету 51 раскрой остаток документами на 2020-06-30", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X028", "text": "бля из чего состоит остаток по 60.01 на 2020-05-31", "expected_intent": "documents_forming_balance", "expected_mode": "address_query" },
{ "id": "X029", "text": "доки по договору 15/24 за 2020", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X030", "text": "покажи документы контракт 15/24", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X031", "text": "docs by contract 15/24 2020", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X032", "text": "по дог 15/24 какие документы", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X033", "text": "договор 15/24 выведи доки", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X034", "text": "нах покажи документы по 15/24", "expected_intent": "list_documents_by_contract", "expected_mode": "address_query" },
{ "id": "X035", "text": "банк операции по договору 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X036", "text": "платежки по дог 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X037", "text": "выписка по контракту 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X038", "text": "bank ops by contract 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X039", "text": "покажи банк опер по дог 15/24 пж", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X040", "text": "епт транзакции договор 15/24", "expected_intent": "bank_operations_by_contract", "expected_mode": "address_query" },
{ "id": "X041", "text": "покажи сальдо по счету 60 за 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60_extra" },
{ "id": "X042", "text": "а теперь только май 2020", "expected_intent": "account_balance_snapshot", "expected_mode": "address_query", "session": "chain_balance_60_extra" }
]

View File

@ -0,0 +1,620 @@
[
{
"id": "S001",
"text": "свк доки за 2020 покаж пж",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S002",
"text": "покеж все доки по свк за 20 год",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S003",
"text": "дай список документов по свк за 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S004",
"text": "какие у свк есть доки за 2020?",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S005",
"text": "че по свк по докам за 2020 год",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S006",
"text": "ёпт покажи доки по свк за 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S007",
"text": "бля, доки свк 2020 вывали",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S008",
"text": "svk docs for 2020 please",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S009",
"text": "docs by counterparty svk year 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S010",
"text": "по контрагенту свк покаж документы за 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S011",
"text": "плс доки по свк 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S012",
"text": "свк док за 2020 гони",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S013",
"text": "по свк банковские операции за 2020 покаж",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S014",
"text": "свк выписка банка 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S015",
"text": "платежи по свк за 2020 выведи",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S016",
"text": "оплаты по свк за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S017",
"text": "свк банк опер за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S018",
"text": "че у свк по банку за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S019",
"text": "свк списания/поступления за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S020",
"text": "bank ops by svk for 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S021",
"text": "transactions by counterparty svk 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S022",
"text": "бля, по свк банковские платежки 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "S023",
"text": "сальдо по счету 60.01 на дату 2020-07-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S024",
"text": "остаток по счету 60.01 на 2020.05",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S025",
"text": "покажи остаток по 60.01 за май 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S026",
"text": "счет 60 остаток на май 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S027",
"text": "баланс account 60.01 as of 2020-07-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S028",
"text": "60.01 saldo на 31.07.2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S029",
"text": "сколько на счете 60 на конец 2020-05",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S030",
"text": "дай остаток 60.02 на 2020-12-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S031",
"text": "епт, сальдо по счету 62.01 на 2020-12-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S032",
"text": "плс остаток по счету 51 на 2020-06-30",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S033",
"text": "как там по счету 60.01 на 2020.07?",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S034",
"text": "сальдо 60 на 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "S035",
"text": "какие документы формируют остаток по счету 60.01 на 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S036",
"text": "из чего состоит остаток по счету 60 на 2020.05",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S037",
"text": "раскрой остаток 60.01 по документам на конец июля 2020",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S038",
"text": "доки под остатком 60.01 на 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S039",
"text": "documents forming balance for account 60.01 as of 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S040",
"text": "бля, какие доки формируют остаток 60.01 на 2020-05-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S041",
"text": "по счету 62.01 раскрой остаток документами на 2020-12-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S042",
"text": "из чего остаток по счету 51 на 2020-06-30",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "S043",
"text": "покажи документы по договору 15/24 за 2020",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S044",
"text": "доки по дог. 15/24 за 2020",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S045",
"text": "какие документы по контракту 15/24",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S046",
"text": "docs by contract 15/24 year 2020",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S047",
"text": "бля, покажи по договору 15/24 доки",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S048",
"text": "договор 15/24 документы",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S049",
"text": "плс документы договор №15/24",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S050",
"text": "покеж документы по 15/24",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "S051",
"text": "банковские операции по договору 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S052",
"text": "платежи по договору 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S053",
"text": "выписка по договору 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S054",
"text": "bank ops by contract 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S055",
"text": "ёпт, покажи банк операции по дог 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S056",
"text": "по контракту 15/24 платежки",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "S057",
"text": "покажи сальдо по счету 60 за 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60"
},
{
"id": "S058",
"text": "а теперь только май 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60"
},
{
"id": "S059",
"text": "ок, теперь 2020.05",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60"
},
{
"id": "S060",
"text": "теперь на 2020-07-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60"
},
{
"id": "X001",
"text": "свк доки кинь за 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X002",
"text": "по свк все документы за 20й год",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X003",
"text": "пж вывали доки контрагент свк 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X004",
"text": "svk poka docy za 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X005",
"text": "какие доки по компании свк за 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X006",
"text": "бля покаж свк документы 2020",
"expected_intent": "list_documents_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X007",
"text": "свк банк операции за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X008",
"text": "по свк выписку банка за 2020 выведи",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X009",
"text": "свк платежки за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X010",
"text": "bank ops svk 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X011",
"text": "транзакции по свк за 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X012",
"text": "ёпт по свк че по банку 2020",
"expected_intent": "bank_operations_by_counterparty",
"expected_mode": "address_query"
},
{
"id": "X013",
"text": "остаток по 60.01 на 2020-07-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X014",
"text": "сальдо 60.01 на 31.07.2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X015",
"text": "что на счете 60 на 2020.05",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X016",
"text": "дай остаток 62.01 на 2020 май",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X017",
"text": "saldo account 60 as of 2020-12-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X018",
"text": "плиз остаток по счету 51 на 2020-06-30",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X019",
"text": "скока по 60.02 на конец 2020-12",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X020",
"text": "бля сальдо 60.01 на 2020-05-31",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query"
},
{
"id": "X021",
"text": "раскрой остаток 60.01 по документам на конец июля 2020",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X022",
"text": "доки под остатком 60.01 на 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X023",
"text": "из чего остаток 60.01 на 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X024",
"text": "какие документы формируют остаток по 60.01 на 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X025",
"text": "docs forming balance 60.01 as of 2020-07-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X026",
"text": "раскидай остаток 62.01 по докам на 2020-12-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X027",
"text": "по счету 51 раскрой остаток документами на 2020-06-30",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X028",
"text": "бля из чего состоит остаток по 60.01 на 2020-05-31",
"expected_intent": "documents_forming_balance",
"expected_mode": "address_query"
},
{
"id": "X029",
"text": "доки по договору 15/24 за 2020",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X030",
"text": "покажи документы контракт 15/24",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X031",
"text": "docs by contract 15/24 2020",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X032",
"text": "по дог 15/24 какие документы",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X033",
"text": "договор 15/24 выведи доки",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X034",
"text": "нах покажи документы по 15/24",
"expected_intent": "list_documents_by_contract",
"expected_mode": "address_query"
},
{
"id": "X035",
"text": "банк операции по договору 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X036",
"text": "платежки по дог 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X037",
"text": "выписка по контракту 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X038",
"text": "bank ops by contract 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X039",
"text": "покажи банк опер по дог 15/24 пж",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X040",
"text": "епт транзакции договор 15/24",
"expected_intent": "bank_operations_by_contract",
"expected_mode": "address_query"
},
{
"id": "X041",
"text": "покажи сальдо по счету 60 за 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60_extra"
},
{
"id": "X042",
"text": "а теперь только май 2020",
"expected_intent": "account_balance_snapshot",
"expected_mode": "address_query",
"session": "chain_balance_60_extra"
}
]

View File

@ -0,0 +1,22 @@
# 2026-04-02_Address_Full_Live_Run_2026-04-02_08-03-09
- Questions total: 37
- HTTP 200 + ok: 34
- Factual replies: 31
- Partial replies: 3
- LLM decomposition applied: 25
- Fallback rules used: 25
- Avg latency (ms): 1157.8
## Top Partial Cases
- #11: Покажи документы по договору 15/24
reply_type=partial_coverage; mcp=materialized_but_filtered_out_by_recipe; limited_reason=recipe_visibility_gap; llm_reason=fallback_rule_applied_after_llm_error
- #13: Есть ли долг по договору 15/24 на 2020-07-31
reply_type=partial_coverage; mcp=materialized_but_not_anchor_matched; limited_reason=empty_match; llm_reason=error:Failed to extract output_text from /responses payload.
- #33: покажи банк опер по дог 15/24 пж
reply_type=partial_coverage; mcp=skipped; limited_reason=unsupported; llm_reason=fallback_rule_applied_after_llm_error
## Artifacts
- full_live_results.json
- run_summary.json
- failures_only.json

View File

@ -0,0 +1,551 @@
[
{
"number": 11,
"question": "Покажи документы по договору 15/24",
"session_key": "single_11",
"session_id": "asst-x504ZNzRpo",
"status_code": 200,
"ok": true,
"elapsed_ms": 2054,
"reply_type": "partial_coverage",
"trace_id": "address-R4AOTGWmNt",
"assistant_reply": "Текущий live recipe не дает нужную видимость данных для этого сценария.\nПричина: строки по якорю найдены, но отфильтрованы intent-specific recipe.\nЧто нужно уточнить: сузьте период, уточните контрагента или документный тип.",
"execution_lane": "address_query",
"detected_mode": "address_query",
"detected_intent": "list_documents_by_contract",
"selected_recipe": "address_documents_by_contract_v1",
"mcp_call_status": "materialized_but_filtered_out_by_recipe",
"limited_reason_category": "recipe_visibility_gap",
"rows_matched": 0,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"llm_provider_used": "local",
"fallback_rule_hit": "documents_contract_rewrite",
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "документы по договору 15/24",
"error_text": null,
"debug": {
"trace_id": "address-R4AOTGWmNt",
"prompt_version": "address_query_runtime_v1",
"schema_version": "address_query_runtime_v1",
"fallback_type": "partial",
"route_summary": null,
"fragments": [
],
"requirements_extracted": [
],
"coverage_report": {
"requirements_total": 0,
"requirements_covered": 0,
"requirements_uncovered": [
],
"requirements_partially_covered": [
],
"clarification_needed_for": [
],
"out_of_scope_requirements": [
]
},
"routes": [
],
"retrieval_status": [
],
"retrieval_results": [
],
"answer_grounding_check": {
"status": "partial",
"route_subject_match": true,
"missing_requirements": [
],
"reasons": [
"address_entity_detected",
"document_list_signal_detected",
"documents_by_contract_signal_detected"
],
"why_included_summary": [
],
"selection_reason_summary": [
]
},
"dropped_intent_segments": [
],
"detected_mode": "address_query",
"detected_mode_confidence": "medium",
"query_shape": "DOCUMENT_LIST",
"query_shape_confidence": "medium",
"detected_intent": "list_documents_by_contract",
"detected_intent_confidence": "medium",
"extracted_filters": {
"sort": "period_desc",
"limit": 20,
"contract": "15/24"
},
"missing_required_filters": [
],
"selected_recipe": "address_documents_by_contract_v1",
"mcp_call_status_legacy": "materialized_but_not_matched",
"account_scope_mode": "preferred",
"account_scope_fallback_applied": false,
"anchor_type": "contract",
"anchor_value_raw": "15/24",
"anchor_value_resolved": "15/24",
"resolver_confidence": "medium",
"ambiguity_count": 0,
"match_failure_stage": "materialized_but_filtered_out_by_recipe",
"match_failure_reason": "rows_filtered_out_by_intent_recipe_after_anchor_match",
"mcp_call_status": "materialized_but_filtered_out_by_recipe",
"rows_fetched": 1000,
"raw_rows_received": 1000,
"rows_after_account_scope": 416,
"rows_after_recipe_filter": 2,
"rows_materialized": 416,
"rows_matched": 0,
"raw_row_keys_sample": [
"Период",
"Регистратор",
"СчетДт",
"СчетКт",
"Сумма",
"Period",
"Registrator",
"AccountDt",
"AccountKt",
"Amount"
],
"materialization_drop_reason": "none",
"account_token_raw": null,
"account_token_normalized": null,
"account_scope_fields_checked": [
"account_dt",
"account_kt",
"registrator",
"analytics"
],
"account_scope_match_strategy": "account_code_regex_plus_alias_map_v1",
"account_scope_drop_reason": "not_applicable",
"runtime_readiness": "REQUIRES_SPECIALIZED_RECIPE",
"limited_reason_category": "recipe_visibility_gap",
"response_type": "LIMITED_WITH_REASON",
"execution_lane": "address_query",
"llm_decomposition_applied": true,
"llm_decomposition_attempted": true,
"llm_provider_used": "local",
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "документы по договору 15/24",
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_contract_rewrite",
"sanitized_user_message": "покажи документы по договору 15/24",
"tool_gate_decision": "run_address_lane",
"tool_gate_reason": "address_signal_detected",
"answer_structure_v11": null,
"investigation_state_snapshot": null,
"normalized": null,
"normalizer_output": null
}
},
{
"number": 13,
"question": "Есть ли долг по договору 15/24 на 2020-07-31",
"session_key": "single_13",
"session_id": "asst-UUVkCb5sCS",
"status_code": 200,
"ok": true,
"elapsed_ms": 2964,
"reply_type": "partial_coverage",
"trace_id": "address-Ea84sfq8iH",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"execution_lane": "address_query",
"detected_mode": "address_query",
"detected_intent": "list_documents_by_contract",
"selected_recipe": "address_documents_by_contract_v1",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"rows_matched": 0,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "error:Failed to extract output_text from /responses payload.",
"llm_provider_used": "local",
"fallback_rule_hit": null,
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "Есть ли долг по договору 15/24 на 2020-07-31",
"error_text": null,
"debug": {
"trace_id": "address-Ea84sfq8iH",
"prompt_version": "address_query_runtime_v1",
"schema_version": "address_query_runtime_v1",
"fallback_type": "partial",
"route_summary": null,
"fragments": [
],
"requirements_extracted": [
],
"coverage_report": {
"requirements_total": 0,
"requirements_covered": 0,
"requirements_uncovered": [
],
"requirements_partially_covered": [
],
"clarification_needed_for": [
],
"out_of_scope_requirements": [
]
},
"routes": [
],
"retrieval_status": [
],
"retrieval_results": [
],
"answer_grounding_check": {
"status": "partial",
"route_subject_match": true,
"missing_requirements": [
],
"reasons": [
"address_action_detected",
"address_entity_detected",
"verify_signal_detected",
"documents_by_contract_signal_detected"
],
"why_included_summary": [
],
"selection_reason_summary": [
]
},
"dropped_intent_segments": [
],
"detected_mode": "address_query",
"detected_mode_confidence": "high",
"query_shape": "VERIFY_FACTUAL",
"query_shape_confidence": "medium",
"detected_intent": "list_documents_by_contract",
"detected_intent_confidence": "medium",
"extracted_filters": {
"sort": "period_desc",
"limit": 20,
"contract": "15/24",
"period_from": "2020-07-01",
"period_to": "2020-07-31"
},
"missing_required_filters": [
],
"selected_recipe": "address_documents_by_contract_v1",
"mcp_call_status_legacy": "materialized_but_not_matched",
"account_scope_mode": "preferred",
"account_scope_fallback_applied": true,
"anchor_type": "contract",
"anchor_value_raw": "15/24",
"anchor_value_resolved": "15/24",
"resolver_confidence": "medium",
"ambiguity_count": 0,
"match_failure_stage": "materialized_but_not_anchor_matched",
"match_failure_reason": "contract_anchor_not_matched_in_materialized_rows",
"mcp_call_status": "materialized_but_not_anchor_matched",
"rows_fetched": 20,
"raw_rows_received": 20,
"rows_after_account_scope": 20,
"rows_after_recipe_filter": 0,
"rows_materialized": 20,
"rows_matched": 0,
"raw_row_keys_sample": [
"Период",
"Регистратор",
"СчетДт",
"СчетКт",
"Сумма",
"Period",
"Registrator",
"AccountDt",
"AccountKt",
"Amount"
],
"materialization_drop_reason": "none",
"account_token_raw": null,
"account_token_normalized": null,
"account_scope_fields_checked": [
"account_dt",
"account_kt",
"registrator",
"analytics"
],
"account_scope_match_strategy": "account_code_regex_plus_alias_map_v1",
"account_scope_drop_reason": "not_applicable",
"runtime_readiness": "LIVE_QUERYABLE_WITH_LIMITS",
"limited_reason_category": "empty_match",
"response_type": "LIMITED_WITH_REASON",
"execution_lane": "address_query",
"llm_decomposition_applied": false,
"llm_decomposition_attempted": true,
"llm_provider_used": "local",
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "Есть ли долг по договору 15/24 на 2020-07-31",
"llm_decomposition_reason": "error:Failed to extract output_text from /responses payload.",
"fallback_rule_hit": null,
"sanitized_user_message": "есть ли долг по договору 15/24 на 2020-07-31",
"tool_gate_decision": "run_address_lane",
"tool_gate_reason": "address_signal_detected",
"answer_structure_v11": null,
"investigation_state_snapshot": null,
"normalized": null,
"normalizer_output": null
}
},
{
"number": 33,
"question": "покажи банк опер по дог 15/24 пж",
"session_key": "single_33",
"session_id": "asst-gXTpxnmWpG",
"status_code": 200,
"ok": true,
"elapsed_ms": 6,
"reply_type": "partial_coverage",
"trace_id": "address-VyJiL2DoTr",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"execution_lane": "address_query",
"detected_mode": "address_query",
"detected_intent": "unknown",
"selected_recipe": null,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"rows_matched": 0,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"llm_provider_used": "local",
"fallback_rule_hit": "noise_cleanup",
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "покажи банк опер по дог 15/24",
"error_text": null,
"debug": {
"trace_id": "address-VyJiL2DoTr",
"prompt_version": "address_query_runtime_v1",
"schema_version": "address_query_runtime_v1",
"fallback_type": "partial",
"route_summary": null,
"fragments": [
],
"requirements_extracted": [
],
"coverage_report": {
"requirements_total": 0,
"requirements_covered": 0,
"requirements_uncovered": [
],
"requirements_partially_covered": [
],
"clarification_needed_for": [
],
"out_of_scope_requirements": [
]
},
"routes": [
],
"retrieval_status": [
],
"retrieval_results": [
],
"answer_grounding_check": {
"status": "partial",
"route_subject_match": true,
"missing_requirements": [
],
"reasons": [
"address_action_detected",
"address_entity_detected",
"shape_not_detected",
"intent_not_supported_in_v1"
],
"why_included_summary": [
],
"selection_reason_summary": [
]
},
"dropped_intent_segments": [
],
"detected_mode": "address_query",
"detected_mode_confidence": "high",
"query_shape": "UNKNOWN",
"query_shape_confidence": "low",
"detected_intent": "unknown",
"detected_intent_confidence": "low",
"extracted_filters": {
"sort": "period_desc",
"limit": 20
},
"missing_required_filters": [
],
"selected_recipe": null,
"mcp_call_status_legacy": "skipped",
"account_scope_mode": "strict",
"account_scope_fallback_applied": false,
"anchor_type": "unknown",
"anchor_value_raw": null,
"anchor_value_resolved": null,
"resolver_confidence": "low",
"ambiguity_count": 0,
"match_failure_stage": "none",
"match_failure_reason": null,
"mcp_call_status": "skipped",
"rows_fetched": 0,
"raw_rows_received": 0,
"rows_after_account_scope": 0,
"rows_after_recipe_filter": 0,
"rows_materialized": 0,
"rows_matched": 0,
"raw_row_keys_sample": [
],
"materialization_drop_reason": "none",
"account_token_raw": null,
"account_token_normalized": null,
"account_scope_fields_checked": [
"account_dt",
"account_kt",
"registrator",
"analytics"
],
"account_scope_match_strategy": "account_code_regex_plus_alias_map_v1",
"account_scope_drop_reason": "not_applicable",
"runtime_readiness": "DEEP_ONLY",
"limited_reason_category": "unsupported",
"response_type": "LIMITED_WITH_REASON",
"execution_lane": "address_query",
"llm_decomposition_applied": true,
"llm_decomposition_attempted": true,
"llm_provider_used": "local",
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": "покажи банк опер по дог 15/24",
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "noise_cleanup",
"sanitized_user_message": "покажи банк опер по дог 15/24",
"tool_gate_decision": "run_address_lane",
"tool_gate_reason": "address_signal_detected",
"answer_structure_v11": null,
"investigation_state_snapshot": null,
"normalized": null,
"normalizer_output": null
}
},
{
"number": 35,
"question": "по свк за весь период че есть",
"session_key": "single_35",
"session_id": null,
"status_code": 502,
"ok": false,
"elapsed_ms": 45,
"reply_type": null,
"trace_id": null,
"assistant_reply": null,
"execution_lane": null,
"detected_mode": null,
"detected_intent": null,
"selected_recipe": null,
"mcp_call_status": null,
"limited_reason_category": null,
"rows_matched": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"llm_provider_used": null,
"fallback_rule_hit": null,
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": null,
"error_text": "",
"debug": null
},
{
"number": 36,
"question": "Покажи технические константы конфигурации",
"session_key": "single_36",
"session_id": null,
"status_code": 502,
"ok": false,
"elapsed_ms": 5,
"reply_type": null,
"trace_id": null,
"assistant_reply": null,
"execution_lane": null,
"detected_mode": null,
"detected_intent": null,
"selected_recipe": null,
"mcp_call_status": null,
"limited_reason_category": null,
"rows_matched": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"llm_provider_used": null,
"fallback_rule_hit": null,
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": null,
"error_text": "",
"debug": null
},
{
"number": 37,
"question": "кто президент США",
"session_key": "single_37",
"session_id": null,
"status_code": 502,
"ok": false,
"elapsed_ms": 3,
"reply_type": null,
"trace_id": null,
"assistant_reply": null,
"execution_lane": null,
"detected_mode": null,
"detected_intent": null,
"selected_recipe": null,
"mcp_call_status": null,
"limited_reason_category": null,
"rows_matched": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"llm_provider_used": null,
"fallback_rule_hit": null,
"llm_decomposition_trace_id": null,
"llm_decomposition_effective_message": null,
"error_text": "",
"debug": null
}
]

View File

@ -0,0 +1,67 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_08-03-09",
"generated_at": "2026-04-02T08:03:52",
"source_questions_file": "docs/ADDRESS/1.txt",
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
"llm_provider": "local",
"llm_base_url": "http://127.0.0.1:1234",
"llm_model": "qwen2.5-14b-instruct-1m",
"totals": {
"questions_total": 37,
"ok_200_count": 34,
"factual_count": 31,
"partial_coverage_count": 3,
"other_reply_types_count": 3,
"llm_decomposition_applied_count": 25,
"fallback_rule_hit_count": 25,
"avg_elapsed_ms": 1157.8
},
"distributions": {
"mcp_call_status": {
"materialized_but_filtered_out_by_recipe": 1,
"skipped": 1,
"matched_non_empty": 31,
"(null)": 3,
"materialized_but_not_anchor_matched": 1
},
"limited_reason_category": {
"empty_match": 1,
"unsupported": 1,
"recipe_visibility_gap": 1
},
"llm_decomposition_reason": {
"error:Failed to extract output_text from /responses payload.": 3,
"fallback_rule_applied_after_llm_error": 25,
"(null)": 3,
"not_address_like": 6
}
},
"followup_sessions": {
"chain_a": "asst-FcMkXBWcu2",
"single_33": "asst-gXTpxnmWpG",
"single_31": "asst-rTMQAu9-iv",
"single_2": "asst-SFu_Ft-HM1",
"single_14": "asst-yxnKwYNQ5c",
"single_12": "asst-gaC9QR3ac9",
"single_17": "asst-QjQxuKBZHt",
"single_32": "asst-7GzzMHDiQZ",
"single_19": "asst-hh3GkT9dJF",
"single_13": "asst-UUVkCb5sCS",
"single_11": "asst-x504ZNzRpo",
"chain_c": "asst-gSWtm2LPha",
"single_9": "asst-d7G1unNF_j",
"single_7": "asst-7AC_NeHrTA",
"single_16": "asst-PhFTkR2mWs",
"single_10": "asst-sny3sFB19c",
"single_18": "asst-RY7LBPJr6i",
"single_8": "asst-koxw3u9Zj9",
"single_6": "asst-h6m3_aXtOM",
"single_4": "asst-ZheKxL2311",
"single_34": "asst-HfTDFjeXdM",
"chain_b": "asst-NzEwL_Cksq",
"single_15": "asst-OyooDcGGLh",
"single_5": "asst-8QOPS213rL",
"single_3": "asst-BS6WQx3BLi",
"single_1": "asst-3TFo9p8UGo"
}
}

View File

@ -0,0 +1,13 @@
# 2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54
- Source questions: docs/ADDRESS/1.txt
- Total: 37
- HTTP 200: 34
- factual: 32
- partial_coverage: 2
- other_reply_types: 0
Artifacts:
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,87 @@
[
{
"number": 13,
"question": "Есть ли долг по договору 15/24 на 2020-07-31",
"session_key": "single_13",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_13",
"status_code": 200,
"ok": true,
"elapsed_ms": 880,
"reply_type": "partial_coverage",
"trace_id": "address-SVQXmJgEIg",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "error:Missing choices in /chat/completions payload.",
"fallback_rule_hit": null
},
{
"number": 21,
"question": "а теперь только за май 2020",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 3198,
"reply_type": "partial_coverage",
"trace_id": "address-_25Y4MfSv4",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 35,
"question": "по свк за весь период че есть",
"session_key": "single_35",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_35",
"status_code": 502,
"ok": false,
"elapsed_ms": 17,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
},
{
"number": 36,
"question": "Покажи технические константы конфигурации",
"session_key": "single_36",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_36",
"status_code": 502,
"ok": false,
"elapsed_ms": 18,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
},
{
"number": 37,
"question": "кто президент США",
"session_key": "single_37",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_37",
"status_code": 502,
"ok": false,
"elapsed_ms": 9,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
}
]

View File

@ -0,0 +1,701 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54",
"generated_at": "2026-04-02T05:32:35",
"summary": {
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54",
"generated_at": "2026-04-02T05:32:35",
"source_questions_file": "docs/ADDRESS/1.txt",
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
"llm_provider": "local",
"llm_base_url": "http://127.0.0.1:1234",
"llm_model": "qwen2.5-14b-instruct-1m",
"totals": {
"questions_total": 37,
"ok_200_count": 34,
"factual_count": 32,
"partial_coverage_count": 2,
"other_reply_types_count": 0,
"llm_decomposition_applied_count": 25,
"fallback_rule_hit_count": 25,
"avg_elapsed_ms": 1111.3
},
"distributions": {
"mcp_call_status": {
"matched_non_empty": 32,
"materialized_but_not_anchor_matched": 2,
"(null)": 3
},
"limited_reason_category": {
"empty_match": 2
},
"llm_decomposition_reason": {
"fallback_rule_applied_after_llm_error": 25,
"error:Missing choices in /chat/completions payload.": 3,
"not_address_like": 6,
"(null)": 3
}
},
"followup_sessions": {
"single_1": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_1",
"single_2": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_2",
"single_3": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_3",
"single_4": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_4",
"single_5": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_5",
"single_6": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_6",
"single_7": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_7",
"single_8": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_8",
"single_9": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_9",
"single_10": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_10",
"single_11": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_11",
"single_12": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_12",
"single_13": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_13",
"single_14": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_14",
"single_15": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_15",
"single_16": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_16",
"single_17": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_17",
"single_18": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_18",
"single_19": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_19",
"chain_a": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"chain_b": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"chain_c": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_c",
"single_31": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_31",
"single_32": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_32",
"single_33": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_33",
"single_34": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_34",
"single_35": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_35",
"single_36": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_36",
"single_37": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_37"
}
},
"rows": [
{
"number": 1,
"question": "Покажи документы по СВК за 2020 год",
"session_key": "single_1",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_1",
"status_code": 200,
"ok": true,
"elapsed_ms": 387,
"reply_type": "factual",
"trace_id": "address-Q3yW1EgrQ6",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 2,
"question": "свк доки за 20й",
"session_key": "single_2",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_2",
"status_code": 200,
"ok": true,
"elapsed_ms": 1017,
"reply_type": "factual",
"trace_id": "address-EMpy2aMBjt",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 3,
"question": "что по свк за 2020 выведи все доки плиз",
"session_key": "single_3",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_3",
"status_code": 200,
"ok": true,
"elapsed_ms": 977,
"reply_type": "factual",
"trace_id": "address-9HbHhhwPcD",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 4,
"question": "Какие документы по контрагенту СВК за весь период",
"session_key": "single_4",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_4",
"status_code": 200,
"ok": true,
"elapsed_ms": 1232,
"reply_type": "factual",
"trace_id": "address-I90YlDQ4RD",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 26.\n1. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 0 / 0 | 20000 | аналитика: Группа\n2. 2021-09-29T12:00:03Z | Поступление на расчетный счет 00000000012 от 29.09.2021 12:00:03 | 0 / 0 | 50000 | аналитика: Группа\n3. 2021-08-31T12:00:04Z | Поступление на расчетный счет 00000000011 от 31.08.2021 12:00:04 | 0 / 0 | 120500 | аналитика: Группа\n4. 2021-06-22T12:00:00Z | Поступление на расчетный счет 00000000010 от 22.06.2021 12:00:00 | 0 / 0 | 498630 | аналитика: Группа\n5. 2021-06-09T12:00:05Z | Поступление на расчетный счет 00000000009 от 09.06.2021 12:00:05 | 0 / 0 | 418960 | аналитика: Группа\n6. 2021-04-28T12:00:08Z | Поступление на расчетный счет 00000000008 от 28.04.2021 12:00:08 | 0 / 0 | 564300 | аналитика: Группа\n7. 2021-04-22T12:00:00Z | Поступление на расчетный счет 00000000007 от 22.04.2021 12:00:00 | 0 / 0 | 982420 | аналитика: Группа\n8. 2021-04-13T12:00:11Z | Поступление на расчетный счет 00000000006 от 13.04.2021 12:00:11 | 0 / 0 | 1882400 | аналитика: Группа\n9. 2021-03-25T12:00:02Z | Поступление на расчетный счет 00000000005 от 25.03.2021 12:00:02 | 0 / 0 | 644315 | аналитика: Группа\n10. 2021-03-24T12:00:03Z | Поступление на расчетный счет 00000000004 от 24.03.2021 12:00:03 | 0 / 0 | 1219990 | аналитика: Группа\n11. 2021-03-18T12:00:00Z | Поступление на расчетный счет 00000000003 от 18.03.2021 12:00:00 | 0 / 0 | 1425310 | аналитика: Группа\n12. 2021-03-12T12:00:03Z | Поступление на расчетный счет 00000000002 от 12.03.2021 12:00:03 | 0 / 0 | 214600 | аналитика: Группа\n13. 2021-02-19T12:00:01Z | Поступление на расчетный счет 00000000001 от 19.02.2021 12:00:01 | 0 / 0 | 518600 | аналитика: Группа\n14. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n15. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n16. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа\n17. 2020-11-30T12:00:07Z | Поступление на расчетный счет 00000000041 от 30.11.2020 12:00:07 | 0 / 0 | 38900 | аналитика: Группа\n18. 2020-11-19T12:00:04Z | Поступление на расчетный счет 00000000039 от 19.11.2020 12:00:04 | 0 / 0 | 3320600 | аналитика: Группа\n19. 2020-11-18T12:00:05Z | Поступление на расчетный счет 00000000038 от 18.11.2020 12:00:05 | 0 / 0 | 745300 | аналитика: Группа\n20. 2020-11-18T12:00:04Z | Поступление на расчетный счет 00000000037 от 18.11.2020 12:00:04 | 0 / 0 | 320000 | аналитика: Группа\n21. 2020-11-13T12:00:03Z | Поступление на расчетный счет 00000000036 от 13.11.2020 12:00:03 | 0 / 0 | 313600 | аналитика: Группа\n22. 2020-11-10T15:39:13Z | Поступление на расчетный счет 00000000035 от 10.11.2020 15:39:13 | 0 / 0 | 328300 | аналитика: Группа\n23. 2020-10-26T12:00:00Z | Поступление на расчетный счет 00000000034 от 26.10.2020 12:00:00 | 0 / 0 | 175000 | аналитика: Группа\n24. 2020-08-20T12:00:06Z | Поступление на расчетный счет 00000000032 от 20.08.2020 12:00:06 | 0 / 0 | 3126005 | аналитика: Группа\n25. 2020-07-30T12:00:00Z | Поступление на расчетный счет 00000000029 от 30.07.2020 12:00:00 | 0 / 0 | 20000 | аналитика: Группа\n26. 2020-07-27T12:00:00Z | Поступление на расчетный счет 00000000028 от 27.07.2020 12:00:00 | 0 / 0 | 40860 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_all_time_rewrite"
},
{
"number": 5,
"question": "какие есть доки по свк с 2000 по 2025 год",
"session_key": "single_5",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_5",
"status_code": 200,
"ok": true,
"elapsed_ms": 2058,
"reply_type": "factual",
"trace_id": "address-t8_hKJBGnh",
"assistant_reply": "По окну 2000-01-01..2000-12-31 строк не найдено; показаны ближайшие доступные данные 2020-07-27..2021-11-10.\nСобран список документов по контрагенту (live address lane).\nСтрок отобрано: 26.\n1. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 0 / 0 | 20000 | аналитика: Группа\n2. 2021-09-29T12:00:03Z | Поступление на расчетный счет 00000000012 от 29.09.2021 12:00:03 | 0 / 0 | 50000 | аналитика: Группа\n3. 2021-08-31T12:00:04Z | Поступление на расчетный счет 00000000011 от 31.08.2021 12:00:04 | 0 / 0 | 120500 | аналитика: Группа\n4. 2021-06-22T12:00:00Z | Поступление на расчетный счет 00000000010 от 22.06.2021 12:00:00 | 0 / 0 | 498630 | аналитика: Группа\n5. 2021-06-09T12:00:05Z | Поступление на расчетный счет 00000000009 от 09.06.2021 12:00:05 | 0 / 0 | 418960 | аналитика: Группа\n6. 2021-04-28T12:00:08Z | Поступление на расчетный счет 00000000008 от 28.04.2021 12:00:08 | 0 / 0 | 564300 | аналитика: Группа\n7. 2021-04-22T12:00:00Z | Поступление на расчетный счет 00000000007 от 22.04.2021 12:00:00 | 0 / 0 | 982420 | аналитика: Группа\n8. 2021-04-13T12:00:11Z | Поступление на расчетный счет 00000000006 от 13.04.2021 12:00:11 | 0 / 0 | 1882400 | аналитика: Группа\n9. 2021-03-25T12:00:02Z | Поступление на расчетный счет 00000000005 от 25.03.2021 12:00:02 | 0 / 0 | 644315 | аналитика: Группа\n10. 2021-03-24T12:00:03Z | Поступление на расчетный счет 00000000004 от 24.03.2021 12:00:03 | 0 / 0 | 1219990 | аналитика: Группа\n11. 2021-03-18T12:00:00Z | Поступление на расчетный счет 00000000003 от 18.03.2021 12:00:00 | 0 / 0 | 1425310 | аналитика: Группа\n12. 2021-03-12T12:00:03Z | Поступление на расчетный счет 00000000002 от 12.03.2021 12:00:03 | 0 / 0 | 214600 | аналитика: Группа\n13. 2021-02-19T12:00:01Z | Поступление на расчетный счет 00000000001 от 19.02.2021 12:00:01 | 0 / 0 | 518600 | аналитика: Группа\n14. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n15. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n16. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа\n17. 2020-11-30T12:00:07Z | Поступление на расчетный счет 00000000041 от 30.11.2020 12:00:07 | 0 / 0 | 38900 | аналитика: Группа\n18. 2020-11-19T12:00:04Z | Поступление на расчетный счет 00000000039 от 19.11.2020 12:00:04 | 0 / 0 | 3320600 | аналитика: Группа\n19. 2020-11-18T12:00:05Z | Поступление на расчетный счет 00000000038 от 18.11.2020 12:00:05 | 0 / 0 | 745300 | аналитика: Группа\n20. 2020-11-18T12:00:04Z | Поступление на расчетный счет 00000000037 от 18.11.2020 12:00:04 | 0 / 0 | 320000 | аналитика: Группа\n21. 2020-11-13T12:00:03Z | Поступление на расчетный счет 00000000036 от 13.11.2020 12:00:03 | 0 / 0 | 313600 | аналитика: Группа\n22. 2020-11-10T15:39:13Z | Поступление на расчетный счет 00000000035 от 10.11.2020 15:39:13 | 0 / 0 | 328300 | аналитика: Группа\n23. 2020-10-26T12:00:00Z | Поступление на расчетный счет 00000000034 от 26.10.2020 12:00:00 | 0 / 0 | 175000 | аналитика: Группа\n24. 2020-08-20T12:00:06Z | Поступление на расчетный счет 00000000032 от 20.08.2020 12:00:06 | 0 / 0 | 3126005 | аналитика: Группа\n25. 2020-07-30T12:00:00Z | Поступление на расчетный счет 00000000029 от 30.07.2020 12:00:00 | 0 / 0 | 20000 | аналитика: Группа\n26. 2020-07-27T12:00:00Z | Поступление на расчетный счет 00000000028 от 27.07.2020 12:00:00 | 0 / 0 | 40860 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 6,
"question": "Покажи документы по контрагенту СВК",
"session_key": "single_6",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_6",
"status_code": 200,
"ok": true,
"elapsed_ms": 1059,
"reply_type": "factual",
"trace_id": "address-lWaThloFl5",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 26.\n1. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 0 / 0 | 20000 | аналитика: Группа\n2. 2021-09-29T12:00:03Z | Поступление на расчетный счет 00000000012 от 29.09.2021 12:00:03 | 0 / 0 | 50000 | аналитика: Группа\n3. 2021-08-31T12:00:04Z | Поступление на расчетный счет 00000000011 от 31.08.2021 12:00:04 | 0 / 0 | 120500 | аналитика: Группа\n4. 2021-06-22T12:00:00Z | Поступление на расчетный счет 00000000010 от 22.06.2021 12:00:00 | 0 / 0 | 498630 | аналитика: Группа\n5. 2021-06-09T12:00:05Z | Поступление на расчетный счет 00000000009 от 09.06.2021 12:00:05 | 0 / 0 | 418960 | аналитика: Группа\n6. 2021-04-28T12:00:08Z | Поступление на расчетный счет 00000000008 от 28.04.2021 12:00:08 | 0 / 0 | 564300 | аналитика: Группа\n7. 2021-04-22T12:00:00Z | Поступление на расчетный счет 00000000007 от 22.04.2021 12:00:00 | 0 / 0 | 982420 | аналитика: Группа\n8. 2021-04-13T12:00:11Z | Поступление на расчетный счет 00000000006 от 13.04.2021 12:00:11 | 0 / 0 | 1882400 | аналитика: Группа\n9. 2021-03-25T12:00:02Z | Поступление на расчетный счет 00000000005 от 25.03.2021 12:00:02 | 0 / 0 | 644315 | аналитика: Группа\n10. 2021-03-24T12:00:03Z | Поступление на расчетный счет 00000000004 от 24.03.2021 12:00:03 | 0 / 0 | 1219990 | аналитика: Группа\n11. 2021-03-18T12:00:00Z | Поступление на расчетный счет 00000000003 от 18.03.2021 12:00:00 | 0 / 0 | 1425310 | аналитика: Группа\n12. 2021-03-12T12:00:03Z | Поступление на расчетный счет 00000000002 от 12.03.2021 12:00:03 | 0 / 0 | 214600 | аналитика: Группа\n13. 2021-02-19T12:00:01Z | Поступление на расчетный счет 00000000001 от 19.02.2021 12:00:01 | 0 / 0 | 518600 | аналитика: Группа\n14. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n15. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n16. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа\n17. 2020-11-30T12:00:07Z | Поступление на расчетный счет 00000000041 от 30.11.2020 12:00:07 | 0 / 0 | 38900 | аналитика: Группа\n18. 2020-11-19T12:00:04Z | Поступление на расчетный счет 00000000039 от 19.11.2020 12:00:04 | 0 / 0 | 3320600 | аналитика: Группа\n19. 2020-11-18T12:00:05Z | Поступление на расчетный счет 00000000038 от 18.11.2020 12:00:05 | 0 / 0 | 745300 | аналитика: Группа\n20. 2020-11-18T12:00:04Z | Поступление на расчетный счет 00000000037 от 18.11.2020 12:00:04 | 0 / 0 | 320000 | аналитика: Группа\n21. 2020-11-13T12:00:03Z | Поступление на расчетный счет 00000000036 от 13.11.2020 12:00:03 | 0 / 0 | 313600 | аналитика: Группа\n22. 2020-11-10T15:39:13Z | Поступление на расчетный счет 00000000035 от 10.11.2020 15:39:13 | 0 / 0 | 328300 | аналитика: Группа\n23. 2020-10-26T12:00:00Z | Поступление на расчетный счет 00000000034 от 26.10.2020 12:00:00 | 0 / 0 | 175000 | аналитика: Группа\n24. 2020-08-20T12:00:06Z | Поступление на расчетный счет 00000000032 от 20.08.2020 12:00:06 | 0 / 0 | 3126005 | аналитика: Группа\n25. 2020-07-30T12:00:00Z | Поступление на расчетный счет 00000000029 от 30.07.2020 12:00:00 | 0 / 0 | 20000 | аналитика: Группа\n26. 2020-07-27T12:00:00Z | Поступление на расчетный счет 00000000028 от 27.07.2020 12:00:00 | 0 / 0 | 40860 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_rewrite"
},
{
"number": 7,
"question": "Покажи банковские операции по СВК за 2020",
"session_key": "single_7",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_7",
"status_code": 200,
"ok": true,
"elapsed_ms": 770,
"reply_type": "factual",
"trace_id": "address-KpnBSMulFy",
"assistant_reply": "Собран список банковских операций по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_counterparty_year_rewrite"
},
{
"number": 8,
"question": "Какие платежи по СВК в 2020",
"session_key": "single_8",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_8",
"status_code": 200,
"ok": true,
"elapsed_ms": 1017,
"reply_type": "factual",
"trace_id": "address-NMHp5iEPp2",
"assistant_reply": "Собран список банковских операций по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_counterparty_year_rewrite"
},
{
"number": 9,
"question": "Покажи банковские операции по контрагенту СВК за весь период",
"session_key": "single_9",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_9",
"status_code": 200,
"ok": true,
"elapsed_ms": 1214,
"reply_type": "factual",
"trace_id": "address-EKioLQerVc",
"assistant_reply": "Собран список банковских операций по контрагенту (live address lane).\nСтрок отобрано: 26.\n1. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 0 / 0 | 20000 | аналитика: Группа\n2. 2021-09-29T12:00:03Z | Поступление на расчетный счет 00000000012 от 29.09.2021 12:00:03 | 0 / 0 | 50000 | аналитика: Группа\n3. 2021-08-31T12:00:04Z | Поступление на расчетный счет 00000000011 от 31.08.2021 12:00:04 | 0 / 0 | 120500 | аналитика: Группа\n4. 2021-06-22T12:00:00Z | Поступление на расчетный счет 00000000010 от 22.06.2021 12:00:00 | 0 / 0 | 498630 | аналитика: Группа\n5. 2021-06-09T12:00:05Z | Поступление на расчетный счет 00000000009 от 09.06.2021 12:00:05 | 0 / 0 | 418960 | аналитика: Группа\n6. 2021-04-28T12:00:08Z | Поступление на расчетный счет 00000000008 от 28.04.2021 12:00:08 | 0 / 0 | 564300 | аналитика: Группа\n7. 2021-04-22T12:00:00Z | Поступление на расчетный счет 00000000007 от 22.04.2021 12:00:00 | 0 / 0 | 982420 | аналитика: Группа\n8. 2021-04-13T12:00:11Z | Поступление на расчетный счет 00000000006 от 13.04.2021 12:00:11 | 0 / 0 | 1882400 | аналитика: Группа\n9. 2021-03-25T12:00:02Z | Поступление на расчетный счет 00000000005 от 25.03.2021 12:00:02 | 0 / 0 | 644315 | аналитика: Группа\n10. 2021-03-24T12:00:03Z | Поступление на расчетный счет 00000000004 от 24.03.2021 12:00:03 | 0 / 0 | 1219990 | аналитика: Группа\n11. 2021-03-18T12:00:00Z | Поступление на расчетный счет 00000000003 от 18.03.2021 12:00:00 | 0 / 0 | 1425310 | аналитика: Группа\n12. 2021-03-12T12:00:03Z | Поступление на расчетный счет 00000000002 от 12.03.2021 12:00:03 | 0 / 0 | 214600 | аналитика: Группа\n13. 2021-02-19T12:00:01Z | Поступление на расчетный счет 00000000001 от 19.02.2021 12:00:01 | 0 / 0 | 518600 | аналитика: Группа\n14. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n15. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n16. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа\n17. 2020-11-30T12:00:07Z | Поступление на расчетный счет 00000000041 от 30.11.2020 12:00:07 | 0 / 0 | 38900 | аналитика: Группа\n18. 2020-11-19T12:00:04Z | Поступление на расчетный счет 00000000039 от 19.11.2020 12:00:04 | 0 / 0 | 3320600 | аналитика: Группа\n19. 2020-11-18T12:00:05Z | Поступление на расчетный счет 00000000038 от 18.11.2020 12:00:05 | 0 / 0 | 745300 | аналитика: Группа\n20. 2020-11-18T12:00:04Z | Поступление на расчетный счет 00000000037 от 18.11.2020 12:00:04 | 0 / 0 | 320000 | аналитика: Группа\n21. 2020-11-13T12:00:03Z | Поступление на расчетный счет 00000000036 от 13.11.2020 12:00:03 | 0 / 0 | 313600 | аналитика: Группа\n22. 2020-11-10T15:39:13Z | Поступление на расчетный счет 00000000035 от 10.11.2020 15:39:13 | 0 / 0 | 328300 | аналитика: Группа\n23. 2020-10-26T12:00:00Z | Поступление на расчетный счет 00000000034 от 26.10.2020 12:00:00 | 0 / 0 | 175000 | аналитика: Группа\n24. 2020-08-20T12:00:06Z | Поступление на расчетный счет 00000000032 от 20.08.2020 12:00:06 | 0 / 0 | 3126005 | аналитика: Группа\n25. 2020-07-30T12:00:00Z | Поступление на расчетный счет 00000000029 от 30.07.2020 12:00:00 | 0 / 0 | 20000 | аналитика: Группа\n26. 2020-07-27T12:00:00Z | Поступление на расчетный счет 00000000028 от 27.07.2020 12:00:00 | 0 / 0 | 40860 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_counterparty_all_time_rewrite"
},
{
"number": 10,
"question": "Покажи документы по договору 15/24 за 2020",
"session_key": "single_10",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_10",
"status_code": 200,
"ok": true,
"elapsed_ms": 1983,
"reply_type": "factual",
"trace_id": "address-m__wS_Sd6g",
"assistant_reply": "Период сохранен. Глубина live-выборки автоматически расширена до 1000 строк.\nСобран список документов по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-08-31T15:00:06Z | Поступление товаров и услуг 00000000024 от 31.08.2020 15:00:06 | 19.04 / 76.05 | 233.33\n2. 2020-08-31T15:00:06Z | Поступление товаров и услуг 00000000024 от 31.08.2020 15:00:06 | 44.01 / 76.05 | 1166.67",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_contract_year_rewrite"
},
{
"number": 11,
"question": "Покажи документы по договору 15/24",
"session_key": "single_11",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_11",
"status_code": 200,
"ok": true,
"elapsed_ms": 1085,
"reply_type": "factual",
"trace_id": "address--jKfQ9r6qS",
"assistant_reply": "Документный фильтр в live дал пустой набор; показываю связанные банковские операции по договору.\nСобран список документов по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_contract_rewrite"
},
{
"number": 12,
"question": "Покажи банковские операции по договору 15/24",
"session_key": "single_12",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_12",
"status_code": 200,
"ok": true,
"elapsed_ms": 1043,
"reply_type": "factual",
"trace_id": "address-XoBIxWaGOQ",
"assistant_reply": "Собран список банковских операций по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_contract_rewrite"
},
{
"number": 13,
"question": "Есть ли долг по договору 15/24 на 2020-07-31",
"session_key": "single_13",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_13",
"status_code": 200,
"ok": true,
"elapsed_ms": 880,
"reply_type": "partial_coverage",
"trace_id": "address-SVQXmJgEIg",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "error:Missing choices in /chat/completions payload.",
"fallback_rule_hit": null
},
{
"number": 14,
"question": "Покажи операции по договору 15/24 за весь период",
"session_key": "single_14",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_14",
"status_code": 200,
"ok": true,
"elapsed_ms": 1143,
"reply_type": "factual",
"trace_id": "address-Ldwi-b0WnK",
"assistant_reply": "Собран список банковских операций по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_contract_all_time_rewrite"
},
{
"number": 15,
"question": "Покажи сальдо по счету 60.01 на дату 2020-07-31",
"session_key": "single_15",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_15",
"status_code": 200,
"ok": true,
"elapsed_ms": 822,
"reply_type": "factual",
"trace_id": "address-KzJCvvIucn",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 5.\nСумма по отобранным движениям: 216200.\n1. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 74400\n2. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 57600\n3. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 42400\n4. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 34200",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 16,
"question": "Какой остаток по счету 60 на 2020.05",
"session_key": "single_16",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_16",
"status_code": 200,
"ok": true,
"elapsed_ms": 979,
"reply_type": "factual",
"trace_id": "address-G4L_tB8MWZ",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 17,
"question": "Какой остаток по счету 60 на 2020 май",
"session_key": "single_17",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_17",
"status_code": 200,
"ok": true,
"elapsed_ms": 1021,
"reply_type": "factual",
"trace_id": "address-j3gDuatATy",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 18,
"question": "Какие документы формируют остаток по счету 60.01 на 2020-07-31",
"session_key": "single_18",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_18",
"status_code": 200,
"ok": true,
"elapsed_ms": 1003,
"reply_type": "factual",
"trace_id": "address-I3PufgNbgw",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 5.\nСумма по отобранным движениям: 216200.\n1. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 74400\n2. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 57600\n3. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 42400\n4. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 34200",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 19,
"question": "Какой остаток по счету 62 на сегодня",
"session_key": "single_19",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_19",
"status_code": 200,
"ok": true,
"elapsed_ms": 1122,
"reply_type": "factual",
"trace_id": "address-0h1oi8K5hC",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 200.\nСумма по отобранным движениям: 63309907.220000006.\n1. 2022-01-20T12:00:02Z | Списание с расчетного счета 00000000004 от 20.01.2022 12:00:02 | 62.02 / 51 | 1808325\n2. 2022-01-20T12:00:02Z | Списание с расчетного счета 00000000004 от 20.01.2022 12:00:02 | 62.02 / 51 | 216600\n3. 2022-01-20T12:00:02Z | Списание с расчетного счета 00000000004 от 20.01.2022 12:00:02 | 62.02 / 51 | 104726\n4. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 51 / 62.02 | 20000",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_account_rewrite"
},
{
"number": 20,
"question": "Покажи документы по СВК за 2020",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 966,
"reply_type": "factual",
"trace_id": "address-oWsaKVOYX7",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 21,
"question": "а теперь только за май 2020",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 3198,
"reply_type": "partial_coverage",
"trace_id": "address-_25Y4MfSv4",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 22,
"question": "а за все время?",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 1136,
"reply_type": "factual",
"trace_id": "address-Bl9Yd0ActH",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 26.\n1. 2021-11-10T12:00:07Z | Поступление на расчетный счет 00000000013 от 10.11.2021 12:00:07 | 0 / 0 | 20000 | аналитика: Группа\n2. 2021-09-29T12:00:03Z | Поступление на расчетный счет 00000000012 от 29.09.2021 12:00:03 | 0 / 0 | 50000 | аналитика: Группа\n3. 2021-08-31T12:00:04Z | Поступление на расчетный счет 00000000011 от 31.08.2021 12:00:04 | 0 / 0 | 120500 | аналитика: Группа\n4. 2021-06-22T12:00:00Z | Поступление на расчетный счет 00000000010 от 22.06.2021 12:00:00 | 0 / 0 | 498630 | аналитика: Группа\n5. 2021-06-09T12:00:05Z | Поступление на расчетный счет 00000000009 от 09.06.2021 12:00:05 | 0 / 0 | 418960 | аналитика: Группа\n6. 2021-04-28T12:00:08Z | Поступление на расчетный счет 00000000008 от 28.04.2021 12:00:08 | 0 / 0 | 564300 | аналитика: Группа\n7. 2021-04-22T12:00:00Z | Поступление на расчетный счет 00000000007 от 22.04.2021 12:00:00 | 0 / 0 | 982420 | аналитика: Группа\n8. 2021-04-13T12:00:11Z | Поступление на расчетный счет 00000000006 от 13.04.2021 12:00:11 | 0 / 0 | 1882400 | аналитика: Группа\n9. 2021-03-25T12:00:02Z | Поступление на расчетный счет 00000000005 от 25.03.2021 12:00:02 | 0 / 0 | 644315 | аналитика: Группа\n10. 2021-03-24T12:00:03Z | Поступление на расчетный счет 00000000004 от 24.03.2021 12:00:03 | 0 / 0 | 1219990 | аналитика: Группа\n11. 2021-03-18T12:00:00Z | Поступление на расчетный счет 00000000003 от 18.03.2021 12:00:00 | 0 / 0 | 1425310 | аналитика: Группа\n12. 2021-03-12T12:00:03Z | Поступление на расчетный счет 00000000002 от 12.03.2021 12:00:03 | 0 / 0 | 214600 | аналитика: Группа\n13. 2021-02-19T12:00:01Z | Поступление на расчетный счет 00000000001 от 19.02.2021 12:00:01 | 0 / 0 | 518600 | аналитика: Группа\n14. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n15. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n16. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа\n17. 2020-11-30T12:00:07Z | Поступление на расчетный счет 00000000041 от 30.11.2020 12:00:07 | 0 / 0 | 38900 | аналитика: Группа\n18. 2020-11-19T12:00:04Z | Поступление на расчетный счет 00000000039 от 19.11.2020 12:00:04 | 0 / 0 | 3320600 | аналитика: Группа\n19. 2020-11-18T12:00:05Z | Поступление на расчетный счет 00000000038 от 18.11.2020 12:00:05 | 0 / 0 | 745300 | аналитика: Группа\n20. 2020-11-18T12:00:04Z | Поступление на расчетный счет 00000000037 от 18.11.2020 12:00:04 | 0 / 0 | 320000 | аналитика: Группа\n21. 2020-11-13T12:00:03Z | Поступление на расчетный счет 00000000036 от 13.11.2020 12:00:03 | 0 / 0 | 313600 | аналитика: Группа\n22. 2020-11-10T15:39:13Z | Поступление на расчетный счет 00000000035 от 10.11.2020 15:39:13 | 0 / 0 | 328300 | аналитика: Группа\n23. 2020-10-26T12:00:00Z | Поступление на расчетный счет 00000000034 от 26.10.2020 12:00:00 | 0 / 0 | 175000 | аналитика: Группа\n24. 2020-08-20T12:00:06Z | Поступление на расчетный счет 00000000032 от 20.08.2020 12:00:06 | 0 / 0 | 3126005 | аналитика: Группа\n25. 2020-07-30T12:00:00Z | Поступление на расчетный счет 00000000029 от 30.07.2020 12:00:00 | 0 / 0 | 20000 | аналитика: Группа\n26. 2020-07-27T12:00:00Z | Поступление на расчетный счет 00000000028 от 27.07.2020 12:00:00 | 0 / 0 | 40860 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 23,
"question": "а по счету 60.01 на ту же дату",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 792,
"reply_type": "factual",
"trace_id": "address-LRHV-3b7dD",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 200.\nСумма по отобранным движениям: 31878451.5.\n1. 2022-04-18T12:00:00Z | Поступление товаров и услуг 00000000007 от 18.04.2022 12:00:00 | 97.21 / 60.01 | 14790\n2. 2022-04-18T12:00:00Z | Поступление товаров и услуг 00000000007 от 18.04.2022 12:00:00 | 60.01 / 60.02 | 14790\n3. 2022-01-20T12:00:01Z | Списание с расчетного счета 00000000003 от 20.01.2022 12:00:01 | 60.01 / 51 | 1705109.5\n4. 2021-05-17T12:00:00Z | Поступление товаров и услуг 00000000009 от 17.05.2021 12:00:00 | 19.04 / 60.01 | 12000",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "error:Missing choices in /chat/completions payload.",
"fallback_rule_hit": null
},
{
"number": 24,
"question": "Покажи банковские операции по договору 15/24",
"session_key": "chain_b",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"status_code": 200,
"ok": true,
"elapsed_ms": 1169,
"reply_type": "factual",
"trace_id": "address-Y3SYGpF0MO",
"assistant_reply": "Собран список банковских операций по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_contract_rewrite"
},
{
"number": 25,
"question": "а за 2020 год",
"session_key": "chain_b",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"status_code": 200,
"ok": true,
"elapsed_ms": 1961,
"reply_type": "factual",
"trace_id": "address-SrM9fPt54E",
"assistant_reply": "Период сохранен. Глубина live-выборки автоматически расширена до 1000 строк.\nСобран список банковских операций по договору (live address lane).\nСтрок отобрано: 3.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53\n3. 2020-08-31T15:00:04Z | Списание с расчетного счета 00000000224 от 31.08.2020 15:00:04 | 91.02 / 51 | 106.47",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 26,
"question": "а теперь только за май 2020",
"session_key": "chain_b",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"status_code": 200,
"ok": true,
"elapsed_ms": 3170,
"reply_type": "factual",
"trace_id": "address-2Jt5sJcLYG",
"assistant_reply": "По окну 2020-05-01..2020-05-31 строк не найдено; показаны ближайшие доступные данные 2020-10-15..2020-10-15.\nСобран список банковских операций по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 27,
"question": "а по счету 51 на ту же дату",
"session_key": "chain_b",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"status_code": 200,
"ok": true,
"elapsed_ms": 753,
"reply_type": "factual",
"trace_id": "address--CeAQrMd0e",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 24.\nСумма по отобранным движениям: 2234531.1100000003.\n1. 2020-05-29T12:00:02Z | Списание с расчетного счета 00000000151 от 29.05.2020 12:00:02 | 91.02 / 51 | 60\n2. 2020-05-28T20:17:50Z | Списание с расчетного счета 00000000150 от 28.05.2020 20:17:50 | 70 / 51 | 50\n3. 2020-05-28T20:17:24Z | Списание с расчетного счета 00000000149 от 28.05.2020 20:17:24 | 91.02 / 51 | 35\n4. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "error:Missing choices in /chat/completions payload.",
"fallback_rule_hit": null
},
{
"number": 28,
"question": "Какой остаток по счету 60 на 2020.05",
"session_key": "chain_c",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_c",
"status_code": 200,
"ok": true,
"elapsed_ms": 1038,
"reply_type": "factual",
"trace_id": "address-FptBoUpCJw",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 29,
"question": "а теперь по 60.01",
"session_key": "chain_c",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_c",
"status_code": 200,
"ok": true,
"elapsed_ms": 1020,
"reply_type": "factual",
"trace_id": "address-DyR5yhasU4",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 30,
"question": "а на ту же дату по 62",
"session_key": "chain_c",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_c",
"status_code": 200,
"ok": true,
"elapsed_ms": 1050,
"reply_type": "factual",
"trace_id": "address-DMeRFm3EcQ",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null
},
{
"number": 31,
"question": "бля епт покажи доки по свк за 20й",
"session_key": "single_31",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_31",
"status_code": 200,
"ok": true,
"elapsed_ms": 978,
"reply_type": "factual",
"trace_id": "address-spVPQ8fXNr",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 32,
"question": "свк 20 год - покажи доки плс",
"session_key": "single_32",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_32",
"status_code": 200,
"ok": true,
"elapsed_ms": 1010,
"reply_type": "factual",
"trace_id": "address-KuIoSi8XtB",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "documents_counterparty_year_rewrite"
},
{
"number": 33,
"question": "покажи банк опер по дог 15/24 пж",
"session_key": "single_33",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_33",
"status_code": 200,
"ok": true,
"elapsed_ms": 1236,
"reply_type": "factual",
"trace_id": "address-jyKrhbkWt6",
"assistant_reply": "Собран список банковских операций по договору (live address lane).\nСтрок отобрано: 2.\n1. 2020-10-15T13:34:53Z | Списание с расчетного счета 00000000246 от 15.10.2020 13:34:53 | 66.02 / 51 | 30819.47\n2. 2020-10-15T13:34:19Z | Списание с расчетного счета 00000000245 от 15.10.2020 13:34:19 | 66.01 / 51 | 134206.53",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "bank_operations_contract_rewrite"
},
{
"number": 34,
"question": "остаток 60 на 2020 май покеж",
"session_key": "single_34",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_34",
"status_code": 200,
"ok": true,
"elapsed_ms": 785,
"reply_type": "factual",
"trace_id": "address-L_uvP4v4kr",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "fallback_rule_applied_after_llm_error",
"fallback_rule_hit": "balance_month_period_rewrite"
},
{
"number": 35,
"question": "по свк за весь период че есть",
"session_key": "single_35",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_35",
"status_code": 502,
"ok": false,
"elapsed_ms": 17,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
},
{
"number": 36,
"question": "Покажи технические константы конфигурации",
"session_key": "single_36",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_36",
"status_code": 502,
"ok": false,
"elapsed_ms": 18,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
},
{
"number": 37,
"question": "кто президент США",
"session_key": "single_37",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_37",
"status_code": 502,
"ok": false,
"elapsed_ms": 9,
"reply_type": "",
"trace_id": "",
"assistant_reply": "",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null
}
]
}

View File

@ -0,0 +1,66 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54",
"generated_at": "2026-04-02T05:32:35",
"source_questions_file": "docs/ADDRESS/1.txt",
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
"llm_provider": "local",
"llm_base_url": "http://127.0.0.1:1234",
"llm_model": "qwen2.5-14b-instruct-1m",
"totals": {
"questions_total": 37,
"ok_200_count": 34,
"factual_count": 32,
"partial_coverage_count": 2,
"other_reply_types_count": 0,
"llm_decomposition_applied_count": 25,
"fallback_rule_hit_count": 25,
"avg_elapsed_ms": 1111.3
},
"distributions": {
"mcp_call_status": {
"matched_non_empty": 32,
"materialized_but_not_anchor_matched": 2,
"(null)": 3
},
"limited_reason_category": {
"empty_match": 2
},
"llm_decomposition_reason": {
"fallback_rule_applied_after_llm_error": 25,
"error:Missing choices in /chat/completions payload.": 3,
"not_address_like": 6,
"(null)": 3
}
},
"followup_sessions": {
"single_1": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_1",
"single_2": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_2",
"single_3": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_3",
"single_4": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_4",
"single_5": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_5",
"single_6": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_6",
"single_7": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_7",
"single_8": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_8",
"single_9": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_9",
"single_10": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_10",
"single_11": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_11",
"single_12": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_12",
"single_13": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_13",
"single_14": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_14",
"single_15": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_15",
"single_16": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_16",
"single_17": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_17",
"single_18": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_18",
"single_19": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_19",
"chain_a": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_a",
"chain_b": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_b",
"chain_c": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-chain_c",
"single_31": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_31",
"single_32": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_32",
"single_33": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_33",
"single_34": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_34",
"single_35": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_35",
"single_36": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_36",
"single_37": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_08-31-54-single_37"
}
}

View File

@ -0,0 +1,19 @@
# 2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32
Generated at: 2026-04-02T06:18:23
Questions file: docs/ADDRESS/1.txt
Backend URL: http://127.0.0.1:8787/api/assistant/message
LLM: local / qwen2.5-14b-instruct-1m @ http://127.0.0.1:1234
## Totals
- questions_total: 63
- ok_200_count: 63
- factual_count: 38
- partial_coverage_count: 18
- clarification_required_count: 7
- http_error_count: 0
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,481 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32",
"generated_at": "2026-04-02T06:18:23",
"failures": [
{
"number": 1,
"question": "Цепочки `FOLLOW-UP` прогоняй в одной сессии подряд.",
"session_key": "single_1",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_1",
"status_code": 200,
"ok": true,
"elapsed_ms": 11103,
"reply_type": "clarification_required",
"trace_id": "JiVKx5ohmlt6t4",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- Часть контекстных токенов не подтверждена напрямую: chain.\n- required anchors claim-bound grounding.\n- evidence.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 2,
"question": "Блоки `SINGLE` можно гонять по отдельности.",
"session_key": "single_2",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_2",
"status_code": 200,
"ok": true,
"elapsed_ms": 8851,
"reply_type": "clarification_required",
"trace_id": "C06HaZtg0-69mc",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 2,
"question": "свк доки за 20й",
"session_key": "single_2",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_2",
"status_code": 200,
"ok": true,
"elapsed_ms": 7735,
"reply_type": "partial_coverage",
"trace_id": "address-0BIB9ZIQQd",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 3,
"question": "Для проверок смотри не только ответ, но и `technical_debug_payload_json`.",
"session_key": "single_3",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_3",
"status_code": 200,
"ok": true,
"elapsed_ms": 9070,
"reply_type": "clarification_required",
"trace_id": "fMCKjmaMDLD3hf",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 7,
"question": "Покажи банковские операции по СВК за 2020",
"session_key": "single_7",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_7",
"status_code": 200,
"ok": true,
"elapsed_ms": 9179,
"reply_type": "partial_coverage",
"trace_id": "address-qOaA9vho_m",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 13,
"question": "Есть ли долг по договору 15/24 на 2020-07-31",
"session_key": "single_13",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_13",
"status_code": 200,
"ok": true,
"elapsed_ms": 6887,
"reply_type": "partial_coverage",
"trace_id": "address-MXgSTOzyOr",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 21,
"question": "а теперь только за май 2020",
"session_key": "chain_a",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_a",
"status_code": 200,
"ok": true,
"elapsed_ms": 3234,
"reply_type": "partial_coverage",
"trace_id": "address-VOI3jtsFc4",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 26,
"question": "а теперь только за май 2020",
"session_key": "chain_b",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_b",
"status_code": 200,
"ok": true,
"elapsed_ms": 3046,
"reply_type": "partial_coverage",
"trace_id": "address-t8Qi4zg85b",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 35,
"question": "по свк за весь период че есть",
"session_key": "single_35",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_35",
"status_code": 200,
"ok": true,
"elapsed_ms": 9012,
"reply_type": "clarification_required",
"trace_id": "v64a_4F0yDXwY4",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 36,
"question": "Покажи технические константы конфигурации",
"session_key": "single_36",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_36",
"status_code": 200,
"ok": true,
"elapsed_ms": 9691,
"reply_type": "clarification_required",
"trace_id": "M6vpWJZjHcihLB",
"assistant_reply": "Коротко: Проблема подтверждается частично; для уверенного вывода нужны уточнения. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 37,
"question": "кто президент США",
"session_key": "single_37",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_37",
"status_code": 200,
"ok": true,
"elapsed_ms": 7959,
"reply_type": "clarification_required",
"trace_id": "4hphPBX8hIAOqY",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 38,
"question": "Кто нам должен на 2020-12-31",
"session_key": "single_38",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_38",
"status_code": 200,
"ok": true,
"elapsed_ms": 11,
"reply_type": "partial_coverage",
"trace_id": "address-vGg7KvBPLM",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 42,
"question": "Покажи незакрытые договоры на 2020-12-31",
"session_key": "single_42",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_42",
"status_code": 200,
"ok": true,
"elapsed_ms": 5713,
"reply_type": "partial_coverage",
"trace_id": "address-oaX8wsSDr3",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: для open_items нужен якорь контрагента или договора.\nЧто нужно уточнить: укажите контрагента или номер/название договора.",
"mcp_call_status": "skipped",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 43,
"question": "Какие открытые договоры есть на 2020-12-31",
"session_key": "single_43",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_43",
"status_code": 200,
"ok": true,
"elapsed_ms": 4924,
"reply_type": "partial_coverage",
"trace_id": "address-CmLjE_XX34",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: для open_items нужен якорь контрагента или договора.\nЧто нужно уточнить: укажите контрагента или номер/название договора.",
"mcp_call_status": "skipped",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 44,
"question": "Покажи хвосты по контрагенту СВК на 2020-12-31",
"session_key": "single_44",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_44",
"status_code": 200,
"ok": true,
"elapsed_ms": 6656,
"reply_type": "partial_coverage",
"trace_id": "address-igBh_WmLUU",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 45,
"question": "Есть ли незакрытые позиции по договору 15/24 на 2020-12-31",
"session_key": "single_45",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_45",
"status_code": 200,
"ok": true,
"elapsed_ms": 6051,
"reply_type": "partial_coverage",
"trace_id": "address-6JB8rJvQcp",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 46,
"question": "Покажи открытые позиции по договору 15/24",
"session_key": "single_46",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_46",
"status_code": 200,
"ok": true,
"elapsed_ms": 5161,
"reply_type": "partial_coverage",
"trace_id": "address-AuGYnsHDC1",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 49,
"question": "а теперь банковские операции",
"session_key": "chain_d",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_d",
"status_code": 200,
"ok": true,
"elapsed_ms": 8365,
"reply_type": "partial_coverage",
"trace_id": "address-RMFmLLemZ_",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "normalized_fragment_same",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 50,
"question": "а за весь период",
"session_key": "chain_d",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_d",
"status_code": 200,
"ok": true,
"elapsed_ms": 2051,
"reply_type": "partial_coverage",
"trace_id": "address-vE8KVirQgi",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 52,
"question": "Покажи незакрытые позиции по контрагенту СВК",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 5942,
"reply_type": "partial_coverage",
"trace_id": "address-Fba2s8OLbT",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 53,
"question": "а на 2020-12-31",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 1053,
"reply_type": "partial_coverage",
"trace_id": "address-NlUK6ZbvyS",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 54,
"question": "а теперь по договору 15/24",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 7295,
"reply_type": "partial_coverage",
"trace_id": "address-Y4iOZPwOh7",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 55,
"question": "а только банковские операции",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 8213,
"reply_type": "partial_coverage",
"trace_id": "address-LtqK2g17SL",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 56,
"question": "а за май 2020",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 2957,
"reply_type": "partial_coverage",
"trace_id": "address-R6p14wCn-Z",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 60,
"question": "kto nam dolzhen na 2020-12-31",
"session_key": "single_60",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_60",
"status_code": 200,
"ok": true,
"elapsed_ms": 10891,
"reply_type": "clarification_required",
"trace_id": "IKFefEoo-lpju-",
"assistant_reply": "Коротко: Проблема подтверждается частично; для уверенного вывода нужны уточнения. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде. Ограничения:\n- Якоря из вопроса без прямого подтверждения: 2020-12, period:2020-12.\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]
}

View File

@ -0,0 +1,87 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32",
"generated_at": "2026-04-02T06:18:23",
"source_questions_file": "docs/ADDRESS/1.txt",
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
"llm_provider": "local",
"llm_base_url": "http://127.0.0.1:1234",
"llm_model": "qwen2.5-14b-instruct-1m",
"totals": {
"questions_total": 63,
"ok_200_count": 63,
"factual_count": 38,
"partial_coverage_count": 18,
"clarification_required_count": 7,
"other_reply_types_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 41,
"fallback_rule_hit_count": 0,
"avg_elapsed_ms": 5571.7
},
"distributions": {
"mcp_call_status": {
"matched_non_empty": 38,
"materialized_but_not_anchor_matched": 15,
"(null)": 7,
"skipped": 3
},
"limited_reason_category": {
"empty_match": 15,
"missing_anchor": 2,
"unsupported": 1
},
"llm_decomposition_reason": {
"normalized_fragment_applied": 41,
"not_address_like": 14,
"(null)": 7,
"normalized_fragment_same": 1
},
"error_code": {}
},
"followup_sessions": {
"single_1": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_1",
"single_2": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_2",
"single_3": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_3",
"single_4": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_4",
"single_5": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_5",
"single_6": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_6",
"single_7": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_7",
"single_8": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_8",
"single_9": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_9",
"single_10": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_10",
"single_11": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_11",
"single_12": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_12",
"single_13": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_13",
"single_14": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_14",
"single_15": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_15",
"single_16": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_16",
"single_17": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_17",
"single_18": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_18",
"single_19": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_19",
"chain_a": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_a",
"chain_b": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_b",
"chain_c": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_c",
"single_31": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_31",
"single_32": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_32",
"single_33": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_33",
"single_34": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_34",
"single_35": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_35",
"single_36": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_36",
"single_37": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_37",
"single_38": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_38",
"single_39": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_39",
"single_40": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_40",
"single_41": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_41",
"single_42": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_42",
"single_43": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_43",
"single_44": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_44",
"single_45": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_45",
"single_46": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_46",
"chain_d": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_d",
"chain_e": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-chain_e",
"single_57": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_57",
"single_58": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_58",
"single_59": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_59",
"single_60": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-12-32-single_60"
}
}

View File

@ -0,0 +1,19 @@
# 2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup
Generated at: 2026-04-02T06:24:42
Questions file: docs/ADDRESS/1.txt
Backend URL: http://127.0.0.1:8787/api/assistant/message
LLM: local / qwen2.5-14b-instruct-1m @ http://127.0.0.1:1234
## Totals
- questions_total: 60
- ok_200_count: 60
- factual_count: 39
- partial_coverage_count: 17
- clarification_required_count: 4
- http_error_count: 0
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,405 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup",
"generated_at": "2026-04-02T06:24:42",
"failures": [
{
"number": 2,
"question": "свк доки за 20й",
"session_key": "single_2",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_2",
"status_code": 200,
"ok": true,
"elapsed_ms": 8345,
"reply_type": "partial_coverage",
"trace_id": "address-go0Zscjzbe",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 7,
"question": "Покажи банковские операции по СВК за 2020",
"session_key": "single_7",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_7",
"status_code": 200,
"ok": true,
"elapsed_ms": 8136,
"reply_type": "partial_coverage",
"trace_id": "address-DPfd0Xhggd",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 9,
"question": "Покажи банковские операции по контрагенту СВК за весь период",
"session_key": "single_9",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_9",
"status_code": 200,
"ok": true,
"elapsed_ms": 6209,
"reply_type": "partial_coverage",
"trace_id": "address-kBQzfbmPMA",
"assistant_reply": "Не удалось выполнить адресный live-запрос в V1.\nПричина: live MCP вызов завершился ошибкой.\nЧто нужно уточнить: MCP fetch failed: This operation was aborted.",
"mcp_call_status": "error",
"limited_reason_category": "execution_error",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 13,
"question": "Есть ли долг по договору 15/24 на 2020-07-31",
"session_key": "single_13",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_13",
"status_code": 200,
"ok": true,
"elapsed_ms": 6909,
"reply_type": "partial_coverage",
"trace_id": "address-j8nun4978Q",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 35,
"question": "по свк за весь период че есть",
"session_key": "single_35",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_35",
"status_code": 200,
"ok": true,
"elapsed_ms": 10358,
"reply_type": "clarification_required",
"trace_id": "-R4PnGpemze3u9",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 36,
"question": "Покажи технические константы конфигурации",
"session_key": "single_36",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_36",
"status_code": 200,
"ok": true,
"elapsed_ms": 9752,
"reply_type": "clarification_required",
"trace_id": "4ynYX0aRtOVrJh",
"assistant_reply": "Коротко: Проблема подтверждается частично; для уверенного вывода нужны уточнения. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 37,
"question": "кто президент США",
"session_key": "single_37",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_37",
"status_code": 200,
"ok": true,
"elapsed_ms": 8017,
"reply_type": "clarification_required",
"trace_id": "6kdfrhpnTV-9et",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Уточните период проверки, чтобы подтвердить проблему без лишнего шума.\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде.\n- Уточните период проверки (например, июль 2020). Ограничения:\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 38,
"question": "Кто нам должен на 2020-12-31",
"session_key": "single_38",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_38",
"status_code": 200,
"ok": true,
"elapsed_ms": 11,
"reply_type": "partial_coverage",
"trace_id": "address-wRcdOYEkks",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 42,
"question": "Покажи незакрытые договоры на 2020-12-31",
"session_key": "single_42",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_42",
"status_code": 200,
"ok": true,
"elapsed_ms": 5873,
"reply_type": "partial_coverage",
"trace_id": "address-g6G7BE6ItI",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: для open_items нужен якорь контрагента или договора.\nЧто нужно уточнить: укажите контрагента или номер/название договора.",
"mcp_call_status": "skipped",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 43,
"question": "Какие открытые договоры есть на 2020-12-31",
"session_key": "single_43",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_43",
"status_code": 200,
"ok": true,
"elapsed_ms": 5013,
"reply_type": "partial_coverage",
"trace_id": "address-_pn_73-bkB",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: для open_items нужен якорь контрагента или договора.\nЧто нужно уточнить: укажите контрагента или номер/название договора.",
"mcp_call_status": "skipped",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 44,
"question": "Покажи хвосты по контрагенту СВК на 2020-12-31",
"session_key": "single_44",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_44",
"status_code": 200,
"ok": true,
"elapsed_ms": 7394,
"reply_type": "partial_coverage",
"trace_id": "address-WQ7p8Vto1p",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 45,
"question": "Есть ли незакрытые позиции по договору 15/24 на 2020-12-31",
"session_key": "single_45",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_45",
"status_code": 200,
"ok": true,
"elapsed_ms": 6120,
"reply_type": "partial_coverage",
"trace_id": "address-RX99SRm2dk",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 46,
"question": "Покажи открытые позиции по договору 15/24",
"session_key": "single_46",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_46",
"status_code": 200,
"ok": true,
"elapsed_ms": 6078,
"reply_type": "partial_coverage",
"trace_id": "address-8v-VptxVtr",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 49,
"question": "а теперь банковские операции",
"session_key": "chain_d",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_d",
"status_code": 200,
"ok": true,
"elapsed_ms": 8303,
"reply_type": "partial_coverage",
"trace_id": "address--f3lxuGwWL",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "normalized_fragment_same",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 50,
"question": "а за весь период",
"session_key": "chain_d",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_d",
"status_code": 200,
"ok": true,
"elapsed_ms": 2171,
"reply_type": "partial_coverage",
"trace_id": "address-jQrlGu5_pL",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 52,
"question": "Покажи незакрытые позиции по контрагенту СВК",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 6035,
"reply_type": "partial_coverage",
"trace_id": "address-2n6cAvvLns",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 53,
"question": "а на 2020-12-31",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 1053,
"reply_type": "partial_coverage",
"trace_id": "address-jZyu9voM25",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 54,
"question": "а теперь по договору 15/24",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 7360,
"reply_type": "partial_coverage",
"trace_id": "address-uOrM8pdJSu",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 55,
"question": "а только банковские операции",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 8148,
"reply_type": "partial_coverage",
"trace_id": "address-lCZsPDCeln",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 56,
"question": "а за май 2020",
"session_key": "chain_e",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"status_code": 200,
"ok": true,
"elapsed_ms": 2925,
"reply_type": "partial_coverage",
"trace_id": "address-SdipomZHF-",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "not_address_like",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"number": 60,
"question": "kto nam dolzhen na 2020-12-31",
"session_key": "single_60",
"session_id": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_60",
"status_code": 200,
"ok": true,
"elapsed_ms": 11119,
"reply_type": "clarification_required",
"trace_id": "YaplyRBkaIxbtZ",
"assistant_reply": "Коротко: Проблема подтверждается частично; для уверенного вывода нужны уточнения. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде. Ограничения:\n- Якоря из вопроса без прямого подтверждения: 2020-12, period:2020-12.\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]
}

View File

@ -0,0 +1,89 @@
{
"run_id": "2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup",
"generated_at": "2026-04-02T06:24:42",
"source_questions_file": "docs/ADDRESS/1.txt",
"backend_url": "http://127.0.0.1:8787/api/assistant/message",
"llm_provider": "local",
"llm_base_url": "http://127.0.0.1:1234",
"llm_model": "qwen2.5-14b-instruct-1m",
"totals": {
"questions_total": 60,
"ok_200_count": 60,
"factual_count": 39,
"partial_coverage_count": 17,
"clarification_required_count": 4,
"other_reply_types_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 41,
"fallback_rule_hit_count": 0,
"avg_elapsed_ms": 5429.8
},
"distributions": {
"mcp_call_status": {
"matched_non_empty": 39,
"materialized_but_not_anchor_matched": 13,
"(null)": 4,
"skipped": 3,
"error": 1
},
"limited_reason_category": {
"empty_match": 13,
"missing_anchor": 2,
"execution_error": 1,
"unsupported": 1
},
"llm_decomposition_reason": {
"normalized_fragment_applied": 41,
"not_address_like": 14,
"(null)": 4,
"normalized_fragment_same": 1
},
"error_code": {}
},
"followup_sessions": {
"single_1": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_1",
"single_2": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_2",
"single_3": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_3",
"single_4": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_4",
"single_5": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_5",
"single_6": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_6",
"single_7": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_7",
"single_8": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_8",
"single_9": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_9",
"single_10": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_10",
"single_11": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_11",
"single_12": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_12",
"single_13": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_13",
"single_14": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_14",
"single_15": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_15",
"single_16": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_16",
"single_17": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_17",
"single_18": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_18",
"single_19": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_19",
"chain_a": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_a",
"chain_b": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_b",
"chain_c": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_c",
"single_31": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_31",
"single_32": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_32",
"single_33": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_33",
"single_34": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_34",
"single_35": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_35",
"single_36": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_36",
"single_37": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_37",
"single_38": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_38",
"single_39": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_39",
"single_40": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_40",
"single_41": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_41",
"single_42": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_42",
"single_43": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_43",
"single_44": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_44",
"single_45": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_45",
"single_46": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_46",
"chain_d": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_d",
"chain_e": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-chain_e",
"single_57": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_57",
"single_58": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_58",
"single_59": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_59",
"single_60": "asst-2026-04-02_Address_Full_Live_Run_2026-04-02_09-19-16_dedup-single_60"
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14
Generated at: 2026-04-02T09:43:17
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_2026-04-02.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
## Totals
- questions_total: 60
- ok_200_count: 60
- semantic_pass_count: 48
- semantic_pass_rate: 0.8
- factual_count: 43
- partial_coverage_count: 17
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 54
- avg_elapsed_ms: 6047.8
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,326 @@
[
{
"index": 4,
"id": "S004",
"question": "какие у свк есть доки за 2020?",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s004",
"status_code": 200,
"ok": true,
"elapsed_ms": 8377,
"reply_type": "partial_coverage",
"trace_id": "address-e49ajdTku0",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: якорь контрагента/договора не найден в материализованных live-строках.\nЧто нужно уточнить: уточните контрагента точным именем или добавьте ИНН/договор.",
"expected_intent": "list_documents_by_counterparty",
"actual_intent": "bank_operations_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 17,
"id": "S017",
"question": "свк банк опер за 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s017",
"status_code": 200,
"ok": true,
"elapsed_ms": 5404,
"reply_type": "partial_coverage",
"trace_id": "address-8Et-1Ef9z7",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 18,
"id": "S018",
"question": "че у свк по банку за 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s018",
"status_code": 200,
"ok": true,
"elapsed_ms": 5484,
"reply_type": "partial_coverage",
"trace_id": "address-YwNwxMgUrG",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 19,
"id": "S019",
"question": "свк списания/поступления за 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s019",
"status_code": 200,
"ok": true,
"elapsed_ms": 6183,
"reply_type": "partial_coverage",
"trace_id": "address-71c-6_L1b0",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 21,
"id": "S021",
"question": "transactions by counterparty svk 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s021",
"status_code": 200,
"ok": true,
"elapsed_ms": 6113,
"reply_type": "factual",
"trace_id": "address-CmnZkVm1CK",
"assistant_reply": "Собран список документов по контрагенту (live address lane).\nСтрок отобрано: 3.\n1. 2020-12-30T12:00:00Z | Поступление на расчетный счет 00000000044 от 30.12.2020 12:00:00 | 0 / 0 | 3248300 | аналитика: Группа\n2. 2020-12-16T16:20:53Z | Поступление на расчетный счет 00000000043 от 16.12.2020 16:20:53 | 0 / 0 | 216600 | аналитика: Группа\n3. 2020-12-14T12:00:00Z | Поступление на расчетный счет 00000000042 от 14.12.2020 12:00:00 | 0 / 0 | 200000 | аналитика: Группа",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 36,
"id": "S036",
"question": "из чего состоит остаток по счету 60 на 2020.05",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s036",
"status_code": 200,
"ok": true,
"elapsed_ms": 6107,
"reply_type": "factual",
"trace_id": "address-tCa1CbcqSD",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 6.\nСумма по отобранным движениям: 849499.\n1. 2020-05-22T10:14:43Z | Списание с расчетного счета 00000000148 от 22.05.2020 10:14:43 | 60.02 / 51 | 142299\n2. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 75367\n3. 2020-05-22T10:12:50Z | Списание с расчетного счета 00000000147 от 22.05.2020 10:12:50 | 60.01 / 51 | 211833\n4. 2020-05-18T12:00:02Z | Списание с расчетного счета 00000000145 от 18.05.2020 12:00:02 | 60.01 / 51 | 187967",
"expected_intent": "documents_forming_balance",
"actual_intent": "account_balance_snapshot",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 37,
"id": "S037",
"question": "раскрой остаток 60.01 по документам на конец июля 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s037",
"status_code": 200,
"ok": true,
"elapsed_ms": 6109,
"reply_type": "factual",
"trace_id": "address-4-HO33hhY_",
"assistant_reply": "Собран список документов по договору (live address lane).\nСтрок отобрано: 5.\n1. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 74400\n2. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 57600\n3. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 42400\n4. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 34200\n5. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 7600",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_contract",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 38,
"id": "S038",
"question": "доки под остатком 60.01 на 2020-07-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s038",
"status_code": 200,
"ok": true,
"elapsed_ms": 6096,
"reply_type": "factual",
"trace_id": "address-_lwIn9s5iS",
"assistant_reply": "Собран список документов по договору (live address lane).\nСтрок отобрано: 5.\n1. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 74400\n2. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 57600\n3. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 42400\n4. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 34200\n5. 2020-07-13T12:00:02Z | Поступление товаров и услуг 00000000029 от 13.07.2020 12:00:02 | 41.01 / 60.01 | 7600",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_contract",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 41,
"id": "S041",
"question": "по счету 62.01 раскрой остаток документами на 2020-12-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s041",
"status_code": 200,
"ok": true,
"elapsed_ms": 8322,
"reply_type": "partial_coverage",
"trace_id": "address-2O8vRhRFfB",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по выбранным фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период, контрагента, договор или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_contract",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "no_raw_rows",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 42,
"id": "S042",
"question": "из чего остаток по счету 51 на 2020-06-30",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s042",
"status_code": 200,
"ok": true,
"elapsed_ms": 5923,
"reply_type": "factual",
"trace_id": "address-rNaUez9YMa",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 30.\nСумма по отобранным движениям: 4579658.75.\n1. 2020-06-30T12:00:07Z | Списание с расчетного счета 00000000180 от 30.06.2020 12:00:07 | 66.03 / 51 | 35000\n2. 2020-06-30T12:00:05Z | Списание с расчетного счета 00000000178 от 30.06.2020 12:00:05 | 60.01 / 51 | 15800\n3. 2020-06-30T12:00:04Z | Списание с расчетного счета 00000000177 от 30.06.2020 12:00:04 | 70 / 51 | 50\n4. 2020-06-30T12:00:03Z | Списание с расчетного счета 00000000176 от 30.06.2020 12:00:03 | 91.02 / 51 | 35",
"expected_intent": "documents_forming_balance",
"actual_intent": "account_balance_snapshot",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 45,
"id": "S045",
"question": "какие документы по контракту 15/24",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s045",
"status_code": 200,
"ok": true,
"elapsed_ms": 8092,
"reply_type": "partial_coverage",
"trace_id": "address-w_HybB7rZk",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "list_documents_by_contract",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 50,
"id": "S050",
"question": "покеж документы по 15/24",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14-s050",
"status_code": 200,
"ok": true,
"elapsed_ms": 5991,
"reply_type": "partial_coverage",
"trace_id": "address-hD4hKSeduf",
"assistant_reply": "Не удалось выполнить адресный live-запрос в V1.\nПричина: live MCP вызов завершился ошибкой.\nЧто нужно уточнить: MCP fetch failed: This operation was aborted.",
"expected_intent": "list_documents_by_contract",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "error",
"limited_reason_category": "execution_error",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,54 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-37-14",
"generated_at": "2026-04-02T09:43:17",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_2026-04-02.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",
"totals": {
"questions_total": 60,
"ok_200_count": 60,
"semantic_pass_count": 48,
"semantic_pass_rate": 0.8,
"factual_count": 43,
"partial_coverage_count": 17,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 54,
"avg_elapsed_ms": 6047.8
},
"distributions": {
"reply_type": {
"partial_coverage": 17,
"factual": 43
},
"actual_intent": {
"list_documents_by_counterparty": 14,
"bank_operations_by_counterparty": 7,
"unknown": 3,
"account_balance_snapshot": 18,
"documents_forming_balance": 3,
"list_documents_by_contract": 9,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 60
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 10,
"matched_non_empty": 43,
"skipped": 3,
"no_raw_rows": 2,
"materialized_but_filtered_out_by_recipe": 1,
"error": 1
},
"limited_reason_category": {
"empty_match": 11,
"missing_anchor": 1,
"unsupported": 3,
"recipe_visibility_gap": 1,
"execution_error": 1
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35
Generated at: 2026-04-02T09:54:42
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_2026-04-02.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
## Totals
- questions_total: 60
- ok_200_count: 60
- semantic_pass_count: 55
- semantic_pass_rate: 0.9167
- factual_count: 43
- partial_coverage_count: 17
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 51
- avg_elapsed_ms: 6112.6
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,137 @@
[
{
"index": 19,
"id": "S019",
"question": "свк списания/поступления за 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35-s019",
"status_code": 200,
"ok": true,
"elapsed_ms": 6024,
"reply_type": "partial_coverage",
"trace_id": "address-amLbVNd2oC",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 37,
"id": "S037",
"question": "раскрой остаток 60.01 по документам на конец июля 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35-s037",
"status_code": 200,
"ok": true,
"elapsed_ms": 8273,
"reply_type": "partial_coverage",
"trace_id": "address-8m-RkQckzz",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 38,
"id": "S038",
"question": "доки под остатком 60.01 на 2020-07-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35-s038",
"status_code": 200,
"ok": true,
"elapsed_ms": 8134,
"reply_type": "partial_coverage",
"trace_id": "address-U9ycLkdr3-",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 41,
"id": "S041",
"question": "по счету 62.01 раскрой остаток документами на 2020-12-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35-s041",
"status_code": 200,
"ok": true,
"elapsed_ms": 9351,
"reply_type": "partial_coverage",
"trace_id": "address-zV1HuiGSO7",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 42,
"id": "S042",
"question": "из чего остаток по счету 51 на 2020-06-30",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35-s042",
"status_code": 200,
"ok": true,
"elapsed_ms": 5960,
"reply_type": "factual",
"trace_id": "address-h38ift_cPc",
"assistant_reply": "Адресный срез по счету собран (по движениям live MCP).\nСтрок отобрано: 30.\nСумма по отобранным движениям: 4579658.75.\n1. 2020-06-30T12:00:07Z | Списание с расчетного счета 00000000180 от 30.06.2020 12:00:07 | 66.03 / 51 | 35000\n2. 2020-06-30T12:00:05Z | Списание с расчетного счета 00000000178 от 30.06.2020 12:00:05 | 60.01 / 51 | 15800\n3. 2020-06-30T12:00:04Z | Списание с расчетного счета 00000000177 от 30.06.2020 12:00:04 | 70 / 51 | 50\n4. 2020-06-30T12:00:03Z | Списание с расчетного счета 00000000176 от 30.06.2020 12:00:03 | 91.02 / 51 | 35",
"expected_intent": "documents_forming_balance",
"actual_intent": "account_balance_snapshot",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "matched_non_empty",
"limited_reason_category": null,
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,51 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-48-35",
"generated_at": "2026-04-02T09:54:42",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_2026-04-02.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",
"totals": {
"questions_total": 60,
"ok_200_count": 60,
"semantic_pass_count": 55,
"semantic_pass_rate": 0.9167,
"factual_count": 43,
"partial_coverage_count": 17,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 51,
"avg_elapsed_ms": 6112.6
},
"distributions": {
"reply_type": {
"partial_coverage": 17,
"factual": 43
},
"actual_intent": {
"list_documents_by_counterparty": 15,
"bank_operations_by_counterparty": 9,
"unknown": 1,
"account_balance_snapshot": 17,
"documents_forming_balance": 4,
"list_documents_by_contract": 8,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 60
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 13,
"matched_non_empty": 43,
"skipped": 1,
"no_raw_rows": 1,
"materialized_but_filtered_out_by_recipe": 2
},
"limited_reason_category": {
"empty_match": 14,
"unsupported": 1,
"recipe_visibility_gap": 2
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-55-53
Generated at: 2026-04-02T10:01:59
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_2026-04-02.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
## Totals
- questions_total: 60
- ok_200_count: 60
- semantic_pass_count: 58
- semantic_pass_rate: 0.9667
- factual_count: 43
- partial_coverage_count: 17
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 49
- avg_elapsed_ms: 6102.7
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,56 @@
[
{
"index": 37,
"id": "S037",
"question": "раскрой остаток 60.01 по документам на конец июля 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-55-53-s037",
"status_code": 200,
"ok": true,
"elapsed_ms": 8271,
"reply_type": "partial_coverage",
"trace_id": "address-ykDM9o9y8I",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 38,
"id": "S038",
"question": "доки под остатком 60.01 на 2020-07-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-55-53-s038",
"status_code": 200,
"ok": true,
"elapsed_ms": 8140,
"reply_type": "partial_coverage",
"trace_id": "address-GvkS1Sux_Y",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,50 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_09-55-53",
"generated_at": "2026-04-02T10:01:59",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_2026-04-02.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",
"totals": {
"questions_total": 60,
"ok_200_count": 60,
"semantic_pass_count": 58,
"semantic_pass_rate": 0.9667,
"factual_count": 43,
"partial_coverage_count": 17,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 49,
"avg_elapsed_ms": 6102.7
},
"distributions": {
"reply_type": {
"partial_coverage": 17,
"factual": 43
},
"actual_intent": {
"list_documents_by_counterparty": 14,
"bank_operations_by_counterparty": 10,
"account_balance_snapshot": 16,
"documents_forming_balance": 6,
"list_documents_by_contract": 8,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 60
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 12,
"matched_non_empty": 43,
"skipped": 1,
"no_raw_rows": 2,
"materialized_but_filtered_out_by_recipe": 2
},
"limited_reason_category": {
"empty_match": 14,
"missing_anchor": 1,
"recipe_visibility_gap": 2
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-07-46
Generated at: 2026-04-02T10:13:40
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_2026-04-02.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
## Totals
- questions_total: 60
- ok_200_count: 60
- semantic_pass_count: 60
- semantic_pass_rate: 1.0
- factual_count: 42
- partial_coverage_count: 18
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 47
- avg_elapsed_ms: 5902.6
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,52 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-07-46",
"generated_at": "2026-04-02T10:13:40",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_2026-04-02.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",
"totals": {
"questions_total": 60,
"ok_200_count": 60,
"semantic_pass_count": 60,
"semantic_pass_rate": 1.0,
"factual_count": 42,
"partial_coverage_count": 18,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 47,
"avg_elapsed_ms": 5902.6
},
"distributions": {
"reply_type": {
"partial_coverage": 18,
"factual": 42
},
"actual_intent": {
"list_documents_by_counterparty": 12,
"bank_operations_by_counterparty": 10,
"account_balance_snapshot": 16,
"documents_forming_balance": 8,
"list_documents_by_contract": 8,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 60
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 10,
"matched_non_empty": 42,
"skipped": 3,
"no_raw_rows": 2,
"materialized_but_filtered_out_by_recipe": 2,
"error": 1
},
"limited_reason_category": {
"empty_match": 12,
"missing_anchor": 3,
"recipe_visibility_gap": 2,
"execution_error": 1
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-13-57
Generated at: 2026-04-02T10:18:28
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_extra_2026-04-02.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
## Totals
- questions_total: 42
- ok_200_count: 42
- semantic_pass_count: 39
- semantic_pass_rate: 0.9286
- factual_count: 25
- partial_coverage_count: 15
- clarification_required_count: 2
- http_error_count: 0
- llm_decomposition_applied_count: 31
- avg_elapsed_ms: 6452.5
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,83 @@
[
{
"index": 11,
"id": "X011",
"question": "транзакции по свк за 2020",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-13-57-x011",
"status_code": 200,
"ok": true,
"elapsed_ms": 10728,
"reply_type": "clarification_required",
"trace_id": "G02R6JpH8F0-M5",
"assistant_reply": "Коротко: Наиболее вероятный механизм проблемы подтвержден частично и требует первичной проверки. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Проверьте связку документов и проводок по проблемному участку в указанном периоде. Ограничения:\n- Якоря из вопроса без прямого подтверждения: 2020, period:2020.\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- required anchors claim-bound grounding.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"expected_intent": "bank_operations_by_counterparty",
"actual_intent": null,
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": null,
"mode_match": false,
"semantic_pass": false,
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 19,
"id": "X019",
"question": "скока по 60.02 на конец 2020-12",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-13-57-x019",
"status_code": 200,
"ok": true,
"elapsed_ms": 10819,
"reply_type": "clarification_required",
"trace_id": "YbgJ6VuXh8C1v1",
"assistant_reply": "Коротко: Наиболее вероятная причина: переход от оплаты к закрытию расчета подтвержден не полностью. Что сломано:\n- Есть признаки проблемы, но без уточнений по периоду и объекту вывод ненадежен. Почему это похоже на проблему:\n- Сигнал проблемы есть, но механизм подтвержден не полностью. На чем это основано:\n- Опора частичная: часть требований покрыта не полностью.\n- Отдельно не подтверждено или покрыто частично: R1. Что проверить первым:\n- Сверьте договор и объект расчетов, затем подтвердите запись в регистре расчетов и документ зачета.\n- Проверьте связку платеж -> расчетный документ -> проводки по 60/62/76 и факт закрытия хвоста. Ограничения:\n- Якоря из вопроса без прямого подтверждения: 60.02, 2020-12, period:2020-12.\n- Ни одно требование не получило подтвержденного покрытия.\n- Нет explainable-сигналов why_included в результатах выборки.\n- supplier/customer polarity.\n- evidence.\n- Targeted evidence acquisition claim target path.",
"expected_intent": "account_balance_snapshot",
"actual_intent": null,
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": null,
"mode_match": false,
"semantic_pass": false,
"mcp_call_status": null,
"limited_reason_category": null,
"llm_decomposition_applied": null,
"llm_decomposition_reason": null,
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 26,
"id": "X026",
"question": "раскидай остаток 62.01 по докам на 2020-12-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-13-57-x026",
"status_code": 200,
"ok": true,
"elapsed_ms": 8298,
"reply_type": "partial_coverage",
"trace_id": "address-5eKPNT2W8Z",
"assistant_reply": "В live-данных по текущему фильтру записи не найдены.\nПричина: по указанному якорю и фильтрам в live-выборке нет строк.\nЧто нужно уточнить: уточните период или снимите часть фильтров.",
"expected_intent": "documents_forming_balance",
"actual_intent": "list_documents_by_counterparty",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "materialized_but_not_anchor_matched",
"limited_reason_category": "empty_match",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,54 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-13-57",
"generated_at": "2026-04-02T10:18:28",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_extra_2026-04-02.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",
"totals": {
"questions_total": 42,
"ok_200_count": 42,
"semantic_pass_count": 39,
"semantic_pass_rate": 0.9286,
"factual_count": 25,
"partial_coverage_count": 15,
"clarification_required_count": 2,
"http_error_count": 0,
"llm_decomposition_applied_count": 31,
"avg_elapsed_ms": 6452.5
},
"distributions": {
"reply_type": {
"partial_coverage": 15,
"factual": 25,
"clarification_required": 2
},
"actual_intent": {
"list_documents_by_counterparty": 7,
"bank_operations_by_counterparty": 5,
"None": 2,
"account_balance_snapshot": 9,
"documents_forming_balance": 7,
"list_documents_by_contract": 6,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 40,
"None": 2
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 7,
"matched_non_empty": 25,
"None": 2,
"no_raw_rows": 1,
"skipped": 4,
"error": 3
},
"limited_reason_category": {
"empty_match": 7,
"missing_anchor": 5,
"execution_error": 3
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-20-51
Generated at: 2026-04-02T10:24:58
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_extra_2026-04-02.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
## Totals
- questions_total: 42
- ok_200_count: 42
- semantic_pass_count: 40
- semantic_pass_rate: 0.9524
- factual_count: 25
- partial_coverage_count: 17
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 29
- avg_elapsed_ms: 5878.3
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,56 @@
[
{
"index": 15,
"id": "X015",
"question": "что на счете 60 на 2020.05",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-20-51-x015",
"status_code": 200,
"ok": true,
"elapsed_ms": 5072,
"reply_type": "partial_coverage",
"trace_id": "address-P9BOSmbc4z",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "account_balance_snapshot",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
},
{
"index": 25,
"id": "X025",
"question": "docs forming balance 60.01 as of 2020-07-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-20-51-x025",
"status_code": 200,
"ok": true,
"elapsed_ms": 5960,
"reply_type": "partial_coverage",
"trace_id": "address-dWtI0q5djq",
"assistant_reply": "Для точного адресного поиска не хватает обязательного якоря.\nПричина: не хватает обязательных фильтров.\nЧто нужно уточнить: уточните: account.",
"expected_intent": "documents_forming_balance",
"actual_intent": "account_balance_snapshot",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "missing_anchor",
"llm_decomposition_applied": false,
"llm_decomposition_reason": "normalized_fragment_rejected_intent_conflict",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,52 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-20-51",
"generated_at": "2026-04-02T10:24:58",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_extra_2026-04-02.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",
"totals": {
"questions_total": 42,
"ok_200_count": 42,
"semantic_pass_count": 40,
"semantic_pass_rate": 0.9524,
"factual_count": 25,
"partial_coverage_count": 17,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 29,
"avg_elapsed_ms": 5878.3
},
"distributions": {
"reply_type": {
"partial_coverage": 17,
"factual": 25
},
"actual_intent": {
"list_documents_by_counterparty": 6,
"bank_operations_by_counterparty": 6,
"account_balance_snapshot": 10,
"unknown": 1,
"documents_forming_balance": 7,
"list_documents_by_contract": 6,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 42
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 7,
"matched_non_empty": 25,
"skipped": 8,
"no_raw_rows": 1,
"error": 1
},
"limited_reason_category": {
"empty_match": 7,
"missing_anchor": 8,
"unsupported": 1,
"execution_error": 1
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-26-25
Generated at: 2026-04-02T10:30:27
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_extra_2026-04-02.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
## Totals
- questions_total: 42
- ok_200_count: 42
- semantic_pass_count: 42
- semantic_pass_rate: 1.0
- factual_count: 24
- partial_coverage_count: 18
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 30
- avg_elapsed_ms: 5757.0
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,50 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-26-25",
"generated_at": "2026-04-02T10:30:27",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_extra_2026-04-02.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",
"totals": {
"questions_total": 42,
"ok_200_count": 42,
"semantic_pass_count": 42,
"semantic_pass_rate": 1.0,
"factual_count": 24,
"partial_coverage_count": 18,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 30,
"avg_elapsed_ms": 5757.0
},
"distributions": {
"reply_type": {
"partial_coverage": 18,
"factual": 24
},
"actual_intent": {
"list_documents_by_counterparty": 6,
"bank_operations_by_counterparty": 6,
"account_balance_snapshot": 10,
"documents_forming_balance": 8,
"list_documents_by_contract": 6,
"bank_operations_by_contract": 6
},
"actual_mode": {
"address_query": 42
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 9,
"matched_non_empty": 24,
"skipped": 6,
"no_raw_rows": 1,
"error": 2
},
"limited_reason_category": {
"empty_match": 9,
"missing_anchor": 7,
"execution_error": 2
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-31-12
Generated at: 2026-04-02T10:41:27
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_full_2026-04-02.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
## Totals
- questions_total: 102
- ok_200_count: 102
- semantic_pass_count: 101
- semantic_pass_rate: 0.9902
- factual_count: 69
- partial_coverage_count: 33
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 76
- avg_elapsed_ms: 6031.8
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,29 @@
[
{
"index": 27,
"id": "S027",
"question": "баланс account 60.01 as of 2020-07-31",
"session": null,
"session_id": "asst-2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-31-12-s027",
"status_code": 200,
"ok": true,
"elapsed_ms": 5229,
"reply_type": "partial_coverage",
"trace_id": "address-Ad2n8uT34g",
"assistant_reply": "Этот запрос не подходит под address_query V1.\nПричина: intent пока не поддержан в address V1.\nЧто нужно уточнить: переформулируйте вопрос как адресный lookup по счету/контрагенту/договору.",
"expected_intent": "account_balance_snapshot",
"actual_intent": "unknown",
"intent_match": false,
"expected_mode": "address_query",
"actual_mode": "address_query",
"mode_match": true,
"semantic_pass": false,
"mcp_call_status": "skipped",
"limited_reason_category": "unsupported",
"llm_decomposition_applied": true,
"llm_decomposition_reason": "normalized_fragment_applied",
"fallback_rule_hit": null,
"error_code": null,
"error_message": null
}
]

View File

@ -0,0 +1,54 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-31-12",
"generated_at": "2026-04-02T10:41:27",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_full_2026-04-02.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",
"totals": {
"questions_total": 102,
"ok_200_count": 102,
"semantic_pass_count": 101,
"semantic_pass_rate": 0.9902,
"factual_count": 69,
"partial_coverage_count": 33,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 76,
"avg_elapsed_ms": 6031.8
},
"distributions": {
"reply_type": {
"partial_coverage": 33,
"factual": 69
},
"actual_intent": {
"list_documents_by_counterparty": 18,
"bank_operations_by_counterparty": 16,
"account_balance_snapshot": 25,
"unknown": 1,
"documents_forming_balance": 16,
"list_documents_by_contract": 14,
"bank_operations_by_contract": 12
},
"actual_mode": {
"address_query": 102
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 17,
"matched_non_empty": 69,
"skipped": 10,
"no_raw_rows": 3,
"materialized_but_filtered_out_by_recipe": 2,
"error": 1
},
"limited_reason_category": {
"empty_match": 19,
"missing_anchor": 10,
"unsupported": 1,
"recipe_visibility_gap": 2,
"execution_error": 1
}
}
}

View File

@ -0,0 +1,23 @@
# 2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-42-26
Generated at: 2026-04-02T10:52:44
Questions file: X:\1C\NDC_1C\docs\ADDRESS\question_sets\address_slang_stress_full_2026-04-02.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
## Totals
- questions_total: 102
- ok_200_count: 102
- semantic_pass_count: 102
- semantic_pass_rate: 1.0
- factual_count: 69
- partial_coverage_count: 33
- clarification_required_count: 0
- http_error_count: 0
- llm_decomposition_applied_count: 77
- avg_elapsed_ms: 6060.8
## Files
- run_summary.json
- full_live_results.json
- failures_only.json

View File

@ -0,0 +1,52 @@
{
"run_id": "2026-04-02_Address_Slang_Live_Stress_2026-04-02_10-42-26",
"generated_at": "2026-04-02T10:52:44",
"source_questions_file": "X:\\1C\\NDC_1C\\docs\\ADDRESS\\question_sets\\address_slang_stress_full_2026-04-02.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",
"totals": {
"questions_total": 102,
"ok_200_count": 102,
"semantic_pass_count": 102,
"semantic_pass_rate": 1.0,
"factual_count": 69,
"partial_coverage_count": 33,
"clarification_required_count": 0,
"http_error_count": 0,
"llm_decomposition_applied_count": 77,
"avg_elapsed_ms": 6060.8
},
"distributions": {
"reply_type": {
"partial_coverage": 33,
"factual": 69
},
"actual_intent": {
"list_documents_by_counterparty": 18,
"bank_operations_by_counterparty": 16,
"account_balance_snapshot": 26,
"documents_forming_balance": 16,
"list_documents_by_contract": 14,
"bank_operations_by_contract": 12
},
"actual_mode": {
"address_query": 102
},
"mcp_call_status": {
"materialized_but_not_anchor_matched": 19,
"matched_non_empty": 69,
"skipped": 8,
"no_raw_rows": 3,
"materialized_but_filtered_out_by_recipe": 2,
"error": 1
},
"limited_reason_category": {
"empty_match": 21,
"missing_anchor": 9,
"recipe_visibility_gap": 2,
"execution_error": 1
}
}
}

View File

@ -721,19 +721,8 @@ export function extractAddressFilters(userMessage: string, intent: AddressIntent
} }
} }
// For document/bank lists we default to a short recent window if no explicit period was provided. // For counterparty document/bank lists we keep period open by default (all-time over available data)
if ( // and rely on runtime limits/recovery instead of forcing a recent window.
(intent === "list_documents_by_counterparty" ||
intent === "bank_operations_by_counterparty") &&
!filters.period_from &&
!filters.period_to &&
!hasAllTimeHint(text)
) {
const today = new Date().toISOString().slice(0, 10);
filters.period_to = today;
filters.period_from = shiftDaysIso(today, -90);
warnings.push("period_defaulted_last_90_days");
}
// For balance-style intents we force as_of_date deterministically: // For balance-style intents we force as_of_date deterministically:
// - explicit as_of has priority; // - explicit as_of has priority;

View File

@ -28,14 +28,20 @@ const ACCOUNT_BALANCE_HINTS = [
"account balance", "account balance",
"balance by account", "balance by account",
"saldo", "saldo",
"баланс",
"остаток по счет", "остаток по счет",
"сальдо по счет", "сальдо по счет",
"по счету" "по счету",
"что на счете",
"что на счёте",
"на конец"
]; ];
const DOCUMENTS_FORMING_BALANCE_HINTS = [ const DOCUMENTS_FORMING_BALANCE_HINTS = [
"documents forming balance", "documents forming balance",
"docs forming balance",
"documents form balance", "documents form balance",
"docs form balance",
"balance documents", "balance documents",
"documents for balance", "documents for balance",
"which documents form balance", "which documents form balance",
@ -61,6 +67,8 @@ const OPEN_ITEMS_HINTS = [
"висят", "висят",
"незакрыт", "незакрыт",
"открыт", "открыт",
"долг",
"задолж",
"позици" "позици"
]; ];
@ -93,14 +101,21 @@ const BANK_OPERATIONS_BY_COUNTERPARTY_HINTS = [
"bank operations by customer", "bank operations by customer",
"show bank operations by counterparty", "show bank operations by counterparty",
"bank ops", "bank ops",
"bank oper",
"transactions by counterparty", "transactions by counterparty",
"транзак",
"банк",
"банков", "банков",
"по банку",
"опер",
"выписк", "выписк",
"платеж", "платеж",
"платёж", "платёж",
"оплат", "оплат",
"списан", "списан",
"списани",
"поступлен", "поступлен",
"поступлени",
"движени" "движени"
]; ];
const DOCUMENTS_BY_CONTRACT_HINTS = [ const DOCUMENTS_BY_CONTRACT_HINTS = [
@ -126,7 +141,10 @@ const BANK_OPERATIONS_BY_CONTRACT_HINTS = [
]; ];
const BANK_OPERATION_CORE_HINTS = [ const BANK_OPERATION_CORE_HINTS = [
"банк",
"банков", "банков",
"операц",
"опер",
"выписк", "выписк",
"платеж", "платеж",
"платёж", "платёж",
@ -148,18 +166,62 @@ function hasAny(text: string, patterns: string[]): boolean {
return patterns.some((item) => text.includes(item)); return patterns.some((item) => text.includes(item));
} }
function hasCompactAccountCodeToken(text: string): boolean {
// Match compact account tokens like 60.01 / 62, while avoiding date fragments.
return /(?<![\d-])\d{2}(?:[.,]\d{1,2})(?![\d-])/u.test(text);
}
function hasDocumentsFormingBalanceSignal(text: string): boolean { function hasDocumentsFormingBalanceSignal(text: string): boolean {
if (hasAny(text, DOCUMENTS_FORMING_BALANCE_HINTS)) { if (hasAny(text, DOCUMENTS_FORMING_BALANCE_HINTS)) {
return true; return true;
} }
const hasDocLexeme = text.includes("документ") || text.includes("доки"); const hasLooseAccountCodeToken = hasCompactAccountCodeToken(text);
const hasDocLexeme = /(?:документ|док(?:и|ам|ах|ов|а)?)/u.test(text);
const hasFormingLexeme = text.includes("формир"); const hasFormingLexeme = text.includes("формир");
const hasBalanceLexeme = text.includes("остат"); const hasBalanceLexeme = text.includes("остат");
const hasAccountLexeme = text.includes("счет") || text.includes("счёт") || hasAccountNumberAnchor(text); const hasAccountLexeme =
text.includes("счет") || text.includes("счёт") || hasAccountNumberAnchor(text) || hasLooseAccountCodeToken;
if (hasDocLexeme && hasFormingLexeme && hasBalanceLexeme && hasAccountLexeme) { if (hasDocLexeme && hasFormingLexeme && hasBalanceLexeme && hasAccountLexeme) {
return true; return true;
} }
return hasBalanceLexeme && hasAccountLexeme && text.includes("из чего состоит"); if (
hasDocLexeme &&
hasBalanceLexeme &&
hasAccountLexeme &&
(text.includes("раскрой") || text.includes("раскид") || text.includes("под остатк"))
) {
return true;
}
if (hasBalanceLexeme && hasAccountLexeme && text.includes("из чего состоит")) {
return true;
}
return hasBalanceLexeme && hasAccountLexeme && /из\s+чего\s+остат/u.test(text);
}
function hasDocumentsFormingBalanceAccountAnchor(text: string): boolean {
if (hasAccountNumberAnchor(text) || text.includes("счет") || text.includes("счёт")) {
return true;
}
// Allow compact account mentions like "60.01" in slang prompts without explicit "счет".
return hasCompactAccountCodeToken(text);
}
function hasAccountBalanceSignal(text: string): boolean {
if (hasAny(text, ACCOUNT_BALANCE_HINTS)) {
return true;
}
const hasAccountLexeme =
hasAccountNumberAnchor(text) || hasCompactAccountCodeToken(text) || /(?:^|\s)по\s+\d{2}(?:[.,]\d{1,2})?(?=$|[\s,.;:!?])/u.test(text);
const hasBalanceLexeme =
text.includes("баланс") ||
text.includes("остат") ||
text.includes("сальд") ||
text.includes("saldo") ||
text.includes("balance") ||
text.includes("скока") ||
text.includes("сколько") ||
/на\s+конец/u.test(text);
return hasAccountLexeme && hasBalanceLexeme;
} }
function isLikelyCounterpartyToken(rawToken: string): boolean { function isLikelyCounterpartyToken(rawToken: string): boolean {
@ -241,6 +303,8 @@ function hasPartyAnchorMention(text: string): boolean {
function hasContractAnchorMention(text: string): boolean { function hasContractAnchorMention(text: string): boolean {
return ( return (
text.includes("договор") || text.includes("договор") ||
text.includes("контракт") ||
/\bдог\.?\b/iu.test(text) ||
text.includes("дог.") || text.includes("дог.") ||
text.includes("contract") || text.includes("contract") ||
text.includes("dogovor") text.includes("dogovor")
@ -265,6 +329,10 @@ function hasContractNumberLikeToken(text: string): boolean {
if (!token) { if (!token) {
continue; continue;
} }
if (/^\d{1,2}\.\d{1,2}$/u.test(token)) {
// Likely an account code like 60.01/51.00, not a contract number.
continue;
}
const parts = token.split(/[./_-]+/u).map((part) => Number(part)); const parts = token.split(/[./_-]+/u).map((part) => Number(part));
if (!parts.every((part) => Number.isFinite(part))) { if (!parts.every((part) => Number.isFinite(part))) {
return true; return true;
@ -381,7 +449,7 @@ function hasDocumentSignal(text: string): boolean {
} }
function hasHeuristicCounterpartyAnchor(text: string): boolean { function hasHeuristicCounterpartyAnchor(text: string): boolean {
if (!hasDocsOrBankSignal(text)) { if (!hasDocsOrBankSignal(text) && !hasBankOperationSignal(text)) {
return false; return false;
} }
const tokens = String(text ?? "") const tokens = String(text ?? "")
@ -441,7 +509,7 @@ export function resolveAddressIntent(userMessage: string): AddressIntentResoluti
}; };
} }
if (hasDocumentsFormingBalanceSignal(text) && (hasAccountNumberAnchor(text) || text.includes("счет"))) { if (hasDocumentsFormingBalanceSignal(text) && hasDocumentsFormingBalanceAccountAnchor(text)) {
return { return {
intent: "documents_forming_balance", intent: "documents_forming_balance",
confidence: "high", confidence: "high",
@ -449,6 +517,17 @@ export function resolveAddressIntent(userMessage: string): AddressIntentResoluti
}; };
} }
if (
hasAny(text, OPEN_ITEMS_HINTS) &&
(text.includes("контраг") || text.includes("договор") || text.includes("counterparty") || text.includes("contract"))
) {
return {
intent: "open_items_by_counterparty_or_contract",
confidence: "medium",
reasons: ["open_items_signal_detected"]
};
}
if ( if (
hasContractAnchorSignal(text) && hasContractAnchorSignal(text) &&
hasBankOperationSignal(text) hasBankOperationSignal(text)
@ -496,7 +575,7 @@ export function resolveAddressIntent(userMessage: string): AddressIntentResoluti
}; };
} }
if (hasAny(text, ACCOUNT_BALANCE_HINTS) || hasAccountNumberAnchor(text)) { if (hasAccountBalanceSignal(text)) {
return { return {
intent: "account_balance_snapshot", intent: "account_balance_snapshot",
confidence: "high", confidence: "high",
@ -512,14 +591,6 @@ export function resolveAddressIntent(userMessage: string): AddressIntentResoluti
}; };
} }
if (hasAny(text, OPEN_ITEMS_HINTS) && (text.includes("контраг") || text.includes("договор") || text.includes("counterparty") || text.includes("contract"))) {
return {
intent: "open_items_by_counterparty_or_contract",
confidence: "medium",
reasons: ["open_items_signal_detected"]
};
}
if (hasAny(text, OPEN_CONTRACTS_HINTS) && (text.includes("договор") || text.includes("contract"))) { if (hasAny(text, OPEN_CONTRACTS_HINTS) && (text.includes("договор") || text.includes("contract"))) {
return { return {
intent: "list_open_contracts", intent: "list_open_contracts",

View File

@ -22,7 +22,11 @@ const ADDRESS_ACTION_TOKENS = [
"кому", "кому",
"какие", "какие",
"что по", "что по",
"че по",
"чё по",
"остаток", "остаток",
"скока",
"сколько",
"долг", "долг",
"задолж", "задолж",
"хвост", "хвост",
@ -64,6 +68,7 @@ const ADDRESS_ENTITY_TOKENS = [
"банк", "банк",
"выписк", "выписк",
"операц", "операц",
"транзак",
"договор", "договор",
"счет", "счет",
"счёт", "счёт",
@ -152,11 +157,15 @@ function hasAddressFollowupSignal(text: string): boolean {
} }
function hasDocsOrBankSignal(text: string): boolean { function hasDocsOrBankSignal(text: string): boolean {
return /(?:док(?:и|умент|ументы|ументов)|docs?|documents?|банк|выписк|платеж|платёж|оплат|поступлен|списан|transactions?|bank\s+ops|bank\s+operations?)/iu.test( return /(?:док(?:и|умент|ументы|ументов)|docs?|documents?|банк|выписк|платеж|платёж|оплат|поступлен|списан|транзак|transactions?|bank\s+ops|bank\s+operations?)/iu.test(
text text
); );
} }
function hasAccountCodeAnchor(text: string): boolean {
return /(?<![\d-])\d{2}(?:[.,]\d{1,2})(?![\d-])/u.test(text);
}
function hasLikelyCounterpartyToken(text: string): boolean { function hasLikelyCounterpartyToken(text: string): boolean {
const stopWords = new Set([ const stopWords = new Set([
"за", "за",
@ -247,8 +256,9 @@ export function detectAddressQuestionMode(userMessage: string): AddressModeDetec
const hasDeepReasoning = hasAnyToken(text, DEEP_REASONING_TOKENS); const hasDeepReasoning = hasAnyToken(text, DEEP_REASONING_TOKENS);
const hasLooseByAnchor = hasLooseByAnchorMention(text); const hasLooseByAnchor = hasLooseByAnchorMention(text);
const hasFollowupSignal = hasAddressFollowupSignal(text); const hasFollowupSignal = hasAddressFollowupSignal(text);
const hasAccountCode = hasAccountCodeAnchor(text);
if (hasAddressAction && hasAddressEntity && !hasDeepReasoning) { if (hasAddressAction && (hasAddressEntity || hasAccountCode) && !hasDeepReasoning) {
return { return {
mode: "address_query", mode: "address_query",
confidence: "high", confidence: "high",
@ -256,7 +266,7 @@ export function detectAddressQuestionMode(userMessage: string): AddressModeDetec
}; };
} }
if (hasLooseByAnchor && (hasAddressAction || hasAddressEntity || hasFollowupSignal) && !hasDeepReasoning) { if (hasLooseByAnchor && (hasAddressAction || hasAddressEntity || hasFollowupSignal || hasAccountCode) && !hasDeepReasoning) {
return { return {
mode: "address_query", mode: "address_query",
confidence: "medium", confidence: "medium",
@ -264,7 +274,7 @@ export function detectAddressQuestionMode(userMessage: string): AddressModeDetec
}; };
} }
if (hasAddressEntity && !hasDeepReasoning) { if ((hasAddressEntity || hasAccountCode) && !hasDeepReasoning) {
return { return {
mode: "address_query", mode: "address_query",
confidence: "medium", confidence: "medium",

View File

@ -996,6 +996,68 @@ export class AddressQueryService {
? "rows_filtered_out_by_intent_recipe_after_anchor_match" ? "rows_filtered_out_by_intent_recipe_after_anchor_match"
: null; : null;
if (filteredRows.length === 0 && intent.intent === "list_documents_by_contract" && filterByAnchors.length > 0) {
const recoveredBankRows = applyIntentSpecificFilter("bank_operations_by_contract", filterByAnchors);
const recoveredRows = recoveredBankRows.length > 0 ? recoveredBankRows : filterByAnchors;
if (recoveredRows.length > 0) {
const factual = composeFactualReply(intent.intent, recoveredRows);
const recoveryReason =
recoveredBankRows.length > 0
? "contract_docs_recovered_via_bank_fallback"
: "contract_docs_recovered_via_anchor_rows";
const replyPrefix =
recoveredBankRows.length > 0
? "Документный фильтр в live дал пустой набор; показываю связанные банковские операции по договору."
: "Документный фильтр в live дал пустой набор; показываю найденные строки по договорному якорю.";
return {
handled: true,
reply_text: `${replyPrefix}\n${factual.text}`,
reply_type: inferReplyType(factual.responseType),
response_type: factual.responseType,
debug: {
detected_mode: mode.mode,
detected_mode_confidence: mode.confidence,
query_shape: shape.shape,
query_shape_confidence: shape.confidence,
detected_intent: intent.intent,
detected_intent_confidence: intent.confidence,
extracted_filters: filters.extracted_filters,
missing_required_filters: [],
selected_recipe: recipeSelection.selected_recipe.recipe_id,
mcp_call_status_legacy: toLegacyMcpStatus("matched_non_empty"),
account_scope_mode: plan.account_scope_mode,
account_scope_fallback_applied: accountScopeFallbackApplied,
anchor_type: anchor.anchor_type,
anchor_value_raw: anchor.anchor_value_raw,
anchor_value_resolved: anchor.anchor_value_resolved,
resolver_confidence: anchor.resolver_confidence,
ambiguity_count: anchor.ambiguity_count,
match_failure_stage: "none",
match_failure_reason: null,
mcp_call_status: "matched_non_empty",
rows_fetched: mcp.fetched_rows,
raw_rows_received: mcp.raw_rows.length,
rows_after_account_scope: normalizedRows.length,
rows_after_recipe_filter: filterByAnchors.length,
rows_materialized: normalizedRows.length,
rows_matched: recoveredRows.length,
raw_row_keys_sample: rowDiagnostics.rawRowKeysSample,
materialization_drop_reason: rowDiagnostics.materializationDropReason,
account_token_raw: accountScopeAudit.accountTokenRaw,
account_token_normalized: accountScopeAudit.accountTokenNormalized,
account_scope_fields_checked: accountScopeAudit.accountScopeFieldsChecked,
account_scope_match_strategy: accountScopeAudit.accountScopeMatchStrategy,
account_scope_drop_reason: accountScopeAudit.accountScopeDropReason,
runtime_readiness: "LIVE_QUERYABLE_WITH_LIMITS",
limited_reason_category: null,
response_type: factual.responseType,
limitations: [...filters.warnings, recoveryReason],
reasons: [...baseReasons, recoveryReason]
}
};
}
}
if (intent.intent === "list_open_contracts" && filteredRows.length > 0 && contractCandidatesFromRows(filteredRows).length === 0) { if (intent.intent === "list_open_contracts" && filteredRows.length > 0 && contractCandidatesFromRows(filteredRows).length === 0) {
return buildLimitedExecutionResult({ return buildLimitedExecutionResult({
mode, mode,

View File

@ -13,6 +13,8 @@ import * as companyAnchorResolver_1 from "./companyAnchorResolver";
import * as assistantRuntimeGuards_1 from "./assistantRuntimeGuards"; import * as assistantRuntimeGuards_1 from "./assistantRuntimeGuards";
import * as assistantClaimBoundEvidence_1 from "./assistantClaimBoundEvidence"; import * as assistantClaimBoundEvidence_1 from "./assistantClaimBoundEvidence";
import * as addressQueryService_1 from "./addressQueryService"; import * as addressQueryService_1 from "./addressQueryService";
import * as addressQueryClassifier_1 from "./addressQueryClassifier";
import * as addressIntentResolver_1 from "./addressIntentResolver";
import iconv from "iconv-lite"; import iconv from "iconv-lite";
function retrievalSummaryForRoute(route) { function retrievalSummaryForRoute(route) {
if (route === "store_canonical") if (route === "store_canonical")
@ -1924,9 +1926,9 @@ const ADDRESS_MONTH_ALIAS_MAP = {
december: "12", december: "12",
dec: "12" dec: "12"
}; };
const ADDRESS_DOCS_SIGNAL_PATTERN = /(?:док|доки|документ|документы|документов|docs?|documents?|bank|выписк|плат[её]ж|оплат|поступлен|списан|операц)/i; const ADDRESS_DOCS_SIGNAL_PATTERN = /(?:док|доки|документ|документы|документов|docs?|documents?|bank|выписк|плат[её]ж|оплат|поступлен|списан|операц|опер|transaction)/i;
const ADDRESS_BANK_SIGNAL_PATTERN = /(?:bank|банк|банков|выписк|плат[её]ж|оплат|поступлен|списан|операц|расчетн)/i; const ADDRESS_BANK_SIGNAL_PATTERN = /(?:bank|банк|банков|выписк|плат[её]ж|оплат|поступлен|списан|операц|опер|расчетн|транзак)/i;
const ADDRESS_CONTRACT_SIGNAL_PATTERN = /(?:договор(?:а|у|ом|е)?|\bcontract\b)/iu; const ADDRESS_CONTRACT_SIGNAL_PATTERN = /(?:договор(?:а|у|ом|е)?|(?:^|[^\p{L}\p{N}_])(?:дог\.?|[dд][oо][gг]\.?|dog\.?)(?=$|[^\p{L}\p{N}_])|contract|dogovor)/iu;
const ADDRESS_BALANCE_SIGNAL_PATTERN = /(?:остат|сальдо|баланс|взаиморасч|долг|saldo|balance)/i; const ADDRESS_BALANCE_SIGNAL_PATTERN = /(?:остат|сальдо|баланс|взаиморасч|долг|saldo|balance)/i;
const ADDRESS_ALL_TIME_PATTERN = /(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+всю\s+истори(?:ю|и)|for\s+all\s+time|all\s+time|entire\s+period|full\s+history)/iu; const ADDRESS_ALL_TIME_PATTERN = /(?:за\s+вс[её]\s+время|за\s+весь\s+период|за\s+всю\s+истори(?:ю|и)|for\s+all\s+time|all\s+time|entire\s+period|full\s+history)/iu;
function normalizeAddressMonthAliasToken(token) { function normalizeAddressMonthAliasToken(token) {
@ -1964,6 +1966,10 @@ function sanitizeAddressMessageForFallback(userMessage) {
.replace(/\bpokezh\b/giu, "покажи") .replace(/\bpokezh\b/giu, "покажи")
.replace(/\bpokazh(?:i)?\b/giu, "покажи") .replace(/\bpokazh(?:i)?\b/giu, "покажи")
.replace(/\bpokaji\b/giu, "покажи") .replace(/\bpokaji\b/giu, "покажи")
.replace(/\bop(?:er|ers?)\b/giu, "операции")
.replace(/(^|[^\p{L}\p{N}_])опер(?:аци[яиюе]|ы|)?(?=$|[^\p{L}\p{N}_])/giu, "$1операции")
.replace(/(^|[^\p{L}\p{N}_])дог\.?(?=$|[^\p{L}\p{N}_])/giu, "$1договор")
.replace(/(^|[^\p{L}\p{N}_])dog\.?(?=$|[^\p{L}\p{N}_])/giu, "$1contract")
.replace(/\bdok(?:i|y)?\b/giu, "доки") .replace(/\bdok(?:i|y)?\b/giu, "доки")
.replace(/\bdocuments?\b/giu, "документы") .replace(/\bdocuments?\b/giu, "документы")
.replace(/\bdocs?\b/giu, "документы") .replace(/\bdocs?\b/giu, "документы")
@ -2070,7 +2076,7 @@ function pickAddressFallbackCounterpartyToken(text) {
!/^\d{2}(?:\.\d{1,2})?$/.test(normalizedByToken) && !/^\d{2}(?:\.\d{1,2})?$/.test(normalizedByToken) &&
!/^(?:19|20)\d{2}$/.test(normalizedByToken) && !/^(?:19|20)\d{2}$/.test(normalizedByToken) &&
!/^(?:янв|фев|мар|апр|май|июн|июл|авг|сен|сент|окт|ноя|дек|january|february|march|april|may|june|july|august|september|october|november|december)/i.test(normalizedByToken) && !/^(?:янв|фев|мар|апр|май|июн|июл|авг|сен|сент|окт|ноя|дек|january|february|march|april|may|june|july|august|september|october|november|december)/i.test(normalizedByToken) &&
!/^(?:договор|договора|договору|договором|договоре|contract)$/.test(normalizedByToken)) { !/^(?:договор|договора|договору|договором|договоре|contract|dogovor|dog|дог|d[oо]g|д[oо]г)$/.test(normalizedByToken)) {
return byToken; return byToken;
} }
} }
@ -2086,7 +2092,7 @@ function pickAddressFallbackCounterpartyToken(text) {
if (/^(?:янв|фев|мар|апр|май|июн|июл|авг|сен|сент|окт|ноя|дек|january|february|march|april|may|june|july|august|september|october|november|december)/i.test(normalized)) { if (/^(?:янв|фев|мар|апр|май|июн|июл|авг|сен|сент|окт|ноя|дек|january|february|march|april|may|june|july|august|september|october|november|december)/i.test(normalized)) {
continue; continue;
} }
if (/^(?:договор|договора|договору|договором|договоре|contract)$/.test(normalized)) { if (/^(?:договор|договора|договору|договором|договоре|contract|dogovor|dog|дог|d[oо]g|д[oо]г)$/.test(normalized)) {
continue; continue;
} }
return token; return token;
@ -2096,8 +2102,8 @@ function pickAddressFallbackCounterpartyToken(text) {
function extractAddressFallbackContractToken(text) { function extractAddressFallbackContractToken(text) {
const source = String(text ?? ""); const source = String(text ?? "");
const patterns = [ const patterns = [
/(?:договор(?:а|у|ом|е)?|\bcontract\b)\s*(?:|#|n|no\.?)?\s*([a-zа-я0-9][a-zа-я0-9/_-]{1,})/iu, /(?:договор(?:а|у|ом|е)?|дог\.?|[dд][oо][gг]\.?|contract|dogovor|dog\.?)\s*(?:|#|n|no\.?)?\s*([a-zа-я0-9][a-zа-я0-9/_-]{1,})/iu,
/(?:|#|n|no\.?)\s*([a-zа-я0-9][a-zа-я0-9/_-]{1,})\s*(?:договор(?:а|у|ом|е)?|\bcontract\b)/iu /(?:|#|n|no\.?)\s*([a-zа-я0-9][a-zа-я0-9/_-]{1,})\s*(?:договор(?:а|у|ом|е)?|дог\.?|[dд][oо][gг]\.?|contract|dogovor|dog\.?)/iu
]; ];
for (const pattern of patterns) { for (const pattern of patterns) {
const match = pattern.exec(source); const match = pattern.exec(source);
@ -2116,7 +2122,7 @@ function extractAddressFallbackContractToken(text) {
} }
return candidate; return candidate;
} }
if (ADDRESS_CONTRACT_SIGNAL_PATTERN.test(source)) { if (ADDRESS_CONTRACT_SIGNAL_PATTERN.test(source) || /(?:^|[^\p{L}\p{N}_])(?:[dд][oо][gг]|dogovor)(?=$|[^\p{L}\p{N}_])/iu.test(source)) {
const generic = source.match(/\b([a-zа-я0-9]{1,10}[/-][a-zа-я0-9]{1,10}(?:[/-][a-zа-я0-9]{1,10})?)\b/iu); const generic = source.match(/\b([a-zа-я0-9]{1,10}[/-][a-zа-я0-9]{1,10}(?:[/-][a-zа-я0-9]{1,10})?)\b/iu);
if (generic && generic[1]) { if (generic && generic[1]) {
return generic[1]; return generic[1];
@ -2157,9 +2163,36 @@ function resolveAddressDeterministicFallback(userMessage, sanitizedUserMessage)
}; };
} }
} }
if (!docsSignal && !contractSignal && !balanceSignal) {
const counterparty = pickAddressFallbackCounterpartyToken(source);
const genericLookupSignal = /(?:\bесть\b|\bпокажи\b|\bвыведи\b|\bч[её]\b|\bчто\b)/iu.test(source);
if (counterparty && (allTime || monthYear || year) && genericLookupSignal) {
let periodClause = "";
let rule = "documents_counterparty_rewrite_from_generic_lookup";
if (allTime) {
periodClause = " за все время";
rule = "documents_counterparty_all_time_rewrite_from_generic_lookup";
}
else if (monthYear) {
periodClause = ` за ${monthYear}`;
rule = "documents_counterparty_month_rewrite_from_generic_lookup";
}
else if (year) {
periodClause = ` за ${year} год`;
rule = "documents_counterparty_year_rewrite_from_generic_lookup";
}
const candidate = compactWhitespace(`документы по контрагенту ${counterparty}${periodClause}`);
if (candidate && candidate !== sourceRaw.toLowerCase()) {
return {
candidate,
rule
};
}
}
}
if (docsSignal) { if (docsSignal) {
if (contractSignal) { const contract = extractAddressFallbackContractToken(sourceRaw || source);
const contract = extractAddressFallbackContractToken(sourceRaw || source); if (contractSignal || contract) {
if (contract) { if (contract) {
let periodClause = ""; let periodClause = "";
let rule = bankSignal ? "bank_operations_contract_rewrite" : "documents_contract_rewrite"; let rule = bankSignal ? "bank_operations_contract_rewrite" : "documents_contract_rewrite";
@ -2642,6 +2675,32 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
reason: normalized?.ok ? "no_usable_fragment" : "normalize_failed" reason: normalized?.ok ? "no_usable_fragment" : "normalize_failed"
}; };
} }
const repairedSourceMessage = repairAddressMojibake(userMessage);
const sourceIntentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(repairedSourceMessage || userMessage);
const candidateIntentResolution = (0, addressIntentResolver_1.resolveAddressIntent)(candidate);
const sourceIntentKnown = sourceIntentResolution.intent !== "unknown";
const candidateIntentKnown = candidateIntentResolution.intent !== "unknown";
const intentConflict = sourceIntentKnown &&
candidateIntentKnown &&
sourceIntentResolution.intent !== candidateIntentResolution.intent;
const intentDroppedByCandidate = sourceIntentKnown && !candidateIntentKnown;
const rejectCandidateForIntentSafety = intentDroppedByCandidate ||
(intentConflict &&
(sourceIntentResolution.confidence === "high" || candidateIntentResolution.confidence !== "high"));
if (rejectCandidateForIntentSafety) {
return {
...baseMeta,
attempted: true,
applied: false,
traceId: normalized?.trace_id ?? null,
effectiveMessage: userMessage,
reason: intentDroppedByCandidate
? "normalized_fragment_rejected_intent_drop"
: "normalized_fragment_rejected_intent_conflict",
fallbackRuleHit: null,
sanitizedUserMessage
};
}
const sourceCompact = compactWhitespace(String(userMessage ?? "").toLowerCase()); const sourceCompact = compactWhitespace(String(userMessage ?? "").toLowerCase());
const candidateCompact = compactWhitespace(candidate.toLowerCase()); const candidateCompact = compactWhitespace(candidate.toLowerCase());
const applied = sourceCompact !== candidateCompact; const applied = sourceCompact !== candidateCompact;
@ -2692,12 +2751,19 @@ async function runAddressLlmPreDecompose(normalizerService, payload, userMessage
} }
} }
function resolveAddressToolGateDecision(addressInputMessage, followupContext) { function resolveAddressToolGateDecision(addressInputMessage, followupContext) {
const hasMessageSignal = isAddressLlmPreDecomposeCandidate(addressInputMessage) || hasAccountingSignal(addressInputMessage); const repairedInputMessage = repairAddressMojibake(String(addressInputMessage ?? ""));
const modeDetection = (0, addressQueryClassifier_1.detectAddressQuestionMode)(repairedInputMessage || addressInputMessage);
const hasClassifierSignal = modeDetection.mode === "address_query";
const hasMessageSignal = hasClassifierSignal ||
isAddressLlmPreDecomposeCandidate(addressInputMessage) ||
isAddressLlmPreDecomposeCandidate(repairedInputMessage) ||
hasAccountingSignal(addressInputMessage) ||
hasAccountingSignal(repairedInputMessage);
if (hasMessageSignal) { if (hasMessageSignal) {
return { return {
runAddressLane: true, runAddressLane: true,
decision: "run_address_lane", decision: "run_address_lane",
reason: "address_signal_detected" reason: hasClassifierSignal ? "address_mode_classifier_detected" : "address_signal_detected"
}; };
} }
if (followupContext) { if (followupContext) {

View File

@ -132,6 +132,9 @@ function shouldFallbackToChatCompletions(error: unknown): boolean {
if (!(error instanceof ApiError)) { if (!(error instanceof ApiError)) {
return false; return false;
} }
if (error.code === "OPENAI_OUTPUT_PARSE_FAILED" || error.code === "OPENAI_NON_JSON_RESPONSE") {
return true;
}
if (error.code !== "OPENAI_REQUEST_FAILED") { if (error.code !== "OPENAI_REQUEST_FAILED") {
return false; return false;
} }
@ -144,6 +147,35 @@ function shouldFallbackToChatCompletions(error: unknown): boolean {
return message.includes("/responses") || message.includes("responses"); return message.includes("/responses") || message.includes("responses");
} }
function extractModelErrorMessage(data: Record<string, unknown>): string | null {
const rawError = data.error;
if (typeof rawError === "string" && rawError.trim().length > 0) {
return rawError.trim();
}
if (rawError && typeof rawError === "object") {
const errorObj = rawError as Record<string, unknown>;
const message = errorObj.message;
if (typeof message === "string" && message.trim().length > 0) {
return message.trim();
}
}
return null;
}
function isRouteMismatchErrorMessage(message: string): boolean {
const source = String(message ?? "").toLowerCase();
if (!source) {
return false;
}
return (
/unexpected endpoint|unexpected route|unknown endpoint|unknown route|unsupported endpoint|unsupported route/.test(source) ||
(/endpoint/.test(source) && /method/.test(source)) ||
(/endpoint/.test(source) && /not found/.test(source)) ||
(/route/.test(source) && /not found/.test(source)) ||
(/path/.test(source) && /not found/.test(source))
);
}
function loadSchemaForTransport(schemaVersion: "v1" | "v2" | "v2_0_1" | "v2_0_2"): Record<string, unknown> { function loadSchemaForTransport(schemaVersion: "v1" | "v2" | "v2_0_1" | "v2_0_2"): Record<string, unknown> {
const schemaFile = const schemaFile =
schemaVersion === "v1" schemaVersion === "v1"
@ -398,11 +430,16 @@ export class OpenAIResponsesClient {
} }
} }
const modelErrorMessage = extractModelErrorMessage(data);
if (modelErrorMessage && canFallbackToAlternativeBase && !isLastCandidate && isRouteMismatchErrorMessage(modelErrorMessage)) {
continue;
}
if (!response.ok) { if (!response.ok) {
const errorObj = (data.error ?? {}) as Record<string, unknown>; const errorObj = (data.error ?? {}) as Record<string, unknown>;
throw new ApiError( throw new ApiError(
"OPENAI_REQUEST_FAILED", "OPENAI_REQUEST_FAILED",
String(errorObj.message ?? `Model endpoint failed: ${response.status}`), modelErrorMessage ?? String(errorObj.message ?? `Model endpoint failed: ${response.status}`),
response.status, response.status,
{ {
route: routePath, route: routePath,
@ -414,6 +451,14 @@ export class OpenAIResponsesClient {
); );
} }
if (modelErrorMessage) {
throw new ApiError("OPENAI_REQUEST_FAILED", modelErrorMessage, 502, {
route: routePath,
url,
status: response.status
});
}
return data; return data;
} }

View File

@ -34,6 +34,17 @@ describe("address query shape classifier", () => {
const result = detectAddressQuestionMode("за любой период есть что-то по свк?"); const result = detectAddressQuestionMode("за любой период есть что-то по свк?");
expect(result.mode).toBe("address_query"); expect(result.mode).toBe("address_query");
}); });
it("keeps slang transaction phrasing in address lane", () => {
const result = detectAddressQuestionMode("транзакции по свк за 2020");
expect(result.mode).toBe("address_query");
});
it("keeps short balance slang with compact account token in address lane", () => {
const result = detectAddressQuestionMode("скока по 60.02 на конец 2020-12");
expect(result.mode).toBe("address_query");
});
}); });
describe("address compose stage utf8 headers", () => { describe("address compose stage utf8 headers", () => {
@ -87,6 +98,16 @@ describe("address intent resolver expansion (M2.3a)", () => {
expect(result.intent).toBe("documents_forming_balance"); expect(result.intent).toBe("documents_forming_balance");
}); });
it("resolves documents forming balance for slang phrase with compact account token", () => {
const result = resolveAddressIntent("раскрой остаток 60.01 по документам на конец июля 2020");
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves documents forming balance for 'доки под остатком' slang phrase", () => {
const result = resolveAddressIntent("доки под остатком 60.01 на 2020-07-31");
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves documents by company phrase as counterparty intent", () => { it("resolves documents by company phrase as counterparty intent", () => {
const result = resolveAddressIntent("Какие документы доступны по компании СВК за 2021 год?"); const result = resolveAddressIntent("Какие документы доступны по компании СВК за 2021 год?");
expect(result.intent).toBe("list_documents_by_counterparty"); expect(result.intent).toBe("list_documents_by_counterparty");
@ -107,6 +128,16 @@ describe("address intent resolver expansion (M2.3a)", () => {
expect(result.intent).toBe("bank_operations_by_contract"); expect(result.intent).toBe("bank_operations_by_contract");
}); });
it("resolves shorthand bank-by-contract slang intent", () => {
const result = resolveAddressIntent("покажи банк опер по дог 15/24 пж");
expect(result.intent).toBe("bank_operations_by_contract");
});
it("resolves debt-by-contract query to open items intent", () => {
const result = resolveAddressIntent("Есть ли долг по договору 15/24 на 2020-07-31");
expect(result.intent).toBe("open_items_by_counterparty_or_contract");
});
it("resolves bank operations by contract for normalized phrase with linked contract wording", () => { it("resolves bank operations by contract for normalized phrase with linked contract wording", () => {
const result = resolveAddressIntent( const result = resolveAddressIntent(
"Показать банковские операции (счета 51, 60, 62) связанные с договором 15/24." "Показать банковские операции (счета 51, 60, 62) связанные с договором 15/24."
@ -139,6 +170,36 @@ describe("address intent resolver expansion (M2.3a)", () => {
expect(result.intent).toBe("list_documents_by_counterparty"); expect(result.intent).toBe("list_documents_by_counterparty");
}); });
it("resolves slang transactions phrase by counterparty", () => {
const result = resolveAddressIntent("транзакции по свк за 2020");
expect(result.intent).toBe("bank_operations_by_counterparty");
});
it("resolves short balance slang with compact account token", () => {
const result = resolveAddressIntent("скока по 60.02 на конец 2020-12");
expect(result.intent).toBe("account_balance_snapshot");
});
it("resolves colloquial 'что на счете' phrasing as account balance snapshot", () => {
const result = resolveAddressIntent("что на счете 60 на 2020.05");
expect(result.intent).toBe("account_balance_snapshot");
});
it("resolves mixed ru/en balance phrasing with account token", () => {
const result = resolveAddressIntent("баланс account 60.01 as of 2020-07-31");
expect(result.intent).toBe("account_balance_snapshot");
});
it("resolves 'по докам' slang as documents forming balance", () => {
const result = resolveAddressIntent("раскидай остаток 62.01 по докам на 2020-12-31");
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves english compact docs-forming phrasing", () => {
const result = resolveAddressIntent("docs forming balance 60.01 as of 2020-07-31");
expect(result.intent).toBe("documents_forming_balance");
});
it("resolves loose by-anchor follow-up as documents by counterparty fallback", () => { it("resolves loose by-anchor follow-up as documents by counterparty fallback", () => {
const result = resolveAddressIntent("за любой период есть что-то по свк?"); const result = resolveAddressIntent("за любой период есть что-то по свк?");
expect(result.intent).toBe("list_documents_by_counterparty"); expect(result.intent).toBe("list_documents_by_counterparty");
@ -174,6 +235,17 @@ describe("address filter extraction for balance drilldown", () => {
expect(result.warnings).not.toContain("period_defaulted_last_90_days"); expect(result.warnings).not.toContain("period_defaulted_last_90_days");
}); });
it("keeps all-time period by default for counterparty docs query without explicit window", () => {
const result = extractAddressFilters(
"Покажи документы по контрагенту тестовый",
"list_documents_by_counterparty"
);
expect(result.extracted_filters.counterparty).toBe("тестовый");
expect(result.extracted_filters.period_from).toBeUndefined();
expect(result.extracted_filters.period_to).toBeUndefined();
expect(result.warnings).not.toContain("period_defaulted_last_90_days");
});
it("extracts counterparty from company phrase and derives year period", () => { it("extracts counterparty from company phrase and derives year period", () => {
const result = extractAddressFilters( const result = extractAddressFilters(
"Какие документы доступны по компании СВК за 2021 год?", "Какие документы доступны по компании СВК за 2021 год?",

View File

@ -62,9 +62,6 @@ describe("assistant address follow-up carryover", () => {
const addressQueryService = { const addressQueryService = {
tryHandle: vi.fn(async (message: string, options?: any) => { tryHandle: vi.fn(async (message: string, options?: any) => {
calls.push({ message, options }); calls.push({ message, options });
if (message === "какие есть доки по свк с 2020 по 2025 год") {
return buildAddressLaneResult();
}
if (message === "а за все время?" && !options?.followupContext) { if (message === "а за все время?" && !options?.followupContext) {
return null; return null;
} }
@ -77,7 +74,7 @@ describe("assistant address follow-up carryover", () => {
} }
}); });
} }
return null; return buildAddressLaneResult();
}) })
} as any; } as any;
@ -101,7 +98,7 @@ describe("assistant address follow-up carryover", () => {
const sessionId = `asst-address-followup-${Date.now()}`; const sessionId = `asst-address-followup-${Date.now()}`;
const first = await service.handleMessage({ const first = await service.handleMessage({
session_id: sessionId, session_id: sessionId,
user_message: "какие есть доки по свк с 2020 по 2025 год", user_message: "покажи документы по свк за 2020",
useMock: true useMock: true
} as any); } as any);
expect(first.ok).toBe(true); expect(first.ok).toBe(true);
@ -121,7 +118,7 @@ describe("assistant address follow-up carryover", () => {
expect(second.debug?.answer_grounding_check?.reasons).toContain("address_followup_context_applied"); expect(second.debug?.answer_grounding_check?.reasons).toContain("address_followup_context_applied");
expect(calls).toHaveLength(2); expect(calls).toHaveLength(2);
expect(calls[0].message).toBe("какие есть доки по свк с 2020 по 2025 год"); expect(calls[0].message.toLowerCase()).toContain("свк");
expect(calls[1].message).toBe("а за все время?"); expect(calls[1].message).toBe("а за все время?");
expect(calls[1].options?.followupContext?.previous_intent).toBe("list_documents_by_counterparty"); expect(calls[1].options?.followupContext?.previous_intent).toBe("list_documents_by_counterparty");
expect(calls[1].options?.followupContext?.previous_anchor_type).toBe("counterparty"); expect(calls[1].options?.followupContext?.previous_anchor_type).toBe("counterparty");

View File

@ -494,6 +494,118 @@ describe("assistant address llm pre-decompose candidate preference", () => {
expect(response.debug?.fallback_rule_hit).toBe("bank_operations_counterparty_year_rewrite"); expect(response.debug?.fallback_rule_hit).toBe("bank_operations_counterparty_year_rewrite");
}); });
it("rewrites shorthand bank/contract slang phrase to bank operations by contract", async () => {
const calls: Array<{ message: string }> = [];
const addressQueryService = {
tryHandle: vi.fn(async (message: string) => {
calls.push({ message });
return buildAddressLaneResult(message);
})
} as any;
const normalizerService = {
normalize: vi.fn(async () => ({
trace_id: "norm-predecompose-bank-contract-slang",
ok: true,
normalized: {
schema_version: "normalized_query_v2_0_2",
user_message_raw: "покажи банк опер по дог 15/24 пж",
message_in_scope: true,
scope_confidence: "medium",
contains_multiple_tasks: false,
fragments: []
},
raw_model_output: null,
validation: { passed: true, errors: [] },
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
latency_ms: 10,
prompt_version: "normalizer_v2_0_2",
schema_version: "v2_0_2",
request_count_for_case: 1
}))
} as any;
const sessions = new AssistantSessionStore();
const service = new AssistantService(
normalizerService,
sessions as any,
{} as any,
{ persistSession: vi.fn() } as any,
addressQueryService
);
const response = await service.handleMessage({
session_id: `asst-predecompose-bank-contract-slang-${Date.now()}`,
user_message: "покажи банк опер по дог 15/24 пж",
llmProvider: "local",
useMock: false
} as any);
expect(response.ok).toBe(true);
expect(response.reply_type).toBe("factual");
expect(calls).toHaveLength(1);
expect(calls[0].message).toBe("банковские операции по договору 15/24");
expect(response.debug?.llm_decomposition_reason).toBe("fallback_rule_applied_after_llm");
expect(response.debug?.fallback_rule_hit).toBe("bank_operations_contract_rewrite");
});
it("keeps loose all-time colloquial lookup in address lane without forcing rewrite", async () => {
const calls: Array<{ message: string }> = [];
const addressQueryService = {
tryHandle: vi.fn(async (message: string) => {
calls.push({ message });
return buildAddressLaneResult(message);
})
} as any;
const normalizerService = {
normalize: vi.fn(async () => ({
trace_id: "norm-predecompose-loose-all-time",
ok: true,
normalized: {
schema_version: "normalized_query_v2_0_2",
user_message_raw: "по свк за весь период че есть",
message_in_scope: true,
scope_confidence: "medium",
contains_multiple_tasks: false,
fragments: []
},
raw_model_output: null,
validation: { passed: true, errors: [] },
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
latency_ms: 10,
prompt_version: "normalizer_v2_0_2",
schema_version: "v2_0_2",
request_count_for_case: 1
}))
} as any;
const sessions = new AssistantSessionStore();
const service = new AssistantService(
normalizerService,
sessions as any,
{} as any,
{ persistSession: vi.fn() } as any,
addressQueryService
);
const response = await service.handleMessage({
session_id: `asst-predecompose-loose-all-time-${Date.now()}`,
user_message: "по свк за весь период че есть",
llmProvider: "local",
useMock: false
} as any);
expect(response.ok).toBe(true);
expect(response.reply_type).toBe("factual");
expect(calls).toHaveLength(1);
expect(calls[0].message).toBe("по свк за весь период че есть");
expect(response.debug?.llm_decomposition_applied).toBe(false);
expect(response.debug?.llm_decomposition_reason).toBe("not_address_like");
expect(response.debug?.fallback_rule_hit).toBeNull();
expect(response.debug?.tool_gate_decision).toBe("run_address_lane");
});
it("normalizes short ordinal year like '20й' in noisy docs phrasing", async () => { it("normalizes short ordinal year like '20й' in noisy docs phrasing", async () => {
const calls: Array<{ message: string }> = []; const calls: Array<{ message: string }> = [];
const addressQueryService = { const addressQueryService = {

View File

@ -0,0 +1,125 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { OpenAIResponsesClient } from "../src/services/openaiResponsesClient";
describe("openai local responses fallback", () => {
const originalFetch = global.fetch;
afterEach(() => {
vi.restoreAllMocks();
global.fetch = originalFetch;
});
it("falls back to /chat/completions when /responses payload is parseable JSON but has no output_text", async () => {
const fetchMock = vi
.fn()
.mockResolvedValueOnce(
new Response(JSON.stringify({ id: "resp-1", output: [], usage: { prompt_tokens: 4, completion_tokens: 3 } }), {
status: 200,
headers: { "content-type": "application/json" }
})
)
.mockResolvedValueOnce(
new Response(
JSON.stringify({
id: "chat-1",
choices: [{ message: { content: "{\"schema_version\":\"normalized_query_v2_0_2\"}" } }],
usage: { prompt_tokens: 7, completion_tokens: 5, total_tokens: 12 }
}),
{
status: 200,
headers: { "content-type": "application/json" }
}
)
);
global.fetch = fetchMock as unknown as typeof fetch;
const client = new OpenAIResponsesClient();
const response = await client.normalize(
{
llmProvider: "local",
apiKey: "",
model: "qwen2.5-14b-instruct-1m",
baseUrl: "http://127.0.0.1:1234",
temperature: 0
},
{
systemPrompt: "system",
developerPrompt: "developer",
domainPrompt: "domain",
userQuestion: "question",
schemaVersion: "v2_0_2"
}
);
expect(response.outputText).toContain("\"schema_version\":\"normalized_query_v2_0_2\"");
expect(response.usage.total_tokens).toBe(12);
expect(fetchMock).toHaveBeenCalledTimes(2);
expect(String(fetchMock.mock.calls[0]?.[0] ?? "")).toContain("/responses");
expect(String(fetchMock.mock.calls[1]?.[0] ?? "")).toContain("/chat/completions");
});
it("retries alternative local base when endpoint mismatch payload is returned for chat completions", async () => {
const fetchMock = vi
.fn()
.mockResolvedValueOnce(
new Response(JSON.stringify({ error: { message: "Unexpected endpoint or method. (POST /responses)" } }), {
status: 404,
headers: { "content-type": "application/json" }
})
)
.mockResolvedValueOnce(
new Response(JSON.stringify({ error: { message: "Unexpected endpoint or method. (POST /responses)" } }), {
status: 404,
headers: { "content-type": "application/json" }
})
)
.mockResolvedValueOnce(
new Response(JSON.stringify({ error: "Unexpected endpoint or method. (POST /chat/completions)" }), {
status: 200,
headers: { "content-type": "application/json" }
})
)
.mockResolvedValueOnce(
new Response(
JSON.stringify({
id: "chat-v1",
choices: [{ message: { content: "{\"schema_version\":\"normalized_query_v2_0_2\"}" } }],
usage: { prompt_tokens: 10, completion_tokens: 7, total_tokens: 17 }
}),
{
status: 200,
headers: { "content-type": "application/json" }
}
)
);
global.fetch = fetchMock as unknown as typeof fetch;
const client = new OpenAIResponsesClient();
const response = await client.normalize(
{
llmProvider: "local",
apiKey: "",
model: "qwen2.5-14b-instruct-1m",
baseUrl: "http://127.0.0.1:1234",
temperature: 0
},
{
systemPrompt: "system",
developerPrompt: "developer",
domainPrompt: "domain",
userQuestion: "question",
schemaVersion: "v2_0_2"
}
);
expect(response.outputText).toContain("\"schema_version\":\"normalized_query_v2_0_2\"");
expect(response.usage.total_tokens).toBe(17);
expect(fetchMock).toHaveBeenCalledTimes(4);
expect(String(fetchMock.mock.calls[0]?.[0] ?? "")).toBe("http://127.0.0.1:1234/responses");
expect(String(fetchMock.mock.calls[1]?.[0] ?? "")).toBe("http://127.0.0.1:1234/v1/responses");
expect(String(fetchMock.mock.calls[2]?.[0] ?? "")).toBe("http://127.0.0.1:1234/chat/completions");
expect(String(fetchMock.mock.calls[3]?.[0] ?? "")).toBe("http://127.0.0.1:1234/v1/chat/completions");
});
});

View File

@ -0,0 +1,25 @@
const { resolveAddressIntent } = require('../dist/services/addressIntentResolver.js');
const { extractAddressFilters } = require('../dist/services/addressFilterExtractor.js');
const { selectAddressRecipe, buildAddressRecipePlan } = require('../dist/services/addressRecipeCatalog.js');
const { executeAddressMcpQuery } = require('../dist/services/addressMcpClient.js');
(async () => {
const q = 'Покажи документы по договору 15/24';
const intentObj = resolveAddressIntent(q);
const filtersObj = extractAddressFilters(q, intentObj.intent);
const sel = selectAddressRecipe(intentObj.intent, filtersObj.extracted_filters);
console.log('intent_obj=', intentObj);
console.log('filters_obj=', filtersObj);
console.log('selection=', sel);
if (!sel.selected_recipe) return;
const plan = buildAddressRecipePlan(sel.selected_recipe, filtersObj.extracted_filters);
const mcp = await executeAddressMcpQuery({ query: plan.query, limit: plan.limit });
const rows = Array.isArray(mcp.raw_rows) ? mcp.raw_rows : [];
const contractNeedle = String(filtersObj.extracted_filters.contract || '').toLowerCase();
const byAnchor = rows.filter((r) => JSON.stringify(r).toLowerCase().includes(contractNeedle));
console.log('query_limit=', plan.limit);
console.log('raw_rows=', rows.length);
console.log('by_anchor=', byAnchor.length);
console.log('sample_registrators=', byAnchor.slice(0,10).map((r)=>String(r['Регистратор'] ?? r['Registrator'] ?? '')));
console.log('sample_rows=', byAnchor.slice(0,5));
})();

View File

@ -0,0 +1,308 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import statistics
import time
import urllib.error
import urllib.request
from collections import Counter
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Any
PROJECT_ROOT = Path(__file__).resolve().parents[1]
@dataclass
class QuestionCase:
id: str
text: str
expected_intent: str | None
expected_mode: str | None
session: str | None
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Run slang stress live-batch against /api/assistant/message and produce summary artifacts."
)
parser.add_argument(
"--questions-file",
required=True,
help="Path to JSON questions file (list of strings or objects with id/text/expected_intent/session).",
)
parser.add_argument(
"--backend-url",
default="http://127.0.0.1:8787/api/assistant/message",
help="Assistant endpoint URL.",
)
parser.add_argument("--prompt-version", default="address_query_runtime_v1")
parser.add_argument("--llm-provider", default="local")
parser.add_argument("--llm-model", default="qwen2.5-14b-instruct-1m")
parser.add_argument("--llm-base-url", default="http://127.0.0.1:1234")
parser.add_argument("--temperature", type=float, default=0.0)
parser.add_argument("--max-output-tokens", type=int, default=900)
parser.add_argument("--timeout-sec", type=int, default=120)
parser.add_argument("--run-id", default="")
parser.add_argument(
"--output-root",
default=str(PROJECT_ROOT / "docs" / "ADDRESS" / "runs"),
help="Root directory where run folder will be created.",
)
return parser.parse_args()
def now_stamp() -> str:
return datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
def load_cases(path: Path) -> list[QuestionCase]:
raw = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(raw, list):
raise ValueError("questions-file must contain JSON array")
cases: list[QuestionCase] = []
for idx, item in enumerate(raw, start=1):
if isinstance(item, str):
text = item.strip()
if not text:
continue
cases.append(
QuestionCase(
id=f"Q{idx:03d}",
text=text,
expected_intent=None,
expected_mode="address_query",
session=None,
)
)
continue
if not isinstance(item, dict):
raise ValueError(f"questions-file element #{idx} must be string or object")
text = str(item.get("text", "")).strip()
if not text:
continue
case_id = str(item.get("id", f"Q{idx:03d}")).strip() or f"Q{idx:03d}"
expected_intent = item.get("expected_intent")
expected_mode = item.get("expected_mode", "address_query")
session = item.get("session")
cases.append(
QuestionCase(
id=case_id,
text=text,
expected_intent=str(expected_intent).strip() if expected_intent else None,
expected_mode=str(expected_mode).strip() if expected_mode else None,
session=str(session).strip() if session else None,
)
)
if not cases:
raise ValueError("questions-file has no non-empty cases")
return cases
def post_json(url: str, payload: dict[str, Any], timeout_sec: int) -> tuple[int, dict[str, Any]]:
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"}, method="POST")
try:
with urllib.request.urlopen(req, timeout=timeout_sec) as response:
status = int(response.getcode())
body = json.loads(response.read().decode("utf-8"))
return status, body
except urllib.error.HTTPError as error:
status = int(error.code)
raw = error.read().decode("utf-8", errors="replace")
try:
return status, json.loads(raw)
except json.JSONDecodeError:
return status, {"ok": False, "error": {"code": "HTTP_ERROR", "message": raw}}
def main() -> None:
args = parse_args()
questions_path = Path(args.questions_file).resolve()
output_root = Path(args.output_root).resolve()
cases = load_cases(questions_path)
run_id = args.run_id.strip() or f"{datetime.now().date().isoformat()}_Address_Slang_Live_Stress_{now_stamp()}"
run_dir = output_root / run_id
run_dir.mkdir(parents=True, exist_ok=True)
session_map: dict[str, str] = {}
rows: list[dict[str, Any]] = []
elapsed_values: list[int] = []
for index, case in enumerate(cases, start=1):
if case.session:
session_id = session_map.get(case.session)
if not session_id:
session_id = f"asst-{run_id}-{case.session}"
session_map[case.session] = session_id
else:
session_id = f"asst-{run_id}-{case.id.lower()}"
payload = {
"session_id": session_id,
"user_message": case.text,
"mode": "assistant",
"promptVersion": args.prompt_version,
"llmProvider": args.llm_provider,
"model": args.llm_model,
"baseUrl": args.llm_base_url,
"temperature": args.temperature,
"maxOutputTokens": args.max_output_tokens,
"useMock": False,
}
started = time.perf_counter()
status_code, body = post_json(args.backend_url, payload, args.timeout_sec)
elapsed_ms = int((time.perf_counter() - started) * 1000)
elapsed_values.append(elapsed_ms)
ok_flag = bool(body.get("ok")) if isinstance(body, dict) else False
debug = {}
if isinstance(body, dict):
debug = body.get("debug") or body.get("conversation_item", {}).get("debug") or {}
if not isinstance(debug, dict):
debug = {}
actual_intent = debug.get("detected_intent")
actual_mode = debug.get("detected_mode")
reply_type = body.get("reply_type") if isinstance(body, dict) else None
trace_id = debug.get("trace_id") or body.get("trace_id")
intent_match = case.expected_intent is None or actual_intent == case.expected_intent
mode_match = case.expected_mode is None or actual_mode == case.expected_mode
semantic_pass = bool(intent_match and mode_match and status_code == 200 and ok_flag)
row = {
"index": index,
"id": case.id,
"question": case.text,
"session": case.session,
"session_id": session_id,
"status_code": status_code,
"ok": ok_flag,
"elapsed_ms": elapsed_ms,
"reply_type": reply_type,
"trace_id": trace_id,
"assistant_reply": body.get("assistant_reply") if isinstance(body, dict) else None,
"expected_intent": case.expected_intent,
"actual_intent": actual_intent,
"intent_match": intent_match,
"expected_mode": case.expected_mode,
"actual_mode": actual_mode,
"mode_match": mode_match,
"semantic_pass": semantic_pass,
"mcp_call_status": debug.get("mcp_call_status"),
"limited_reason_category": debug.get("limited_reason_category"),
"llm_decomposition_applied": debug.get("llm_decomposition_applied"),
"llm_decomposition_reason": debug.get("llm_decomposition_reason"),
"fallback_rule_hit": debug.get("fallback_rule_hit"),
"error_code": body.get("error", {}).get("code") if isinstance(body, dict) and isinstance(body.get("error"), dict) else None,
"error_message": body.get("error", {}).get("message") if isinstance(body, dict) and isinstance(body.get("error"), dict) else None,
}
rows.append(row)
print(
f"[{index:03d}/{len(cases):03d}] {case.id} | status={status_code} reply={reply_type} "
f"intent={actual_intent} mode={actual_mode} pass={semantic_pass}"
)
reply_counter = Counter(str(r.get("reply_type")) for r in rows)
intent_counter = Counter(str(r.get("actual_intent")) for r in rows)
mode_counter = Counter(str(r.get("actual_mode")) for r in rows)
mcp_counter = Counter(str(r.get("mcp_call_status")) for r in rows)
limited_counter = Counter(str(r.get("limited_reason_category")) for r in rows if r.get("limited_reason_category") is not None)
semantic_pass_count = sum(1 for r in rows if r.get("semantic_pass"))
factual_count = sum(1 for r in rows if r.get("reply_type") == "factual")
ok_200_count = sum(1 for r in rows if r.get("status_code") == 200 and r.get("ok"))
llm_decomposition_applied_count = sum(1 for r in rows if r.get("llm_decomposition_applied") is True)
avg_elapsed = round(statistics.mean(elapsed_values), 1) if elapsed_values else 0.0
summary = {
"run_id": run_id,
"generated_at": datetime.now().isoformat(timespec="seconds"),
"source_questions_file": str(questions_path),
"backend_url": args.backend_url,
"llm_provider": args.llm_provider,
"llm_model": args.llm_model,
"llm_base_url": args.llm_base_url,
"totals": {
"questions_total": len(rows),
"ok_200_count": ok_200_count,
"semantic_pass_count": semantic_pass_count,
"semantic_pass_rate": round(semantic_pass_count / len(rows), 4) if rows else 0.0,
"factual_count": factual_count,
"partial_coverage_count": sum(1 for r in rows if r.get("reply_type") == "partial_coverage"),
"clarification_required_count": sum(1 for r in rows if r.get("reply_type") == "clarification_required"),
"http_error_count": sum(1 for r in rows if r.get("status_code") != 200),
"llm_decomposition_applied_count": llm_decomposition_applied_count,
"avg_elapsed_ms": avg_elapsed,
},
"distributions": {
"reply_type": dict(reply_counter),
"actual_intent": dict(intent_counter),
"actual_mode": dict(mode_counter),
"mcp_call_status": dict(mcp_counter),
"limited_reason_category": dict(limited_counter),
},
}
failures = [
r
for r in rows
if not r.get("semantic_pass")
or r.get("status_code") != 200
or r.get("reply_type") in {"clarification_required", "backend_error"}
]
(run_dir / "run_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
(run_dir / "full_live_results.json").write_text(
json.dumps({"run_id": run_id, "generated_at": summary["generated_at"], "summary": summary, "rows": rows}, ensure_ascii=False, indent=2)
+ "\n",
encoding="utf-8",
)
(run_dir / "failures_only.json").write_text(json.dumps(failures, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
lines = [
f"# {run_id}",
"",
f"Generated at: {summary['generated_at']}",
f"Questions file: {questions_path}",
f"Backend URL: {args.backend_url}",
f"LLM: {args.llm_provider} / {args.llm_model} @ {args.llm_base_url}",
"",
"## Totals",
f"- questions_total: {summary['totals']['questions_total']}",
f"- ok_200_count: {summary['totals']['ok_200_count']}",
f"- semantic_pass_count: {summary['totals']['semantic_pass_count']}",
f"- semantic_pass_rate: {summary['totals']['semantic_pass_rate']}",
f"- factual_count: {summary['totals']['factual_count']}",
f"- partial_coverage_count: {summary['totals']['partial_coverage_count']}",
f"- clarification_required_count: {summary['totals']['clarification_required_count']}",
f"- http_error_count: {summary['totals']['http_error_count']}",
f"- llm_decomposition_applied_count: {summary['totals']['llm_decomposition_applied_count']}",
f"- avg_elapsed_ms: {summary['totals']['avg_elapsed_ms']}",
"",
"## Files",
"- run_summary.json",
"- full_live_results.json",
"- failures_only.json",
]
(run_dir / "README.md").write_text("\n".join(lines) + "\n", encoding="utf-8")
print(f"\nRun directory: {run_dir}")
print(f"Semantic pass: {semantic_pass_count}/{len(rows)}")
if __name__ == "__main__":
main()