Похоже ≠ то же: идентичность против сходства
Почему «близко по смыслу» и «одно и то же» — принципиально разные вещи
Представьте, что вы ищете человека по имени «Алексей Иванов». Вам говорят: «Вот Алексей Петров — очень похоже!». Или: «Вот Иванов Алексей Николаевич — почти то же самое».
Для поиска друга на вечеринке — сойдёт. Для юридического документа — катастрофа.
В мире данных эта разница определяет, получит ли ИИ правильный ответ или красивую ошибку.
Два вопроса, которые звучат одинаково
Когда ИИ ищет нужную таблицу в хранилище данных, он фактически решает один из двух принципиально разных вопросов:
Вопрос сходства: на что это похоже? «Студент» и 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 в двух разных таблицах, где обе колонки действительно хранят номер студента. Поиск по сходству справляется. Поиск по идентичности подтверждает.
Похожи, но разные: 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 — и оно действительно про студентов. Здесь работает и поиск по сходству, и поиск по идентичности.
Разница проявляется только на сложных случаях: семантически непрозрачные имена, омонимия, синонимия через несколько поколений систем. Именно эти случаи определяют качество в реальных корпоративных данных.
Если тестировать систему только на простых случаях — оба метода покажут похожие результаты. Если тестировать на реальных хранилищах с десятилетиями истории — разница становится критической.
Сходство говорит: «это могло бы быть тем же». Идентичность говорит: «это было тем же — я видел это тысячу раз в реальных запросах». Разница между «могло бы» и «было» — это разница между догадкой и свидетельством.