13.5.2 퍼지 매칭(Fuzzy Matching)을 이용한 공급자명 정규화 및 ID 매핑

13.5.2 퍼지 매칭(Fuzzy Matching)을 이용한 공급자명 정규화 및 ID 매핑

바로 앞 13.5.1절에서 확인했듯, LLM이 추출한 데이터를 엔터프라이즈 데이터베이스(DB)와 조인(JOIN) 할 때 가로막는 가장 거대하고도 지독한 장벽은 바로 **‘인간 자연어의 무한한 다형성(Polymorphism)’**이다.

동일한 기업이라도 사내 ERP DB의 마스터(Master) 레코드에는 아주 무겁고 공식적인 법인명인 Apple Computer Inc.로 등록되어 있을 수 있다. 그러나 현실 세계의 영수증이나 지류 인보이스에 찍히는 이름은 철저히 판매자의 마음이다. LLM이 비전(Vision)으로 읽어낸 추출 텍스트는 Apple Store #123 (Gangnam)일 수도 있고, 대충 줄여 쓴 Apple Inc일 수도 있으며, 심지어 잉크가 번지거나 OCR 환각이 겹쳐져 타이포(Typo)가 섞인 Aple Inc.일 수도 있다.

이러한 개판인 상황에서, 멍청하고 기계적인 SQL의 SELECT * FROM vendors WHERE vendor_name = 'Apple Store #123' 같은 쿼리를 날려버리면, 오라클은 볼 것도 없이 참담한 0개의 레코드(결과 없음)를 반환하며 치명적 예외를 던지고 파워를 꺼버릴 것이다.
따라서 3단계 오라클 아키텍처는 일대일의 딱딱하고 융통성 없는 동치(Exact Match) 비교를 초월하여, ‘퍼지 매칭(Fuzzy Matching)’ 기술을 파이프라인 중간에 샌드위치처럼 도입해야만 한다. 이를 통해 지저분하게 비정형화된 텍스트 변형을 데이터베이스의 깨끗하게 정규화된 유일 식별키(Master Vendor ID)로 부드럽게 흡수하는 무적의 중개자(Middleman) 레이어를 생성해야 한다.

1. 레벤슈타인 거리(Levenshtein Distance) 알고리즘 기반의 룩업 엔진

퍼지 매칭 오라클은 주로 파이썬의 TheFuzz(구 FuzzyWuzzy, 레벤슈타인 거리 기반) 라이브러리나 TF-IDF 벡터 기반의 코사인 유사도(Cosine Similarity) 코드를 활용하여, LLM에서 입력된 지저분한 텍스트와 사내 DB 마스터 테이블 내 벤더 리스트 간의 ’수학적 편집 거리(문자적 유사도)’를 런타임에 평가한다.

예를 들어, LLM이 추출한 비정형 결과가 텐서 X 이고, 사내 DB 마스터 리스트가 닫힌 집합 M 일 때, Pydantic 오라클은 다음과 같은 탐색(Search) 알고리즘을 수행한다.

from pydantic import BaseModel, model_validator
from thefuzz import process, fuzz
import typing

# 사내 ERP 시스템의 벤더 마스터 사전 (Redis 등에 인메모리로 캐싱되었다고 가정)
ERP_VENDOR_MASTER_CACHE = {
    "V-001": "Apple Computer Inc.",
    "V-002": "Microsoft Corporation",
    "V-003": "Amazon Web Services",
}

class VendorNormalizationFuzzyOracle(BaseModel):
    # LLM이 이미지에서 눈으로 보고 추출한 (오타나 수식어가 섞여 있을 수 있는) 원래 이름
    raw_vendor_name: str 
    
    # 오라클이 퍼지 매칭을 거친 후 마스터 DB와 연동하여 자동으로 부여해 줄 정규화 외래키
    normalized_vendor_id: typing.Optional[str] = None 
    
    @model_validator(mode='after')
    def execute_fuzzy_match_vendor(self):
        """ 
        LLM이 무지성으로 추출한 텍스트를 사내 마스터 DB와 퍼지 알고리즘으로 매칭하여, 
        가장 합리적인 ID에 강제로 편입(Mapping) 시키는 정규화 작업을 수행한다. 
        """
        master_names_list = list(ERP_VENDOR_MASTER_CACHE.values())
        
        # 1. TheFuzz 엔진을 구동하여 유사도 점수(0~100) 추출 배열 확보
        # extractOne 메서드는 (가장 비슷한 DB 이름 후보, 타격 점수 Score) 튜플을 반환함
        best_match_candidate, similarity_score = process.extractOne(
            self.raw_vendor_name, 
            master_names_list, 
            scorer=fuzz.token_sort_ratio # 순서가 섞여도(Inc Apple) 잘 찾아내는 알고리즘 적용
        )
        
        # 2. 오라클의 가혹한 승인 임계치(Threshold) 룰셋 심문 체계
        THRESHOLD = 85 # 85점 이상 일치하면 같은 회사로 간주하겠다는 엔터프라이즈의 암묵적 합의
        
        if similarity_score >= THRESHOLD:
            # 3. 벤더 이름을 마스터 ID로 매핑하여 상태 갱신 (비정형 -> 정형 테이블화 성공)
            for vendor_id, master_name in ERP_VENDOR_MASTER_CACHE.items():
                if master_name == best_match_candidate:
                    self.normalized_vendor_id = vendor_id
                    
                    # LLM이 쓴 지저분한 오타 객체(Apple Store 123) 자체를 
                    # DB상의 깔끔한 정규화 텍스트(Apple Computer Inc.)로 영구 정화시킴
                    self.raw_vendor_name = master_name 
                    break
        else:
            # 4. 만약 유사도가 85점 미만일 경우 매칭 실패 (환각이거나, 완전 첫 거래 신규 벤더)
            raise ValueError(
                f"[마스터 퍼지 매칭 실패] AI가 추출한 벤더명 '{self.raw_vendor_name}'과 일치하는 "
                f"사내 마스터 텐서가 존재하지 않습니다. (최고 유사도 후보: {best_match_candidate} / {similarity_score}점). "
            )
            
        return self

2. 퍼지 매칭 오라클이 부여하는 공학적 ’복원력(Resilience)’의 위대함

이 퍼지 매칭 중개자 매커니즘이 도입됨으로써, 비정형 LLM 파이프라인은 가히 핵무기급의 거대한 **‘복원력과 내결함성(Resilience)’**을 획득하게 된다.
물리적인 영수증 스캔본에 원두커피 얼룩이 묻어서 ’Microsoft’가 ’M!crosoft’나 ’Microsft’로 참담하게 잘못 추출되었다 하더라도 파이프라인은 파괴되지 않는다. 중간에 위치한 오라클의 퍼지 매치 엔진이 그 망가진 글자를 보고 90점 이상의 유사도를 기록하여, 스스로 안전하게 V-002라는 ERP 마스터 DB 레코드 ID로 자동 치유(Self-healing) 및 맵핑(Mapping) 해주기 때문이다.

이는 파이프라인이 AI의 고질적인 시각적 OCR 예외 환각과, 현실 세계가 지닌 자연어의 더러운 다형성을 수학적으로 계산된 ‘허용 오차(Tolerance)’ 곡선 안으로 블랙홀처럼 둥글게 흡수해버리는, **엔터프라이즈 데이터 정규화(Data Normalization)의 극한의 아름다움(Culmination)**을 증명하는 완벽한 공학적 사례다.