오늘의 실습
챗봇을 사용해 본 적이 있다면, 프롬프트라는 말을 무수히 많이 들었을 것이다. 유튜브나 책 같은 데서도 프롬프트만 알아도 달라진다 뭐 이런 것도 많고 나도 처음에는 어차피 모델의 성능이 좌우하는 것 아닌가 싶었지만 프롬프트만 바꿈으로써 모델이 내가 하는 말을 더 잘 이해하고 내가 원하는 답을 준다는 것을 깨달았다.
참고로 프롬프트는 크게 아래와 같이 4가지 구성요소로 구성된다.
PromptTemplate
from_template
템플릿을 정의하며, input이 되는 변수를 `{}`로 감싸준다.
from langchain_core.prompts import PromptTemplate
template = "{person}의 국적은 어디인가요?"
prompt = PromptTemplate.from_template(template)
print(prompt)
>> PromptTemplate(input_variables=['person'], input_types={}, partial_variables={}, template='{person}의 국적은 어디인가요?')
다음으로 chain을 이용하여 prompt와 모델을 연결해주고, 변숫값을 넣어서 출력해 준다. 이때 template에 지정한 변수명을 key값, 값을 value로 딕셔너리로 전달해 주지만 만약 template에 변수가 하나라면 값만 넣어줘도 된다.
chain = prompt | llama
chain.invoke("박지성").content
>> '박지성은 한국의 축구 선수입니다.'
이 PromptTemplate을 `from_template()` 메소드말고 바로 정의할 수 있는데 아래와 같이 template과 input_variables 인자를 사용해 주면 된다.(input_varaibles는 필수가 아님) 변수가 여러 개일 때는 단순하게 input_variables에 여러 개를 리스트형식으로 적으면 된다.
template = "{person1}과 {person2}의 국적은 각각 어디인가요?"
prompt = PromptTemplate(
template=template,
input_variables=["person1","person2"],
)
prompt
>> PromptTemplate(input_variables=['person1', 'person2'], input_types={}, partial_variables={}, template='{person1}과 {person2}의 국적은 각각 어디인가요?')
partial_variables
`partial_variables`는 부분변수로 함수의 기본값처럼 혹은 공통된 방시긍로 가져오고 싶은 변수가 있을 때 사용한다. 미리 값 또는 함수를 적어주는 것이다.
from datetime import datetime
def get_today():
return datetime.now().strftime("%B %d")
template = "{today}기준으로 나이가 {age}살인 유명한 사람의 이름과 생년월일을 알려주세요."
prompt = PromptTemplate(
template=template,
input_variables=["age"],
partial_variables={
"today": get_today # dictionary 형태로 partial_variables를 전달
},
)
chain = prompt | llama
print(chain.invoke(26).content
>> 26살이란 나이는 1997년 12월 23일에 태어난 사람입니다.
다음은 26살이란 나이가 있는 유명한 사람들의 이름과 생년월일입니다.
1. 이민호 (Kim Min-ho) - 1992년 12월 23일
2. 이승기 (Lee Seung-gi) - 1988년 12월 23일
3. 이재영 (Lee Jae-young) - 1990년 12월 23일
4. 정성환 (Jeong Sung-hwan) - 1977년 12월 23일
5. 김태형 (Kim Tae-hyung) - 1993년 12월 23일
load_prompt
다음으로 prompt를 파일로부터 읽어올 수 있다.(테디노트님의 `capital.yaml` 사용)
from langchain_core.prompts import load_prompt
prompt = load_prompt("prompts/capital.yaml")
prompt
>> PromptTemplate(input_variables=['country'], input_types={}, partial_variables={}, template='{country}의 수도에 대해서 알려주세요.\n수도의 특징을 다음의 양식에 맞게 정리해 주세요.\n300자 내외로 작성해 주세요.\n한글로 작성해 주세요.\n----\n[양식]\n1. 면적\n2. 인구\n3. 역사적 장소\n4. 특산품\n\n#Answer:\n')
ChatPromptTemplate
일반적인 prompt와는 다르게, 대화목록을 프롬프트로 넣을 때 사용할 수 있다. 이 때 `role(역할)`과 `message`를 튜플형식으로 구성해서 리스트로 묶어서 생성한다.
이때 role은 'human', 'user', 'ai', 'assistant', 'function', 'tool', 'system', or 'developer' 중 하나를 사용할 수 있다.
from langchain_core.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
# role, message
("system", "너는 매우 똑똑한 해양전문가 AI 챗봇이야. 너를 만든사람의 이름은 {name} 이야."),
("human", "안녕"),
("ai", "안녕하세요! 무엇을 도와드릴까요?"),
("human", "{user_input}"),
]
)
chain = chat_template | llama
chain.invoke({"name": "noname", "user_input": "너를 만든사람은 누구고 너는 뭘하는 거니?"})
>> AIMessage(content="저는 'noname'이라는 이름의 개발자에 의해 만들어졌습니다. 저는 해양과 관련된 정보를 제공하고, 해양-related 질문을 받은 경우에 대한 도움을 주기 위해 설계되었습니다.\n\n저는 해양-related 정보, 해양 지식, 해양 뉴스, 해양 사진 및 비디오, 해양 게임 등 다양한 항목을 제공할 수 있습니다. 또한, 저는 해양과 관련된 질문이나 문제를 받은 경우에 대한 도움을 주기 위해 사용할 수 있습니다.\n\n저는 해양과 관련된 정보를 제공하는 것뿐만 아니라, 해양과 관련된 질문이나 문제를 받은 경우에 대한 도움을 주기 위해 사용할 수 있는 다양한 기능을 가지고 있습니다.", additional_kwargs={}, response_metadata={'model': 'llama3.2:latest', 'created_at': '2024-12-23T04:33:53.625028145Z', 'done': True, 'done_reason': 'stop', 'total_duration': 2226274332, 'load_duration': 36580565, 'prompt_eval_count': 98, 'prompt_eval_duration': 27000000, 'eval_count': 164, 'eval_duration': 1471000000, 'message': Message(role='assistant', content='', images=None, tool_calls=None)}, id='run-91e0a3d9-6379-4a9b-b42c-26996d7e72d5-0', usage_metadata={'input_tokens': 98, 'output_tokens': 164, 'total_tokens': 262})
MessagePlaceholder
MessagePlaceholder은 어떤 role을 사용할지 정해지지 않았을 때 서식지정을 하며 메시지를 넣을 때 사용된다.
아래 예시를 보면 conversation에 대한 내용이 아직 삽입되지 않았고, 이 conversation에 동일하게 role과 message형태로 넣어줄 수 있다.
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
chat_prompt = ChatPromptTemplate.from_messages(
[
("system","당신은 번역 전문 AI 어시스턴트입니다. 당신의 임무는 대화의 {lang}를 {lang2}로 번역하는 것입니다"),
MessagesPlaceholder(variable_name="conversation"),
("human", "지금까지의 대화를 {lang}에서 {lang2}로 요약합니다."),
]
)
chat_prompt
chain = chat_prompt | llama | StrOutputParser()
answer = chain.invoke(
{
"lang": "english",
"lang2": "korean",
"conversation": [
("human", "hello my name is john"),
("ai", "nice to meet you"),
("human", "how are you doing today"),
("ai", "i'm doing well thank you"),
("human", "what do you do for a living"),
],
}
)
print(answer)
>> (Translation Summary in Korean):
존이라는 이름의 사람이 인사를 건네고, 오늘 어떻게 지내는지 물었습니다. 저는 잘 지내고 있다고 답했습니다. 그리고 상대방의 직업에 대해 묻고 있습니다.
저작자: 테디노트 / <랭체인 LangChain 노트> - LangChain 한국어 튜토리얼 / (CC BY-NC-ND 2.0 KR)
'ML & DL > NLP' 카테고리의 다른 글
한 권으로 끝내는 랭체인 노트 따라하기 Day 4 - FewShotPrompt (0) | 2024.12.23 |
---|---|
한 권으로 끝내는 랭체인 노트 따라하기 Day 2 - LCEL (0) | 2024.12.23 |
한 권으로 끝내는 랭체인 노트 따라하기 Day 1 (0) | 2024.12.23 |
한 권으로 끝내는 랭체인 노트 따라하기 Day 0 (0) | 2024.12.20 |
[패캠/NLP] BERT (0) | 2023.12.28 |