langchain / / 2024. 8. 31. 09:54

[langchain] PromptTemplate, ChatPromptTemplate 사용법

LangChain을 활용하여 대화형 AI 모델의 프롬프트를 효율적으로 구성하고 관리하는 방법을 알아보자. 특히, PromptTemplateChatPromptTemplate을 이용해 다양한 방식으로 프롬프트를 생성하고 사용하는 방법을 예제를 통해 살펴보자.

PromptTemplate

1. from_template을 통해 한번에 prompt 만드는 방법

PromptTemplatefrom_template 메서드를 사용하면 간단히 프롬프트를 만들 수 있다. 아래 예시는 특정 작업을 지정된 프로그래밍 언어로 수행하는 로직을 요청하는 프롬프트를 생성하는 방법을 보여준다.

from langchain_core.prompts import PromptTemplate

template = "{task}을 수행하는 로직을 {language}으로 작성해 줘~"

prompt_template = PromptTemplate.from_template(template)
prompt = prompt_template.format(task="0부터 10까지 계산", language="파이썬")

if __name__ == "__main__":
    print(prompt)  # 0부터 10까지 계산을 수행하는 로직을 파이썬으로 작성해 줘~

2. 생성자를 통해 prompt_template을 생성하는 방법

PromptTemplate은 생성자를 통해서도 만들 수 있다. 이 방법을 사용하면 input_variables를 명시적으로 지정할 수 있다. 흥미롭게도, input_variables를 생략해도 프롬프트 생성이 가능하다.

from langchain_core.prompts import PromptTemplate

template = "{task}을 수행하는 로직을 {language}으로 작성해 줘~"
prompt_template = PromptTemplate(
    template=template,
    input_variables=["task", "language"],
    # input_variables=[],  # input_variables=[] 으로 해도 실행된다.
)

prompt = prompt_template.format(task="0부터 10까지 계산", language="파이썬")
if __name__ == "__main__":
    print(prompt)  # 0부터 10까지 계산을 수행하는 로직을 파이썬으로 작성해 줘~

PromptTemplate의 input_variables은 없어도 동일하게 실행이 된다.

prompt_template = PromptTemplate(
    template=template,
    # input_variables=[],  # input_variables=[] 으로 해도 실행된다.
)

3. json 파일을 통해 PromptTemplate 생성하는 방법

프롬프트 템플릿을 JSON 파일로 관리할 수도 있다. 이를 통해 프롬프트 구성을 외부 파일에서 불러와 사용할 수 있다.

from langchain_core.prompts import load_prompt

prompt_template = load_prompt("sample/template.json")
prompt = prompt_template.format(task="0부터 10까지 계산", language="파이썬")
print(prompt) # 0부터 10까지 계산을 수행하는 로직을 파이썬으로 작성해 줘~

template.json 파일 내용

{
  "name": null,
  "input_variables": [
    "task",
    "language"
  ],
  "input_types": {},
  "output_parser": null,
  "partial_variables": {},
  "template": "{task}을 수행하는 로직을 {language}으로 작성해 줘~",
  "template_format": "f-string",
  "validate_template": false,
  "_type": "prompt"
}

4. partial_variables으로 함수를 전달하여 prompt_template을 생성하는 방법

partial_variables는 체인의 일부 변수에 대해 미리 정의된 값을 제공하여 체인 실행에 필요한 모든 변수를 한 번에 지정하지 않고도 체인을 실행할 수 있다. 예를 들어, 체인의 일부 변수는 고정된 값으로 설정하고 나머지 변수만 실행 시점에 제공하도록 할 수 있다.

def get_language():
    return "파이썬"

prompt_template = PromptTemplate(
    template="{task}을 수행하는 로직을 {language}으로 작성해 줘~",
    input_variables=["task"],
    partial_variables={"language": get_language},  # partial_variables에 함수를 전달
)

prompt = prompt_template.format(task="0부터 10까지 계산")
print(prompt)

위의 로직은 아래와 같이 RunnablePassthrough를 사용하여 더 유연하게 적용할 수 있다.

prompt_template = PromptTemplate(
    template="{task}을 수행하는 로직을 {language}으로 작성해 줘~",
    input_variables=["task"],
    partial_variables={"language": get_language},
)
runnable_template = {"task": RunnablePassthrough()} | prompt_template
prompt = runnable_template.invoke("0부터 10까지 계산")
print(prompt.text)

ChatPromptTemplate

대화형 AI 모델에 특화된 프롬프트 템플릿을 만들 때는 ChatPromptTemplate을 사용할 수 있다. 이는 메시지 기반의 대화 흐름을 구성하는 데 유용하다.

from langchain_core.prompts import ChatPromptTemplate

prompt_template = ChatPromptTemplate.from_messages(
    [
        ("system", "당신은 맛집 전문가이다."),
        ("ai", "나는 {city}을 방문하려고 한다."),
        ("human", "{question}"),
    ]
)

prompt = prompt_template.format_messages(city="서울", question="맛집 추천해줘")
print(prompt) 

실행 결과는 메시지 리스트로 반환된다.

실행결과

 [
     SystemMessage(content='당신은 맛집 전문가이다.'), 
     AIMessage(content='나는 서울을 방문하려고 한다.'), 
     HumanMessage(content='맛집 추천해줘')
 ]

또는 invoke 메서드를 사용하면 동일한 결과를 얻을 수 있다.

prompt = prompt_template.invoke({"city": "서울", "question": "맛집 추천해줘"})
print(prompt) # 

실행결과

messages=[SystemMessage(content='당신은 맛집 전문가이다.'), AIMessage(content='나는 서울을 방문하려고 한다.'), HumanMessage(content='맛집 추천해줘')]

MessagePlaceholder

체인의 메시지 흐름에서 특정 위치에 동적으로 삽입될 메시지를 추가하는데 사용된다. 이는 대화형 AI 모델이나 다른 응답 생성 시스템을 구축할 때 유용하며, 특정 메시지가 실행 시점에 동적으로 생성되거나 제공되어야 하는 경우에 사용된다.

LLM 호출할 때 이전 메시지 내용을 전부 전달할 때 사용되며 우리가 메시지 내용을 일일히 구성할 필요없이 이전 메시지 내용을 conversation 배열에 넣어서 전달하고 위치만 정하면 알아서 메시지 내용을 구성해준다.

template = ChatPromptTemplate(
    [
        ("system", "너는 AI 봇이야"),
        ("placeholder", "{conversation}"),
        ("human", "거기에 1을 더하면?"),
    ]
)

ChatPromptTemplateplaceholder를 키로 conversation을 추가하면 된다. 또는 아래와 같이 사용해도 된다.

template = ChatPromptTemplate(
    [
        ("system", "너는 AI 봇이야"),
        MessagesPlaceholder(variable_name="conversation", optional=True)
        ("human", "거기에 1을 더하면?"),
    ]
)

실제 사용을 할 때는 아래와 같이 conversation에 이전 대화 이력을 추가하고 호출하면 된다.

prompt = template.invoke(
    {
        "conversation": [
            ("human", "안녕~"),
            ("ai", "무엇을 도와드릴까요?"),
            ("human", "1+1은 뭐야?"),
            ("ai", "2입니다."),
        ]
    }
)

print(prompt)

실행결과

messages=[SystemMessage(content='너는 AI 봇이야'), HumanMessage(content='안녕~'), AIMessage(content='무엇을 도와드릴까요?'), HumanMessage(content='1+1은 뭐야?'), AIMessage(content='2입니다.'), HumanMessage(content='거기에 1을 더하면?')]

실제 LLM을 호출해보자.

langchain.debug = True
load_dotenv()

llm = ChatOpenAI(temperature=0, model_name="gpt-4o")

chain = template | llm | StrOutputParser()
result = chain.invoke(
    {
        "conversation": [
            ("human", "안녕~"),
            ("ai", "무엇을 도와드릴까요?"),
            ("human", "1+1은 뭐야?"),
            ("ai", "2입니다."),
        ]
    }
)

print(result)

langchain.debug = True를 해서 실제 llm 호출내용을 확인해보면 아래와 같다.

[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
  "prompts": [
    "System: 너는 AI 봇이야\nHuman: 안녕~\nAI: 무엇을 도와드릴까요?\nHuman: 1+1은 뭐야?\nAI: 2입니다.\nHuman: 거기에 1을 더하면?"
  ]
}

System, Human, Ai의 메시자가 \n를 구분으로 입력이 된다.

참고

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유