2.2.5. 다이나믹 퓨샷 프롬프트 (Dynamic Few-Shot Prompting)

다이나믹 퓨샷 프롬프트(Dynamic Few-Shot Prompting)는 대규모 언어 모델(LLM)을 활용하여 특정 작업에 최적화된 응답을 생성하기 위한 고급 프롬프트 엔지니어링 기법입니다. 이 기법은 정적인 프롬프트와 달리, 작업의 맥락이나 입력 데이터에 따라 동적으로 예제를 선택하거나 생성하여 모델의 성능을 향상시킵니다

다이나믹 퓨샷 프롬프트의 개념

퓨샷 러닝(Few-Shot Learning)은 모델이 소수의 예제를 통해 새로운 작업을 학습하도록 유도하는 방법입니다. 다이나믹 퓨샷 프롬프트는 이러한 예제를 고정적으로 제공하는 대신, 입력 데이터의 특성, 작업 유형, 또는 사용자 요구사항에 따라 예제를 동적으로 선택하거나 생성합니다. 이는 모델이 더 관련성 높은 맥락을 이해하고, 작업에 최적화된 출력을 생성하도록 돕습니다.

주요 특징

  • 맥락 적응성: 입력 데이터에 따라 가장 적합한 예제를 선택하거나 생성.
  • 효율성: 불필요한 예제를 배제하여 프롬프트의 길이를 최적화.
  • 확장성: 다양한 작업과 도메인에 적용 가능.
  • 성능 최적화: 모델의 응답 품질을 개선하고, 오답 가능성을 줄임.

다이나믹 퓨샷 프롬프트를 설계할 때 고려해야 할 주요 원칙은 다음과 같습니다:

  1. 예제 관련성: 선택된 예제는 입력 데이터와 작업의 맥락에 밀접하게 관련되어야 합니다. 예를 들어, 감정 분석 작업에서는 입력 문장의 감정 톤과 유사한 예제를 선택하는 것이 중요합니다.
  2. 다양성: 예제는 작업의 다양한 측면을 커버해야 하며, 편향된 결과를 방지하기 위해 균형 잡힌 데이터셋에서 추출되어야 합니다.
  3. 최적화된 예제 수: 너무 많은 예제는 토큰 제한을 초과하거나 모델을 혼란스럽게 할 수 있습니다. 일반적으로 3~5개의 예제가 적절합니다.
  4. 동적 생성: 예제를 실시간으로 생성하거나 데이터베이스에서 검색하여 프롬프트에 통합.
  5. 명확한 지시사항: 프롬프트는 작업의 목표와 기대되는 출력 형식을 명확히 정의해야 합니다.

다음은  감정 분석 작업을 위한 다이나믹 퓨샷 프롬프트 구현 예제입니다.

사용자가 입력한 문장의 감정을 긍정, 부정, 중립으로 분류하는 작업을 수행한다고 가정합니다. 다이나믹 퓨샷 프롬프트는 입력 문장의 특성(예: 키워드, 문장 길이)에 따라 적합한 예제를 선택합니다.

from langchain.prompts import PromptTemplate
from langchain_ollama import OllamaLLM
from langchain.chains import LLMChain
import random

llm = OllamaLLM(model="exaone3.5")

example_db = [
    {"text": "이 영화 정말 재미있었어요!", "label": "긍정"},
    {"text": "서비스가 너무 느려서 짜증났습니다.", "label": "부정"},
    {"text": "제품은 괜찮은데 배송이 좀 늦었네요.", "label": "중립"},
    {"text": "최고의 경험이었어요!", "label": "긍정"},
    {"text": "별로였어요, 기대 이하였습니다.", "label": "부정"}
]

def select_dynamic_examples(input_text, num_examples=3):
    keywords = input_text.split()
    scored_examples = []

    for example in example_db:
        score = sum(1 for word in keywords if word in example["text"])
        scored_examples.append((score, example))

    scored_examples.sort(key=lambda x: x[0], reverse=True)
    selected = [ex[1] for ex in scored_examples[:num_examples]]
    return selected

prompt_template = PromptTemplate(
    input_variables=["examples", "input_text"],
    template="""
다음 예시들을 참고하여 새로운 입력을 분류하세요:

{examples}

새로운 입력: {input_text}
분류 결과:"""
)

def format_examples(examples):
    formatted = ""
    for ex in examples:
        formatted += f"입력: {ex['text']}\n출력: {ex['label']}\n\n"
    return formatted

chain = prompt_template | llm

# 테스트
input_text = "이 레스토랑 음식이 정말 맛있었어요!"
dynamic_examples = select_dynamic_examples(input_text)
formatted_examples = format_examples(dynamic_examples)

# 수정된 부분: 단일 딕셔너리 입력으로 변경
result = chain.invoke({"examples": formatted_examples, "input_text": input_text})
print(f"입력: {input_text}")
print(f"출력: {result.strip()}")
입력: 이 레스토랑 음식이 정말 맛있었어요!
출력: 분류 결과: 긍정

이와 같은 예시에서는 example의 수가 적기 때문에 비용적으로 부담되지 않지만 수가 커진다면 부담이 될 수 있습니다. 이럴 때 dynamic few shot prompting을 사용하면 부담을 줄일 수 있습니다.

코드 설명

  1. 모델 초기화: Ollama를 통해 EXAONE 3.5 모델을 로드합니다.
  2. 예제 선택: select_dynamic_examples 함수는 입력 문장의 키워드를 분석하여 가장 관련성 높은 예제를 선택합니다. 실제 구현에서는 텍스트 임베딩(예: Sentence-BERT)을 사용하여 더 정교한 유사성 계산을 수행할 수 있습니다.
  3. 프롬프트 템플릿: LangChain의 PromptTemplate을 사용하여 동적으로 예제를 삽입할 수 있는 프롬프트를 정의합니다.
  4. 체인 실행: LLMChain을 통해 프롬프트와 모델을 연결하고, 입력 문장에 대한 감정 분석 결과를 생성합니다.

다이나믹 퓨샷 프롬프트는 감정 분석 외에도 다양한 작업에 적용될 수 있습니다. 예를 들어:

  • 질문 답변: 사용자의 질문과 유사한 질문-답변 쌍을 동적으로 선택.
  • 텍스트 생성: 특정 스타일(예: 공식 문서, 캐주얼 대화)에 맞는 예제를 선택하여 생성된 텍스트의 톤을 조정.
  • 코드 생성: 입력된 코드 스니펫과 유사한 예제를 제공하여 더 정확한 코드 완성을 유도.

고급 구현 팁

  • 임베딩 기반 예제 선택: LangChain의 벡터 스토어(Vector Store)를 활용하여 입력과 예제 간의 코사인 유사도를 계산.
  • 예제 생성: EXAONE 3.5 자체를 사용하여 입력에 맞는 예제를 생성한 후 프롬프트에 통합.
  • 프롬프트 최적화: LangChain의 PromptSelector를 활용하여 작업 유형별로 최적의 프롬프트 템플릿을 선택.

다이나믹 퓨샷 프롬프트는 언어 모델의 성능을 극대화하는 강력한 도구입니다. 동적으로 선택된 예제는 모델이 작업 맥락을 더 잘 이해하도록 돕고, 다양한 도메인에서 높은 품질의 출력을 보장합니다.

이 글은 카테고리: 랭체인 (LangChain)에 포함되어 있습니다. 고유주소를 북마크하세요.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다