Статьи · Данные и ИИ

Похоже ≠ то же: идентичность против сходства

Почему «близко по смыслу» и «одно и то же» — принципиально разные вещи

~10 мин · identity vs similarity

Представьте, что вы ищете человека по имени «Алексей Иванов». Вам говорят: «Вот Алексей Петров — очень похоже!». Или: «Вот Иванов Алексей Николаевич — почти то же самое».

Для поиска друга на вечеринке — сойдёт. Для юридического документа — катастрофа.

В мире данных эта разница определяет, получит ли ИИ правильный ответ или красивую ошибку.

Два вопроса, которые звучат одинаково

Когда ИИ ищет нужную таблицу в хранилище данных, он фактически решает один из двух принципиально разных вопросов:

Вопрос сходства: на что это похоже? «Студент» и SIS_STUDENT — семантически близко. «Зачисление» и ENROLLMENT_DETAIL — тоже. Поиск по сходству найдёт оба варианта и вернёт самые близкие.

Вопрос идентичности: это то же самое? SIS_ID в одной таблице и STUDENT_NUMBER в другой — это один и тот же реальный объект (номер студенческого билета), просто записанный по-разному в разных системах.

Кажется, что это две формулировки одной задачи. На самом деле это разные задачи с разными методами решения и разными типами ошибок.

Как работает поиск по сходству

Современные системы поиска таблиц используют векторные представления (embeddings): имя таблицы, описание, примеры данных превращаются в вектор из сотен чисел. Вопрос пользователя тоже превращается в вектор. Чем ближе векторы — тем «похожее» таблица на вопрос.

Это мощный подход. Он улавливает семантику: «студент» и STUDENT оказываются близко в векторном пространстве, даже если это разные слова. «Зачисление» и ENROLL — тоже. Языковые модели научились понимать эти соответствия из миллиардов текстов.

Но у поиска по сходству есть два фундаментальных слабых места.

Слабое место первое: похожее ≠ нужное. Запрос «покажи бюджет кафедры» найдёт все таблицы, где есть слово BUDGET. Таблица DEPT_BUDGET_SUMMARY окажется близко. Но рядом окажется и GRANT_BUDGET_DETAIL, и PROJECT_BUDGET_ALLOCATION — они тоже о бюджете, но совсем другом. Поиск нашёл похожее. Но нужное ли?

Слабое место второе: одно и то же выглядит по-разному. OBJ_ID в таблице PERSONS_ACADEMIC — это идентификатор студента. Семантически OBJ_ID не похож ни на «студент», ни на STUDENT_ID. Вектор этого поля будет далеко от вопроса о студентах. Поиск его не найдёт. Но именно оно нужно.

Как работает поиск по идентичности

Альтернативный подход не спрашивает «похоже ли это?», а спрашивает «это то же самое?»

Идентичность устанавливается не через смысловую близость, а через структурное доказательство. Если в тысяче исторических SQL-запросов поле OBJ_ID таблицы PERSONS_ACADEMIC всегда появляется там, где другие запросы используют STUDENT_ID таблицы SIS_STUDENT, — это не совпадение. Это свидетельство, что оба поля обозначают одно и то же.

Такое свидетельство можно извлечь из реальных запросов. Каждый SQL-запрос — это документ, где аналитик неявно сказал: «эти таблицы связаны», «это поле означает то». Из тысяч таких документов складывается граф идентичности: не «похожи ли эти поля?», а «используются ли они как одно и то же?»

Это и есть разница между сходством и идентичностью: одно измеряет расстояние в пространстве смыслов, другое устанавливает тождество через использование.

Четыре случая, один принцип

Рассмотрим матрицу. У нас есть два поля: насколько похожи их имена и насколько они обозначают одно и то же.

Похожие имена Непохожие имена Одно и то же Разные вещи STUDENT_ID = STUDENT_ID оба метода находят OBJ_ID ↔ STUDENT_NUMBER сходство провалит, идентичность находит BUDGET_AMOUNT ≠ BUDGET_AMOUNT сходство путает, идентичность различит DEPT_CODE GRANT_REF оба не смешают
Критичны два угла: похожие, но разные (омонимы) и непохожие, но одинаковые (синонимы). Там сходство ошибается, а идентичность даёт ответ.

Похожи и одинаковы: STUDENT_ID в двух разных таблицах, где обе колонки действительно хранят номер студента. Поиск по сходству справляется. Поиск по идентичности подтверждает.

Похожи, но разные: BUDGET_AMOUNT в таблице финансов (утверждённый бюджет) и BUDGET_AMOUNT в таблице грантов (запрошенная сумма). Имена одинаковые — смысл разный. Поиск по сходству не разберёт. Поиск по идентичности увидит: в запросах они никогда не взаимозаменяемы.

Непохожи, но одинаковы: OBJ_ID и STUDENT_NUMBER — разные имена для одного объекта. Поиск по сходству провалится. Поиск по идентичности найдёт: в исторических запросах они появляются в JOIN-условиях вида OBJ_ID = STUDENT_NUMBER.

Непохожи и разные: DEPT_CODE и GRANT_REF — разные вещи, разные имена. Оба поиска правильно не смешают.

Критичные случаи — второй и третий. Именно там поиск по сходству ошибается системно. Именно там идентичность даёт другой ответ.

Что говорят числа

В эксперименте с реальным хранилищем данных детерминированный парсер SQL показал recall 0.96 — почти всегда находил нужные таблицы. Но F1 составил только 0.77: парсер добавлял лишние «таблицы», которые на самом деле были временными именами подзапросов (CTE-псевдонимы). Это ошибка идентичности: алгоритм не распознал, что dept_stats в запросе — не реальная таблица, а временное имя.

Векторный поиск с переранжированием дал recall 0.93 — чуть ниже, но без проблемы ложных псевдотаблиц. Зато уязвим к семантически непрозрачным именам (OBJ_ID, REC_NUM), где нет ничего, за что зацепиться векторно.

Оба метода ошибаются — но в разных местах. Это не случайность. Это следствие фундаментального различия между тем, что они измеряют.

Дубликаты кода: та же проблема в другом масштабе

Задача идентичности возникает не только в схемах баз данных.

В больших кодовых базах существуют клоны — фрагменты кода, скопированные с небольшими изменениями. Два метода сортировки могут быть «похожи» (оба работают с массивами, оба используют сравнение) — но не идентичны. А два метода могут быть идентичны по структуре (одинаковый алгоритм) при совершенно разных именах переменных.

Для обнаружения клонов исследователи используют структурные хэши: преобразуют код в абстрактное синтаксическое дерево, нормализуют имена переменных, вычисляют хэш. Два фрагмента с одинаковым хэшем — структурно идентичны, независимо от того, как называются переменные.

Это же можно применить к SQL: одинаковые подзапросы в разных местах кодовой базы — структурные дубликаты. Одинаковые паттерны JOIN — свидетельство семантической связи таблиц. Граф таких совпадений кодирует идентичность, которую сходство не уловит.

Почему это важно для конечных пользователей

Аналитик, который спрашивает «покажи зачисление студентов по факультетам», не думает о том, какой метод поиска использует система. Он просто хочет ответ.

Но от выбора метода зависит, получит ли он правильный ответ — или уверенно поданный неправильный.

Поиск по сходству может вернуть таблицу GRANT_ENROLLMENT вместо SIS_ENROLLMENT: оба слова «зачисление», оба близко в векторном пространстве. Система не предупредит об ошибке — она уверена. Аналитик получит данные, построит отчёт, примет решение. И только потом выяснится, что смотрел не туда.

Это не гипотетический сценарий. В корпоративных данных омонимия — норма, а не исключение. «Бюджет», «проект», «контракт» — каждое слово может означать разное в разных подсистемах одной организации.

Система, которая понимает разницу между сходством и идентичностью, ведёт себя иначе: она не угадывает по имени, а опирается на то, как таблица реально использовалась в тысячах реальных запросов. И если уверенности нет — говорит об этом, а не молча подставляет похожее.

Для конечного пользователя это разница между инструментом, которому можно доверять, и инструментом, который нужно постоянно перепроверять.

Откуда берётся путаница

Сходство и идентичность так часто смешивают потому, что в простых случаях они дают одинаковый ответ. Поле называется STUDENT_ID — и оно действительно про студентов. Здесь работает и поиск по сходству, и поиск по идентичности.

Разница проявляется только на сложных случаях: семантически непрозрачные имена, омонимия, синонимия через несколько поколений систем. Именно эти случаи определяют качество в реальных корпоративных данных.

Если тестировать систему только на простых случаях — оба метода покажут похожие результаты. Если тестировать на реальных хранилищах с десятилетиями истории — разница становится критической.

Сходство говорит: «это могло бы быть тем же». Идентичность говорит: «это было тем же — я видел это тысячу раз в реальных запросах». Разница между «могло бы» и «было» — это разница между догадкой и свидетельством.

Читать также