OpenAI Assistants API 사용해보기
개요
Workflow
- OpenAI의 Assistants API는 OpenAI의 model, tool, file을 이용하여 대화형 AI시스템을 구축할 수 있는 API이다.
- 기존 OpenAI Chat Completion과 Assistant API의 차이점은
- Chat Completion은 각 질문이 독립적으로 수행되어 대화의 context를 고려한 답변을 제시하지 않는다.
- Assistants API는
Thread
를 통해 사용자와 assistant간의 대화 맥락을 유지하며 답변을 제공한다.
- 현재 openai api (v1.54.4) 에서는 code interpreter, file search, custom function calling tool을 제공하고 있다.
Assistant API에서는
- 하나의 thread에서 사용자와 assistant간의 대화 기록이 저장되어 Assistant는 대화 문맥을 기반으로 답변을 제공하고 (= session)
- 사용자가 질문 (message)를 입력하면 run을 통해 assistant에게 전달되어
- Tool 사용, 답변 생성의 step을 통해 assistant가 적절한 답변을 제공한다.
Assistant API에서는
- 하나의 thread에서 사용자와 assistant간의 대화 기록이 저장되어 Assistant는 대화 문맥을 기반으로 답변을 제공하고 (= session)
- 사용자가 질문 (message)를 입력하면 run을 통해 assistant에게 전달되어
- Tool 사용, 답변 생성의 step을 통해 assistant가 적절한 답변을 제공한다.
주요 용어 정리
- Assistant: Task 수행에 필요한 구성 요소를 정의
- Instruction (= system message), OpenAI model, 사용할 tool 등
- Thread: 사용자-assistant간의 대화 session
- Message: 대화 참여자 (사용자/assistant)가 생성하는 message
- Run: 사용자의 질문을 assistant의 답변으로 변환하는 단계
- Run step: run을 실행 시 수반되는 단계
- Function call, file search, code interpreter, message creation 등
2. 세부 사항
Assistant
- Assistant는 task를 수행하는 요소들(instruction, OpenAI model, 사용할 tool 등)로 정의된다.
- Instruction은 각 assistant가 작동해야 하는 방식(rule, persona, tone 등)을 설정한다.
- Assistant에 설정한 instruction은 모든 run에서 동일하게 적용된다(system message와 유사한 역할 수행).
- 각 run마다 다른 task를 수행하기 위해서는 개별 run에서 instruction을 수정하거나 추가할 수 있다(Run 참조).
- Generation parameter(temperature, top_p)를 설정하여 모델의 무작위성을 조절할 수 있다.
- 어떤 tool을 사용할지 설정할 수 있다.
- TODO: response_format
Code
from openai import OpenAI client = OpenAI() assistant = client.beta.assistants.create( description="DESCRIPTION OF ASSISTANT" # assistant에 관한 설명. 실제 response 생성 과정에서는 영향이 없는 것으로 파악됨. instructions="SYSTEM MESSAGE", # system prompt와 비슷함. 한번 설정되면 name="NAME OF THE CLIENT", model="gpt-4o", # GPT 계열의 모델 설정 가능 https://platform.openai.com/docs/models tools=[{"type": "code_interpreter"}, {"type": "file_search"}], tool_resources={ "file_search": { "vector_store_ids": [vector_store_id] }, "code_interpreter": { "file_ids": [file_id] }, }, temperature=1.0, top_p=1.0 )
Thread
- Thread는 사용자와 assistant 간의 대화 상호작용이 이루어지는 세션을 의미한다.
- 일반적인 OpenAI의 Chat Completion과 달리, Thread에서는 대화 기록이 유지된다. 이로 인해 새로운 run이 실행될 때마다 이전 맥락을 고려하여 답변을 제공할 수 있다.
- ChatGPT의 세션과 유사한 개념이다.
- 동일한 세션에서 대화를 이어가려면 해당 thread의 ID만 정확히 전달하면 된다.
- 새로운 thread를 생성할 때 (1) 대화 내용이 없는 빈 thread를 만들거나, (2) 사용자의 질문이 포함된 thread를 만들 수 있다.
- (1) 빈 thread를 만들 때는 추가로 사용자나 assistant의 message를 넣어야 한다.
- (2) (1)의 과정을 한 번에 수행하여 사용자의 message가 포함된 thread를 생성한다.
Code
from openai import OpenAI client = OpenAI() # Thread without user messages and add message empty_thread = client.beta.threads.create() thread_message = client.beta.threads.message.create( thread_id=empty_thread.id, role="user" OR "assistant", content="MESSAGE" ) # Thread with user message message_thread = client.beta.threads.create( messages=[{"role": "user" OR "assistant", "content": "MESSAGE" }] )
Messages
- Message는 thread에 사용자나 assistant의 메시지를 전달한다.
- 사용자 message는
run
을 통해 assistant에게 전달될 메시지를 의미한다. - TODO: assistant message의 동작법
- Message는 단순한 입력이므로, 실제 출력을 얻기 위해서는
run
을 실행해야 한다.
Code
from openai import OpenAI client = OpenAI() thread = client.beta.threads.create() thread_message = client.beta.threads.message.create( thread_id=thread.id, role="user" OR "assistant", content="MESSAGE" )
Run
- Run은 thread에서 assistant를 실행하여 (tool을 사용하거나 generation config에 맞춰) 답변을 생성한다.
- ChatGPT의 한 번의 질문과 답변 pair와 유사함
- Run은 비동기적으로 실행되며, 종료되어야 response를 받을 수 있다.
- Run이 완료되기를 확인해야 한다 (status == “completed”)
threads.runs.create_and_poll()
을 사용하면 run 생성과 종료 시 polling을 한 번에 수행한다.
- 매 run마다 instruction을 수정(override)하거나 추가할 수 있으며, message 생성과 run을 동시에 진행할 수 있다.
- File search tool을 사용하는 경우,
include=[step_details.tool_calls[*].file_search.results[*].content]
를 추가하여 file search 결과를 불러올 수 있다. - 각 file search 결과는 run step 참조
Code
from openai import OpenAI client = OpenAI() # Create a run run = client.beta.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id ) # Create a thread and execute run = client.beta.threads.create_and_run( assistant_id=assistant.id, thread={ "messages": [ {"role": "user" OR "assistant", "content": "MESSAGE"} ] } # Create a run and poll when completed run = client.beta.threads.runs.create_and_poll( assistant_id=assistant.id, thread_id=thread.id, instructions="INSTRUCTION TO OVERRIDE", additional_instructions="INSTRUCTION TO APPEND AT ASSISTANT'S INSTRUCTION", additional_messages=[ { "role": "user" OR "assistant", "content": "A MESSAGE FOR NEW RUN" } ], include=[step_details.tool_calls[*].file_search.results[*].content] )
Run steps
- Run step은 run이 실행되는 동안의 모델 작업과 도구 호출에 대한 단계를 나타낸다.
- Run이 실행되면 자동으로 생성되므로 thread와 run ID를 통해 각 단계별 출력을 확인할 수 있다.
Code
from openai import OpenAI client = OpenAI() # Get the run steps run_steps = client.beta.threads.runs.steps.list( thread_id=thread.id, run_id=run.id ) # Retrieve the specific step output run_step = client.beta.threads.runs.steps.retrieve( thread_id=thread.id, run_id=run.id, step_id=step.id, # To include the search file results, please add the line below include=["step_details.tool_calls[*].file_search.results[*].content"], )