실제로 응답을 생성하는 주체

AI

3 분 읽기

Output Parser

(1) 개념

  • Output Parser는 Model이 생성한 출력 결과를 원하는 형태로 변환해주는 구성요소입니다.
  • LCEL에서 Parser는 보통 Model 뒤에서 응답을 문자열, JSON 등 특정 형식으로 가공합니다.
  • 즉, Parser는 Model의 응답을 애플리케이션에서 다루기 쉬운 형태로 정리하는 역할을 담당합니다.

(2) 예시

  • ChatOpenAI 와 같은 Chat Model의 응답은 보통 AIMessage 객체입니다.
  • 먼저, Parser를 사용하지 않은 답변을 출력해보면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
AIMessage(
  content='LCEL의 Parser는 텍스트 데이터를 분석하여...',
  additional_kwargs={'refusal': None},
  response_metadata={'token_usage':
      {'completion_tokens': 96,
       'prompt_tokens': 30,
       'total_tokens': 126,
       'completion_tokens_details':
           {'accepted_prediction_tokens': 0,
            'audio_tokens': 0,
            'reasoning_tokens': 0,
            'rejected_prediction_tokens': 0
            },
            'prompt_tokens_details':
                {'audio_tokens': 0, 'cached_tokens': 0}},
                'model_provider': 'openai',
                'model_name': 'gpt-4o-mini-2024-07-18',
                'system_fingerprint': '...',
                'id': '...',
                'service_tier': 'default',
                'finish_reason': 'stop',
                'logprobs': None},
              id='..',
              tool_calls=[],
              invalid_tool_calls=[],
              usage_metadata={
                'input_tokens': 30,
                'output_tokens': 96,
                'total_tokens': 126,
                'input_token_details':
                  {'audio': 0,
                  'cache_read': 0
                  },
                'output_token_details': {'audio': 0, 'reasoning': 0}})
  • 이때 StrOutputParser 를 이용하면 응답 본문만 문자열로 쉽게 추출할 수 있습니다.
  • 즉, Parser를 사용하면 모델의 출력을 후속 처리에 적합한 형태로 변환할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
import os

# model 준비
os.environ["OPENAI_API_KEY"] = "my API Key..."
model = ChatOpenAI(model="gpt-4o-mini")

# prompt 준비
system_prompt = "{topic}에 대해 초보자도 이해할 수 있도록 3문장으로 설명하시오"
prompt = PromptTemplate.from_template(system_prompt)

# parser 준비
parser = StrOutputParser()

# chain 준비
chain = prompt | model | parser

# 추론
result = chain.invoke({"topic" : "LCEL의 Parser"})
print(result)
1
2
3
LCEL의 Parser는 텍스트 데이터를 분석하여 의미 있는 정보를 추출하는 프로그램입니다.
입력된 문장을 구성하는 단어와 구문을 이해하고, 그 관계를 파악하여 구조화된 데이터를 생성합니다.
이 과정을 통해 사용자에게 유용한 결과를 제공하고, 다양한 언어 처리 작업을 지원합니다.

(3) 종류

  • StrOutputParser : LLM의 응답에서 메타데이터를 제외하고 순수하게 메시지 내용(content)만 문자열로 추출
  • JsonOutputParser : LLM의 응답을 JSON 형식으로 변환. 보통 프롬프트에 원하는 JSON 스키마를 함께 전달하여 LLM으로부터 JSON형식의 답변을 받아올 떄 사용
  • JsonOutputKeyToolsParser : OpenAI와 같은 모델이 Tool Calling을 할 때, 도구 중 특정 키값에 해당하는 인자만 JSON 형태로 출력
  • PydanticToolsParser : 모델의 도구 호출 결과를 Pydantic 모델 객체로 변환
  • XMLOutputParser : LLM의 응답에서 XML 태그 형식을 찾아 파싱함.
  • CommaSeparatedListOutputParser : 콤마로 구분된 문자열 응답을 Python 리스트 형식으로 변환
  • BaseOutputParser : 모든 출력 파서의 최상위 추상 클래스
  • BaseLLMOutputParser : BaseOutputParser 의 하위 클래스

(4) 각 OutputParser 예시

  • JsonOutputParser : 응답을 dictionary 형태로 변환하기 쉬워집니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_openai import ChatOpenAI
import os

os.environ["OPENAI_API_KEY"] = "my API Key..."

model = ChatOpenAI(model="gpt-4o-mini")
parser = JsonOutputParser()

prompt = PromptTemplate.from_template("""
다음 질문에 답하고, 반드시 JSON 형식으로만 출력하세요.

질문: {question}

출력 형식:
{
 {
  "question": "질문 내용",
  "answer": "질문에 대한 답변"
 }
}
""")

chain = prompt | model | parser

result = chain.invoke({"question": "LCEL은 무엇인가요?"})
print(result)
1
2
3
4
5
# 출력 예시
{
  'question': 'LCEL은 무엇인가요?',
  'answer': 'LCEL은 LangChain Expression Language의 약자로, LangChain에서 체인을 선언적으로 연결하기 위한 표현 방식입니다.'
}
  • PydanticOutputParser : 출력 형식을 엄격하게 관리할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
import os

os.environ["OPENAI_API_KEY"] = "my API Key..."

class AnswerSchema(BaseModel):
    question: str = Field(description="사용자의 질문")
    answer: str = Field(description="질문에 대한 답변")

parser = PydanticOutputParser(pydantic_object=AnswerSchema)
model = ChatOpenAI(model="gpt-4o-mini")

prompt = PromptTemplate.from_template("""
다음 질문에 답하세요.

질문: {question}

{format_instructions}
""")

prompt = prompt.partial(format_instructions=parser.get_format_instructions())

chain = prompt | model | parser

result = chain.invoke({"question": "Prompt Template은 무엇인가요?"})
print(result)
1
2
3
# 출력 예시
question='Prompt Template은 무엇인가요?'
answer='Prompt Template은 변수 값을 삽입해 재사용 가능한 프롬프트를 만들기 위한 템플릿입니다.'

(5) Parser를 이용하는 이유

  • Model의 출력은 그대로 사용하기 어려울 수 있으므로, 원하는 형태로 변환 필요
  • 어떤 때는 문자열, 또 다른 상황에서는 JSON 등 상황에 따라 필요한 응답 구조를 사용
  • 이를 통해 후속 코드에서 결과를 쉽게 재사용할 수 있음
  • LCEL에서는 prompt | model | parser 형태로 연결해서 사용

// reading compass

이 글과 이어지는 경로

시리즈, 카테고리, 태그 겹침, 최신도를 점수화해 가까운 글일수록 중심에 배치합니다.

hover nodes or cards · click a node to pin
Next reads 0

    댓글 남기기