Nathaniel

5. Lagnchain-prompt-template 생성 본문

AI

5. Lagnchain-prompt-template 생성

Nathaniel1 2025. 3. 7. 11:54

prompt template을 생성할 때 변수 {}, {} 두 개가 있을 경우 한 개를 중간에 끼워 넣어서 변수를 대신해서 쓸 수 있다.

 

prompt_template을 만들 때, .yaml 파일 형식 안에 내가 원하는 내용을 넣어서 Template을 만들어서 사용하면 RAG를 할 때 더욱더 좋다는 것을 알 수 있다.

_type: "prompt"
template: |
  {country}의 수도에 대해서 알려주세요.
  수도의 특징을 다음의 양식에 맞게 정리해 주세요.
  300자 내외로 작성해 주세요.
  한글로 작성해 주세요.

  #양식:
  1. 면적
  2. 인구
  3. 역사적 장소
  4. 특산품

input_variables: ["country"]

 

채팅형식의 챗봇을 사용할 때는 ChatpromptTemplate를 사용하면 더 좋은 답변을 얻을 수 있다.

이유는 Chat이 붙어 있는데, 대화형 형식으로 prompt를 작성하는 것이 chat prompt작성이다.

더보기

메시지는 튜플(tuple)형식으로 구성하며, (role, Message)로 구성하여 리스트로 생성할 수 있다.

Message에는 내가 입력한 지시사항이거나, AI의 답변이 되거나 System Prompt설정이 될 수 있다.

. rolre
 - system : 시스템 설정 메시지이자 주로 전역설정 관련 프롬프트
    > "당신은 금융권에서의 전문가입니다. 앞으로의 금융관련 질문에 대해서 명확히 설명해주세요"
 - human : 사용자 입력 메시지
    > "은행마다의 적금 이자율에 대해서 알려줘"
 - ai : AI 답변 메시지
    > "OO은행, OO은행은 연 이자율 5.9%입니다"

 

Placeholder

MessagePlaceholder는 확정된 메시지가 아니지만 나중에 언제든 채워질 메시지를 Placeholder로 잡아두는 것이다.

대화내용 기록을 불러오기 위해  MessagePlaceholder, Chat history로 변수를 만들어서 기록할 수 있다.

결론 : 대화내용, 대화 기록 등을 공간만 미리 잡아두고 나중에 넣어주는 방식으로 쓸 수 있으니 유용하게 사용해 보자

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

chat_prompt = ChatPromptTemplate.from_messages(
    [
        MessagesPlaceholder(variable_name="conversation"),
        ("human", "지금까지의 대화를 {word_count} 단어로 요약합니다."),
    ]
)
chat_prompt
# chain 실행 및 결과확인
chain.invoke(
    {
        "word_count": 5,
        "conversation": [
            (
                "human",
                "처음뵙겠습니다! 저는 Nathaniel 입니다. 만나서 반갑습니다.",
            ),
            ("ai", "반가워요! 앞으로 잘 부탁 드립니다."),
        ],
    }
)

 

One-shot-prompt / Few-shot-prompt

Oneshot과 Fewshot의 차이 Oneshot은 하나의 답변 예시를 보여주었다면 Fewshot은 두 개 이상의 답변 예시를 보여준다 

내가 과거에 했던 한 개의 이력들을 input Prompt에 넣으면 One-shot

두 개의 과거 이력을 예시로 input Prompt에 넣으면 Few-shot이 된다.

그럼 예상할 수 있는 건 zero-shot은? 예시 없이 그냥 질문하는 것이 zero-shot이 된다.

 

GPT는 따라 하는 것을 굉장히 잘한다. 그래서 Few-shot_prompt를 작성하면 말 그대로 내가 하는 질문 내용 요점을 부분 수정해서 추가 질문, 중간 답변, 추가 질문, 중간 답변에 넣어 답변을 준다.

첫 번째 answer은 스티브 잡스와 아인슈타인 관련된 내용이 나오지만 사용자인 내가 다른 내용을 넣게 된다면, 스티브 잡스와 아인슈타인이 다른 이름으로 바뀌고 나머지 질문 내용을 그대로 작성되어 출력된다.

from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser


examples = [
    {
        "question": "스티브 잡스와 아인슈타인 중 누가 더 오래 살았나요?",
        "answer": """이 질문에 추가 질문이 필요한가요: 예.
추가 질문: 스티브 잡스는 몇 살에 사망했나요?
중간 답변: 스티브 잡스는 56세에 사망했습니다.
추가 질문: 아인슈타인은 몇 살에 사망했나요?
중간 답변: 아인슈타인은 76세에 사망했습니다.
최종 답변은: 아인슈타인
""",
    },
    {
        "question": "네이버의 창립자는 언제 태어났나요?",
        "answer": """이 질문에 추가 질문이 필요한가요: 예.
추가 질문: 네이버의 창립자는 누구인가요?
중간 답변: 네이버는 이해진에 의해 창립되었습니다.
추가 질문: 이해진은 언제 태어났나요?
중간 답변: 이해진은 1967년 6월 22일에 태어났습니다.
최종 답변은: 1967년 6월 22일
""",
    },
    {
        "question": "율곡 이이의 어머니가 태어난 해의 통치하던 왕은 누구인가요?",
        "answer": """이 질문에 추가 질문이 필요한가요: 예.
추가 질문: 율곡 이이의 어머니는 누구인가요?
중간 답변: 율곡 이이의 어머니는 신사임당입니다.
추가 질문: 신사임당은 언제 태어났나요?
중간 답변: 신사임당은 1504년에 태어났습니다.
추가 질문: 1504년에 조선을 통치한 왕은 누구인가요?
중간 답변: 1504년에 조선을 통치한 왕은 연산군입니다.
최종 답변은: 연산군
""",
    },
    {
        "question": "올드보이와 기생충의 감독이 같은 나라 출신인가요?",
        "answer": """이 질문에 추가 질문이 필요한가요: 예.
추가 질문: 올드보이의 감독은 누구인가요?
중간 답변: 올드보이의 감독은 박찬욱입니다.
추가 질문: 박찬욱은 어느 나라 출신인가요?
중간 답변: 박찬욱은 대한민국 출신입니다.
추가 질문: 기생충의 감독은 누구인가요?
중간 답변: 기생충의 감독은 봉준호입니다.
추가 질문: 봉준호는 어느 나라 출신인가요?
중간 답변: 봉준호는 대한민국 출신입니다.
최종 답변은: 예
""",
    },
]

 

하지만 Few-shot 예제를 넣으면 input Prompt에 적용되기 때문에 그만큼 비용 부분에서 더 많이 지출될 수 있다.

최대한 비용을 절감하고 사용하기 위해서는 입력 예제에 사용되는 예시인 Few-shot을 적게 사용하는 게 좋다.

출력되는 양에 비해 입력되는 양이 훨씬 더 많기 때문에 유의해야 한다.

 

. MMR(MaxMarginalRelevanceExampleSelector) 알고리즘

 > 답변의 취향과 답변에 대해서 다양성을 고려할 때 사용하는 알고리즘

 > 람다 값에 의해 조절이 가능하며, 값이 클수록 관련성을, 작을수록 다양성을 더 중시한다.

. SemanticSimilarityExampleSelector 알고리즘

 > 하지만 3개의 예제가 비슷하면 다양한 답변에 대한 것들을 받아볼 수 없다.

 > 유사도 기준으로 1, 2, 3등을 나눠서 답변을 나눈다.

코드는 아래와 같이 사용하면 된다.

from langchain_core.example_selectors import (
    SemanticSimilarityExampleSelector, MaxMarginalRelevanceExampleSelector)


excample_selectors 관련 Langchain 레퍼런스 주소

 

https://api.python.langchain.com/en/latest/core/example_selectors.html

 

Langsmith-hub(prompt 가져오기, 만들기)

Prompt를 어떻게 하면 가장 잘 작성해야 할지에 대해서 궁금한데 이러한 부분을 상쇄할 수 있는 것이 있다

Langchain → Langsmith에 있는 hub를 찾아보면 가장 많이 다운로드 받아온 rlm/rag-prompt라는 프롬프트 이름이다.

 

이게 굉장히 좋은 게 오픈소스로 Langchain 공식 홈페이지 hub로 받아올 수 있고, 해당 코드의 이름만 넣으면 프롬프트의 전반적인 내용들을 가져올 수 있다는 것이다.

 

 

내용은 전반적으로 엄청 길게 쓰여있는 건 아니고, 템플릿 작성 예시로 적혀있다는 것을 볼 수 있다.

코드로 간단하게 프롬프트 템플릿 rlm/rag-prompt를 가져옴

그리고 프롬프트의 버전마다 업데이트 됐을 때 해쉬코드들이 변경되는데 다른 버전의 프롬프트들을 가져오고 싶다면,

Commits을 눌러서 버전마다 업데이트되었을 때의 해쉬코드를 넣으면 된다.

해쉬코드의 번호들은 아래의 사진처럼 프롬프트 이름의 뒷부분에 넣으면 된다. 

 

반면에 내가 프로젝트를 진행했을 때, 프롬프트를 매번 작성해서 LLM 모델 프롬프트에 넣어줘야 하는데 랭체인 hub에

내가 작성한 프롬프트를 등록하면 prompt = hub.pull("내가 작성한 프롬프트 이름 / ") 코드로 불러올 수 있다~~

 

hub.push("내가 등록한 프롬프트 이름/", prompt)로 작성해서 langhcain에 올리면 내 프롬프트 등록이 완료!!!

 

 

 

'AI' 카테고리의 다른 글

7. Langchain 캐싱(API 호출 비용 감소)  (0) 2025.03.17
6. Langchain Parser??  (0) 2025.03.11
4. Runnable(Passthrough, Parallel,Lambda)  (0) 2025.03.02
3. Langchain LCEL, Parallel  (4) 2025.03.02
RAG 코드 암기하기 D1  (0) 2025.02.26