일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- 12기
- zero-shot
- ai캠프
- 임베딩
- sk네트웍스familyai캠프12기
- Rag
- 최종프로젝트
- 어셈블
- 중복인클루드
- 회고록
- 헤더가드
- one-shot
- sk네트웍스family
- #include
- 컴파일
- sk네트웍스ai캠프
- 소스코드
- openai
- 배포
- 전처리
- 주간회고
- FastAPI
- C++
- Docker
- sk네트웍스familyai캠프
- Fine-tuning
- Langchain
- 21주차
- AWS
- few-shot
- Today
- Total
ansir 님의 블로그
[ SK 네트웍스 Family AI 캠프 수업 내용 복습 ] zero-shot, one-shot, few-shot, fine-tuning 2025-05-08 본문
[ SK 네트웍스 Family AI 캠프 수업 내용 복습 ] zero-shot, one-shot, few-shot, fine-tuning 2025-05-08
ansir 2025. 5. 8. 20:34Prompt란?
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는 입력된 텍스트를 처리할 때 다음과 같은 절차를 따릅니다:
- 입력 텍스트를 토큰으로 분할
예: "하늘은 파랗다" → ['하늘', '은', ' ', '파랗', '다'] - 각 토큰에 대해 다음 토큰의 확률 분포를 예측
모델은 이전까지의 입력을 보고 다음에 어떤 단어(토큰)가 올지 확률적으로 예측합니다.
예를 들어, 입력이 "하늘은"일 경우 다음과 같은 예측을 할 수 있습니다:- "파랗다" → 확률 0.4
- "맑다" → 확률 0.3
- "어둡다" → 확률 0.1
- 그 외 다른 단어들...
- 가장 높은 확률(또는 특정 샘플링 방식에 따른 토큰)을 선택하여 출력에 추가
그다음 다시 예측 → 반복하면서 문장을 생성해 나감
핵심 개념 정리
항목 | 설명 |
입력 처리 방식 | 텍스트를 토큰 단위로 분리 |
학습 목표 | 다음에 올 토큰의 확률 분포를 최대한 정확히 예측 |
출력 생성 방식 | 예측된 확률 분포에 따라 하나씩 토큰을 이어붙여 문장 생성 |
모델 구조 | 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
코드 설명
- 라이브러리 임포트
- openai: OpenAI의 GPT 모델을 API를 통해 사용할 수 있게 해줌
- os: 환경 변수 관리를 위한 표준 라이브러리
- API 키 설정
- os.environ을 사용해 시스템 환경 변수에 API 키를 설정하고 이를 openai.api_key에 등록
- 실제 개발 환경에서는 .env 파일, 환경 변수 설정, 비밀 관리 서비스 등을 사용하는 것이 안전함
- 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
코드 설명
- 라이브러리 임포트
- requests: HTTP 요청을 보내는 라이브러리로, 웹 페이지를 가져오는 데 사용됩니다.
- BeautifulSoup: HTML 문서에서 데이터를 추출할 때 사용하는 라이브러리로, 웹 페이지의 구조를 파싱하여 원하는 데이터를 쉽게 추출할 수 있게 도와줍니다.
- 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)만큼 질문을 가져옵니다.
- 반환 값:
- 크롤링한 질문 리스트를 반환합니다. 예를 들어, 사용자가 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}")
코드 설명
- 리뷰 목록 (reviews):
- 분석할 리뷰들을 리스트 형태로 저장합니다.
- 예시로 3개의 리뷰를 포함시켰습니다.
- for 루프:
- 각 리뷰에 대해 감정 분석을 실행합니다.
- 리뷰를 하나씩 처리하면서 그에 맞는 프롬프트를 생성합니다.
- 프롬프트 생성 (sentiment_prompt):
- 각 리뷰에 대해 "긍정", "부정", "중립" 중 하나를 출력하도록 모델에 요청하는 프롬프트를 만듭니다.
- 리뷰 텍스트를 프롬프트에 포함시켜서 모델에 전달할 수 있도록 구성합니다.
- call_openai 함수 호출:
- 생성된 프롬프트를 OpenAI 모델에 전달하여 감정 분석 결과를 받습니다.
- call_openai 함수는 위에서 정의된 대로 OpenAI API를 호출하고 결과를 반환합니다.
- 결과 출력:
- 각 리뷰와 그에 대한 감정 분석 결과를 출력합니다.
# 각 헤드라인에 대해 zero-shot 카테고리 분류
for headline in headlines:
# 카테고리 분류를 위한 프롬프트 생성
category_prompt = f'''
다음 뉴스 기사 헤드라인의 카테고리를 정해줘:
헤드라인: {headline}
카테고리:
'''
# OpenAI 모델을 사용하여 카테고리 분류 결과 얻기
result = call_openai(category_prompt)
# 헤드라인과 카테고리 출력
print(f"headline: {headline}\\ncategory: {result}")
코드 설명
- 헤드라인 목록 (headlines):
- 분석할 뉴스 헤드라인들을 리스트로 저장합니다.
- 각 헤드라인은 뉴스 기사 제목을 나타냅니다.
- for 루프:
- 각 뉴스 헤드라인에 대해 카테고리 분류를 실행합니다.
- 헤드라인을 하나씩 처리하면서, 그에 맞는 카테고리 분류 프롬프트를 생성합니다.
- 프롬프트 생성 (category_prompt):
- 각 헤드라인에 대해 해당 뉴스가 속하는 카테고리를 출력하도록 모델에 요청하는 프롬프트를 만듭니다.
- 헤드라인 텍스트를 프롬프트에 포함시켜서 모델에 전달합니다.
- call_openai 함수 호출:
- 생성된 프롬프트를 OpenAI 모델에 전달하여 카테고리 분류 결과를 얻습니다.
- call_openai 함수는 위에서 정의한 대로 OpenAI API를 호출하고 결과를 반환합니다.
- 결과 출력:
- 각 헤드라인과 그에 대한 카테고리 분류 결과를 출력합니다.
- 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
코드 설명
- 라이브러리 임포트:
- requests: 웹페이지에서 데이터를 가져오기 위한 라이브러리입니다. requests.get()을 통해 웹페이지를 요청할 수 있습니다.
- BeautifulSoup: HTML 페이지를 파싱하고, 원하는 정보를 쉽게 추출할 수 있도록 도와주는 라이브러리입니다.
- 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:
- 문장: "오늘 아침에 일어난 교통사고로 인해 많은 사람들이 지각을 했습니다."
- 단계별 설명: 핵심 명사인 '아침', '교통사고', '사람들', '지각' 식별 → 일반 단어는 제외 → 키워드 목록: ['교통사고', '사람들', '지각']
- 예시 1:
이와 같이 여러 개의 예시를 통해 모델에게 작업을 수행하는 방법을 교육할 수 있습니다.
# 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 과정은 다음과 같이 진행됩니다:
- 데이터 업로드: 학습에 사용할 jsonl 파일을 OpenAI로 업로드합니다.
- Fine-tuning 작업 생성: jobs.create API를 호출하여 Fine-tuning 작업을 생성합니다.
- 모델 호출: Fine-tuning된 모델은 생성된 모델의 ID를 사용하여 API 호출 시 사용됩니다.
- 결과 관리: Fine-tuning의 결과는 base64로 인코딩되어 반환됩니다. 이때 OpenAI 디코더를 사용하여 결과를 복원합니다.
Fine-Tuning 예시
- 데이터 포맷 예시:
- {"messages": [ {"role": "user", "content": "배송이 너무 느려요"}, {"role": "assistant", "content": "배송이 지연되고 있어 죄송합니다. 빠르게 처리하도록 하겠습니다."} ]}
- 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 챗봇과 대화형 챗봇이 있으며, 프롬프트 설계 및 최적화를 통해 성능을 향상시킬 수 있습니다.
챗봇 유형
- FAQ 챗봇: 자주 묻는 질문에 대한 자동 응답을 제공합니다. 주로 정해진 질문에 대해 고정된 답변을 제공합니다.
- 대화형 챗봇: 사용자의 의도를 파악하고, 적절한 응답을 생성하여 대화를 이어갑니다. 더 자연스럽고 유연한 대화가 가능합니다.
프롬프트 설계
챗봇의 응답 품질을 높이기 위해서는 효과적인 프롬프트 설계가 필요합니다.
- Few-shot: 사용자 문의와 응답을 여러 쌍으로 제공하여 모델이 패턴을 학습할 수 있도록 합니다.
- 예시: "문의: 배송이 언제 되나요?", "응답: 배송은 2~3일 내에 완료됩니다."
- Role-based: 모델에 특정 역할을 부여하여 응답 스타일을 조정합니다. 예를 들어, "친절한 고객 상담사" 역할을 부여하면 더욱 부드럽고 친절한 응답을 유도할 수 있습니다.
- 한글 최적화: 한국어 표현에 맞게 프롬프트를 설계합니다. 또한 존댓말/반말을 적절히 조정하여 대화의 톤을 맞추는 것이 중요합니다.
챗봇 최적화
- 간결한 프롬프트: 토큰 소모를 최소화하여 효율적인 모델 호출을 할 수 있도록 합니다.
- 맥락 유지: 대화의 흐름을 이어갈 수 있도록 이전 대화 내용을 포함하는 방법입니다. 예를 들어, 메시지 리스트를 사용하여 대화의 연속성을 유지합니다.
성능 평가
챗봇의 성능은 여러 기준으로 평가할 수 있습니다.
- 정확도: 챗봇의 응답이 사용자 문의에 적합한지 평가합니다.
- 자연스러움: 한국어 표현이 얼마나 자연스럽고 유연한지 평가합니다.
- 응답 시간: API 호출 속도나 챗봇의 응답 속도도 중요한 평가 기준입니다.
사용자 경험
- 친절한 톤: 사용자가 보다 친근하게 느낄 수 있도록 존댓말을 사용하고, 공감 표현을 넣는 것이 중요합니다.
- 오류 처리: 모호한 질문이나 요청에 대해서는 기본적인 응답을 제공하여 사용자에게 혼란을 최소화합니다.
개선 방법
- 추가 Fine-tuning: 챗봇이 잘못된 응답을 제공하는 경우, 이를 수정하기 위해 fine-tuning을 추가로 적용합니다. 이를 통해 모델의 품질을 개선할 수 있습니다.
- 프롬프트 조정: 특정 문의 유형에 대해 더 나은 응답을 제공하도록 프롬프트를 조정하여 성능을 개선합니다.
결론
챗봇을 개발할 때에는 효율적인 프롬프트 설계, 자연스러운 대화 흐름 유지, 그리고 성능 최적화를 고려하여 사용자 경험을 향상시키는 것이 중요합니다.
# 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}