LLM & Generative AI/RAG in Practice

[LangChain RAG 구축 시리즈 Ep.08] 🧠 OpenAI Embedding 실습: JSON을 임베딩해보기

ygtoken 2025. 4. 5. 19:43
728x90

이 글에서는 실제 Iceberg의 metadata.json 파일에서 필요한 정보를 추출하여,
자연어 기반 문서로 가공한 뒤, OpenAI의 임베딩 모델을 활용해 벡터로 변환하는 과정을 실습합니다.


🎯 목표

  • metadata.json에서 테이블 정보를 추출
  • 사람이 이해할 수 있는 문장 형태로 재구성
  • LangChain의 OpenAIEmbeddings로 벡터화
  • 향후 검색(Retriever)에서 활용 가능한 문서 벡터 생성

🔍 Step 1. 예시 JSON 데이터 준비 (💬 상세 주석 포함)

{
  "table-name": "products",  // 테이블 이름
  "schema": {
    "fields": [  // 테이블 컬럼 정의 목록
      { "id": 1, "name": "product_id", "type": "long" },     // 첫 번째 컬럼: 상품 ID (정수형)
      { "id": 2, "name": "product_name", "type": "string" }, // 두 번째 컬럼: 상품명 (문자열)
      { "id": 3, "name": "category", "type": "string" }      // 세 번째 컬럼: 카테고리 (문자열)
    ]
  },
  "partition-spec": [  // 파티션 정의
    { 
      "source-id": 3,        // 파티션 기준이 되는 컬럼의 ID
      "name": "category",    // 파티션 컬럼 이름
      "transform": "identity" // 파티션 분할 방식: 그대로 사용(identity transform)
    }
  ]
}

🧾 Step 2. 자연어 문서로 변환 (Python 전처리 함수, 라인별 주석 포함)

def convert_metadata_to_text(json_data: dict) -> str:
    # 테이블명을 추출하고, 없을 경우 'unknown'을 기본값으로 설정
    table = json_data.get("table-name", "unknown")

    # 컬럼 목록 추출 (schema 내부 fields)
    fields = json_data["schema"]["fields"]

    # 파티션 컬럼 이름들만 리스트로 추출
    partition_fields = [p["name"] for p in json_data.get("partition-spec", [])]

    # 결과 텍스트 문서 시작
    doc = f"📂 테이블명: {table}\n🧾 컬럼 목록:\n"

    # 각 컬럼에 대해 이름과 타입을 한 줄씩 추가
    for field in fields:
        doc += f"- {field['name']} ({field['type']})\n"

    # 파티션 컬럼이 존재할 경우 별도 라인 추가
    if partition_fields:
        doc += f"🧩 파티션 컬럼: {', '.join(partition_fields)}\n"

    return doc  # 최종 텍스트 반환

 

✅ 실행 시 결과 예시:

📂 테이블명: products  
🧾 컬럼 목록:  
- product_id (long)  
- product_name (string)  
- category (string)  
🧩 파티션 컬럼: category

🧠 Step 3. OpenAI 임베딩으로 벡터화하기

from langchain.embeddings import OpenAIEmbeddings  # OpenAI 임베딩 클래스 import

# OpenAI 임베딩 모델 인스턴스 생성 (기본적으로 text-embedding-ada-002 사용)
embedding_model = OpenAIEmbeddings()

# 앞서 만든 전처리 함수로 JSON → 자연어 텍스트 변환
text = convert_metadata_to_text(sample_json)

# 자연어 문서를 임베딩하여 벡터 생성
vector = embedding_model.embed_query(text)

# 생성된 벡터 길이 출력 (보통 1536차원)
print(f"벡터 길이: {len(vector)}")

🧪 결과 예시: 생성된 벡터 형태

[0.019, -0.321, 0.202, ..., -0.040]  // 실수형 벡터, 1536개 요소

이 벡터는 "products" 테이블의 전체 설명을 수치화한 결과입니다.
나중에 문서 검색 및 질문 매칭에 사용됩니다.


📦 보너스: 여러 테이블을 한꺼번에 처리하고 Chroma에 저장하기

import json
from langchain.vectorstores import Chroma  # Chroma 벡터스토어 모듈 import

docs = []  # 변환된 문서를 저장할 리스트

# 여러 metadata.json 객체들을 순회
for metadata_json in list_of_metadata:
    text = convert_metadata_to_text(metadata_json)  # 자연어로 변환
    docs.append(text)  # 리스트에 추가

# 전체 문서 임베딩 후, ChromaDB에 저장
vectordb = Chroma.from_texts(docs, embedding_model)

📎 요약 및 핵심 정리

  • Iceberg의 metadata.json은 구조적이지만,
    → RAG에서는 자연어 문서로 바꿔야 임베딩 성능이 향상됩니다.
  • LangChain의 OpenAIEmbeddings로 문서를 벡터로 변환합니다.
  • 변환된 벡터는 Vector DB에 저장되어 이후 검색(Retriever)에서 사용됩니다
728x90