오늘은 Python 과 ChatGPT API로 간단한 챗봇을 만들어 보겠습니다.
import os import openai def open_file(filepath): with open(filepath, 'r', encoding='utf-8') as infile: return infile.read() openai.api_key = open_file('openaiapikey.txt') while True: prompt = input("\n Ask OpenAI Anything: ") completions = openai.Completion.create(prompt = prompt, engine='text-ada-001', #engine="text-davinci-003", max_tokens=100) print(completions)
아직 완성된 코드는 아닙니다. 하나 하나 보겠습니다.
Openai.api_key 부분 까지는 계속 반복되는 코드 블럭입니다.
Openai에게 api 사용 권한을 받기 위해 api key를 제공하는 부분 입니다.
챗봇 기능이 이뤄지는 부분은 while 문 부터 입니다.
while True: 는 무한 루프 입니다.
이 프로그램을 실행하면 끝마치는 방법은 강제 종료 (Ctrl Z) 해야 합니다.
그 다음은 prompt 변수 부분입니다.
이 변수는 openai.Completion.create api를 사용할 때 필요한 건데요. 이전 글에서도 봤듯이 사용자가 궁금해 하는 질문이 여기에 들어가게 됩니다.
prompt = input("\n Ask OpenAI Anything: ")
input()은 Python 의 메소드로 사용자의 입력을 받겠다는 겁니다.
이 부분은 실행되면 "" 안에 있는 내용이 출력 되고 Python은 사용자의 입력을 받을 준비를 하게 됩니다.
그 다음 부분이 openai의 API 입니다.
openai.Completion.create() api를 사용해서 질문을 던지고 대답을 받습니다.
파라미터는 간단하게 3가지만 전달합니다.
질문은 prompt 이구요. 여기에는 사용자가 입력한 질문이 들어가게 됩니다.
사용하는 openai 모델은 text-ada-001 입니다. 가장 저렴한 모델입니다.
좋은 모델을 사용하려면 text-davinci-003을 쓰면 됩니다.
요즘 유행하는 ChatGPT는 아직 api가 공개 되지 않았습니다.
나중에 공개 되면 그 모델 이름을 넣으면 ChatGPT API를 사용할 수 있습니다.
마지막 파라미터로는 max_tokens 가 사용 됐습니다.
Token 에 대해서는 여기서 알아 보세요.
https://platform.openai.com/tokenizer
OpenAI API
An API for accessing new AI models developed by OpenAI
platform.openai.com
여기서는 특정 문장이 몇개의 토큰으로 이뤄 졌는지 알 수 있는데요.
예를 들어 What is a capital city of South Korea? 가 몇개의 토큰으로 이뤄 져 있는지 알아 보겠습니다.
글자 수는 총 38자 이지만 토큰은 9개 이네요. 이 토큰은 GPT 모델이 사용하는 단위 입니다. 대개 한 단어가 1개의 토큰으로 이뤄 집니다. (그렇지 않은 경우도 있구요.)
위 경우를 보면 tokenized는 token과 ized 이렇게 두개의 토큰으로 간주 하는 것을 볼 수 있습니다.
하여간 이 코드에서 사용한 아래 스크립트 내용은 최대 100개의 토큰까지 허용하겠다는 겁니다.
max_tokens=100
토큰이 많으면 비용과 시간이 늘어 날 수 있겠죠.
이렇게 openai.Completion.creat() api를 이용해서 질문을 보내면 response를 받게 되는데요.
이 response는 completions라는 변수에 담기게 됩니다.
print(completions) 는 이 completions를 출력하라는 python 메소드 입니다.
이 코드를 실행해서 질문을 던져 보겠습니다.
남한의 수도는 어디냐고 물어봤더니 긴 Json 형식의 대답을 받았습니다.
openai.Completion.creat() api 는 질문에 대한 답을 이런 형식으로 줍니다.
다양한 정보가 담겨 있습니다.
질문에 대한 답변은 choices 에 있는 text 부분입니다.
서울이 남한의 수도라는 대답이 담겨 있습니다.
이 부분만 따로 뽑아서 표시해야 제대로 된 chatbot이 될 것 같습니다.
그 방법은 아래와 같이 하면 됩니다.
completion = completions.choices[0].text
print(completion)
completions의 choices 라는 배열 안에 있는 text 값만 따로 completion이라는 변수에 담아서 이것을 출력 하는 겁니다.
이렇게 하면 다음과 같이 질문을 계속 주고 받을 수 있습니다.
답변이 모두 정답은 아닙니다.
왜냐하면 여기서 사용한 모델은 가장 저렴한 테스트 용인 text-ada-001 이기 때문입니다.
좀 더 정확한 답을 받으려면 text-davinci-003 를 사용하면 됩니다. 이 모델이 조금 더 비싸죠.
이 모델은 남한의 수도만 서울이라고 맞히고 북한, 캐나다, 호주의 수도는 다 틀렸습니다.
(정답은 북한 - 평양, 캐나다 - 오타와, 호주 - 캔버라 입니다.)
이렇게 계속 질문을 하고 답변을 받는 채팅 기능이 완성 됐습니다.
전체 코드는 아래와 같습니다.
import os import openai def open_file(filepath): with open(filepath, 'r', encoding='utf-8') as infile: return infile.read() openai.api_key = open_file('openaiapikey.txt') while True: prompt = input("\n Ask OpenAI Anything: ") completions = openai.Completion.create(prompt = prompt, engine='text-ada-001', #engine="text-davinci-003", max_tokens=100) completion = completions.choices[0].text print(completion)
한가지 불완전한 부분이 있는데요.
GPT3와 응답을 하게 되면 GPT3 가 이전 질문을 기억하고 그 맥락에 맞는 답변을 하게 됩니다.
그런데 이렇게 openai.Completion.create() api 에 질문을 하나만 넣으면 이 전에 대화 했던 내용은 전혀 참고가 될 수 없습니다.
맥락이 있는 대화를 할 수 있는 챗봇을 만들려면 이 질문 부분에 이전의 질문까지 다 같이 보내야 합니다.
이 부분은 list를 사용해서 간단히 해결 할 수 있습니다.
그 소스는 다음 글에서 분석해 보겠습니다.