2023년 11월 6일에 열린 OpenAI Dev Day에서 Assistants API가 발표되었습니다. 현재 2024년 1월 7일까지 베타 상태로 빠르게 변화하고 있습니다. 이 글에서는 Assistants API가 무엇인지, 그리고 어떤 방식으로 사용할 수 있는지 알아보겠습니다.
Assistants API란?
Assistants API는 자체 애플리케이션에서 인공지능(AI) 기반의 도우미나 챗봇을 구축할 수 있게 해주는 OpenAI의 API입니다. 이 API를 통해 개발자들은 쉽게 고급 AI 기능을 자신의 애플리케이션에 통합할 수 있습니다.
Assistant는 사용자의 Instruction을 포함하며, OpenAI가 제공하는 언어 Model, Code Interperter, Retrieval, Function 기능 등 다양한 Tool를 활용하여 사용자의 질문에 응답합니다. 현재 Assistants API는 베타(Beta) 상태로, 지속적인 개선과 업데이트가 진행 중입니다.
Assistants Playgound 사용
Assistants Playgound 소개
기본 화면입니다. Assistant, Thread, Message 로 구성된 것을 볼 수 있습니다.
- Assistant : Instruction, Model, Tool, Function 등 다양한 매개변수를 사용하여 사용자의 메시지에 응답하는 개체입니다.
- Thread : 대화 흐름을 나타냅니다.
- Message : 텍스트와 선택적으로 사용자가 업로드하도록 허용한 모든 파일이 포함됩니다.
Assistant 생성
OpenAI의 공식문서를 참조하여 수학 선생님 Assistant를 만들어 보겠습니다.Create
버튼을 누르고 필요한 정보를 입력합니다.
각 항목을 입력하고 Save
버튼을 누릅니다.
항목 | 내용 |
---|---|
Name | Math Tutor Playgound |
Instructions | You are a personal math tutor. Write and run code to answer math questions. |
Model | gpt-4-1106-preview |
Tools | Code interpreter |
Assistants 탭을 확인해 보면 Math Tutor Playgound
라는 Assistant가 등록된 것을 확인할 수 있습니다.
Message 생성
Message를 입력하고 +
버튼을 눌러 추가합니다.
Run 실행
Run에 instruction을 추가할 수 있으며 Assistant 의 기본 instruction 보다 우선합니다.
Run 버튼 옆 ▼ 를 누르고 Add run instructions
항목에 ‘Please address the user as Jane Doe. The user has a premium account.’를 입력하고 Run 버튼을 눌러 추가된 Message를 실행시킵니다.
Run 결과 확인
일반적인 ChatGPT와 동일하게 채팅 형태의 Thread 화면을 보여줍니다.
Run 실행 시 Instruction 을 추가하지 않는 경우
Run 실행 시 instruction을 추가하지 않으면 기본 Assistant의 instruction에 따라 응답합니다.
확실히 Run에 추가된 instruction으로 인해 유저를 premium account
로 설정한 것과는 비교되는 단순한 답변을 하게 됨을 알 수 있습니다.
Python으로 Assstants API 실행
Assistants API를 사용하기 위해 먼저 openai python 패키지를 설치하거나 업데이트 해야 합니다.
- 설치 (설치가 되어 있지 않은 경우)
pip install openai
- 업데이트 (기존 버전이 설치되어 있는 경우)
pip install --upgrade openai
OpenAI를 사용하기 위해 Python 코드 상단에는 다음 코드가 포함됩니다. YOUR_OPENAI_API_KEY
에는 본인의 OpenAI API 키를 입력해 주면 됩니다.
from openai import OpenAI client = OpenAI(api_key="YOUR_OPENAI_API_KEY")
Assistant 생성
OpenAI의 공식문서를 참조하여 수학 선생님 Assistant를 만들어 보겠습니다.
assistant = client.beta.assistants.create( name="Math Tutor Python", instructions="You are a personal math tutor. Write and run code to answer math questions.", tools=[{"type": "code_interpreter"}], model="gpt-4-1106-preview" ) print(assistant)
실행하면 다음과 같은 결과를 확인할 수 있습니다.
Assistant(id='asst_VaOJkNfnmxRT7huCpqVOZYRF', created_at=1704613835, description=None, file_ids=[], instructions='You are a personal math tutor. Write and run code to answer math questions.', metadata={}, model='gpt-4-1106-preview', name='Math Tutor Python', object='assistant', tools=[ToolCodeInterpreter(type='code_interpreter')])
생성된 Assistant는 Playground에서도 확인할 수 있습니다.
Thread 생성
Thread를 생성해 보겠습니다. 현재로는 Thread와 Assistant의 연관성이 없으므로 따로 만들면 됩니다.
thread = client.beta.threads.create() print(thread)
실행해 보면 thread_
로 시작하는 id로 Thread가 생성된 것을 확인할 수 있습니다.
Thread(id='thread_jJTPlfeeI2pDPOQKnSu7wpOh', created_at=1704613879, metadata={}, object='thread')
Thread에 Message 생성
Message는 Thread에 추가되는 것이므로 thread_id
가 필요합니다.
message = client.beta.threads.messages.create( thread_id="thread_jJTPlfeeI2pDPOQKnSu7wpOh", role="user", content="I need to solve the equation `3x + 11 = 14`. Can you help me?" ) print(message)
Thread에 Message가 추가된 것을 확인할 수 있습니다.
ThreadMessage(id='msg_Q0cnUaimpXyaNa6FK2fm54v8', assistant_id=None, content=[MessageContentText(text=Text(annotations=[], value='I need to solve the equation `3x + 11 = 14`. Can you help me?'), type='text')], created_at=1704613934, file_ids=[], metadata={}, object='thread.message', role='user', run_id=None, thread_id='thread_jJTPlfeeI2pDPOQKnSu7wpOh')
Run 생성
Thread에 Message를 추가하는 것만으로는 원하는 응답을 받을 수 없습니다. Assistant로부터 응답을 받기 위해 Run을 생성해야 합니다.
run = client.beta.threads.runs.create( thread_id="thread_jJTPlfeeI2pDPOQKnSu7wpOh", assistant_id="asst_VaOJkNfnmxRT7huCpqVOZYRF", instructions="Please address the user as Jane Doe. The user has a premium account." ) print(run)
Run이 생성되었습니다.
Run(id='run_DmymSYOQXSe8uv1M4yTaZih3', assistant_id='asst_VaOJkNfnmxRT7huCpqVOZYRF', cancelled_at=None, completed_at=None, created_at=1704613982, expires_at=1704614582, failed_at=None, file_ids=[], instructions='Please address the user as Jane Doe. The user has a premium account.', last_error=None, metadata={}, model='gpt-4-1106-preview', object='thread.run', required_action=None, started_at=None, status='queued', thread_id='thread_jJTPlfeeI2pDPOQKnSu7wpOh', tools=[ToolAssistantToolsCode(type='code_interpreter')])
Run 상태 확인
기본적으로 Run을 생성하면 queued
상태가 됩니다. 앞에서 생성한 Run을 얻어와 status
를 확인하여 completed
상태이면 응답이 완료된 상태입니다.
run = client.beta.threads.runs.retrieve( thread_id="thread_jJTPlfeeI2pDPOQKnSu7wpOh", run_id="run_DmymSYOQXSe8uv1M4yTaZih3" ) print(run)
실행하면 Run의 정보를 확인할 수 있습니다.
Run(id='run_DmymSYOQXSe8uv1M4yTaZih3', assistant_id='asst_VaOJkNfnmxRT7huCpqVOZYRF', cancelled_at=None, completed_at=1704613991, created_at=1704613982, expires_at=None, failed_at=None, file_ids=[], instructions='Please address the user as Jane Doe. The user has a premium account.', last_error=None, metadata={}, model='gpt-4-1106-preview', object='thread.run', required_action=None, started_at=1704613982, status='completed', thread_id='thread_jJTPlfeeI2pDPOQKnSu7wpOh', tools=[ToolAssistantToolsCode(type='code_interpreter')])
Thread의 Message 리스트 조회
Run의 status
가 completed
이면 Thread의 Message 리스트를 통해 응답결과를 확인할 수 있습니다.
다른 정보는 배제하고 Message의 내용만 출력하면 다음과 같습니다.
messages = client.beta.threads.messages.list( thread_id="thread_jJTPlfeeI2pDPOQKnSu7wpOh", ) for i, message in enumerate(reversed(messages.data), start=1): print(f"\n# Message {i}:") for content in message.content: print(content.text.value)
Message 1
은 내가 한 질문이고 Message 2
는 Assistant가 수학선생님으로서 응답한 결과입니다.
실제로는 최신 메시지가 messages.data[0]
이므로 reversed
를 사용해 역으로 오래된 것부터 출력했습니다.
# Message 1: I need to solve the equation `3x + 11 = 14`. Can you help me? # Message 2: The solution to the equation \(3x + 11 = 14\) is \(x = 1\).
Thread 삭제
필요한 작업을 완료한 Thread는 삭제할 수 있습니다.
response = client.beta.threads.delete("thread_jJTPlfeeI2pDPOQKnSu7wpOh") print(response)
삭제에 성공하면 다음과 같은 결과를 확인할 수 있습니다.
ThreadDeleted(id='thread_jJTPlfeeI2pDPOQKnSu7wpOh', deleted=True, object='thread.deleted')
Playgound vs Assstants API
기본적인 동작은 동일하지만 세부적인 기능은 Assistants API에서만 지원됩니다. Assistant 생성 같은 경우 Playground에서 하는 것이 더 편리하지 않을까 생각합니다.
Assistants API vs Langchain
개발적인 측면에서 Langchain을 사용하는 것은 개발자에게 더 다양한 선택지를 제공합니다. 다른 LLM(Large Language Model) 서비스를 사용하거나 Retrieval 기능을 직접 구현하거나, 원하는 서비스를 선택할 수 있는 유연성이 있습니다. 반면, OpenAI의 Assistants API를 사용하면 복잡한 설정 없이 쉽게 구현할 수 있는 것이 주요 장점입니다.
비용 측면에서는 Assistants API가 더 높은 비용이 들 것으로 예상됩니다. Langchain을 사용하면 로컬 VectorDB를 활용해 Retrieval 기능을 직접 구현하거나 무료 LLM 서비스를 이용할 수 있으며, 필요에 따라 ChatGPT의 기능도 활용할 수 있습니다. 반면, OpenAI의 Assistants API는 고정된 가격 정책에 따라 비용이 청구되므로, 비용 면에서 중요한 고려 사항이 될 수 있습니다.
Assistants API 가격정책
- Assistants API에 사용되는 토큰은 선택한 언어 모델의 토큰당 입력/출력 요금으로 청구됩니다.
- Code Interpreter
Code Interpreter 가격은 세션당 $0.03입니다. Assistant가 서로 다른 두 개의 Thread에서 동시에 Code Interpreter를 호출하면 두 개의 Code Interpreter 세션이 생성됩니다(2 * $0.03). 각 세션은 기본적으로 1시간 동안 활성화되므로 사용자가 동일한 Thread에서 Code Interpreter에게 최대 1시간 동안 계속 지시를 내릴 경우 이 요금은 한 번만 지불하면 됩니다.
- Retrieval
검색 요금은 Assistant 당 하루 $0.20/GB로 책정됩니다. 애플리케이션에서 하루 동안 1GB의 파일을 저장하고 검색을 목적으로 두 명의 Assistant (예: 고객 대면 Assistant와 내부 직원 Assistant)에게 전달할 경우 이 저장 요금이 두 번 청구됩니다(2 * 하루 $0.20). 이 요금은 특정 Assistant로부터 지식을 검색하는 최종 사용자 및 스레드 수에 따라 달라지지 않습니다.
정리
Assistants API의 출시는 사용자에게 다양한 선택지를 제공하는 긍정적인 변화입니다. 실제 사용 여부는 상황, 비용, 제공되는 기능에 따라 달라질 수 있습니다. OpenAI의 Assistants API는 개발자에게 사용의 편리함과 간편함을 제공하며, Langchain과 같은 다른 대안도 고려할 수 있습니다.
본 글은 GPTers에 게시되고 있습니다.
https://www.gpters.org/c/ai-developers/openai-assistants-api