카탈로그 혼란에서 실시간 추천으로: LLM과 Neo4j를 사용한 제품 그래프 구축

발행: (2025년 12월 12일 오후 12:52 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

대부분의 제품 추천 시스템은 기본적으로 고급 키워드 매처에 불과합니다. 클릭 데이터가 수백만 건이라면 그럭저럭 동작하지만, 다음과 같은 상황에서는 완전히 무너집니다:

  • 상호작용 데이터가 전혀 없는 새로운 제품을 출시했을 때 📉
  • 카탈로그가 일관성 없는 태그와 설명으로 엉망일 때 🤦
  • 해당 제품을 추천하는지 설명하고 싶을 때 (단순히 블랙박스 점수를 보여주는 것이 아니라)

저는 LLM과 그래프 데이터베이스를 활용해 제품을 실제로 이해하는 실시간 추천 엔진을 만들었습니다. 핵심 로직은 파이썬 100줄 정도에 불과합니다.

비밀 소스: 제품 분류 체계 + 지식 그래프

사용자 행동만을 의존하는 대신, LLM에게 다음을 이해하도록 가르칩니다:

  • 제품이 실제로 무엇인지 (“사무용품”이 아니라 “젤펜” 같은 세분화된 분류)
  • 사람들이 함께 구매하는 제품 (예: “젤펜” → “노트”, “펜꽂이” 같은 보완 제품)

이 모든 정보를 Neo4j 그래프 데이터베이스에 저장해 관계를 일급 시민으로 다룹니다. 이제 “이 젤펜과 보완적인 분류를 공유하는 모든 제품을 보여줘” 같은 쿼리를 할 수 있습니다.

실제 사례: 젤펜 문제

누군가 젤펜을 탐색하면 전통적인 추천 시스템은 다음을 보여줄 수 있습니다:

  • 같은 카테고리의 다른 젤펜
  • 판매량 기반 인기 아이템
  • 충분한 데이터가 있다면 “고객이 함께 구매한” 무작위 아이템

우리 방식에서는 LLM이 제품 설명을 분석해 다음을 추출합니다:

  • 주요 분류: gel pen, writing instrument
  • 보완 분류: notebook, pencil case, desk organizer

그래프가 이러한 관계를 알게 되므로, 젤펜을 볼 때 노트, 플래너, 정리함 등을 설명 가능한 연결과 함께 제시할 수 있습니다.

아키텍처 (단순화)

Product JSONs → CocoIndex Pipeline → LLM Extraction → Neo4j Graph

1. 제품을 스트림으로 ingest

자동 새로고침이 가능한 폴더의 제품 JSON 파일을 감시합니다:

data_scope["products"] = flow_builder.add_source(
    cocoindex.sources.LocalFile(
        path="products",
        included_patterns=["*.json"]
    ),
    refresh_interval=datetime.timedelta(seconds=5)
)

제품 파일이 변경될 때마다 파이프라인이 업데이트되며, 수동 재빌드가 필요 없습니다.

2. 데이터 정제 및 정규화

원시 JSON을 깔끔한 구조로 매핑합니다:

@cocoindex.op.function(behavior_version=2)
def extract_product_info(product: cocoindex.typing.Json, filename: str) -> ProductInfo:
    return ProductInfo(
        id=f"{filename.removesuffix('.json')}",
        url=product["source"],
        title=product["title"],
        price=float(product["price"].lstrip("$").replace(",", "")),
        detail=Template(PRODUCT_TEMPLATE).render(**product),
    )

detail 필드는 LLM에 전달되는 마크다운 형태의 “제품 시트”가 됩니다.

3. LLM에게 무거운 작업을 맡기기

분류 계약을 데이터클래스로 정의합니다:

@dataclasses.dataclass
class ProductTaxonomy:
    """
    A concise noun or short phrase based on core functionality.
    Use lowercase, avoid brands/styles.
    Be specific: "pen" not "office supplies".
    """
    name: str

@dataclasses.dataclass
class ProductTaxonomyInfo:
    taxonomies: list[ProductTaxonomy]
    complementary_taxonomies: list[ProductTaxonomy]

그 다음 LLM을 호출합니다:

taxonomy = data["detail"].transform(
    cocoindex.functions.ExtractByLlm(
        llm_spec=cocoindex.LlmSpec(
            api_type=cocoindex.LlmApiType.OPENAI,
            model="gpt-4.1"
        ),
        output_type=ProductTaxonomyInfo
    )
)

LLM은 마크다운 설명을 읽고 스키마에 맞는 구조화된 JSON을 반환합니다—파싱 지옥이 없습니다.

4. Neo4j에 지식 그래프 구축

세 가지 요소를 내보냅니다:

  • Product 노드: id, title, price, url
  • Taxonomy 노드: “gel pen”, “notebook” 같은 고유 라벨
  • 관계: PRODUCT_TAXONOMYPRODUCT_COMPLEMENTARY_TAXONOMY
product_node.export(
    "product_node",
    cocoindex.storages.Neo4j(
        connection=conn_spec,
        mapping=cocoindex.storages.Nodes(label="Product")
    ),
    primary_key_fields=["id"],
)

Neo4j는 기본 키를 기준으로 자동 중복 제거를 수행합니다. 다섯 개의 제품이 모두 “notebook”을 보완 분류로 언급하면, 모두 동일한 Taxonomy 노드에 연결됩니다.

실시간 실행

Postgres(코코인덱스의 증분 처리용)와 Neo4j를 설정한 뒤 다음을 실행합니다:

pip install -e .
cocoindex update --setup main

다음과 같은 출력이 보일 것입니다:

documents: 9 added, 0 removed, 0 updated

그런 다음 http://localhost:7474에서 Neo4j Browser를 열고 실행합니다:

MATCH p=()-->() RETURN p

Boom—전체 제품 그래프가 시각화됩니다.

왜 실제로 동작하는가

  • LLM은 텍스트 이해에 뛰어나다 – 스키마와 docstring을 통해 모델에게 복잡한 자연어 해석을 맡깁니다.
  • 그래프는 관계에 최적화돼 있다 – 설명 가능한 연결을 얻고, PageRank, 커뮤니티 탐지, 최단 경로 등 그래프 알고리즘을 바로 적용할 수 있습니다.
  • 증분 업데이트가 무료 – CocoIndex가 모든 파이프라인을 처리합니다; 제품 파일을 추가하면 그래프가 자동으로 업데이트됩니다.

다음에 만들 수 있는 것들

  • 브랜드, 재질, 사용 사례 같은 분류를 별도 노드 타입으로 추가.
  • 클릭스트림 데이터를 연결해 엣지 가중치를 부여하거나 FREQUENTLY_BOUGHT_WITH 관계를 생성.
  • 필요에 따라 Ollama(온프레미스 LLM)로 OpenAI를 교체해 완전한 제어권 확보.
  • 그래프 알고리즘을 레이어링해 제품 클러스터를 찾거나 트렌드 카테고리를 감지.

직접 해보기

전체 작업 코드는 오픈소스입니다:

👉 CocoIndex Product Recommendation Example

레포지토리에는 다음이 포함됩니다:

  • 완전한 플로우 정의
  • LLM 추출 연산
  • Neo4j 매핑
  • 샘플 제품 JSON

LLM‑네이티브 데이터 파이프라인이나 그래프 기반 추천을 실험하고 있다면, 여러분이 만들고 있는 것을 듣고 싶습니다. 댓글을 남기거나 저를 태그해 주세요!

P.S. 이 글이 도움이 되었다면 CocoIndex 레포에 별 ⭐을 주세요.

P.P.S. 파이프라인을 시각적으로 탐색하고 싶다면 CocoInsight (무료 베타)를 사용해 보세요 — 데이터 보관 없이 DevTools처럼 파이프라인을 살펴볼 수 있습니다.

Back to Blog

관련 글

더 보기 »