LangChain: Prompt Template으로 프롬프트 다루기

PromptTemplate

LangChain의 프롬프트 템플릿은 LLMs에 메시지를 전달하기 전에 문장 구성을 편리하게 만들어주는 기능입니다. 코드를 보겠습니다.

from langchain.prompts import PromptTemplate

prompt = PromptTemplate.from_template("부산에 대해 알려줘.")
prompt.format() # 결과: "부산에 대해 알려줘."

이게 다라면 그냥 문자열을 쓰는게 더 간편하겠죠? 포맷 기능을 봅시다.

from langchain.prompts import PromptTemplate

prompt = PromptTemplate.from_template("{city}에 대해 알려줘.")
prompt.format(city="부산") # 결과: "부산에 대해 알려줘."

# 다른 방법
prompt = PromptTemplate(input_variables=["city"],
                        template="{city}에 대해 알려줘.")
prompt.format(city="부산") # 결과: "부산에 대해 알려줘."

사실 위의 포맷 기능도 파이썬 기본 문자열에서 지원하는 기능입니다. 그럼에도 불구하고 프롬프트 템플릿을 사용하면 코드 가독성, 일관성과 재사용성이 좋아지고, 에러를 방지할 수 있습니다.

ChatPromptTemplate

앞에서 본 PromptTemplate은 기본적으로 문장 완성 모델(Completion model: llms)을 위한 템플릿입니다. 챗모델(Chat completion model: chat_models)을 위한 템플릿은 ChatPromptTemplate입니다.

from langchain.prompts import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
)

system_message_prompt = SystemMessagePromptTemplate.from_template(
    "당신은 {input_language}를 {output_language}로 번역하는 전문 번역가입니다."
)

human_message_prompt = HumanMessagePromptTemplate.from_template("{text}")

chat_prompt = ChatPromptTemplate.from_messages(
    [system_message_prompt, human_message_prompt]
)

chat_prompt.format_messages(input_language="영어", output_language="한국어", text="I love programming.")

### 결과
[SystemMessage(content='당신은 영어를 한국어로 번역하는 전문 번역가입니다.', additional_kwargs={}),
 HumanMessage(content='I love programming.', additional_kwargs={}, example=False)]

SystemMessagePromptTemplate과 HumanMessagePromptTemplate은 각각 시스템 메시지와 사용자 메시지를 만드는 템플릿입니다. ChatPromptTemplate은 위 코드에서와 같이 메시지들의 리스트를 입력으로 받습니다. 포맷할 때도 format_messages를 사용하는데, 시스템 메시지의 변수인 input_languageoutput_language, 사용자 메시지의 변수인 text를 모두 치환할 수 있습니다. 위 코드는 아래와 같이 쓸 수도 있습니다.

from langchain.prompts import ChatPromptTemplate

chat_prompt = ChatPromptTemplate.from_messages(
    [("system","당신은 {input_language}를 {output_language}로 번역하는 전문 번역가입니다."),
     ("human","{text}")]
)

chat_prompt.format_messages(input_language="영어", output_language="한국어", text="I love programming.")

시스템 메시지와 사용자 메시지를 (type, content) 튜플로 만들어서 입력했습니다. 앞에서는 MessagePromptTemplate를 사용했었죠. 그래도 결과는 동일합니다. 치환이 필요 없는 경우 BaseMessage 객체(아래에서 SystemMessage)를 사용하는 것도 가능합니다.

from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import SystemMessage, HumanMessagePromptTemplate

template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(content="당신은 영어를 한국어로 번역하는 전문 번역가입니다."),
        HumanMessagePromptTemplate.from_template("{text}")
    ]
)

from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI()
llm(template.format_messages(text='I love programming.'))

### 결과
AIMessage(content='나는 프로그래밍을 사랑합니다.', additional_kwargs={}, example=False)

참고로, 위 코드들에서 ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate은 langchain.prompts 또는 langchain.prompts.chat 모듈에서 import 가능합니다. 반면에 SystemMessage는 langchain.prompts.chat 모듈에서 import 해야 합니다.

기타 프롬프트 템플릿, 메시지 프롬프트 템플릿과 메시지 클래스

위에서 다룬 프롬프트 템플릿 외에도 예제를 제시하기 위한 FewShotPromptTemplate, FewShotChatMessagePromptTemplate이 있고, 여러 개의 예제들 중 몇 개를 추출해서 넣을 수 있는 ExampleSelector들도 있습니다. StringPromptTemplate을 이용해 사용자 정의 프롬프트 템플릿을 만들 수도 있습니다.

MessagePromptTemplate에는 HumanMessagePromptTemplate 외에도 SystemMessagePromptTemplate과 AIMessagePromptTemplate이 있습니다. 다른 role을 지정하고 싶으면 ChatMessagePromptTemplate를 사용하면 됩니다.

BaseMessage에는 SystemMessage 외에도 HumanMessage, AIMessage, FunctionMessage도 있습니다.

댓글 남기기