한 권으로 끝내는 랭체인 노트 따라하기 Day 3 - prompt

2024. 12. 23. 14:16·ML & DL/NLP

오늘의 실습

 

CH02 프롬프트(Prompt)

프롬프트 단계는 검색기에서 검색된 문서들을 바탕으로 **언어 모델이 사용할 질문이나 명령을 생성하는 과정**입니다. 이 단계는 **검색된 정보를 바탕**으로 최종 사용자의 질문에…

wikidocs.net

 

챗봇을 사용해 본 적이 있다면, 프롬프트라는 말을 무수히 많이 들었을 것이다. 유튜브나 책 같은 데서도 프롬프트만 알아도 달라진다 뭐 이런 것도 많고 나도 처음에는 어차피 모델의 성능이 좌우하는 것 아닌가 싶었지만 프롬프트만 바꿈으로써 모델이 내가 하는 말을 더 잘 이해하고 내가 원하는 답을 준다는 것을 깨달았다.

참고로 프롬프트는 크게 아래와 같이 4가지 구성요소로 구성된다.

출처: Upstage(https://ko.upstage.ai/blog/insight/prompt-engineering-guide-maximizing-the-use-of-llm-with-prompt-design)

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)
728x90

'ML & DL > NLP' 카테고리의 다른 글

AutoRAG 개발자님 인터뷰 정리  (0) 2025.03.19
한 권으로 끝내는 랭체인 노트 따라하기 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
'ML & DL/NLP' 카테고리의 다른 글
  • AutoRAG 개발자님 인터뷰 정리
  • 한 권으로 끝내는 랭체인 노트 따라하기 Day 4 - FewShotPrompt
  • 한 권으로 끝내는 랭체인 노트 따라하기 Day 2 - LCEL
  • 한 권으로 끝내는 랭체인 노트 따라하기 Day 1
창빵맨
창빵맨
  • 창빵맨
    Let's be Developers
    창빵맨
    로그인/로그아웃
  • 전체
    오늘
    어제
    • 분류 전체보기 (471)
      • 알쓸신잡 (79)
      • ML & DL (85)
        • Computer v.. (22)
        • NLP (22)
        • 파이썬 머신러닝 완.. (3)
        • 개념정리 (38)
      • 리눅스 (21)
      • 프로젝트 (29)
        • 산불 발생 예측 (6)
        • 음성비서 (12)
        • pdf 병합 프로그.. (0)
        • 수위 예측 (5)
        • 가짜 뉴스 분류 (5)
        • 전력사용량 예측 (1)
      • 코딩테스트 (217)
        • 프로그래머스[Pyt.. (17)
        • 프로그래머스[Fai.. (3)
        • 백준[Python] (160)
        • 이것이취업을위한코딩.. (18)
        • 파이썬 알고리즘 (19)
      • 데이터분석실습 (25)
        • 데이터 과학 기반의.. (18)
        • 헬로 데이터 과학 (7)
      • 메모장 (0)
      • 잡담 (4)
  • Personal

    GITHUB
    Instagram
  • 공지사항

  • 인기 글

  • 태그

    그리디
    DFS
    백준
    이코테
    dp
    이것이취업을위한코딩테스트다
    이분탐색
    BFS
    나동빈
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3

HOME

HOME

상단으로

티스토리툴바