Векторный поиск как инструмент дедупликации лидов в реальном времени
- Sarov+

- 8 hours ago
- 4 min read
Дедупликация данных — давняя головная боль CRM-команд. Exact match пропускает опечатки, fuzzy match требует сложной настройки, а ручной ввод неизбежно порождает «грязные» записи. В этой статье мы расскажем о нашем эксперименте с векторными эмбеддингами и Microsoft Drasi для обнаружения дубликатов лидов в реальном времени — подходе, который неожиданно оказался гораздо эффективнее традиционных методов.
А узнать больше можно в нашем видео:
Предыстория: RAG-система и первый опыт с векторами
На одной из предыдущих академий мы разбирали RAG-системы и рассказывали, как расширяли контекстное окно кастомного Copilot'а данными из CRM. Напомним архитектуру: Dataverse с 300 лидами, Drasi как orchestration layer на виртуальной машине, который переводил записи в эмбеддинги и загружал их в Qdrant. Запрос строился по ключевому слову — Qdrant возвращал похожие записи.
Уже тогда мы увидели очевидные преимущества: стандартный Copilot находил 5 имён из 300 лидов, наш агент — 13+ с группировкой. Но была одна проблема: «Олег Вакарчук» и «Вакарчук» давали разные векторы. Написать просто «Вакарчук» и найти запись не получалось — для этого по-прежнему нужен был обычный SQL-запрос с name contains.
Именно это наблюдение стало отправной точкой для нового эксперимента.
Как работает традиционная дедупликация — и в чём её пределы
В CRM-системах дедупликация строится на двух подходах.
Exact match — самый простой: если email или другое поле совпадает точно, запись помечается как дубликат. Настраивается правилами прямо в CRM. Но стоит допустить опечатку или переставить имя и фамилию — и система ничего не найдёт.
Fuzzy match — более гибкий вариант: позволяет искать по паттернам и опечаткам. Требует дополнительной настройки и формализации правил, но всё равно опирается на сравнение отдельных полей, а не на целостное представление о записи.
Ни один из этих методов не справляется с ситуацией, когда одновременно неправильно написаны несколько полей — имя, фамилия, email, почтовый индекс.
Идея: сравнивать весь лид как единый вектор
Наш подход принципиально иной. Мы загружаем весь лид в вектор — не разбивая на чанки, а как одну длинную векторную сущность — в фиксированном порядке полей: FirstName, LastName, CompanyName и так далее. Этот порядок критически важен: он должен совпадать между базой и новым лидом.
Drasi следит за изменениями в Dataverse и при каждом создании или обновлении записи прогоняет её через embedding-модель и обновляет вектор в Qdrant. Параллельно работает Power Automate Flow: при создании нового лида он формирует вектор в той же последовательности полей и запрашивает Qdrant — «найди похожие векторы». Если схожесть превышает заданный порог (в нашем случае — 0,80), на почту приходит уведомление о возможном дубликате.
Ключевая идея: мы не ищем совпадение по конкретному полю и не анализируем смысл слов — мы сравниваем два «слепка» лида в семантическом пространстве.
Результаты эксперимента
Честно говоря, мы были шокированы. После предыдущих опытов, которые поставили под сомнение практическую ценность векторного поиска для дедупликации, результаты оказались обнадёживающими.
Сценарий 1: множественные опечатки в разных полях. В базе была запись Evelyn Robinson. Мы создали новый лид с именем «Eveln» (без буквы), другой фамилией, изменённым почтовым индексом и ошибкой в email. С точки зрения SQL — это абсолютно разные записи. Вектор нашёл совпадение со схожестью 0,97.
Сценарий 2: одинаковые поля, разные имя и фамилия. James Harris и John Alves с идентичными адресами, email и другими восемью полями. Несмотря на то что ни имена, ни фамилии не совпадают, вектор выдал схожесть 0,95.
Важное замечание: обычные фамилии и названия городов (Houston, Robinson) не несут семантического смысла сами по себе. Но суммарное сравнение двух векторных сущностей всё равно показывает устойчивые и многообещающие результаты.
Ограничения и открытые вопросы
Эксперимент был небольшим, и мы честно говорим о том, что ещё предстоит проверить.
Масштаб данных. Если в базе сотни тысяч лидов из одного города с похожими именами, порог 0,80 или 0,90 может давать слишком много ложных срабатываний. Это нужно тестировать на реальных данных.
Выбор полей. Когда у лида много связанных сущностей и таблиц, надо очень взвешенно решать, какой массив данных загружать в вектор. Рекомендуем начать с «грязных» дублей из реального проекта и вручную прогнать их через вектор — посмотреть, насколько они окажутся близки.
Latency. Drasi отрабатывает практически мгновенно, но Power Automate Flow в демо-режиме может занимать от одной до трёх минут. Команда Drasi предлагает перенести логику уведомлений на уровень orchestration layer — это ускорит работу и уберёт зависимость от Flow.
Варианты написания адресов, длинные строки. Это тоже не тестировалось и требует отдельного исследования.
Где это будет работать — и где нет
Векторный поиск не заменяет существующие инструменты дедупликации — он их дополняет. Для крупных компаний это fine-tuning поверх уже выстроенной инфраструктуры.
Но мы видим очевидную ценность для небольших компаний и проектов с ручным вводом данных: там, где нет бюджета на разработку сложных правил дедупликации, вектор может прийти в Teams или на почту и просто написать: «Слушай, тут есть похожая запись — посмотри».
Заключение
Загнав данные лида в вектор как единую сущность, мы получаем семантическое пространство, в котором работает то, что не работает в обычном SQL: сравнение двух записей в целом, а не по отдельным полям.
Мы уже знаем, каким клиентам это предложить и где оно будет полезно. Следующий шаг — тестирование на реальных данных: если у вас есть грязный массив с известными дублями, мы готовы помочь прогнать их через вектор и посмотреть на результат. Пространство для экспериментов открыто.



Comments