본문 바로가기
AI/RAG 비법노트

18일차: 테디노트의 RAG 비법노트: 랭체인을 활용한 GPT부터 로컬 모델까지의 RAG 강의 후기 (pandas, datetime enum output parser)

by 말하는 감자에요 2025. 6. 23.
728x90
반응형

LangChain은 LLM의 출력을 목적에 맞는 데이터 구조로 쉽게 변환할 수 있도록 다양한 OutputParser를 제공합니다.

오늘은 그 중에서도 데이터 분석, 시간 정보 처리, 범주형 값 처리와 관련된 유용한 파서 세 가지를 소개하겠습니다.

  • PandasDataFrameOutputParser : LLM 결과를 Pandas DataFrame 기반으로 파싱
  • DatetimeOutputParser : 날짜·시간 값을 datetime 객체로 파싱
  • EnumOutputParser : 미리 정의된 Enum 값 중 하나로 파싱

1. PandasDataFrameOutputParser

PandasDataFrameOutputParser는 사용자가 제공한 Pandas DataFrame을 바탕으로, LLM이 의미 있는 쿼리를 수행하도록 돕고, 그 결과를 딕셔너리 형태로 반환해주는 파서입니다.

데이터 분석이나 실시간 질의응답 시스템 등에서 유용하게 활용할 수 있습니다.

✅ 주요 특징

  • LLM이 DataFrame의 구조를 이해하고 열, 행, 통계 등을 추출
  • get_format_instructions()를 통해 쿼리 형식을 자동 제공
  • 결과는 dict 형식으로 변환 가능하여 후속 처리 용이

🛠️ 예제 코드

# 모델 및 파서 초기화
model = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
df = pd.read_csv("./data/titanic.csv")
parser = PandasDataFrameOutputParser(dataframe=df)

# 파서의 지시사항을 출력합니다.
print(parser.get_format_instructions())

쿼리 형식 예시 (LLM에게 제공될 지침)

The output should be formatted as a string as the operation, followed by a colon, followed by the column or row to be queried on, followed by optional array parameters.
1. The column names are limited to the possible columns below.
2. Arrays must either be a comma-separated list of numbers formatted as [1,3,5], or it must be in range of numbers formatted as [0..4].
3. Remember that arrays are optional and not necessarily required.
4. If the column is not in the possible columns or the operation is not a valid Pandas DataFrame operation, return why it is invalid as a sentence starting with either "Invalid column" or "Invalid operation".

As an example, for the formats:
1. String "column:num_legs" is a well-formatted instance which gets the column num_legs, where num_legs is a possible column.
2. String "row:1" is a well-formatted instance which gets row 1.
3. String "column:num_legs[1,2]" is a well-formatted instance which gets the column num_legs for rows 1 and 2, where num_legs is a possible column.
4. String "row:1[num_legs]" is a well-formatted instance which gets row 1, but for just column num_legs, where num_legs is a possible column.
5. String "mean:num_legs[1..3]" is a well-formatted instance which takes the mean of num_legs from rows 1 to 3, where num_legs is a possible column and mean is a valid Pandas DataFrame operation.
6. String "do_something:num_legs" is a badly-formatted instance, where do_something is not a valid Pandas DataFrame operation.
7. String "mean:invalid_col" is a badly-formatted instance, where invalid_col is not a possible column.

Here are the possible columns:
```
PassengerId, Survived, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, Embarked
```

열 조회 예시

df_query = "Age column 을 조회해 주세요."
parser_output = chain.invoke({"question": df_query})
format_parser_output(parser_output)

{'Age': {0: 22.0, 1: 38.0, 2: 26.0, ... }}

행 조회 예시

df_query = "Retrieve the first row."
parser_output = chain.invoke({"question": df_query})
format_parser_output(parser_output)

평균값 예시

df_query = "Retrieve the average of the Ages from row 0 to 4."
parser_output = chain.invoke({"question": df_query})
print(parser_output)  # {'mean': 31.2}

⚠️ 유의사항

  • 열 이름이나 연산자가 유효하지 않을 경우, 오류 메시지를 반환합니다.
  • 출력은 항상 딕셔너리로 반환되어, 후속 분석이 용이합니다.
  • 대규모 DataFrame의 경우, row 인덱싱은 정확하게 지정해줘야 합니다.

2. DatetimeOutputParser

DatetimeOutputParser는 자연어 질문의 답변으로 반환된 날짜 정보를 datetime.datetime 객체로 파싱해주는 도구입니다.

예를 들어, 사용자가 “Google이 설립된 날짜는?”과 같은 질문을 하면, 모델은 "1998-09-04"처럼 포맷된 문자열을 출력하고, 이 파서는 이를 datetime 객체로 바꿔줍니다.

✅ 주요 특징

  • 날짜 포맷 지정 가능 (%Y-%m-%d, %Y/%m/%d, etc.)
  • LLM이 날짜 형식을 벗어날 경우 예외 처리 용이
  • 시간 기반 자동화, 필터링 등에 활용 가능

🛠️ 예제 코드

output_parser = DatetimeOutputParser()
output_parser.format = "%Y-%m-%d"

prompt = PromptTemplate.from_template(
    template,
    partial_variables={
        "format_instructions": output_parser.get_format_instructions()
    },
)
chain = prompt | ChatOpenAI() | output_parser

사용 예시

output = chain.invoke({"question": "Google 이 창업한 연도"})
print(output)           # datetime.datetime(1998, 9, 4, 0, 0)
print(output.strftime("%Y-%m-%d"))  # '1998-09-04'

⚠️ 유의사항

  • 날짜 포맷(%Y-%m-%d)은 반드시 LLM에 지시해야 정확한 결과가 나옵니다.
  • 예외적으로 텍스트 응답이 올 경우, 파싱 오류가 발생할 수 있습니다.

3. EnumOutputParser

EnumOutputParser는 LLM의 출력을 사전에 정의한 Enum 값 중 하나로 변환해주는 파서입니다.

주로 범주형 응답 (예: 색상, 감정, 상태 등)이 필요한 분류 문제에 적합합니다.

✅ 주요 특징

  • 출력 값의 정합성 보장: 모델이 생성한 값이 반드시 Enum 내에 존재해야 함
  • 파싱된 결과는 Enum 객체로 반환되므로, 후속 처리 간편
  • 예상치 못한 결과 제거 → 예측 가능성 증가

🛠️ 예제 코드

from enum import Enum
from langchain.output_parsers.enum import EnumOutputParser

class Colors(Enum):
    RED = "빨간색"
    GREEN = "초록색"
    BLUE = "파란색"

parser = EnumOutputParser(enum=Colors)

프롬프트 예시

prompt = PromptTemplate.from_template(
    """다음의 물체는 어떤 색깔인가요?

Object: {object}

Instructions: {instructions}"""
).partial(instructions=parser.get_format_instructions())

체인 실행

response = chain.invoke({"object": "하늘"})
print(response)        # Colors.BLUE
print(response.value)  # '파란색'

⚠️ 유의사항

  • 모델 출력이 Enum에 없는 값일 경우 예외가 발생할 수 있습니다.
  • 출력 문자열은 공백/줄바꿈 등을 포함하더라도 자동 정리됩니다.

✅ 마무리

이번 글에서는 다음 세 가지 LangChain 파서를 소개했습니다:

 

파서 용도 반환 형태
PandasDataFrameOutputParser DataFrame 기반 질의/연산 응답 dict (DataFrame)
DatetimeOutputParser 날짜 정보 추출 및 변환 datetime 객체
EnumOutputParser 미리 정의된 값으로 파싱 Enum 객체

 

이러한 파서들을 적절히 활용하면 LLM의 응답을 구조화된 형태로 안전하게 가공할 수 있으며, 분석, 분류, 자동화에 효과적으로 연결할 수 있습니다.

 

읽어주셔서 감사합니다!!

728x90
반응형