From 6e970d723194cdcb8b7aef6706afa13b94792c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 1 Jul 2026 05:27:45 +0300 Subject: [PATCH] =?UTF-8?q?fix(=D0=B0=D0=B2=D1=82=D0=BE=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B1=D0=BE=D1=80):=20=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=20=D0=92?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D0=B5=D1=82=20=D1=87?= =?UTF-8?q?=D0=B8=D1=81=D1=82=D1=8B=D0=B9=20=D1=81=D1=82=D0=BE=D0=BF-?= =?UTF-8?q?=D0=BB=D0=B8=D1=81=D1=82=20=E2=80=94=20=D0=B4=D1=83=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8-=D1=84=D0=B8=D0=BB=D0=B8=D0=B0=D0=BB=D1=8B=20=D1=81?= =?UTF-8?q?=D1=85=D0=BB=D0=BE=D0=BF=D0=BD=D1=83=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Стоп-лист известных для ИИ канала В дедуплицировался только в проверке видели/не видели, а в промпт уходил с повторами (Корунд ×27, КрасЛомбард ×19). Теперь чистим и сам список по ключу имени — ИИ видит каждое имя один раз: короче, дешевле по токенам, точнее. TDD, 137/137 unit зелёные. Co-Authored-By: Claude Opus 4.8 --- .../Agent/ChannelB/ChannelBSearch.php | 6 +++++- .../ChannelB/ChannelBSearchTest.php | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/app/Services/Autopodbor/Agent/ChannelB/ChannelBSearch.php b/app/app/Services/Autopodbor/Agent/ChannelB/ChannelBSearch.php index 3014c863..32c5ce8d 100644 --- a/app/app/Services/Autopodbor/Agent/ChannelB/ChannelBSearch.php +++ b/app/app/Services/Autopodbor/Agent/ChannelB/ChannelBSearch.php @@ -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; } diff --git a/app/tests/Unit/Autopodbor/ChannelB/ChannelBSearchTest.php b/app/tests/Unit/Autopodbor/ChannelB/ChannelBSearchTest.php index 676e1647..f52e5929 100644 --- a/app/tests/Unit/Autopodbor/ChannelB/ChannelBSearchTest.php +++ b/app/tests/Unit/Autopodbor/ChannelB/ChannelBSearchTest.php @@ -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');