본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] Pydantic으로 LLM 비정형 데이터를 구조화하는 7가지 방법과 해결책

by Papa Martino V 2026. 4. 14.
728x90

Pydantic v2
Pydantic v2

 

최근 대규모 언어 모델(LLM)을 서비스에 도입할 때 가장 큰 기술적 장벽 중 하나는 '출력의 불확실성'입니다. LLM은 본래 텍스트 생성 모델이기 때문에, 우리가 원하는 특정 JSON 규격이나 데이터 타입을 항상 일정하게 유지하지 못하는 경우가 많습니다. 이러한 문제를 해결하기 위해 파이썬 생태계에서 가장 강력한 데이터 검증 라이브러리인 Pydantic이 필수적인 도구로 자리 잡았습니다.

본 포스팅에서는 단순한 파싱을 넘어, 실무에서 LLM 응용 프로그램을 개발할 때 비정형 텍스트를 견고한 데이터 모델로 변환하는 전문적인 기법과 실제 발생할 수 있는 예외 상황에 대한 해결책을 심도 있게 다룹니다.


1. 왜 LLM 구조화에 Pydantic인가? (전통적 파싱과의 차이)

과거에는 re(정규표현식)나 json.loads()를 사용해 LLM의 출력을 가공했습니다. 하지만 LLM이 텍스트 중간에 설명을 덧붙이거나, JSON 필드명을 미세하게 틀리는 경우 기존 방식은 쉽게 무너집니다. Pydantic은 '강력한 타입 힌팅''런타임 데이터 검증'을 통해 데이터의 신뢰성을 보장합니다.

비교 항목 전통적인 JSON 파싱 Pydantic 기반 구조화
데이터 검증 수동으로 필드 존재 유무 확인 필요 선언적 모델 정의로 자동 검증
타입 강제 불가능 (문자열 숫자를 직접 변환해야 함) 자동 타입 캐스팅 (Coercion) 지원
가독성 코드가 복잡해질수록 유지보수 어려움 클래스 기반으로 직관적이고 명확함
예외 처리 ValueError 등 원인 파악이 힘듦 ValidationError를 통한 구체적 위치 파악

2. 실무 적용을 위한 핵심 Example 7선

실제 개발 현장에서 즉시 활용할 수 있는 코드 예제입니다. 이 예제들은 OpenAI API나 LangChain 등 다양한 환경에서 Pydantic 모델을 스키마로 전달할 때 매우 유용합니다.

Example 1: 기본적인 엔티티 추출 및 데이터 타입 강제

사용자의 질문에서 이름, 나이, 관심사를 추출하는 가장 기본적인 형태입니다.

from pydantic import BaseModel, Field
from typing import List

class UserProfile(BaseModel):
    name: str = Field(..., description="사용자의 성명")
    age: int = Field(..., description="사용자의 나이, 숫자만 포함")
    hobbies: List[str] = Field(default=[], description="사용자의 취미 목록")

# LLM 출력 예시: "이 사용자는 홍길동이고 25살이며 축구와 독서를 좋아해."
# 이 문자열을 Pydantic 모델로 변환하여 API 응답으로 활용합니다.

Example 2: 열거형(Enum)을 활용한 감성 분석 및 카테고리 분류

LLM이 임의의 단어를 생성하지 못하도록 정해진 카테고리 내에서만 답변을 고르게 합니다.

from enum import Enum
from pydantic import BaseModel

class SentimentEnum(str, Enum):
    POSITIVE = "긍정"
    NEGATIVE = "부정"
    NEUTRAL = "중립"

class SentimentAnalysis(BaseModel):
    score: float = Field(..., ge=0, le=1) # 0.0 ~ 1.0 사이 검증
    sentiment: SentimentEnum
    reason: str

Example 3: 중첩된 구조(Nested Models)를 통한 복잡한 정보 추출

뉴스 기사에서 여러 개의 상품 정보와 가격 정보를 동시에 추출할 때 사용합니다.

class Item(BaseModel):
    product_name: str
    price: int
    currency: str = "KRW"

class ShoppingExtraction(BaseModel):
    store_name: str
    items: List[Item]
    total_count: int

Example 4: 데이터 정제 및 커스텀 검증(Validator) 활용

LLM이 날짜 형식을 잘못 생성했을 때, Pydantic의 field_validator를 통해 형식을 강제합니다.

from pydantic import field_validator
import re

class EventDate(BaseModel):
    date_str: str

    @field_validator('date_str')
    @classmethod
    def validate_date_format(cls, v: str) -> str:
        if not re.match(r"^\d{4}-\d{2}-\d{2}$", v):
            raise ValueError("날짜 형식은 YYYY-MM-DD여야 합니다.")
        return v

Example 5: 동적 필드 처리를 위한 Union 타입 활용

LLM이 상황에 따라 다른 형태의 데이터를 응답해야 할 때 유연하게 대처합니다.

from typing import Union, Literal

class SuccessResponse(BaseModel):
    status: Literal["success"]
    data: dict

class ErrorResponse(BaseModel):
    status: Literal["error"]
    message: str

class LLMOutput(BaseModel):
    result: Union[SuccessResponse, ErrorResponse]

Example 6: 비정형 텍스트 요약 및 키워드 가중치 구조화

단순 요약을 넘어 메타데이터를 함께 관리하는 방식입니다.

class Keyword(BaseModel):
    term: str
    importance: float = Field(..., description="0.0에서 1.0 사이의 중요도")

class SummaryReport(BaseModel):
    summary_text: str
    key_points: List[str]
    keywords: List[Keyword]

Example 7: Self-Correction(자기 수정) 로직 구현을 위한 스키마 추출

Pydantic 모델에서 JSON 스키마를 추출하여 LLM에게 프롬프트로 전달, 오류 발생 시 재시도하게 만드는 핵심 기법입니다.

import json

class TechnicalSpec(BaseModel):
    cpu: str
    ram: str
    storage: str

# LLM에게 전달할 JSON 스키마 정의
json_schema = TechnicalSpec.model_json_schema()
print(json.dumps(json_schema, indent=2))
# 이 스키마를 프롬프트에 포함하여 "반드시 이 스키마를 지켜줘"라고 지시합니다.

3. 고도화된 해결 전략: LLM의 환각(Hallucination) 방지

데이터 구조화 과정에서 LLM이 없는 사실을 지어내는 경우, Pydantic의 Strict Mode를 활용하면 효과적입니다. Strict Mode는 자동 타입 변환을 제한하여, 모델이 조금이라도 잘못된 형식을 내뱉으면 즉시 에러를 발생시켜 잘못된 데이터가 시스템에 유입되는 것을 원천 차단합니다. 또한, LangChain의 PydanticOutputParser나 Instructor와 같은 라이브러리를 병행 사용하면, ValidationError가 발생했을 때 에러 메시지를 다시 LLM에게 피드백으로 보내어 '자기 치유(Self-healing)' 과정을 자동화할 수 있습니다.


4. 결론: 견고한 AI 애플리케이션을 위한 첫걸음

비정형 출력을 구조화하는 것은 단순히 데이터를 예쁘게 정리하는 작업이 아닙니다. 이는 AI 모델과 확정적인 소프트웨어 시스템 사이의 신뢰 계약을 맺는 과정입니다. Pydantic을 활용하면 코드의 가독성이 비약적으로 향상될 뿐만 아니라, 운영 단계에서 발생할 수 있는 수많은 엣지 케이스를 사전에 방어할 수 있습니다. 본 가이드에서 제시한 7가지 예제를 바탕으로 여러분의 LLM 프로젝트에 안정적인 데이터 파이프라인을 구축해 보시기 바랍니다.


참조 및 출처

  • Pydantic 공식 문서 
  • OpenAI API Documentation - Structured Outputs Guide
  • Python Type Hinting (PEP 484) 규격
  • LangChain Output Parsers Conceptual Guide
728x90