이번 강의에서는 출력 파서(Output Parser)를 사용하여 대형 언어 모델(LLM)의 출력을 원하는 데이터 형식으로 변환하는 방법에 대해 알아보겠습니다. 특히 LangChain 라이브러리를 활용하여 LLM의 출력인 문자열을 파싱하고, 이를 Python의 데이터 타입으로 변환하는 과정을 살펴볼 것입니다.
LLM은 강력한 자연어 처리 도구이지만, 그 출력은 기본적으로 문자열입니다. 그러나 실제 애플리케이션에서는 특정 데이터 형식이 필요할 때가 많습니다. 예를 들어:
datetime
객체출력 파서를 사용하면 LLM의 출력을 원하는 데이터 유형으로 쉽게 변환할 수 있습니다. 이는 다음과 같은 이점을 제공합니다:
출력 파서는 두 가지 주요 요소로 구성되어 있습니다:
datetime
객체로 변환합니다.datetime
객체로 사용하고 싶습니다.parse
메서드 사용: 모델의 출력을 받아 파싱하고, Python의 datetime
객체로 변환합니다.from langchain.output_parsers import DatetimeOutputParser
output_parser = DatetimeOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = f"{user_input}\n{format_instructions}"
response = llm(prompt)
parsed_output = output_parser.parse(response)
import os
from dotenv import load_dotenv
from langchain import OpenAI
from langchain.output_parsers import CommaSeparatedListOutputParser
# .env 파일에서 API 키 로드
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# LLM 모델 초기화
llm = OpenAI(temperature=0.7, openai_api_key=OPENAI_API_KEY)
# 출력 파서 인스턴스 생성
output_parser = CommaSeparatedListOutputParser()
# 형식 설명서 얻기
format_instructions = output_parser.get_format_instructions()
# 사용자 요청
user_input = "개의 특징을 다섯 가지 말해줘."
# 프롬프트 생성 (형식 설명서 추가)
prompt = f"{user_input}\n\n{format_instructions}"
# 모델 응답 받기
response = llm(prompt)
# 출력 파싱
parsed_output = output_parser.parse(response)
print("모델의 원본 응답:")
print(response)
print("\n파싱된 출력:")
print(parsed_output)
아래는 위에서 설명한 모든 단계를 포함한 전체 코드입니다.
import os
from dotenv import load_dotenv
from langchain import OpenAI
from langchain.output_parsers import CommaSeparatedListOutputParser
# .env 파일에서 API 키 로드
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# LLM 모델 초기화
llm = OpenAI(temperature=0.7, openai_api_key=OPENAI_API_KEY)
# 출력 파서 인스턴스 생성
output_parser = CommaSeparatedListOutputParser()
# 형식 설명서 얻기
format_instructions = output_parser.get_format_instructions()
# 사용자 요청
user_input = "개의 특징을 다섯 가지 말해줘."
# 프롬프트 생성 (형식 설명서 추가)
prompt = f"{user_input}\n\n{format_instructions}"
# 모델 응답 받기
response = llm(prompt)
# 출력 파싱
parsed_output = output_parser.parse(response)
# 결과 출력
print("모델의 원본 응답:")
print(response)
print("\n파싱된 출력:")
print(parsed_output)
환경 변수 로드:
dotenv
라이브러리를 사용하여 .env
파일에 저장된 OPENAI_API_KEY
를 불러옵니다.LLM 모델 초기화:
OpenAI
클래스를 사용하여 LLM 모델을 초기화합니다.temperature
파라미터는 출력의 창의성을 조절합니다.출력 파서 및 형식 설명서:
CommaSeparatedListOutputParser
를 사용하여 쉼표로 구분된 목록을 파싱합니다.get_format_instructions()
메서드를 통해 형식 설명서를 얻습니다.프롬프트 생성:
모델 응답 및 파싱:
parse()
메서드를 사용하여 파싱합니다.결과 출력:
모델의 원본 응답:
충성심이 강함, 후각이 예민함, 사회성이 높음, 다양한 품종이 있음, 사람과 친화적임
파싱된 출력:
['충성심이 강함', '후각이 예민함', '사회성이 높음', '다양한 품종이 있음', '사람과 친화적임']
DatetimeOutputParser
, BooleanOutputParser
등출력 파서는 LLM의 출력을 원하는 데이터 형식으로 변환하는 데 매우 유용한 도구입니다. 이를 통해 데이터 처리의 효율성과 안정성을 높일 수 있습니다. 이번 설명에서는 쉼표로 구분된 목록 출력 파서를 예시로 사용했지만, 다양한 파서를 활용하여 여러 형태의 데이터를 처리할 수 있습니다.
OPENAI_API_KEY를 .env
파일에 저장하고 불러오는 방법도 함께 살펴보았습니다. 제공된 전체 실습 코드를 직접 실행해 보시면서 이해를 더욱 깊게 하실 수 있을 것입니다.
이번 강의에서는 출력 파서(Output Parser)를 사용하는 방법에 대해 심화 학습을 진행합니다. 특히, 모델의 출력이 원하는 형식과 맞지 않을 때 이를 해결하는 방법에 대해 알아볼 것입니다.
이 두 가지 방법을 통해 모델의 출력이 형식 지침과 일치하지 않을 때 문제를 해결할 수 있습니다.
대형 언어 모델(LLM)은 자연어 처리에 뛰어나지만, 출력 결과가 항상 우리가 원하는 형식과 일치하지 않을 수 있습니다. 예를 들어, 날짜 정보를 요청했을 때 다양한 형식으로 반환될 수 있습니다:
이렇게 다양한 형식의 출력은 후속 데이터 처리에 어려움을 줄 수 있습니다. 따라서 일관된 형식의 출력을 얻는 것은 매우 중요합니다.
system_prompt = "당신은 항상 질문에 날짜와 시간 패턴에 맞게만 답변해야 합니다."
format_instructions = output_parser.get_format_instructions()
prompt = f"{system_prompt}\n\n{user_input}\n\n{format_instructions}"
response = llm(prompt)
parsed_output = output_parser.parse(response)
사용자가 "13차 수정헌법이 언제 비준되었나요?"라고 물었을 때, 모델이 추가적인 정보 없이 정확한 날짜만 반환하도록 시스템 프롬프트를 사용합니다.
잘못된 출력 확인: 모델의 출력이 형식과 일치하지 않는 경우를 확인합니다.
Output Fixing Parser 생성: 원본 파서와 모델을 사용하여 Output Fixing Parser의 인스턴스를 생성합니다.
from langchain.output_parsers import OutputFixingParser
fixing_parser = OutputFixingParser.from_llm(parser=output_parser, llm=llm)
출력 수정 요청: 잘못된 출력을 Output Fixing Parser에 전달하여 수정된 출력을 받습니다.
fixed_output = fixing_parser.parse(bad_output)
결과 확인: 수정된 출력이 원하는 형식과 일치하는지 확인합니다.
모델이 "수정헌법 제13조는 1865년 12월 6일에 비준되었습니다."와 같이 추가 정보를 포함한 출력을 반환했을 때, Output Fixing Parser를 사용하여 정확한 날짜만 추출합니다.
아래는 위에서 설명한 두 가지 방법을 모두 포함한 전체 실습 코드입니다.
import os
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import DatetimeOutputParser, OutputFixingParser
from langchain.prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
# .env 파일에서 API 키 로드
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# LLM 모델 초기화
llm = ChatOpenAI(temperature=0.0, openai_api_key=OPENAI_API_KEY)
# 출력 파서 인스턴스 생성 (DatetimeOutputParser)
output_parser = DatetimeOutputParser()
# 형식 지침 얻기
format_instructions = output_parser.get_format_instructions()
# 사용자 요청
user_input = "13차 수정헌법이 언제 비준되었나요?"
# 방법 1: 시스템 프롬프트 사용
# 시스템 프롬프트 생성
system_prompt = SystemMessagePromptTemplate.from_template(
"당신은 항상 질문에 날짜와 시간 패턴에 맞게만 답변해야 합니다."
)
# 인간 프롬프트 생성
human_prompt = HumanMessagePromptTemplate.from_template(
"{user_input}\n\n{format_instructions}"
)
# 전체 프롬프트 구성
chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])
# 프롬프트 포맷팅
messages = chat_prompt.format_messages(
user_input=user_input, format_instructions=format_instructions
)
# 모델 응답 받기
response = llm(messages)
# 출력 파싱
try:
parsed_output = output_parser.parse(response.content)
print("방법 1 - 파싱된 출력:")
print(parsed_output)
except Exception as e:
print("방법 1 - 파싱 실패:")
print(e)
# 방법 2: Output Fixing Parser 사용
# 잘못된 출력 (시스템 프롬프트 없이 얻은 응답)
bad_response = "수정헌법 제13조는 1865년 12월 6일에 미국에서 비준되었습니다."
# Output Fixing Parser 생성
fixing_parser = OutputFixingParser.from_llm(parser=output_parser, llm=llm)
# 출력 수정 요청
try:
fixed_output = fixing_parser.parse(bad_response)
print("\n방법 2 - 수정된 출력:")
print(fixed_output)
except Exception as e:
print("방법 2 - 출력 수정 실패:")
print(e)
.env
파일에서 OPENAI_API_KEY
를 로드합니다.get_format_instructions()
를 사용하여 형식 지침을 얻습니다.user_input
: 사용자가 모델에게 묻는 질문입니다.datetime
객체로 변환합니다.방법 1 - 파싱된 출력:
1865-12-06 00:00:00
방법 2 - 수정된 출력:
1865-12-06 00:00:00
try-except
블록을 사용하여 에러를 처리합니다.이번 강의에서는 모델의 출력이 원하는 형식과 맞지 않을 때 이를 해결하는 두 가지 방법에 대해 알아보았습니다.
이러한 방법을 통해 모델의 출력 형식을 일관되게 유지하고, 후속 데이터 처리를 용이하게 할 수 있습니다.
주의: 제공된 코드를 실행하려면 .env
파일에 OPENAI_API_KEY
를 설정해야 합니다. .env
파일은 다음과 같이 작성됩니다:
OPENAI_API_KEY=YOUR_OPENAI_API_KEY
YOUR_OPENAI_API_KEY
를 실제 API 키로 교체해주세요.
이상으로 요청하신 내용을 쉽게, 자세하게, 그리고 길게 설명해 드렸습니다. 추가로 궁금하신 사항이나 도움이 필요하신 부분이 있다면 언제든지 말씀해 주세요!
안녕하세요! 요청하신 내용을 쉽게, 자세하게, 그리고 길게 설명해 드리겠습니다. 또한 마지막에 작동 가능한 전체 실습 코드를 제공해 드리겠습니다. OPENAI_API_KEY는 .env
파일에 저장하여 불러오는 방식으로 진행하겠습니다.
이번 강의에서는 Pydantic 라이브러리를 활용하여 LangChain의 출력 파서(Output Parser)를 사용하고, 이를 통해 대형 언어 모델(LLM)의 출력을 사용자 정의 Python 객체로 변환하는 방법에 대해 알아보겠습니다.
LLM은 기본적으로 문자열 형태로 응답합니다. 하지만 실제 애플리케이션에서는 이 문자열을 특정 데이터 타입이나 객체로 변환해야 할 때가 많습니다. PydanticOutputParser를 사용하면 LLM의 출력을 자동으로 사용자 정의 Pydantic 모델로 변환할 수 있습니다.
Pydantic 라이브러리가 설치되어 있지 않다면 다음 명령어를 사용하여 설치합니다:
pip install pydantic
.env
파일을 생성합니다..env
파일에 다음과 같이 API 키를 저장합니다.OPENAI_API_KEY=YOUR_OPENAI_API_KEY
YOUR_OPENAI_API_KEY
를 실제 OpenAI API 키로 대체하세요.
import os
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from langchain.prompts import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
.env
파일에서 환경 변수를 로드하기 위해 load_dotenv()
를 사용합니다.load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
class Scientist(BaseModel):
name: str = Field(description="과학자의 이름")
discoveries: list = Field(description="과학자의 발견 목록")
BaseModel
을 상속받아 Scientist
클래스를 정의합니다.name
: 과학자의 이름을 나타내는 문자열 필드입니다.discoveries
: 과학자의 발견을 담은 리스트 필드입니다.description
을 추가하여 모델에 대한 설명을 제공합니다.# PydanticOutputParser 인스턴스 생성
output_parser = PydanticOutputParser(pydantic_object=Scientist)
pydantic_object
매개변수에 우리가 정의한 Scientist
클래스를 전달합니다.Scientist
객체로 파싱합니다.# 형식 지침 얻기
format_instructions = output_parser.get_format_instructions()
# 사용자 요청
user_input = "유명한 과학자에 대해 알려주세요."
# 인간 프롬프트 생성
human_prompt = HumanMessagePromptTemplate.from_template(
"{user_input}\n\n{format_instructions}"
)
# 전체 프롬프트 구성
chat_prompt = ChatPromptTemplate.from_messages([human_prompt])
# 프롬프트 포맷팅
messages = chat_prompt.format_messages(
user_input=user_input, format_instructions=format_instructions
)
# LLM 모델 초기화
llm = ChatOpenAI(temperature=0.0, openai_api_key=OPENAI_API_KEY)
# 모델 응답 받기
response = llm(messages)
temperature
를 0으로 설정하여 출력의 일관성을 높입니다.# 출력 파싱
parsed_output = output_parser.parse(response.content)
Scientist
객체로 변환합니다.# 결과 출력
print("모델의 원본 응답:")
print(response.content)
print("\n파싱된 출력:")
print(parsed_output)
parsed_output
은 Scientist
객체입니다.아래는 위에서 설명한 모든 단계를 포함한 전체 코드입니다.
import os
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from langchain.prompts import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
# .env 파일에서 API 키 로드
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# LLM 모델 초기화
llm = ChatOpenAI(temperature=0.0, openai_api_key=OPENAI_API_KEY)
# Pydantic 모델 정의
class Scientist(BaseModel):
name: str = Field(description="과학자의 이름")
discoveries: list = Field(description="과학자의 발견 목록")
# PydanticOutputParser 인스턴스 생성
output_parser = PydanticOutputParser(pydantic_object=Scientist)
# 형식 지침 얻기
format_instructions = output_parser.get_format_instructions()
# 사용자 요청
user_input = "유명한 과학자에 대해 알려주세요."
# 인간 프롬프트 생성
human_prompt = HumanMessagePromptTemplate.from_template(
"{user_input}\n\n{format_instructions}"
)
# 전체 프롬프트 구성
chat_prompt = ChatPromptTemplate.from_messages([human_prompt])
# 프롬프트 포맷팅
messages = chat_prompt.format_messages(
user_input=user_input, format_instructions=format_instructions
)
# 모델 응답 받기
response = llm(messages)
# 출력 파싱
parsed_output = output_parser.parse(response.content)
# 결과 출력
print("모델의 원본 응답:")
print(response.content)
print("\n파싱된 출력:")
print(parsed_output)
# 파싱된 출력의 세부 정보 출력
print("\n과학자 이름:", parsed_output.name)
print("발견 목록:", parsed_output.discoveries)
.env
파일에서 OPENAI_API_KEY
를 로드합니다.ChatOpenAI
를 사용하여 LLM 모델을 초기화하고, temperature
를 0으로 설정하여 모델의 출력이 일관되게 만듭니다.output_parser
: Scientist
Pydantic 모델을 사용하여 출력 파서를 생성합니다.Scientist
객체로 파싱합니다.output_parser.parse()
를 사용하여 응답을 Scientist
객체로 변환합니다.Scientist
객체를 출력합니다.모델의 원본 응답:
{
"name": "알베르트 아인슈타인",
"discoveries": [
"특수 상대성 이론",
"일반 상대성 이론",
"광전 효과",
"브라운 운동 설명",
"에너지 질량 등가성 (E=mc²)"
]
}
파싱된 출력:
name='알베르트 아인슈타인' discoveries=['특수 상대성 이론', '일반 상대성 이론', '광전 효과', '브라운 운동 설명', '에너지 질량 등가성 (E=mc²)']
과학자 이름: 알베르트 아인슈타인
발견 목록: ['특수 상대성 이론', '일반 상대성 이론', '광전 효과', '브라운 운동 설명', '에너지 질량 등가성 (E=mc²)']
temperature
를 낮게 설정하면 모델의 출력이 더 일관적이고 예측 가능해집니다.temperature
를 낮게 설정하고, 명확한 지시를 제공합니다.이번 강의에서는 Pydantic을 활용하여 LLM의 출력을 사용자 정의 Python 객체로 변환하는 방법에 대해 알아보았습니다. 이를 통해 데이터 타입 검증과 자동 파싱이 가능하며, 후속 데이터 처리를 더욱 효율적으로 할 수 있습니다.
OPENAI_API_KEY를 .env
파일에 저장하고 불러오는 방법도 함께 살펴보았습니다. 제공된 전체 실습 코드를 직접 실행해 보시면서 이해를 더욱 깊게 하실 수 있을 것입니다.
주의: 코드를 실행하기 전에 필요한 라이브러리가 모두 설치되어 있는지 확인하세요.
pip install openai langchain pydantic python-dotenv