diff --git a/app/app/Services/Bot/BotAnswerService.php b/app/app/Services/Bot/BotAnswerService.php index 511e1307..598893c1 100644 --- a/app/app/Services/Bot/BotAnswerService.php +++ b/app/app/Services/Bot/BotAnswerService.php @@ -75,6 +75,12 @@ class BotAnswerService return new BotAnswer(self::ESCALATE_TEXT, escalate: true); } + // LLM признался, что в фрагментах ответа нет (слабое совпадение поиска по общим + // словам) → это «не знаю»: честная эскалация, никаких кнопок «Показать». + if (preg_match('/в (инструкции|фрагментах)( этого)? (ответа )?нет/ui', $text) === 1) { + return new BotAnswer(self::UNKNOWN_TEXT, escalate: true); + } + $tour = $chunks[0]->tour; if ($tour !== null && (bool) config('services.jivo_bot.tours_enabled')) { $text .= "\n\n👉 Показать на портале: ".rtrim((string) config('app.url'), '/').'/?tour='.$tour; diff --git a/app/resources/help/konkurentnoe-pole.md b/app/resources/help/konkurentnoe-pole.md index 1df947d1..e3f5d03a 100644 --- a/app/resources/help/konkurentnoe-pole.md +++ b/app/resources/help/konkurentnoe-pole.md @@ -1,7 +1,7 @@ --- title: Конкурентное поле — автоподбор конкурентов tour: konkurentnoe-pole -topics: конкурентное поле, автоподбор, найти конкурентов, собрать конкурентов, собрать источники, изучение конкурента, откуда лиды, радар, добавить конкурента вручную, руками, самому, самостоятельно, без ИИ, бесплатно +topics: конкурентное поле, автоподбор, найти конкурентов, собрать конкурентов, собрать источники, изучение конкурента, откуда лиды, радар, добавить конкурента вручную, руками, самому, самостоятельно, без ИИ, бесплатно, объединить дубли, дубликаты, почистить поле, одинаковые конкуренты --- «Конкурентное поле» — раздел, где искусственный интеллект находит ваших конкурентов @@ -30,5 +30,12 @@ topics: конкурентное поле, автоподбор, найти ко вручную на его странице — «добавьте источник вручную». Платный ИИ-сбор нужен только когда хотите, чтобы система сама нашла конкурентов или вскрыла их сайты и телефоны. +«Найти и объединить дубли» (кнопка с метёлкой 🧹 на экране поля) — уборка одинаковых +карточек. Один и тот же конкурент может попасть в поле дважды: например, вы добавили его +руками, а потом его же нашёл автоподбор. Система находит такие пары-двойники и показывает +их вам группами; вы смотрите и подтверждаете — подтверждённые склеиваются в одну карточку, +ничего не теряется. Без вашего подтверждения ничего не объединяется и не удаляется. +Это бесплатно. На кнопке виден счётчик — сколько групп дублей найдено. + Из найденного источника в один клик создаётся проект — дальше он работает как обычный проект и приносит заявки в раздел «Сделки». diff --git a/app/tests/Feature/Bot/BotAnswerServiceTest.php b/app/tests/Feature/Bot/BotAnswerServiceTest.php index 29182cfe..210a9296 100644 --- a/app/tests/Feature/Bot/BotAnswerServiceTest.php +++ b/app/tests/Feature/Bot/BotAnswerServiceTest.php @@ -82,6 +82,24 @@ it('вопрос-продолжение: история разговора сп }); }); +it('LLM ответил «в инструкции этого нет» → честная эскалация БЕЗ кнопки экскурсии', function () { + // Живой урок 12.07.2026: «а что такое объединить дубли?» → слабое совпадение поиска + // («что», «такое») → LLM честно сказал «В инструкции этого нет», а мы приляпали + // кнопку «Показать на портале». Незнание = эскалация, без кнопок. + config()->set('services.jivo_bot.tours_enabled', true); + Http::fake([ + 'llm.api.cloud.yandex.net/*' => Http::response([ + 'result' => ['alternatives' => [['message' => ['role' => 'assistant', 'text' => 'В инструкции этого нет.']]]], + ]), + ]); + + $answer = app(BotAnswerService::class)->answer('что такое объединить дубли?'); + + expect($answer->escalate)->toBeTrue() + ->and($answer->text)->not->toContain('Показать на портале') + ->and($answer->text)->toContain('живому специалисту'); +}); + it('просьба позвать человека → эскалация', function () { Http::fake();