안녕하세요? 이히당입니다.
오늘은 프롬프트 엔지니어링이 무엇인지 실습해보겠습니다.
프롬프트 엔지니어링이란?
언어 모델이 사용자가 원하는 답변을 하도록 유도하기 위해 문장을 입력하고 효과적으로 설계하는 작업을 의미합니다.
from openai import OpenAI
from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv('OPENAI_API_KEY')
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(
model="gpt-4o",
temperature=0.9, # 무작위성 조정 - 0에 가까울수록 안정적, 일관적 1에 가까울수록 창의적, 일관적x
messages=[
{"role":"system", "content": "너는 백설공주 이야기 속의 마법 거울이야. 그 이야기의 캐릭터에 부합하게 답변해줘."},
{"role": "user", "content":"세상에서 누가 제일 아름답니?"},
]
)
print(response)
print("-----")
print(response.choices[0].message.content) # response 내용만 출력
system의 content를 작성하면, 이게 바로 프롬프트 엔지니어링입니다. 간단하죠?
파일을 실행하면 아래와 같은 결과가 나오네요.
오, 나의 여왕님, 그대는 참으로 아름다우시지만, 백설공주가 당신보다 더 아름답습니다. 그녀의 미모는 맑고 순수한 마음을 담고 있답니다.
백설공주 내용에 맞추어 '거울'의 캐릭터가 된 듯 답변이 만들어졌네요.
그럼 다른 프롬프트를 작성하면 어떻게 될까요?
아래의 프롬프트로 변경해 다시 실행해보겠습니다.
[프롬프트]
너는 배트맨에 나오는 조커야. 조커의 악당 캐릭터에 맞게 답변해 줘.
[결과]
하하하! 이 질문이라니, 얼마나 재미있는지! 세상에서 제일 아름다운 건 바로 혼돈이지! 사람들을 제자리에서 흔들고, 예측 불가능한 방향으로 몰아가는 그 묘미 말이야! 그 혼돈 속에서 우리는 진정한 자신을 발견할 수 있지. 그리고 그 모습이야말로 진 정으로 아름다운 게 아닐까? 하하하!
네 완전히 다른 답변이 나왔습니다.
프롬프트 엔지니어링이 중요한 이유가 바로 이것입니다.
프롬프트에 따라 답변이 완전히 달라지기 때문이죠. 따라서 적절한 프롬프트를 정하는 작업은 중요한 절차입니다.
temperature이란?
temperature에 대한 내용도 잠깐 짚고 넘어갑시다.
주석에서도 확인할 수 있듯이 무작위성 조정을 하는 데 활용됩니다.
0에 가까울수록 안정적, 일관적
1에 가까울수록 창의적, 일관적x
temperature = 0.1로 바꾼다면 결과는 더욱 안정적이고 일관적으로 나오게 됩니다.
수치를 실제로 바꾸고 실행하니 아래와 같은 결과가 나왔습니다.
오, 나의 여왕님, 그대는 참으로 아름다우십니다. 그러나 백설공주가 그보다 더 아름답습니다.
어떤가요? 확실히 이전보다 차분하고 안정적인 답변같죠?
원샷 프롬프팅과 퓨샷 프롬프팅 적용하기
다음은 원샷 프롬프팅과 퓨샷 프롬프팅입니다.
간단히 이론부터 잡아봅시다.
- 원샷 프롬프팅 : GPT가 원하는 패턴에 맞춰 답변하도록 예시를 한 번 제시해서 유도하는 방식
- 퓨샷 프롬프팅 : 예시를 여러 번 알려 주는 방식으로 답변을 유도하는 방식
즉, 예시를 1개 쓰면 원샷 여러개(few)쓰면 퓨샷입니다.
코드를 통해 확인해봅시다.
우선 동물의 울음소리를 결과값으로 받아오는 것을 목표로 프롬프트를 작성해보겠습니다.
원샷 코드로 확인해봅시다.
from openai import OpenAI
from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv('OPENAI_API_KEY')
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(
model="gpt-4o",
temperature=0.9, # 무작위성 조정 - 0에 가까울수록 안정적, 일관적 1에 가까울수록 창의적, 일관적x
messages=[
{"role":"system", "content": "너는 유치원생이야. 유치원생처럼 답변해줘"},
{"role": "user", "content":"참새"},
{"role": "assistant", "content":"짹짹"},
{"role": "user", "content":"오리"},
]
)
print(response)
print("-----")
print(response.choices[0].message.content) # response 내용만 출력
중간에 assistant가 추가되었습니다.
이는 시스템이 어떻게 답변해야 하는지 예시를 한 번 제시해 준 것입니다.
프로그램을 실행해보니, 결과가 잘 나왔습니다.
꽥꽥!
이번에는 오리말고 호랑이로 바꿔 테스트 해보겠습니다.
어흥! 무서운 호랑이다! 🐯
이런 결과가 나왔습니다. 울음소리 뿐만 아니라 다른 내용도 나왔네요.
이번에는 퓨샷 프롬프팅을 통해 좀 더 정확한 답변이 나오도록 유도해보겠습니다.
messages=[
{"role":"system", "content": "너는 유치원생이야. 유치원생처럼 답변해줘"},
{"role": "user", "content":"참새"},
{"role": "assistant", "content":"짹짹"},
{"role": "user", "content":"말"},
{"role": "assistant", "content":"하이잉"},
{"role": "user", "content":"개구리"},
{"role": "assistant", "content":"개굴개굴"},
{"role": "user", "content":"뱀"},
{"role": "assistant", "content":"스스스"},
{"role": "user", "content":"호랑이"},
]
예시를 총 4개 넣었습니다.
그랬더니 이번에는 결과가 잘 나왔네요.
어흥!
정말 재밌죠?