ansir 님의 블로그

[ SK 네트웍스 Family AI 캠프 수업 내용 복습 ] zero-shot, one-shot, few-shot, fine-tuning 2025-05-08 본문

SK 네트웍스 family AI 캠프/수업 내용 복습

[ SK 네트웍스 Family AI 캠프 수업 내용 복습 ] zero-shot, one-shot, few-shot, fine-tuning 2025-05-08

ansir 2025. 5. 8. 20:34

Prompt란?

Prompt는 LLM(Large Language Model, 대형 언어 모델)에 전달되는 입력을 의미합니다.
이 입력은 다음과 같은 구성 요소를 포함할 수 있습니다:

  • 질문 (Question): 모델에게 알고 싶은 정보나 답변을 직접적으로 요청
    예: "AI란 무엇인가요?"
  • 지시 (Instruction): 모델에게 특정 작업을 수행하도록 명령
    예: "다음 문장을 영어로 번역하세요."
  • 문맥 (Context): 모델이 보다 정확한 출력을 생성할 수 있도록 제공하는 배경 정보
    예: "이 글은 초등학생을 대상으로 합니다."

Prompt의 역할

Prompt는 단순한 입력 그 이상으로, 모델의 출력을 유도하는 역할을 합니다.
즉, 모델이 어떤 방식으로 응답할지 결정짓는 핵심 요소입니다.

예시

Prompt 형태 예시 모델 출력 예시
질문 "피보나치 수열이 뭐야?" "피보나치 수열은 0과 1로 시작하고, 그 다음 수는 앞의 두 수를 더한 값입니다..."
지시 "다음 문장을 요약해줘: ... " "이 문장은 요약하면 다음과 같습니다..."
문맥 포함 "초등학생에게 설명하듯이 뉴턴의 운동 법칙을 알려줘" "뉴턴의 운동 법칙은 쉽게 말해서, 물체는 힘을 받으면 움직인다는 거야..."
 

보충 설명

Prompt의 품질은 LLM의 출력 품질에 직접적인 영향을 미칩니다.
따라서 명확하고 목적에 맞게 설계된 Prompt는 더 정확하고 유용한 결과를 만들어냅니다.
이러한 이유로 "Prompt Engineering"이라는 분야가 등장하게 되었으며, 이는 LLM을 잘 활용하기 위한 기술로 주목받고 있습니다.

 


 

GPT (Generative Pre-trained Transformer)

GPT는 Generative Pre-trained Transformer의 약자로, OpenAI에서 개발한 대표적인 대형 언어 모델(LLM) 입니다.
Transformer라는 딥러닝 아키텍처를 기반으로 하며, 두 가지 주요 특징이 이름에 포함되어 있습니다:

  • Pre-trained: 대규모 텍스트 데이터를 사용해 사전 학습
  • Generative: 주어진 입력으로부터 새로운 텍스트를 생성할 수 있음

작동 방식 요약

GPT는 입력된 텍스트를 처리할 때 다음과 같은 절차를 따릅니다:

  1. 입력 텍스트를 토큰으로 분할
    예: "하늘은 파랗다" → ['하늘', '은', ' ', '파랗', '다']
  2. 각 토큰에 대해 다음 토큰의 확률 분포를 예측
    모델은 이전까지의 입력을 보고 다음에 어떤 단어(토큰)가 올지 확률적으로 예측합니다.
    예를 들어, 입력이 "하늘은"일 경우 다음과 같은 예측을 할 수 있습니다:
    • "파랗다" → 확률 0.4
    • "맑다" → 확률 0.3
    • "어둡다" → 확률 0.1
    • 그 외 다른 단어들...
  3. 가장 높은 확률(또는 특정 샘플링 방식에 따른 토큰)을 선택하여 출력에 추가
    그다음 다시 예측 → 반복하면서 문장을 생성해 나감

핵심 개념 정리

항목 설명
입력 처리 방식 텍스트를 토큰 단위로 분리
학습 목표 다음에 올 토큰의 확률 분포를 최대한 정확히 예측
출력 생성 방식 예측된 확률 분포에 따라 하나씩 토큰을 이어붙여 문장 생성
모델 구조 Transformer의 Decoder만 사용 (Autoregressive 구조)
 

보충 설명

  • Autoregressive 모델: GPT는 입력을 순차적으로 읽고, 한 토큰씩 예측해 나가는 구조입니다. 이전 토큰 정보만 활용하고 미래 토큰은 보지 않습니다.
  • 확률 분포 기반 생성: 단순히 가장 확률이 높은 단어만 고르면 항상 똑같은 문장이 생성될 수 있으므로, Top-k, Top-p (nucleus sampling) 같은 샘플링 기법을 활용하여 창의적인 출력도 가능하게 만듭니다.
  • Pre-training & Fine-tuning:
    • 사전학습(Pre-training): 방대한 웹 텍스트로 "다음 단어 맞추기" 방식으로 학습
    • 미세조정(Fine-tuning): 특정 목적에 맞게 추가 데이터로 보정 (예: 대화, 요약 등)

 


 

LLM 생성 관련 주요 파라미터 정리

LLM(GPT 등)에서 출력 텍스트의 스타일, 길이, 다양성을 제어하는 주요 파라미터는 다음과 같습니다:


1. Temperature

  • 역할: 모델이 다음 단어를 고를 때의 무작위성(랜덤성)을 조절합니다.
  • 작동 방식:
    Temperature는 모델이 예측한 다음 단어의 확률 분포를 얼마나 평탄하게 만들지 결정합니다.
    • 낮은 값 → 높은 확률을 가진 단어는 더 높아지고, 낮은 확률을 가진 단어는 더 낮아짐 → 결정적
    • 높은 값 → 확률 분포가 평평해짐 → 다양한 단어들이 선택될 가능성 증가 → 창의적
  • 예시:
    • Temperature = 0.2 → "하늘은 파랗다"처럼 일반적이고 예측 가능한 문장
    • Temperature = 0.9 → "하늘은 꿈의 캠퍼스다"처럼 창의적이고 독특한 표현도 가능
Temperature 값 출력 성격 예시
낮음 (예: 0.2) 결정적, 일관됨 "하늘은 파랗다"
높음 (예: 0.9) 창의적, 예측 불가 "하늘은 꿈의 캠퍼스다"
 
  • 요약: 값이 낮을수록 정답에 가까운 안정된 응답, 높을수록 창의적이고 예상치 못한 표현이 증가

2. Top-p (Nucleus Sampling)

  • 역할: 확률 분포 상위 p% 누적 확률에 포함되는 토큰들 중에서 선택
  • 작동 방식: 전체 후보 중 누적 확률이 p를 넘지 않는 범위 내에서만 샘플링
Top-p 값 선택 범위 출력 특성
0.1 상위 10%만 고려 매우 보수적, 정확도 우선
0.9 대부분의 유의미한 토큰 고려 다양성 증가
 
  • 요약: 값이 클수록 다양성 증가, 작을수록 보수적이고 안정적인 응답

3. Top-k

  • 역할: 확률이 가장 높은 상위 k개의 토큰만 고려해 샘플링
  • 예시:
    • Top-k = 5 → 예측된 상위 5개 단어 중 하나를 무작위 선택
  • 비교: Top-p는 누적 확률 기반, Top-k는 개수 기반
  • 실제 사용: 최근에는 Top-p를 더 자주 사용하며, Top-k는 비교적 단순한 제어 방식으로 사용됨

4. Max Tokens

  • 역할: 생성할 최대 토큰 수 제한
  • 영향: 출력의 길이 제한을 통해 응답을 지나치게 길거나 무한 생성되지 않도록 제어
  • 주의: 너무 작은 값은 불완전한 응답을, 너무 큰 값은 불필요한 출력이나 시간 지연을 유발할 수 있음

보충 요약

파라미터 기능 요약 주요 영향
Temperature 다음 단어를 선택할 때의 무작위성 정도를 조절 다양성 vs 일관성
Top-p 누적 확률 기반 토큰 필터링 선택의 폭 (보수적/다양)
Top-k 개수 기준 상위 토큰 제한 예측 범위 단순 제어
Max Tokens 출력 토큰 수 제한 응답 길이 제어

 


 

import openai  # OpenAI API 사용을 위한 라이브러리
import os      # 환경 변수 사용을 위한 표준 라이브러리

# 환경 변수에 API 키를 설정 (실제 코드에서는 키를 직접 노출하지 말고 보안 관리 필요)
os.environ["OPENAI_API_KEY"] = "private key"

# openai 라이브러리에 API 키 등록
openai.api_key = os.environ["OPENAI_API_KEY"]

# OpenAI API 호출 함수 정의
def call_openai(prompt, model="gpt-3.5-turbo", temperature=0.5, max_tokens=100):
    response = openai.chat.completions.create(
        model=model,  # 사용할 모델 지정 (기본은 gpt-3.5-turbo)
        messages=[
            {"role": "user", "content": prompt}  # 사용자 메시지를 입력
        ],
        temperature=temperature,      # 생성 무작위성 조절 (0~2)
        max_tokens=max_tokens         # 최대 출력 토큰 수 제한
    )
    # 생성된 응답 텍스트 반환
    return response.choices[0].message.content

코드 설명

  1. 라이브러리 임포트
    • openai: OpenAI의 GPT 모델을 API를 통해 사용할 수 있게 해줌
    • os: 환경 변수 관리를 위한 표준 라이브러리
  2. API 키 설정
    • os.environ을 사용해 시스템 환경 변수에 API 키를 설정하고 이를 openai.api_key에 등록
    • 실제 개발 환경에서는 .env 파일, 환경 변수 설정, 비밀 관리 서비스 등을 사용하는 것이 안전함
  3. call_openai 함수
    • 인자:
      • prompt: 사용자 입력 문자열
      • model: 사용할 GPT 모델명 (기본값 "gpt-3.5-turbo")
      • temperature: 생성의 무작위성을 조절 (0에 가까울수록 결정적, 1 이상은 창의적)
      • max_tokens: 응답으로 생성할 최대 토큰 수
    • 역할: 사용자의 prompt를 GPT에 전달하고, 응답으로 생성된 텍스트 중 첫 번째 응답 내용을 반환

 

# 테스트할 프롬프트 목록 정의
prompts = [
    "AI공부를 잘 하려면",        # 프롬프트 1
    "자격증을 취득하려면"        # 프롬프트 2
]

# 각 프롬프트에 대해 서로 다른 temperature 값을 적용하여 결과 비교
for prompt in prompts:
    print(f"입력: {prompt}")  # 현재 프롬프트 출력
    
    # temperature=0.2: 결정적이고 일관된 응답
    print(f"temperature=0.2:{call_openai(prompt, temperature=0.2)}")

    # temperature=0.9: 창의적이고 다양한 응답
    print(f"temperature=0.9:{call_openai(prompt, temperature=0.9)}")

    print()  # 결과 사이에 빈 줄 추가

코드 설명

이 코드는 하나의 질문(prompt)에 대해 temperature 값만 바꿔가며 GPT의 응답이 어떻게 달라지는지를 비교하는 실험입니다.

  • temperature=0.2:
    • 매우 보수적이고 일관된 답변을 기대할 수 있습니다.
    • 같은 질문에 대해 거의 비슷하거나 같은 답변을 반복합니다.
  • temperature=0.9:
    • 창의성 있게 다양한 표현을 시도합니다.
    • 응답이 더 자유롭고, 예상하지 못한 단어나 문장을 포함할 수 있습니다.
입력: AI공부를 잘 하려면
temperature=0.2:다음과 같은 방법을 추천합니다:

1. 기초 이론 공부: AI의 기본 이론과 원리를 이해하는 것이 중요합니다. 
머신러닝, 딥러닝, 자연어 처리 등의 기초 이론을 공부해야 합니다.

2. 프로그래밍 언어 습득: Python
temperature=0.9:다음과 같은 방법들을 고려해볼 수 있습니다:

1. 이론 공부: AI의 기본 이론과 원리를 이해하고 학습하는 것이 중요합니다. 
딥 러닝, 머신 러닝, 자연어 처리 등 AI의 다양한 분야에 대한 이론적 지식을

입력: 자격증을 취득하려면
temperature=0.2: 해당 자격증을 취득하기 위한 시험을 응시하고 통과해야 합니다. 
자격증의 종류에 따라 필요한 시험과 요건이 다를 수 있으니 해당 자격증을 취득하기 위한 자세한 정보는 해당 기관이나 단체의 공식 웹사이트를
temperature=0.9: 해당 자격증을 취득하기 위한 요건 및 절차를 파악해야 합니다. 
일반적으로 자격증을 취득하기 위해서는 해당 자격증이 요구하는 교육과정을 이수하고 시험에 합격해야 합니다. 

자격증을 취득하기 위

 


 

네이버 지식인 질문을 prompt로 해서 실행

  • 네이버 지식인 크롤링
import requests            # HTTP 요청을 보내는 라이브러리
from bs4 import BeautifulSoup  # HTML 파싱을 위한 라이브러리

# 네이버 지식인에서 질문을 크롤링하는 함수 정의
def crawl_naver_kin(question, limit=3):
    # 네이버 지식인에서 질문 검색을 위한 URL 생성
    url = "<https://kin.naver.com/search/list.naver?query=>" + question
    
    # requests를 사용하여 URL에 GET 요청을 보내고 응답을 받음
    response = requests.get(url)
    
    # 응답의 HTML 텍스트를 가져옴
    html = response.text
    
    # BeautifulSoup을 사용하여 HTML을 파싱
    soup = BeautifulSoup(html, 'html.parser')
    
    # 질문 리스트를 저장할 빈 리스트 생성
    questions = []
    
    # 선택된 HTML 요소에서 질문 제목을 가져와 questions 리스트에 추가 (limit 수만큼만)
    for item in soup.select('#s_content > div.section > ul > li > dl > dt > a')[:limit]:
        questions.append(item.text)
    
    # 질문 리스트 반환
    return questions

코드 설명

  1. 라이브러리 임포트
    • requests: HTTP 요청을 보내는 라이브러리로, 웹 페이지를 가져오는 데 사용됩니다.
    • BeautifulSoup: HTML 문서에서 데이터를 추출할 때 사용하는 라이브러리로, 웹 페이지의 구조를 파싱하여 원하는 데이터를 쉽게 추출할 수 있게 도와줍니다.
  2. crawl_naver_kin 함수
    • 목적: 네이버 지식인에서 주어진 질문에 대해 관련된 다른 질문들을 크롤링해오는 함수입니다.
    • 인자:
      • question: 검색할 질문 문자열.
      • limit: 가져올 질문의 개수 (기본값은 3).
    • 작동 방식:
      • url: 네이버 지식인에서 검색할 URL을 생성합니다. question 파라미터를 URL에 쿼리 파라미터로 전달합니다.
      • response: requests.get(url)을 사용해 해당 URL에서 데이터를 가져옵니다.
      • html: 응답으로 받은 HTML 텍스트를 response.text에서 추출합니다.
      • soup: BeautifulSoup 객체로 HTML을 파싱하여 페이지 구조를 분석할 수 있게 합니다.
      • questions: 네이버 지식인에서 제공하는 질문 제목들을 추출하여 questions 리스트에 저장합니다.
      • soup.select('#s_content > div.section > ul > li > dl > dt > a'): HTML 요소 중 특정 CSS 선택자에 해당하는 부분을 찾아 질문 제목을 추출합니다.
      • 마지막으로, 요청한 개수(limit)만큼 질문을 가져옵니다.
  3. 반환 값:
    • 크롤링한 질문 리스트를 반환합니다. 예를 들어, 사용자가 question으로 "AI 공부"를 입력했다면, 관련된 질문들의 제목을 리스트로 반환합니다.
for question in crawl_naver_kin("코딩테스트"):
  print(f"질문: {question}")
  print(f"0.2: {call_openai(question, temperature=0.2)}")
  print(f"0.9: {call_openai(question, temperature=0.9)}")
질문: 코딩테스트 알고리즘 공부법
0.2: 1. 기본적인 알고리즘 개념 학습: 먼저 기본적인 알고리즘 개념을 학습하고 이해하는 것이 중요합니다. 이를 통해 문제 해결에 필요한 기본적인 알고리즘을 이해하고 활용할 수 있습니다.

2. 문제 해결 능
0.9: 1. 기본적인 알고리즘 개념 이해: 알고리즘을 공부하기 전에 기본적인 알고리즘 개념을 이해해야 합니다. 이를 위해 책이나 온라인 자료를 참고하여 알고리즘에 대한 이해를 높일 수 있습니다.

2. 코딩
질문: 자바 코딩테스트 교제
0.2: 자바 코딩테스트를 대비하기 위한 교재로는 다음과 같은 책들이 추천됩니다.

1. "이것이 취업을 위한 코딩 테스트다 with 파이썬" - 나동빈
2. "자바로 배우는 코딩 테스트" - 김영재

0.9: 자바 코딩테스트에 대한 교재로는 다음과 같은 책들이 추천됩니다:

1. "이것이 취업을 위한 코딩 테스트다 with 파이썬" - 나동인 지음
2. "프로그래밍 대회에서 배우는 알고리즘 문제해결 전략"
질문: 코딩테스트 질문
0.2: 1. 주어진 문자열이 회문인지 확인하는 함수를 작성하시오.
2. 두 개의 정렬된 배열이 주어졌을 때, 두 배열을 병합하여 정렬된 배열을 반환하는 함수를 작성하시오.
3. 주어진 배열에서 중복된 숫자를 제거하는 함수를 작성하시오.
4. 이진 탐색 알
0.9: 1. 주어진 배열에서 중복된 숫자를 제거하는 함수를 작성하시오.
2. 두 개의 정렬된 배열이 주어졌을 때, 두 배열을 병합하여 하나의 정렬된 배열을 반환하는 함수를 작성하시오.
3. 주어진 문자열이 회문인지 판별하는 함수를 작성하시오.
4. 이

 


 

Zero-Shot

  • 정의:
    모델이 예시나 학습 없이 주어진 작업을 수행하는 방식입니다.
    사용자가 제공하는 프롬프트만을 바탕으로 모델이 작업을 자동으로 수행하도록 유도합니다.
  • 적합한 상황:
    • 감정 분석: 문장의 감정을 긍정, 부정, 중립으로 분류하는 작업
    • 카테고리 분류: 뉴스 기사나 텍스트를 정치, 경제, 스포츠 등의 카테고리로 분류하는 작업

예시

  • 감정 분석:
    • 프롬프트: "이 영화는 정말 재미있었다. 긍정적인 감정인가요?"
    • 모델 출력: 긍정
  • 카테고리 분류:
    • 프롬프트: "오늘 정부의 새로운 경제 정책 발표에 대한 기사는 어떤 카테고리에 속하나요?"
    • 모델 출력: 경제

특징

  • 학습 데이터 불필요: 모델은 훈련되지 않은 작업도 프롬프트만으로 수행할 수 있습니다.
  • 효율성: 예시 없이 즉시 다양한 작업을 처리할 수 있어 빠른 응답이 가능합니다.

Zero-shot 방식은 사전 훈련된 모델다양한 작업에 적용될 수 있는 능력을 가지고 있다는 점에서 큰 장점이 있습니다.

 

# 감정분류용 리뷰
reviews = [
    "이 제품은 정말 훌륭합니다. 적극 추천합니다."
    , "배송이 너무 느리고 품질도 별로에요."
    , "가격 대비 괜찮은 제품인 거 같습니다."
]
# 카테고리 분류용 헤드라인
headlines = [
    "정부, 기후 변화 대응 위한 국가 전략 발표"
    , "A기업, 차세대 5G 기술 개발 성공 발표"
    , "서울시, 교통 체증 해소를 위한 새로운 도로 확장 계획 발표"
]

 

# 각 리뷰에 대해 zero-shot 감정 분석을 실행
for review in reviews:
    # 감정 분석을 위한 프롬프트 생성
    sentiment_prompt = f'''
    다음 리뷰의 감정을 긍정 부정 중립으로 분류해줘:
    리뷰: {review}
    감정:
    '''
    
    # OpenAI 모델을 사용하여 감정 분석 결과 얻기
    result = call_openai(sentiment_prompt)
    
    # 리뷰와 감정 출력
    print(f"review: {review}\\nsentiment: {result}")

코드 설명

  1. 리뷰 목록 (reviews):
    • 분석할 리뷰들을 리스트 형태로 저장합니다.
    • 예시로 3개의 리뷰를 포함시켰습니다.
  2. for 루프:
    • 각 리뷰에 대해 감정 분석을 실행합니다.
    • 리뷰를 하나씩 처리하면서 그에 맞는 프롬프트를 생성합니다.
  3. 프롬프트 생성 (sentiment_prompt):
    • 각 리뷰에 대해 "긍정", "부정", "중립" 중 하나를 출력하도록 모델에 요청하는 프롬프트를 만듭니다.
    • 리뷰 텍스트를 프롬프트에 포함시켜서 모델에 전달할 수 있도록 구성합니다.
  4. call_openai 함수 호출:
    • 생성된 프롬프트를 OpenAI 모델에 전달하여 감정 분석 결과를 받습니다.
    • call_openai 함수는 위에서 정의된 대로 OpenAI API를 호출하고 결과를 반환합니다.
  5. 결과 출력:
    • 각 리뷰와 그에 대한 감정 분석 결과를 출력합니다.

 

# 각 헤드라인에 대해 zero-shot 카테고리 분류
for headline in headlines:
    # 카테고리 분류를 위한 프롬프트 생성
    category_prompt = f'''
    다음 뉴스 기사 헤드라인의 카테고리를 정해줘:
    헤드라인: {headline}
    카테고리:
    '''
    
    # OpenAI 모델을 사용하여 카테고리 분류 결과 얻기
    result = call_openai(category_prompt)
    
    # 헤드라인과 카테고리 출력
    print(f"headline: {headline}\\ncategory: {result}")

코드 설명

  1. 헤드라인 목록 (headlines):
    • 분석할 뉴스 헤드라인들을 리스트로 저장합니다.
    • 각 헤드라인은 뉴스 기사 제목을 나타냅니다.
  2. for 루프:
    • 각 뉴스 헤드라인에 대해 카테고리 분류를 실행합니다.
    • 헤드라인을 하나씩 처리하면서, 그에 맞는 카테고리 분류 프롬프트를 생성합니다.
  3. 프롬프트 생성 (category_prompt):
    • 각 헤드라인에 대해 해당 뉴스가 속하는 카테고리를 출력하도록 모델에 요청하는 프롬프트를 만듭니다.
    • 헤드라인 텍스트를 프롬프트에 포함시켜서 모델에 전달합니다.
  4. call_openai 함수 호출:
    • 생성된 프롬프트를 OpenAI 모델에 전달하여 카테고리 분류 결과를 얻습니다.
    • call_openai 함수는 위에서 정의한 대로 OpenAI API를 호출하고 결과를 반환합니다.
  5. 결과 출력:
    • 각 헤드라인과 그에 대한 카테고리 분류 결과를 출력합니다.
    • headline과 그에 대한 카테고리(result)를 출력하여 분석된 카테고리를 확인할 수 있습니다.

 


 

One-Shot

  • 정의:Zero-Shot보다 더 명확한 가이드를 제공하여 성능이 향상됩니다.
  • 모델에게 하나의 예시만을 제공하여 작업을 수행하도록 하는 방식입니다.
  • 프롬프트 구조:
  • 예시 입력 -> 예시 출력 -> 실제 입력 -> 출력 요청
  • 특징:
    • 성능 향상: 예시를 통해 모델이 작업에 대해 더 잘 이해하고 성능이 개선됩니다.
    • 단점: 예시 선택이 결과에 큰 영향을 미칩니다. 부적절한 예시는 오히려 모델 성능을 저하시킬 수 있습니다.
    • 예시 중요성:
      • 대표성: 예시는 일반적이고 대표적인 사례여야 합니다.
      • 명확성: 예시는 모호하지 않아야 하며, 구체적이고 분명해야 합니다.
      • 일관성: 예시와 실제 입력은 형식과 도메인이 일관되어야 합니다.
  • 적합한 상황:
  • One-Shot 방식은 모델이 하나의 예시로부터 충분히 학습할 수 있는 상황에 적합합니다. 예를 들어, 감정 분석에서는 강한 긍정강한 부정을 명확하게 구분하는 예시를 제공하면 성능이 더 잘 나올 수 있습니다.

예시

감정 분석

예시 입력: "정말 훌륭한 영화였어요! 강력히 추천합니다."
예시 출력: 긍정

실제 입력: "별로였어요. 기대 이하였어요."
출력 요청: 부정

카테고리 분류

예시 입력: "국가안보실, 북 미사일 대응 안보상황 점검회의"
예시 출력: 정치

실제 입력: "삼성전자, 차세대 5G 기술 개발 성공 발표"
출력 요청: 경제

주의사항

  • 예시 선택: 잘못된 예시는 성능을 크게 저하시킬 수 있으므로, 예시는 정확하고 대표적인 사례여야 합니다.
  • 프롬프트 디자인: 예시를 주고 나서 실제 입력을 요청하는 방식은 모델이 이해할 수 있도록 명확하고 일관성 있게 작성해야 합니다.

 

# one-shot

for review in reviews:
  one_shot_sentiment_prompt = f'''
  다음 리뷰의 감정을 긍정, 부정, 중립으로 분류해줘:

  예시:
  리뷰: "정말 훌륭한 제품입니다. 적극 추천합니다."
  감정: 긍정

  리뷰: "{review}"
  감정: 
  '''
  result = call_openai(one_shot_sentiment_prompt)
  print(f"review: {review}\\nsentiment: {result}")
# one-shot 뉴스 카테고리에 적용
for headline in headlines:
  one_shot_article_prompt = f'''
  다음 뉴스의 헤드라인의 카테고리를 정치, 경제, 사회, 생활/문화, IT/과학, 세계로 분류해줘

  예시:
  헤드라인: "네이버 지도로 부산 지하철 정보 실시간 확인"
  카테고리: IT/과학

  헤드라인: "{headline}"
  카테고리:
  '''
  result = call_openai(one_shot_article_prompt)
  print(f"headline: {headline}\\ncategory: {result}")

 


 

# 필요한 라이브러리 임포트
import requests  # 웹에서 데이터를 가져오기 위한 라이브러리
from bs4 import BeautifulSoup  # HTML 파싱을 위한 라이브러리

# 네이버 뉴스 헤드라인 크롤링 함수 정의
def crawl_naver_news_headline(limit=4):
    # 네이버 뉴스의 URL 설정
    url = "<https://news.naver.com/>"
    
    # 네이버 뉴스 페이지 요청 (GET 방식으로)
    response = requests.get(url)
    
    # 페이지의 HTML을 텍스트 형식으로 저장
    html = response.text
    
    # BeautifulSoup을 사용하여 HTML 파싱
    soup = BeautifulSoup(html, 'html.parser')
    
    # 헤드라인을 저장할 리스트 초기화
    headlines = []
    
    # 뉴스 헤드라인을 추출
    # 'strong' 태그 중 클래스가 'cnf_news_title'인 요소를 찾음
    # 최대 limit 개수만큼 추출 (limit 파라미터 기본값 4)
    for item in soup.find_all('strong', class_='cnf_news_title')[:limit]:
        # 만약 텍스트가 숫자라면 제외 (단순 숫자는 뉴스 제목이 아님)
        if item.text.isdigit() != True:
            headlines.append(item.text)  # 뉴스 제목을 리스트에 추가
    
    # 크롤링한 헤드라인 리스트를 반환
    return headlines

코드 설명

  1. 라이브러리 임포트:
    • requests: 웹페이지에서 데이터를 가져오기 위한 라이브러리입니다. requests.get()을 통해 웹페이지를 요청할 수 있습니다.
    • BeautifulSoup: HTML 페이지를 파싱하고, 원하는 정보를 쉽게 추출할 수 있도록 도와주는 라이브러리입니다.
  2. crawl_naver_news_headline 함수:
    • 목적: 네이버 뉴스 사이트에서 헤드라인을 크롤링하여 리스트로 반환합니다.
    • 파라미터: limit은 크롤링할 헤드라인의 수를 지정합니다. 기본값은 4입니다.
    • url: 네이버 뉴스 메인 페이지 URL을 지정합니다.
    • response = requests.get(url): 네이버 뉴스 페이지를 요청하여 HTML 텍스트를 가져옵니다.
    • BeautifulSoup(html, 'html.parser'): 가져온 HTML을 BeautifulSoup을 사용하여 파싱합니다.
    • soup.find_all('strong', class_='cnf_news_title'): 뉴스 헤드라인이 포함된 strong 태그의 클래스를 'cnf_news_title'로 지정하여 해당 요소들을 찾습니다.
    • item.text.isdigit() != True: 텍스트가 숫자인 경우는 제외합니다. 예를 들어, 단순히 "1"이나 "2"처럼 숫자만 있는 항목을 필터링합니다.
    • headlines.append(item.text): 뉴스 제목을 headlines 리스트에 추가합니다.
    • return headlines: 최종적으로 추출한 헤드라인 리스트를 반환합니다.
one_shot_article_prompt = '''
다음 뉴스의 헤드라인의 카테고리를 정치, 경제, 사회, 생활/문화, IT/과학, 세계로 분류해줘

예시:
헤드라인: "네이버 지도로 부산 지하철 정보 실시간 확인"
카테고리: IT/과학

헤드라인: "{}"
카테고리:
'''

for headline in crawl_naver_news_headline():
  result = call_openai(one_shot_article_prompt.format(headline))
  print(f"headline: {headline}\\ncategory: {result}")

 


 

Few-Shot

Few-shot learning은 여러 개의 예시를 제공하여 모델이 더 복잡한 작업을 수행할 수 있도록 돕는 방법입니다. 이 방법은 특히 키워드 추출, 논리적 추론과 같은 작업에서 매우 효과적입니다. 예시를 제공함으로써 모델이 더 정확한 예측을 할 수 있도록 합니다.

특징

  • 효율성: 예시의 수는 보통 3~5개로 제한됩니다. 이는 토큰의 효율성을 고려한 제한입니다.
  • 복잡한 작업에 적합: 예시를 통해 모델이 더 복잡한 패턴을 학습하고, 보다 정확한 결과를 도출하도록 돕습니다.
  • Chain-of-Thought (CoT): 사고 과정을 단계별로 설명하도록 유도하는 전략입니다. 이를 통해 모델이 문제를 푸는 과정을 체계적으로 설명하면서 논리적 사고를 강화할 수 있습니다.

예시

  • 키워드 추출:
    1. 핵심 명사 식별
    2. 일반적인 단어는 제외
    3. 최종적으로 키워드 목록 작성

작업 지시문 예시

  • "단계별로 설명하라"라는 문구를 작업 지시문에 추가하면 모델이 사고 과정을 자세히 설명하도록 유도할 수 있습니다.

적용 예시

  • 키워드 추출 작업:
    • 예시 1:
      • 문장: "서울에서 열린 국제 회의에서 여러 나라의 지도자들이 모였습니다."
      • 단계별 설명: 핵심 명사인 '서울', '국제 회의', '나라', '지도자' 식별 → 일반 단어는 제외 → 키워드 목록: ['서울', '국제 회의', '지도자']
    • 예시 2:
      • 문장: "오늘 아침에 일어난 교통사고로 인해 많은 사람들이 지각을 했습니다."
      • 단계별 설명: 핵심 명사인 '아침', '교통사고', '사람들', '지각' 식별 → 일반 단어는 제외 → 키워드 목록: ['교통사고', '사람들', '지각']

이와 같이 여러 개의 예시를 통해 모델에게 작업을 수행하는 방법을 교육할 수 있습니다.

 

# few shot 감정 분석
few_shot_sentiment_prompt = '''
다음 리뷰의 감정을 긍정, 부정, 중립으로 분류해줘

예시1: 
리뷰: "정말 훌륭한 제품입니다. 또 구매할 의향 있습니다."
감정: 긍정

예시2: 
리뷰: "품질이 너무 안좋네요. 실망했습니다."
감정: 부정

예시3: 
리뷰: "보통이네요. 특별히 좋고 싫은 점이 없습니다. 쓸만해요"
감정: 중립

리뷰: "{}"
감정:
'''

for review in reviews:
  result = call_openai(few_shot_sentiment_prompt.format(review))
  print(f"review: {review}\\nsentiment: {result}")
review: 이 제품은 정말 훌륭합니다. 적극 추천합니다.
sentiment: 긍정
review: 배송이 너무 느리고 품질도 별로에요.
sentiment: 부정
review: 가격 대비 괜찮은 제품인 거 같습니다.
sentiment: 긍정
# 키워드 추출 문장
sentences = [
    "스마트폰은 강력한 프로세스와 긴 배터리 수명을 제공한다",
    "컨퍼런스는 AI, 클라우드 컴퓨팅, 사이버 보안을 논의했다"
]

# few-shot 키워드 추출 문장( CoT 포함 )
few_shot_keyword_prompt = '''
다음 문장에서 주요 키워드를 추출해줘. 단계별 추론 과정을 설명한 뒤 키워드를 추출해

예시1:
문장: "자동차는 첨단 안전 기능과 뛰어난 연비를 제공한다"
추론: 
1 핵심 명사와 구체적 개념 식별: 자동차, 안전 기능, 연비
2 일반 단어 제외: 제공한다, 뛰어난
3 최종 키워드 선택: 자동차, 안전 기능, 연비

예시2:
문장 : "인공지능 기술은 다양한 산업 분야에서 활용되고 있다"
추론:
1 핵심 명사 와 구체적 개념식별: 인공지능 기술, 산업 분야
2 일반 단어 제외 : 다양한, 활용되고 있다
3 최종키워드 선택 : 인공지능 기술, 산업 분야

예시3:
문장 : "스마트폰은 사용자 경험을 향상시키기 위한 여러 기능을 탑재하고 있다"
추론:
1 핵심 명사 와 구체적 개념식별: 스마트폰, 사용자 경험, 기능
2 일반 단어 제외 : 향상시키기 위한, 여러, 탑재하고 있다
3 최종키워드 선택 : 스마트폰, 사용자 경험, 기능

문장: {}
추론: 
키워드: 
'''

for sentence in sentences:
  result = call_openai(few_shot_keyword_prompt.format(sentence))
  print(f"sentence: {sentence}\\nkeywords: {result}")
sentence: 스마트폰은 강력한 프로세스와 긴 배터리 수명을 제공한다
keywords: 1. 핵심 명사와 구체적 개념 식별: 스마트폰, 프로세스, 배터리 수명
2. 일반 단어 제외: 강력한, 제공한다
3. 최종 키워드 선택: 스마트폰, 프로세스, 배터리 수명
sentence: 컨퍼런스는 AI, 클라우드 컴퓨팅, 사이버 보안을 논의했다
keywords: 1. 핵심 명사와 구체적 개념 식별: 컨퍼런스, AI, 클라우드 컴퓨팅, 사이버 보안
2. 일반 단어 제외: 논의했다
3. 최종 키워드 선택: 컨퍼런스, AI, 클라우드
# 네이버 뉴스 헤드라인을 CoT를 적용한 Few-Shot 러닝으로 각 헤드라인의 키워드를 추출
cot_few_shot_keyword_prompt = '''
다음 뉴스 기사의 헤드라인에서 주요 키워드를 추출해줘. 예시를 준 것처럼 단계별로 키워드 추출 과정을 설명하고 키워드를 추출해줘

예시1
헤드라인: “속이 자꾸 쓰리네”…위 보호하려면 ‘이 음식’이 효과적, 왜?
추론 과정
1.핵심 명사와 구체적 개념 식별: 속, 위, 보호, 음식, 효과
2.일반 단어 제외: 속, 보호, 효과 → 일반적인 개념이므로 제외
3.최종 키워드 선택: 위, 음식

예시 2
헤드라인: "비 오는 날, 관절이 쑤신다?"…날씨와 통증의 상관관계
추론 과정
1.핵심 명사와 구체적 개념 식별: 비, 관절, 통증, 날씨, 상관관계
2.일반 단어 제외: 상관관계, 날씨 → 추상적 개념이므로 제외
3.최종 키워드 선택: 비, 관절, 통증

예시 3
헤드라인: “하루 30분 걷기만 해도” 치매 위험 낮춘다
추론 과정
1.핵심 명사와 구체적 개념 식별: 하루, 걷기, 치매, 위험
2.일반 단어 제외: 하루, 위험 → 일반적이거나 추상적 개념이므로 제외
3.최종 키워드 선택: 걷기, 치매

헤드라인: {}
추론 과정:
키워드:
'''

for headline in crawl_naver_news_headline():
  result = call_openai(cot_few_shot_keyword_prompt.format(headline),max_tokens=250)
  print(f"headline: {headline}\\nresult:\\n{result}")
  print('*'*10)

 


 

Fine-Tuning

Fine-tuning은 기존 모델에 추가 학습 데이터를 제공하여 특정 작업에 최적화하는 과정입니다. 이를 통해 모델이 특정 도메인이나 작업에 더욱 정확하게 대응할 수 있도록 합니다.

주요 특징

  • 모델 최적화: 일반적인 모델을 특정 작업이나 도메인에 맞게 세부 조정합니다.
  • 데이터 품질: 최소한 50개 이상의 고품질 데이터가 필요합니다. 데이터의 품질이 중요하며, 부정확한 데이터는 모델 성능을 저하시킬 수 있습니다.
  • 비용 증가: Fine-tuning은 학습 데이터를 추가하고, 추가 학습을 거쳐야 하므로 비용이 증가할 수 있습니다.

데이터 포맷

Fine-tuning을 위한 데이터는 jsonl (JSON Lines) 형식으로 제공해야 하며, 각 라인에 하나의 JSON 객체가 포함됩니다.

  • 형식:
    • "role": 역할을 정의, user는 사용자, assistant는 모델의 응답
    • "content": 해당 역할의 텍스트 내용
  • {"messages": [ {"role": "user", "content": "입력"}, {"role": "assistant", "content": "출력"} ]}

한글 전처리

Fine-tuning을 위한 데이터 전처리 과정에서는 다음과 같은 사항들을 고려해야 합니다.

  • 띄어쓰기 정제: "배송 느리" → "배송 느림"
  • 도메인 용어 통일: "AI" → "인공지능" (도메인 용어의 일관성을 유지)
  • 데이터 정제: 비속어, 오타, 불필요한 기호 등을 제거

프로세스

Fine-tuning 과정은 다음과 같이 진행됩니다:

  1. 데이터 업로드: 학습에 사용할 jsonl 파일을 OpenAI로 업로드합니다.
  2. Fine-tuning 작업 생성: jobs.create API를 호출하여 Fine-tuning 작업을 생성합니다.
  3. 모델 호출: Fine-tuning된 모델은 생성된 모델의 ID를 사용하여 API 호출 시 사용됩니다.
  4. 결과 관리: Fine-tuning의 결과는 base64로 인코딩되어 반환됩니다. 이때 OpenAI 디코더를 사용하여 결과를 복원합니다.

Fine-Tuning 예시

  1. 데이터 포맷 예시:
  2. {"messages": [ {"role": "user", "content": "배송이 너무 느려요"}, {"role": "assistant", "content": "배송이 지연되고 있어 죄송합니다. 빠르게 처리하도록 하겠습니다."} ]}
  3. Fine-tuning 작업:
    • Fine-tuning을 위한 데이터 파일을 준비하고 OpenAI API를 통해 업로드합니다.
    • 업로드된 파일을 기반으로 Fine-tuning 작업을 생성하고 완료된 후, 이를 통해 최적화된 모델을 호출합니다.

Fine-tuning을 통해 모델을 특정 도메인이나 작업에 맞게 정밀 조정하면 더 나은 성능을 기대할 수 있습니다.

 

# 감정 분석용 데이터 10개
training_data = [
  {"messages":[{"role":"user","content":"배송도 빠르고 제품 상태도 아주 좋아요!"},{"role":"assistant","content":"긍정"}]}
  , {"messages":[{"role":"user","content":"정말 기대 이상이에요. 다음에도 꼭 재구매할게요."},{"role":"assistant","content":"긍정"}]}
  , {"messages":[{"role":"user","content":"디자인이 예쁘고 사용하기도 편하네요."},{"role":"assistant","content":"긍정"}]}
  , {"messages":[{"role":"user","content":"처음 사용해보는데 만족도가 높아요."},{"role":"assistant","content":"긍정"}]}
  , {"messages":[{"role":"user","content":"가격 대비 성능이 뛰어납니다."},{"role":"assistant","content":"긍정"}]}

  , {"messages":[{"role":"user","content":"작동이 안 돼서 너무 화가 납니다."},{"role":"assistant","content":"부정"}]}
  , {"messages":[{"role":"user","content":"광고랑 다르게 품질이 별로였어요."},{"role":"assistant","content":"부정"}]}
  , {"messages":[{"role":"user","content":"고장이 자주 나서 불편합니다."},{"role":"assistant","content":"부정"}]}
  , {"messages":[{"role":"user","content":"배송이 느리고 포장도 부실했어요."},{"role":"assistant","content":"부정"}]}
  , {"messages":[{"role":"user","content":"기대한 만큼의 성능이 아니네요."},{"role":"assistant","content":"부정"}]}

  , {"messages":[{"role":"user","content":"기능은 많은데 아직 다 써보진 않았어요."},{"role":"assistant","content":"중립"}]}
  , {"messages":[{"role":"user","content":"사용 중 특별한 문제는 없었어요."},{"role":"assistant","content":"중립"}]}
  , {"messages":[{"role":"user","content":"평범한 제품입니다. 특별히 좋지도 나쁘지도 않아요."},{"role":"assistant","content":"중립"}]}
  , {"messages":[{"role":"user","content":"가격도 적당하고 일반적인 성능이에요."},{"role":"assistant","content":"중립"}]}
  , {"messages":[{"role":"user","content":"그럭저럭 쓸만합니다. 무난한 제품이에요."},{"role":"assistant","content":"중립"}]}
]

# 테스트 데이터
test_reviews = [
  '''
흰색 모델은 작동이 잘 안 되고 소리도 이상했지만, 충전 후엔 정상 작동했습니다. 청록색은 바람 세기가 조금 약한 느낌. 가격 대비 저렴해 보여 선물용으로는 아쉬운 제품이지만, 폰 거치대 기능은 유용하네요.              
  '''
]

# 필요한 라이브러리 import
from openai import OpenAI
import os
import time
import json

# open ai 세팅
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

# json 파일 생성
def create_jsonl_file(data, filename="training_data.jsonl"):
  with open(filename, "w", encoding="utf-8") as f:
    for item in training_data:
      json_line = json.dumps(item, ensure_ascii=False)
      f.write(json_line + "\\n")
  return filename

# 파인튜닝 데이터 업로드
def upload_file(filename):
  with open(filename, "rb") as f:
    tuning_data = client.files.create(
        file=f,
        purpose="fine-tune"
    )
  return tuning_data.id

# 파인튜닝 작업 생성
def create_fine_tuning_job(file_id, model="gpt-3.5-turbo"):
  job = client.fine_tuning.jobs.create(
      training_file=file_id,
      model=model
  )
  return job.id

# 파인튜닝 상태 확인
def check_fine_tuning_status(job_id):
  status = client.fine_tuning.jobs.retrieve(job_id)
  return status.status, status.fine_tuned_model

# openai api 호출 함수(비용추적 및 예외처리)
def call_openai(prompt, model="gpt-3.5-turbo", temperature=0.3, max_tokens=50,n=1):
  try:
    start_time = time.time()
    response = client.chat.completions.create(
      model=model,
      messages=[
        {"role": "user", "content": prompt}
      ],
      temperature=temperature,
      max_tokens=max_tokens,
      n=n
    )
    elapsed_time = time.time() - start_time
    tokens_used = response.usage.total_tokens
    return {
        "results" : [choice.message.content for choice in response.choices],
        "tokens_used" : tokens_used,
        "elapsed_time" : elapsed_time
    }
  except Exception as e:
    print(f'api 호출 오류 : {e}')
    return {
        "results" : [],
        "tokens_used" : 0,
        "elapsed_time" : 0
    }
# 파일생성 및 업로드
jsoned_file = create_jsonl_file(training_data, "20250508.jsonl")
file_id = upload_file(jsoned_file)
print(f"file id: {file_id}")
# 파인튜닝 작업( job 생성 )
job_id = create_fine_tuning_job(file_id)
print(f"job id: {job_id}")
# 상태확인
status, fine_tuned_model = check_fine_tuning_status(job_id)
print(f"status: {status}, model: {fine_tuned_model}")
# 감정 분석
sentiment_prompt = '''
리뷰: "{}"
감정: 
'''
for review in test_reviews:
  result = call_openai(sentiment_prompt.format(review), max_tokens=20, model=fine_tuned_model)
  print(f"리뷰: {review}")
  print(f"감정: {result}")

 


 

챗봇

챗봇은 특정 작업을 수행하거나 사용자와의 대화를 통해 다양한 정보나 서비스를 제공하는 AI 시스템입니다. 주로 FAQ 챗봇대화형 챗봇이 있으며, 프롬프트 설계 및 최적화를 통해 성능을 향상시킬 수 있습니다.

챗봇 유형

  1. FAQ 챗봇: 자주 묻는 질문에 대한 자동 응답을 제공합니다. 주로 정해진 질문에 대해 고정된 답변을 제공합니다.
  2. 대화형 챗봇: 사용자의 의도를 파악하고, 적절한 응답을 생성하여 대화를 이어갑니다. 더 자연스럽고 유연한 대화가 가능합니다.

프롬프트 설계

챗봇의 응답 품질을 높이기 위해서는 효과적인 프롬프트 설계가 필요합니다.

  1. Few-shot: 사용자 문의와 응답을 여러 쌍으로 제공하여 모델이 패턴을 학습할 수 있도록 합니다.
    • 예시: "문의: 배송이 언제 되나요?", "응답: 배송은 2~3일 내에 완료됩니다."
  2. Role-based: 모델에 특정 역할을 부여하여 응답 스타일을 조정합니다. 예를 들어, "친절한 고객 상담사" 역할을 부여하면 더욱 부드럽고 친절한 응답을 유도할 수 있습니다.
  3. 한글 최적화: 한국어 표현에 맞게 프롬프트를 설계합니다. 또한 존댓말/반말을 적절히 조정하여 대화의 톤을 맞추는 것이 중요합니다.

챗봇 최적화

  1. 간결한 프롬프트: 토큰 소모를 최소화하여 효율적인 모델 호출을 할 수 있도록 합니다.
  2. 맥락 유지: 대화의 흐름을 이어갈 수 있도록 이전 대화 내용을 포함하는 방법입니다. 예를 들어, 메시지 리스트를 사용하여 대화의 연속성을 유지합니다.

성능 평가

챗봇의 성능은 여러 기준으로 평가할 수 있습니다.

  1. 정확도: 챗봇의 응답이 사용자 문의에 적합한지 평가합니다.
  2. 자연스러움: 한국어 표현이 얼마나 자연스럽고 유연한지 평가합니다.
  3. 응답 시간: API 호출 속도나 챗봇의 응답 속도도 중요한 평가 기준입니다.

사용자 경험

  1. 친절한 톤: 사용자가 보다 친근하게 느낄 수 있도록 존댓말을 사용하고, 공감 표현을 넣는 것이 중요합니다.
  2. 오류 처리: 모호한 질문이나 요청에 대해서는 기본적인 응답을 제공하여 사용자에게 혼란을 최소화합니다.

개선 방법

  1. 추가 Fine-tuning: 챗봇이 잘못된 응답을 제공하는 경우, 이를 수정하기 위해 fine-tuning을 추가로 적용합니다. 이를 통해 모델의 품질을 개선할 수 있습니다.
  2. 프롬프트 조정: 특정 문의 유형에 대해 더 나은 응답을 제공하도록 프롬프트를 조정하여 성능을 개선합니다.

결론

챗봇을 개발할 때에는 효율적인 프롬프트 설계, 자연스러운 대화 흐름 유지, 그리고 성능 최적화를 고려하여 사용자 경험을 향상시키는 것이 중요합니다.

 

# prompt: fine-tuning용 FAQ 데이터 10개 생성

training_data = [
  {"messages":[{"role":"user","content":"배송은 보통 얼마나 걸리나요?"},{"role":"assistant","content":"일반적으로 배송은 2~3일 정도 소요됩니다. 지역에 따라 다를 수 있습니다."}]},
  {"messages":[{"role":"user","content":"반품은 어떻게 신청하나요?"},{"role":"assistant","content":"마이페이지 > 주문 내역에서 해당 상품을 선택하고 반품 신청 버튼을 눌러주세요."}]},
  {"messages":[{"role":"user","content":"회원가입은 무료인가요?"},{"role":"assistant","content":"네, 회원가입은 무료이며 누구나 가입하실 수 있습니다."}]},
  {"messages":[{"role":"user","content":"고객센터 운영 시간은 어떻게 되나요?"},{"role":"assistant","content":"고객센터는 평일 오전 9시부터 오후 6시까지 운영됩니다."}]},
  {"messages":[{"role":"user","content":"현금영수증 발급 가능한가요?"},{"role":"assistant","content":"네, 결제 시 현금영수증 발급을 선택하시면 자동으로 발급됩니다."}]},
  {"messages":[{"role":"user","content":"비밀번호를 잊어버렸어요. 어떻게 해야 하나요?"},{"role":"assistant","content":"로그인 화면에서 '비밀번호 찾기'를 클릭하여 안내에 따라 재설정하실 수 있습니다."}]},
  {"messages":[{"role":"user","content":"제품 보증 기간은 얼마나 되나요?"},{"role":"assistant","content":"제품에 따라 다르지만 일반적으로 1년의 무상 보증 기간이 제공됩니다."}]},
  {"messages":[{"role":"user","content":"쿠폰은 어디서 확인할 수 있나요?"},{"role":"assistant","content":"마이페이지 > 쿠폰함에서 보유하신 쿠폰을 확인하실 수 있습니다."}]},
  {"messages":[{"role":"user","content":"배송지를 변경하고 싶어요."},{"role":"assistant","content":"배송 준비 전이라면 마이페이지에서 배송지 변경이 가능합니다. 준비 완료 이후에는 변경이 어려울 수 있습니다."}]},
  {"messages":[{"role":"user","content":"해외에서도 주문할 수 있나요?"},{"role":"assistant","content":"현재는 국내 배송만 지원하고 있으며, 해외 배송은 준비 중입니다."}]}
]

# 테스트 데이터
test_inputs = [
    '배송이 언제 도착하나요?',
    '교환은 어떻게 하나요?',
    '환불은 어떻게 하면 되나요?',
    '상품이 파손되어 도착했어요. 이럴 때는 어떻게 하나요?'
]
# 파일생성 및 업로드
jsoned_file = create_jsonl_file(training_data, "chat_bot_training_data.jsonl")
file_id = upload_file(jsoned_file)
print(f"file id: {file_id}")
# 파인튜닝 작업( job 생성 )
job_id = create_fine_tuning_job(file_id, model="gpt-4.1-mini-2025-04-14")
print(f"job id: {job_id}")
# 상태확인
status, fine_tuned_model = check_fine_tuning_status(job_id)
print(f"status: {status}, model: {fine_tuned_model}")
# 챗봇 답변 생성
chat_bot_prompt = '''
질문: "{}"
답변: 
'''
for test_input in test_inputs:
  result = call_openai(chat_bot_prompt.format(test_input), max_tokens=50, model=fine_tuned_model)
  print(f"리뷰: {test_input}")
  print(f"감정: {result}")
리뷰: 배송이 언제 도착하나요?
감정: {'results': ['일반적으로 배송은 2~3일 정도 소요됩니다. 지역에 따라 다를 수 있습니다.'], 'tokens_used': 48, 'elapsed_time': 0.7134959697723389}
리뷰: 교환은 어떻게 하나요?
감정: {'results': ['교환을 원하시는 경우, 상품 수령 후 7일 이내에 고객센터로 문의해 주시기 바랍니다.'], 'tokens_used': 52, 'elapsed_time': 0.5615718364715576}
리뷰: 환불은 어떻게 하면 되나요?
감정: {'results': ['마이페이지 > 주문 내역에서 해당 상품을 선택하고 환불 신청 버튼을 눌러주세요.'], 'tokens_used': 48, 'elapsed_time': 0.49699878692626953}
리뷰: 상품이 파손되어 도착했어요. 이럴 때는 어떻게 하나요?
감정: {'results': ['상품이 파손되어 도착한 경우, 고객센터(1234-5678)로 연락주시거나 마이페이지 > 주문 내역에서 해당 상품을 선택하여 교환/반품 신청을 해주세요.'], 'tokens_used': 81, 'elapsed_time': 0.7670507431030273}
반응형