OutputFixingParser는 LLM(Large Language Model)의 출력에서 발생할 수 있는 오류나 형식 문제를 수정해주는 도구입니다. Langchain은 LLM을 활용한 애플리케이션 개발을 지원하는 프레임워크로, 모델의 출력이 예상한 형식(예: JSON, 특정 데이터 구조 등)을 따르지 않을 때 이를 보정하는 데 OutputFixingParser가 유용하게 사용됩니다.
주요 개념
LLM은 텍스트 생성에 강력하지만, 때로는 사용자가 원하는 정확한 형식이나 구조를 따르지 않는 출력을 내놓을 수 있습니다. 예를 들어:
- JSON 형식이어야 할 출력에서 구문 오류가 발생하거나
- 필수 필드가 누락되거나
- 데이터 타입이 일치하지 않는 경우
OutputFixingParser는 이런 문제를 해결하기 위해 설계되었으며, 원래의 출력 파서(PydanticOutputParser 등)와 결합하여 모델이 생성한 잘못된 출력을 자동으로 수정하거나 재시도하도록 돕습니다.
동작 방식
- 기본 파서와 함께 사용: OutputFixingParser는 보통 PydanticOutputParser 같은 기존 파서를 래핑(wrap)하여 동작합니다. 이 기본 파서는 출력이 따라야 할 스키마(예: Pydantic 모델)를 정의합니다.
- 오류 감지: LLM 출력이 스키마에 맞지 않으면(예: JSON 파싱 실패, 필드 누락 등), OutputFixingParser가 이를 감지합니다.
- 출력 수정 시도:
- LLM에게 잘못된 출력을 기반으로 다시 생성하도록 요청하거나
- 자체적으로 간단한 수정(예: 누락된 필드 채우기, 구문 오류 수정 등)을 시도합니다.
- 결과 반환: 수정된 출력을 사용자에게 반환하거나, 수정이 불가능한 경우 오류를 발생시킵니다.
from langchain.output_parsers import PydanticOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field
from typing import List
class Actor(BaseModel):
name: str = Field(description="name of an actor")
film_names: List[str] = Field(description="list of names of films they starred in")
parser = PydanticOutputParser(pydantic_object=Actor)
# 잘못된 형식을 일부러 입력
misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
# 잘못된 형식으로 입력된 데이터를 파싱하려고 시도
parser.parse(misformatted)
langchain_core.exceptions.OutputParserException: Invalid json output: {‘name’: ‘Tom Hanks’, ‘film_names’: [‘Forrest Gump’]}
For troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE
OutputFixingParser 를 사용하여 잘못된 형식을 바로 잡도록 하겠습니다.
from langchain.output_parsers import PydanticOutputParser, OutputFixingParser
from pydantic import BaseModel, Field
from typing import List
from langchain_ollama import OllamaLLM
from langchain.prompts import PromptTemplate
class Actor(BaseModel):
name: str = Field(description="name of an actor")
film_names: List[str] = Field(description="list of names of films they starred in")
parser = PydanticOutputParser(pydantic_object=Actor)
misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
llm_model = OllamaLLM(model="exaone3.5", temperature=0)
fix_prompt = PromptTemplate(
template="Instructions:\nPlease correct it.\n\nCompletion:\n{completion}\n\nHuman: The above output was supposed to be in the following format:\njson \nPlease fix it.\n\nAssistant: Here's the fixed output:",
input_variables=["instructions", "completion", "format_instructions"]
)
new_parser = OutputFixingParser.from_llm(parser=parser, llm=llm_model, prompt=fix_prompt)
# OutputFixingParser를 사용하여 잘못된 형식의 출력을 파싱
actor = new_parser.parse(misformatted)
print(actor)
name=’Tom Hanks’ film_names=[‘Forrest Gump’]
이렇게 수정된 코드를 활용하여, “톰행크스가 출현한 영화 알려주세요.”이 질문을 template에 맞추어 대답을 얻습니다.
from langchain_core.prompts import PromptTemplate
# 프롬프트 템플릿을 생성합니다.
prompt = PromptTemplate.from_template(
"answer the question\nQuery: {query}\nInstructions: {instructions}").partial(instructions=new_parser.get_format_instructions()
)
from langchain_ollama import OllamaLLM
llm_model = OllamaLLM(model="exaone3.5", temperature=0)
# 프롬프트와 Ollama, 파서를 연결합니다.
chain = prompt | llm_model | new_parser
response = chain.invoke({"query": "톰행크스가 출현한 영화 알려주세요."})
print(response)
name=’톰행크스’ film_names=[‘포레스트 검프’, ‘캐스트 어웨이’, ‘시애틀의 잠 못 이루는 밤’, ‘빅’, ‘인터스텔라’, ‘토이 스토리 시리즈 (목소리 연기 포함)’]