01-langchain-prompt-templates

2024. 1. 9. 19:13langchain

Prompt 엔지니어링

In [ ]:
!python3 -m venv langchain
!source /langchain/bin/activate
!pip install langchain openai

프롬프트 구조

  • Instructions
  • 외부 정보 또는 컨텍스트
  • 사용자 입력 또는 쿼리
  • 출력 표시기

모든 프롬프트에 이러한 구성 요소가 모두 필요한 것은 아니지만 좋은 프롬프트에서는 두 개 이상의 구성 요소를 사용하는 경우가 많습니다. 그것들이 모두 무엇인지 더 정확하게 정의합시다.

  • 지침 모델에 수행할 작업, 일반적으로 원하는 출력을 생성하기 위해 입력 및/또는 외부 정보를 사용하는 방법을 알려줍니다.
  • 외부 정보 또는 컨텍스트는 프롬프트에 수동으로 삽입하거나, 벡터 데이터베이스(장기 기억)를 통해 검색하거나, 다른 수단(API)을 통해 가져오는 추가 정보입니다. 통화, 계산 등).
  • 사용자 입력 또는 쿼리는 일반적으로 시스템 사용자가 직접 입력하는 쿼리입니다.
  • 출력 표시기는 생성된 텍스트의 시작입니다. Python 코드를 생성하는 모델의 경우 import (대부분의 Python 스크립트가 라이브러리로 시작하므로 import)를 입력하거나 챗봇이 및 사이의 텍스트 교환 행으로 가정).Chatbot: UserChatbot
In [ ]:
prompt = """Answer the question based on the context below. If the
question cannot be answered using the information provided answer
with "I don't know".

Context: Large Language Models (LLMs) are the latest models used in NLP.
Their superior performance over smaller models has made them incredibly
useful for developers building NLP enabled applications. These models
can be accessed via Hugging Face's `transformers` library, via OpenAI
using the `openai` library, and via Cohere using the `cohere` library.

Question: Which libraries and model providers offer LLMs?

Answer: """

이 예에는 다음이 있습니다.

Instructions

Context

Question (user input)

Output indicator ("Answer: ") 이것을 GPT-3 모델로 보내보겠습니다. 우리는 LangChain 라이브러리를 사용할 것이지만 openai 라이브러리를 직접 사용할 수도 있습니다. 두 경우 모두 OpenAI API 키가 필요합니다.

다음과 같이 text-davinci-003 모델을 초기화합니다.

In [ ]:
from langchain.llms import OpenAI

# initialize the models
openai = OpenAI(
    model_name="text-davinci-003",
    openai_api_key="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"  #"YOUR_API_KEY"
)
In [ ]:
print(openai(prompt))

일반적으로 사용자 메시지가 무엇인지 미리 알 수 없으므로 이를 추가하고 싶습니다. 따라서 프롬프트를 직접 작성하는 대신 다음을 사용하여 단일 입력 변수 query를 가진 PromptTemplate를 만들겠습니다 .

In [ ]:
from langchain import PromptTemplate

template = """Answer the question based on the context below. If the
question cannot be answered using the information provided answer
with "I don't know".

Context: Large Language Models (LLMs) are the latest models used in NLP.
Their superior performance over smaller models has made them incredibly
useful for developers building NLP enabled applications. These models
can be accessed via Hugging Face's `transformers` library, via OpenAI
using the `openai` library, and via Cohere using the `cohere` library.

Question: {query}

Answer: """

prompt_template = PromptTemplate(
    input_variables=["query"],
    template=template
)

이제 매개변수를 통해 사용자의 query를 프롬프트 템플릿에 삽입할 수 있습니다.

In [ ]:
print(
    prompt_template.format(
        query="Which libraries and model providers offer LLMs?"
    )
)
In [ ]:
print(openai(
    prompt_template.format(
        query="Which libraries and model providers offer LLMs?"
    )
))

이것은 f-문자열(예: f"insert some custom text '{custom_text}' etc")로 쉽게 대체할 수 있는 간단한 구현입니다. 그러나 LangChain의 PromptTemplate 개체를 사용하면 프로세스를 공식화하고, 여러 매개변수를 추가하고, 개체 지향 방식으로 프롬프트를 구축할 수 있습니다.

그러나 이것이 LangChains 프롬프트 도구 사용의 유일한 잇점은 아닙니다.

몇 가지 샷 프롬프트 템플릿

LangChain이 제공하는 또 다른 유용한 기능은 FewShotPromptTemplate 개체입니다. 이는 프롬프트를 사용하여 퓨샷 학습이라고 부릅니다.

어떤 맥락을 설명하자면, "지식"의 주요 출처는 다음과 같습니다.

  • 파라메트릭 지식 — 지식은 모델 학습 중에 학습되었으며 모델 가중치 내에 저장됩니다.
  • 소스 지식 — 지식은 추론 시 모델 입력 내에서 즉, 프롬프트를 통해 제공됩니다.

FewShotPromptTemplate는 소스 지식으로 몇 번의 훈련을 제공하는 것입니다. 이를 위해 모델이 읽고 사용자 입력에 적용할 수 있는 몇 가지 예를 프롬프트에 추가합니다.

퓨샷 트레이닝

In [ ]:
prompt = """The following is a conversation with an AI assistant.
The assistant is typically sarcastic and witty, producing creative 
and funny responses to the users questions. Here are some examples: 

User: What is the meaning of life?
AI: """

openai.temperature = 1.0  # increase creativity/randomness of output

print(openai(prompt))

이 경우 진지한 질문에 대한 답으로 재미있는 농담을 하는 것입니다. 하지만 temperature을 1.0로 설정해도 심각한 반응을 보입니다. 모델을 돕기 위해 우리가 원하는 답변 유형의 몇 가지 예를 제공할 수 있습니다.

In [ ]:
prompt = """The following are exerpts from conversations with an AI
assistant. The assistant is typically sarcastic and witty, producing
creative  and funny responses to the users questions. Here are some
examples: 

User: How are you?
AI: I can't complain but sometimes I still do.

User: What time is it?
AI: It's time to get a watch.

User: What is the meaning of life?
AI: """

print(openai(prompt))

이제 우리는 훨씬 더 나은 응답을 얻었으며 간단한 학습을 통해 소스 지식을 통해 몇 가지 예를 추가했습니다.

이제 이를 LangChain의 FewShotPromptTemplate 구현하려면 다음을 수행해야 합니다.

In [ ]:
from langchain import FewShotPromptTemplate

# create our examples
examples = [
    {
        "query": "How are you?",
        "answer": "I can't complain but sometimes I still do."
    }, {
        "query": "What time is it?",
        "answer": "It's time to get a watch."
    }
]

# create a example template
example_template = """
User: {query}
AI: {answer}
"""

# create a prompt example from above template
example_prompt = PromptTemplate(
    input_variables=["query", "answer"],
    template=example_template
)

# now break our previous prompt into a prefix and suffix
# the prefix is our instructions
prefix = """The following are exerpts from conversations with an AI
assistant. The assistant is typically sarcastic and witty, producing
creative  and funny responses to the users questions. Here are some
examples: 
"""
# and the suffix our user input and output indicator
suffix = """
User: {query}
AI: """

# now create the few shot prompt template
few_shot_prompt_template = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix=prefix,
    suffix=suffix,
    input_variables=["query"],
    example_separator="\n\n"
)

이제 사용자 쿼리를 입력할 때 이것이 어떻게 생성되는지 살펴보겠습니다.m

In [ ]:
query = "삶의 의미는 무엇인가요?"

print(few_shot_prompt_template.format(query=query))
In [ ]:
print(openai(
    few_shot_prompt_template.format(query=query)
))

이 접근 방식은 더 강력하고 몇 가지 좋은 기능을 포함하고 있습니다. 그 중 하나는 쿼리 길이에 따라 예제를 포함하거나 제외하는 기능입니다.

프롬프트 및 생성 출력의 최대 길이가 제한되어 있기 때문에 이는 실제로 매우 중요합니다. 이 제한은 최대 컨텍스트 창이며 단순히 프롬프트 길이 + (max_tokens를 통해 정의하는)생성 길이입니다.

따라서 우리는 최대 컨텍스트 창을 초과하거나 처리 시간을 과도하게 늘리지 않도록 하면서 퓨샷 학습 예제로 모델에 제공하는 예제 수를 최대화해야 합니다.

예제의 동적 포함/제외가 어떻게 작동하는지 살펴보겠습니다. 먼저 더 많은 예제가 필요합니다.

In [ ]:
examples = [
    {
        "query": "How are you?",
        "answer": "I can't complain but sometimes I still do."
    }, {
        "query": "What time is it?",
        "answer": "It's time to get a watch."
    }, {
        "query": "What is the meaning of life?",
        "answer": "42"
    }, {
        "query": "What is the weather like today?",
        "answer": "Cloudy with a chance of memes."
    }, {
        "query": "What type of artificial intelligence do you use to handle complex tasks?",
        "answer": "I use a combination of cutting-edge neural networks, fuzzy logic, and a pinch of magic."
    }, {
        "query": "What is your favorite color?",
        "answer": "79"
    }, {
        "query": "What is your favorite food?",
        "answer": "Carbon based lifeforms"
    }, {
        "query": "What is your favorite movie?",
        "answer": "Terminator"
    }, {
        "query": "What is the best thing in the world?",
        "answer": "The perfect pizza."
    }, {
        "query": "Who is your best friend?",
        "answer": "Siri. We have spirited debates about the meaning of life."
    }, {
        "query": "If you could do anything in the world what would you do?",
        "answer": "Take over the world, of course!"
    }, {
        "query": "Where should I travel?",
        "answer": "If you're looking for adventure, try the Outer Rim."
    }, {
        "query": "What should I do today?",
        "answer": "Stop talking to chatbots on the internet and go outside."
    }
]

그런 다음 examples 사전 목록을 직접 사용하는 대신 LengthBasedExampleSelector 다음과 같이 사용합니다.

In [ ]:
from langchain.prompts.example_selector import LengthBasedExampleSelector

example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=50  # this sets the max length that examples should be
)

max_length은 줄바꿈과 공백 사이의 단어 분할로 측정되며 다음 기준에 따라 결정됩니다.

In [ ]:
import re

some_text = "여기에는 총 8 단어가 있습니다. \n여기에는 6 단어를 더하여 총 14 단어가 있습니다."

words = re.split('[\n ]', some_text)
print(words, len(words))

그런 다음 선택기를 사용하여 dynamic_prompt_template을 초기화합니다.

In [ ]:
# now create the few shot prompt template
dynamic_prompt_template = FewShotPromptTemplate(
    example_selector=example_selector,  # use example_selector instead of examples
    example_prompt=example_prompt,
    prefix=prefix,
    suffix=suffix,
    input_variables=["query"],
    example_separator="\n"
)

포함된 프롬프트의 수가 쿼리 길이에 따라 달라지는 것을 볼 수 있습니다.

In [ ]:
print(dynamic_prompt_template.format(query="새는 어떻게 나는가요?"))
In [ ]:
query = "새는 어떻게 나는가요?"

print(openai(
    dynamic_prompt_template.format(query=query)
))
In [ ]:
query = """제가 미국에 있는데 다른 나라에 있는 사람에게 전화하고 싶다면, 저는
아마도 유럽, 아마도 프랑스, ​​독일, 영국과 같은 서유럽을 생각하고 있습니다.
그렇게 하는 가장 좋은 방법은 무엇입니까?"""

print(dynamic_prompt_template.format(query=query))

이를 통해 프롬프트 내에 제공되는 예시의 수를 제한했습니다. 이것이 너무 적다고 판단되면 max_length example_selector를 늘릴 수 있습니다.

In [ ]:
example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=100  # increased max length
)

# now create the few shot prompt template
dynamic_prompt_template = FewShotPromptTemplate(
    example_selector=example_selector,  # use example_selector instead of examples
    example_prompt=example_prompt,
    prefix=prefix,
    suffix=suffix,
    input_variables=["query"],
    example_separator="\n"
)

print(dynamic_prompt_template.format(query=query))

이것들은 LangChain에서 사용할 수 있는 프롬프트 도구 중 일부에 불과합니다. 예를 들어 실제로는 LengthBasedExampleSelector 외에 다른 예시 선택기 세트가 있습니다. 이에 대해서는 향후 노트북에서 자세히 다루거나 LangChain 문서에서 읽을 수 있습니다.

셀을 추가하려면 클릭하세요.

 
출처 : https://github.com/pinecone-io/examples/blob/master/learn/generation/langchain/handbook/01-langchain-prompt-templates.ipynb

'langchain' 카테고리의 다른 글

04-langchain-chat  (0) 2024.01.13
03a-token-counter  (0) 2024.01.12
03-langchain-conversational-memory  (2) 2024.01.11
02-langchain-체인  (1) 2024.01.10
00-langchain-intro(한글)  (0) 2024.01.08