티스토리 뷰

728x90
반응형

LangChain은 LLM(대형 언어 모델)과의 상호작용을 체계화하기 위해 다양한 유틸리티를 제공합니다. 그중 PydanticOutputParser는 LLM으로부터 받은 자유로운 텍스트 출력을 Pydantic 모델을 통해 안전하고 구조화된 데이터로 변환하는 핵심 도구입니다. 이 글에서는 PydanticOutputParser의 개념, 어노테이션 활용법, 실제 예시 코드를 중심으로 자세히 살펴보겠습니다.


1. PydanticOutputParser란?

  • LangChain이 제공하는 출력 파서(output parser) 중 하나로, PydanticBaseModel을 내부적으로 활용합니다.
  • LLM의 응답을 파싱(parse) 한 뒤, Pydantic 모델을 사용해 타입 검증구조 검증을 수행합니다.
  • 파싱 실패 시 OutputParserException을 발생시켜 호출 코드에서 안전하게 예외 처리를 할 수 있습니다.

주요 기능

  1. 자동 JSON 파싱: LLM이 반환한 JSON 문자열을 Python 딕셔너리로 변환
  2. 모델 검증: Pydantic BaseModel의 타입 검사, 필수 속성 검사
  3. 에러 메시지 제공: 검증 실패 시 어떤 필드, 어떤 이유로 에러가 났는지 상세히 알려줌

2. Pydantic 모델 어노테이션하기

PydanticOutputParser를 사용하려면 먼저 Pydantic 모델을 정의해야 합니다. 이때 파이썬 타입 어노테이션Field, validator를 활용해 세부 설정을 추가할 수 있습니다.

from pydantic import BaseModel, Field, validator
from typing import List, Literal
from datetime import date

class WeatherForecast(BaseModel):
    date: date = Field(..., description="예측 날짜")
    condition: Literal['sunny', 'cloudy', 'rainy', 'snowy'] = Field(..., description="날씨 상태")
    temp_high: float = Field(..., gt=-50, lt=60, description="최고 온도(C)")
    temp_low: float = Field(..., gt=-50, lt=60, description="최저 온도(C)")
    notes: List[str] = Field(default_factory=list, description="추가 메모 목록")

    @validator('temp_low')
    def check_low_less_than_high(cls, v, values):
        if 'temp_high' in values and v > values['temp_high']:
            raise ValueError('최저 온도는 최고 온도보다 낮아야 합니다.')
        return v
  • Field를 통해 설명(description), 범위(gt, lt), **기본값(factory)**를 지정합니다.
  • Literal허용되는 문자열을 제한합니다.
  • @validator로 필드 간 커스텀 검증 로직을 작성합니다.

3. PydanticOutputParser 사용법

LangChain에서 PydanticOutputParser를 사용하려면, 파싱 대상 모델파서 인스턴스를 생성한 뒤 LLMChain이나 Agent에 연결합니다.

3-1. 파서 인스턴스 생성

from langchain.output_parsers import PydanticOutputParser

# 앞서 정의한 Pydantic 모델을 파서에 전달
parser = PydanticOutputParser(pydantic_object=WeatherForecast)

3-2. 독립 사용 예시

# LLM 응답 예시 (JSON 형태)
raw_response = '''
{
  "date": "2025-07-28",
  "condition": "sunny",
  "temp_high": 31.2,
  "temp_low": 20.1,
  "notes": ["맑고 시원함", "자외선 주의"]
}
'''

try:
    # 파싱 수행: 딕셔너리 대신 Pydantic 모델 인스턴스 반환
    forecast: WeatherForecast = parser.parse(raw_response)
    print(forecast.date, forecast.condition)
except Exception as e:
    # OutputParserException 또는 ValidationError 처리
    print("파싱 실패:", e)

3-3. LLMChain과 통합하기

from langchain import OpenAI, LLMChain, PromptTemplate

template = """
다음 형식(JSON)으로 오늘 날씨를 예측해 주세요:
{format_instructions}
"""
# 포맷 지침을 parser로부터 받아옴
prompt = PromptTemplate(
    input_variables=[],
    partial_variables={
        "format_instructions": parser.get_format_instructions()
    },
    template=template
)

llm = OpenAI(temperature=0)
chain = LLMChain(llm=llm, prompt=prompt)

# 체인 실행 및 파싱
result = chain.run({})  # LLM이 반환하는 JSON 문자열
try:
    forecast = parser.parse(result)
    print(forecast.json())
except Exception as e:
    print("체인 결과 파싱 오류:", e)
  • get_format_instructions() 메서드는 LLM에게 출력 형식을 강제하기 위한 템플릿 지침을 제공합니다.
  • LLMChain.run() 호출 후 parser.parse()를 이용해 구조화된 모델을 반환받습니다.

4. 고급 팁

  1. 맞춤형 에러 처리: 파싱 실패 시 e.errors()로 필드별 상세 오류 목록을 확인하고, 사용자에게 친절한 메시지를 노출하세요.
  2. 다중 모델 파싱: 상황별로 다른 Pydantic 모델이 필요하다면, 각 모델마다 개별 파서를 생성하여 사용합니다.
  3. formatter 활용: parser.get_format_instructions()를 PromptTemplate에 삽입하여, 일관된 JSON 스키마를 LLM에 강제할 수 있습니다.
  4. 리스트 파싱: 출력이 리스트 형태일 때는 ListModel = List[MyModel] 형태로 어노테이션하고 파서를 만들 수 있습니다.

5. 정리

  • PydanticOutputParser는 LangChain과 Pydantic을 연결하는 다리 역할을 합니다.
  • 파이썬 어노테이션과 Pydantic의 검증 기능을 활용해, LLM 출력을 안전하게 구조화할 수 있습니다.
  • 실제 LLMChain 통합 예시를 통해 파서 사용법을 익히고, 안정적인 애플리케이션을 구현해 보시기 바랍니다.

이제 LangChain 프로젝트에서 PydanticOutputParser를 적극 활용하여, 예측 결과나 API 응답을 깔끔하게 처리해 보세요! 🚀

728x90
반응형