6a3a9e5d3a
1. Экскурсии «Показать на портале» включены обратно. Прежнее правило давало ссылку, если совпало ХОТЯ БЫ ОДНО слово, — бот вёл на уведомления в ответ на «первое сообщение подряд». Теперь два условия: реплика должна быть ВОПРОСОМ и слово из него должно попасть в заголовок статьи или её синонимы. Плюс экскурсия предлагается ТОЛЬКО клиенту из кабинета: гостю с лендинга ссылка внутрь кабинета бесполезна. Ссылки в окошке стали кликабельными (без innerHTML — текст ответа от модели). 2. На «hello» бот отвечал «в моей инструкции нет ответа» и просил телефон: заготовка знала только русские приветствия. Приветствие — не вопрос, эскалировать его глупо. 3. «Хочу, чтобы менеджер не видел биллинг» бот принимал за просьбу позвать НАШЕГО менеджера и уводил к специалисту, хотя ответ есть в статье, — и через реплику сам же отвечал, отчего выглядел противоречащим себе. Правило про доступ дополнено. Статья «Команда и доступ» дописана: сколько человек можно пустить, почему нельзя скрыть раздел, баланс общий на всех. Тесты 161/161. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65 lines
3.7 KiB
PHP
65 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\KnowledgeChunk;
|
|
use App\Services\Bot\KnowledgeSearch;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
/**
|
|
* Экскурсия «Показать на портале» цеплялась, если у вопроса и статьи совпало ХОТЯ БЫ ОДНО
|
|
* слово, — поэтому на болтовню («первое сообщение подряд») бот предлагал экскурсию по
|
|
* уведомлениям, а на вопрос про поддержку уводил в другой раздел (живая проверка 13.07.2026,
|
|
* до этого два десятка таких ссылок в прогоне 12.07).
|
|
*
|
|
* Правило: экскурсия только тогда, когда реплика — ВОПРОС (есть «?» или вопросительное
|
|
* слово) И слово из него попало в заголовок статьи или её синонимы. «Показать на портале»
|
|
* имеет смысл, только если человек о чём-то спрашивает.
|
|
*/
|
|
beforeEach(function () {
|
|
KnowledgeChunk::create([
|
|
'source_path' => 'help/create.md', 'title' => 'Как создать проект', 'tour' => 'create-project',
|
|
'topics' => 'создать проект, новый проект, запустить сбор', 'chunk_index' => 0,
|
|
'content' => 'Проект создаётся в разделе «Проекты», кнопка «Создать».',
|
|
]);
|
|
KnowledgeChunk::create([
|
|
'source_path' => 'help/notify.md', 'title' => 'Уведомления портала', 'tour' => 'notifications',
|
|
'topics' => 'уведомления, сообщение, письмо, колокольчик', 'chunk_index' => 0,
|
|
'content' => 'Уведомления приходят в колокольчик и на почту.',
|
|
]);
|
|
});
|
|
|
|
it('на болтовню без сути экскурсию не предлагает', function () {
|
|
$search = app(KnowledgeSearch::class);
|
|
$notify = KnowledgeChunk::where('tour', 'notifications')->firstOrFail();
|
|
|
|
foreach (['привет', 'ага', 'слушаю', 'спасибо'] as $chatter) {
|
|
expect($search->isOnTopic($notify, $chatter))->toBeFalse();
|
|
}
|
|
});
|
|
|
|
it('реплика не-вопрос экскурсию не получает, даже если слово совпало', function () {
|
|
$search = app(KnowledgeSearch::class);
|
|
$notify = KnowledgeChunk::where('tour', 'notifications')->firstOrFail();
|
|
|
|
// «сообщение» есть в ключевых словах статьи про уведомления — но человек ни о чём
|
|
// не спрашивает. Именно так бот и водил на экскурсию по уведомлениям (13.07.2026).
|
|
expect($search->isOnTopic($notify, 'первое сообщение подряд'))->toBeFalse();
|
|
});
|
|
|
|
it('вопрос по теме статьи экскурсию получает', function () {
|
|
$search = app(KnowledgeSearch::class);
|
|
$create = KnowledgeChunk::where('tour', 'create-project')->firstOrFail();
|
|
|
|
expect($search->isOnTopic($create, 'как создать проект?'))->toBeTrue();
|
|
});
|
|
|
|
it('совпадение по двум ключевым словам тоже считается', function () {
|
|
$search = app(KnowledgeSearch::class);
|
|
$notify = KnowledgeChunk::where('tour', 'notifications')->firstOrFail();
|
|
|
|
expect($search->isOnTopic($notify, 'куда приходит письмо и колокольчик?'))->toBeTrue();
|
|
});
|