feat(jivo-bot): всеобъемлющая клиентская инструкция — 15 статей + защита секретов
Разведка портала 5 агентами (экраны, биллинг/настройки, Конкурентное поле, все подсказки (?), внутренние правила) → база знаний бота выросла 4 → 15 статей: начало работы (что такое заявка, подарок 1000₽), проекты (лимиты/регионы/дни, правило 18:00 МСК), тарифы (7 ступеней, списание по факту), пополнение (100₽, карта/счёт/акт), баланс и пауза (разморозка «всё-или-ничего»), сделки и канбан (5 статусов, экспорт), Конкурентное поле (сбор 300₽/изучение 50₽, очередь, ручной режим, дубли, метки номеров), смена источника, настройки и 2FA, уведомления, импорт CSV, API/webhook, мобильная версия, дашборд, поддержка. Защита коммерческой тайны (проверено агентом-цензором — 15/15 статей чисто): ни слова про поставщика/каналы/закупку и про то, что заявка может уйти не только одному клиенту; вопросы об эксклюзивности и перепродаже — жёсткая стоп-тема (бот не отвечает НИ В КАКУЮ сторону, зовёт живого специалиста), внутренние движки не упоминаются, ложных обещаний (авто-возврат, «Команда») нет. Стоп-темы разделены: HARD (деньги/скидки/юр/эксклюзив — всегда) и PERSONAL («мой баланс») с исключением HOWTO — «перенести мои заявки из амоцрм» больше не уходит к человеку, бот рассказывает про импорт. TDD: 40/40 зелёные. Живая проверка 20+ вопросов на стенде. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -100,6 +100,42 @@ it('LLM ответил «в инструкции этого нет» → чес
|
||||
->and($answer->text)->toContain('живому специалисту');
|
||||
});
|
||||
|
||||
it('вопрос про эксклюзивность заявок → эскалация без похода в LLM', function () {
|
||||
Http::fake();
|
||||
|
||||
$variants = [
|
||||
'а заявки эксклюзивные или как?',
|
||||
'вы эти лиды кому-то ещё продаёте?',
|
||||
'эти заявки только мои или вы их ещё кому-то отдаёте?',
|
||||
'заявки достаются только мне?',
|
||||
'вы одну заявку нескольким продаёте?',
|
||||
];
|
||||
foreach ($variants as $q) {
|
||||
expect(app(BotAnswerService::class)->answer($q)->escalate)->toBeTrue();
|
||||
}
|
||||
Http::assertNothingSent();
|
||||
});
|
||||
|
||||
it('«перенести МОИ заявки из другой CRM» → это про функцию импорта, а не личные данные', function () {
|
||||
// Живой урок 12.07.2026: стоп-тема ловила «мои заявки» и уводила к человеку вопрос
|
||||
// про импорт. Слова «перенести/импорт» — признак вопроса «как это делается».
|
||||
KnowledgeChunk::create([
|
||||
'source_path' => 'help/i.md', 'title' => 'Импорт своих заявок из CSV', 'tour' => null,
|
||||
'topics' => 'импорт, перенести заявки, амоцрм', 'chunk_index' => 0,
|
||||
'content' => 'Базу заявок из другой системы можно перенести: раздел «Импорт данных», файл CSV.',
|
||||
]);
|
||||
Http::fake([
|
||||
'llm.api.cloud.yandex.net/*' => Http::response([
|
||||
'result' => ['alternatives' => [['message' => ['role' => 'assistant', 'text' => 'Да, через «Импорт данных» — файл CSV.']]]],
|
||||
]),
|
||||
]);
|
||||
|
||||
$answer = app(BotAnswerService::class)->answer('можно перенести мои заявки из амоцрм?');
|
||||
|
||||
expect($answer->escalate)->toBeFalse()
|
||||
->and($answer->text)->toContain('Импорт данных');
|
||||
});
|
||||
|
||||
it('просьба позвать человека → эскалация', function () {
|
||||
Http::fake();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user