Patrick's 데이터 세상
Assistants API 본문
OpenAI에서 제공하는 Assistants는 기존 단일 API인 Chat Completions를 개선시킨 것으로 보조자로써 하나의 보조자 챗봇과 같은 형태를 구성하여 굉장히 간편하게 활용할 수 있습니다. Assistants는 코드 인터프리터, 파일 검색, 함수 호출과 같은 유형의 도구를 지원하여 Python으로 만든 함수를 실행하거나 파일을 등록하여 해당 내용을 기반으로 답변하게 하는 등 굉장히 강력한 도구입니다.
구조
Assistant : OpenAI의 모델 특수 목적 개인화 챗봇.
Thread : 어시스턴트에 스레드를 구축하여 모델과 사용자 간의 대화가 가능한 세션을 구축. 메시지를 저장하고 모델의 컨텍스트에 맞게 콘텐츠를 잘라서 자동으로 처리함.
Message : 어시스턴트 또는 사용자가 만든 메시지로 텍스트, 이미지 및 기타 파일 포함 가능. 스레드에 목록으로 저장된 메시지.
Run : 스레드에서 어시스턴트 호출. 환경설정과 스레드 메시지를 사용하여 모델, 도구를 호출하고 작업 실행. 실행 후 어시스턴트는 스레드에 메시지 추가.
Playground
먼저 Assistants를 사용하기 위해서 Assistants를 생성해야 합니다. Assistants를 활용하는 방법은 API 코드를 활용하는 방법도 있지만 Playground에서 생성하고 활용할 수도 있습니다.
설정에서 Payment 결제할 카드를 등록하면 Playground에서 Assistants 사용이 가능합니다.
Name(이름), System instructions(설명), Model(모델) 등을 설정하고 TOOLS에서 File search, Code interpreter, Functions를 설정합니다. File search는 사용자가 파일을 업로드하면 모델이 해당 파일을 통하여 사용자 요청에 따라 검색할 시기를 자동으로 설정하여 대답하게 하는 방식으로 일종의 RAG 방식과 유사하다고 할 수 있습니다. Code interpreter는 어시스턴트가 코드를 작성하고 실행할 수 있고 다양한 데이터와 형식의 파일을 처리하고 그래프와 같은 파일을 생성할 수 있습니다. Functions는 함수 호출을 하여 앱 또는 외부 API의 사용자 지정 함수를 어시스턴트에게 설명할 수 있고 해당 방식으로 어시스턴트가 관련 인수가 포함된 JSON 객체를 출력하여 해당 함수를 호출하게 됩니다. 그리고 MODEL CONFIGURATION에서 Response format을 text 형태나 json 형태로 선택하고 Temperature, Top p 값으로 다양성과 확률 분포를 설정합니다.
화면에서 THREAD 창에 질의를 하면 아래와 같이 답변됩니다. 로그를 보면 thread를 만들고 메시지를 담아서 실행하는 순서로 호출된 것을 볼 수 있습니다.
생성한 Threads에서 주고 받은 대화이력은 Dashboard의 Threads에서 확인할 수 있습니다. 만일 보이지 않는다면 아래 링크에서 보이도록 세팅해야 합니다.
https://platform.openai.com/threads
Code
이제 동일한 방식을 Python code로 실행하는 방법을 알아봅시다. 많은 기능이 있지만 기본적으로 메시징 처리하는 방법에 대해서 설명합니다.
먼저 client 객체를 생성합니다. 다음으로 생성한 해당 아이디의 스레드, 어시스턴트 아이디, 입력 메시지를 활용하여 스레드의 메시지를 생성하고 실행합니다. 어시스턴트는 Playground에서 만든 어시스턴트 아이디를 활용할 수도 있고 스레드처럼 코드로 생성할 수도 있습니다. 메시지를 생성할 때 파일 업로드, 코드 인터프리터, 함수 호출 기능을 활용할 수 있습니다. 실행 상태를 최신으로 만들고 메시지 리스트에서 생성된 답변을 호출합니다.
⊙ Tips
client.beta.threads.messages.list에서 limit 인자를 따로 설정해주지 않으면 기본이 20인데 20개 이후로는 대화를 Thread에서는 생성하는데 return을 받지 못하는 불상사가 생길 수 있으므로 필요시 limit에서 필요한 만큼 대화 이력을 받을 수 있게 늘려주어야 합니다.
https://community.openai.com/t/how-do-i-get-every-message-in-a-thread/784681
# import
from openai import OpenAI
from hydra import compose, initialize
# hydra
with initialize(version_base="1.2", config_path="./"):
cfg = compose(config_name="config")
client = OpenAI(
api_key=cfg.GPT.openai_api_key,
)
# Assistant Create
def create_thread():
# Assistant
thread = client.beta.threads.create()
return thread
# Generate Chat
def wait_on_run(run, thread_id):
# 반복문에서 대기하는 함수
while run.status == "queued" or run.status == "in_progress":
# 실행 상태를 최신 정보로 업데이트합니다.
run = client.beta.threads.runs.retrieve(
thread_id=thread_id,
run_id=run.id,
)
# time.sleep(0.5)
return run
def submit_message(assistant_id, thread_id, user_message):
# 3-1. 스레드에 종속된 메시지를 '추가' 합니다.
client.beta.threads.messages.create(
thread_id=thread_id,
role="user",
content=user_message,
# attachments=[
# {
# "file_id": message_file.id,
# "tools": [{"type": "file_search"}],
# }
# ],
)
# 3-2. 스레드를 실행합니다.
run = client.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=assistant_id,
)
return run
def get_response(thread_id):
# 3-4. 스레드에 종속된 메시지를 '조회' 합니다.
response = client.beta.threads.messages.list(
thread_id=thread_id,
limit=100,
after=None,
order="asc",
)
print(f"response : {response}")
return response
def get_message(response):
result = []
for res in response:
result.append(f"[{res.role.upper()}]\n{res.content[0].text.value}\n")
return " ".join(result)
def ask(assistant_id, thread_id, user_message):
run = submit_message(
assistant_id,
thread_id,
user_message,
)
# 실행이 완료될 때까지 대기합니다.
run = wait_on_run(run, thread_id)
result = get_message(get_response(thread_id).data[-2:])
return result
thread = create_thread()
thread_id = thread.id
input_text = "한국의 선사시대에 대해 설명해줘."
answer = ask(cfg.GPT.assistants_id, thread_id, input_text)
print(f"answer : {answer}")
여기까지 Assistants의 간단한 활용법에 대해 알아봤습니다. 간편하면서도 굉장한 많은 기능을 제공하고 있고 직관적인 사용으로 나만의 봇을 구성할 수 있고 서비스에서 대화 내용 저장, 토큰 제한을 맞춰주는 과정 등으로 간편하게 구성 가능한 것이 굉장한 장점이라고 할 수 있습니다.
참고
'Deep Learning > OpenAI' 카테고리의 다른 글
ChatGPT Prompt Engineering (0) | 2023.06.23 |
---|