fix(автоподбор): канал В получает чистый стоп-лист — дубли-филиалы схлопнуты

Стоп-лист известных для ИИ канала В дедуплицировался только в проверке
видели/не видели, а в промпт уходил с повторами (Корунд ×27, КрасЛомбард ×19).
Теперь чистим и сам список по ключу имени — ИИ видит каждое имя один раз:
короче, дешевле по токенам, точнее. TDD, 137/137 unit зелёные.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-07-01 05:27:45 +03:00
parent f9f4743392
commit 6e970d7231
2 changed files with 24 additions and 1 deletions
@@ -44,7 +44,11 @@ TXT;
if ($name === '') {
continue;
}
$seen[$this->key($name)] = true;
$k = $this->key($name);
if (isset($seen[$k])) {
continue; // чистим стоп-лист от дублей-филиалов: «Корунд» ×27 → один
}
$seen[$k] = true;
$stop[] = $name;
}
@@ -78,6 +78,25 @@ it('пустой ответ прохода не падает и не добав
expect($out)->toHaveCount(1)->and($out[0]['name'])->toBe('Cashmotor');
});
it('чистый стоп-лист для ИИ: дубли-филиалы схлопнуты — каждое имя один раз', function () {
// Канал А отдал филиалы: «Корунд» ×3 (в т.ч. другой регистр), «КрасЛомбард» ×2.
// В промпт ИИ должно уйти по одному — иначе «- Корунд» повторится 27 раз (реальный случай).
$fake = new FakeResearcher(['[]']);
$search = new ChannelBSearch($fake, new ResearcherParser);
$search->harvest(
profile: 'займы под залог авто',
region: 'Красноярский край',
clientSite: 'lkomega.ru',
known: ['Корунд', 'Корунд', 'корунд', 'КрасЛомбард', 'КрасЛомбард'],
passes: 1,
);
$prompt = $fake->userPrompts[0];
expect(substr_count($prompt, '- Корунд'))->toBe(1)
->and(substr_count($prompt, '- КрасЛомбард'))->toBe(1);
});
it('системный промт просит ТОЛЬКО названия (§11.3)', function () {
expect(ChannelBSearch::SYSTEM_PROMPT)->toContain('только НАЗВАНИЯ')
->and(ChannelBSearch::SYSTEM_PROMPT)->toContain('строго JSON');