1. OpenAI의 어시스턴트 API 소개

1.1 어시스턴트 API의 정의와 목적

어시스턴트 API를 사용하면 개발자는 자신의 응용 프로그램 내에서 인공 지능 어시스턴트를 구축할 수 있습니다. 사용자 정의 명령을 정의하고 모델을 선택함으로써, 어시스턴트는 모델, 도구 및 지식을 사용하여 사용자 쿼리에 응답할 수 있습니다. 현재 어시스턴트 API는 코드 해석기, 검색 및 함수 호출의 세 가지 유형의 도구를 지원합니다.

1.2 어시스턴트 API의 응용

어시스턴트 API는 상호 작용하는 AI 지원이 필요한 다양한 시나리오에 적합합니다. 예를 들면:

  • 고객 지원: 일반적인 질문에 자동으로 답변하여 인간 고객 서비스의 작업 부하를 줄입니다.
  • 온라인 교육: 학생들의 질문에 답변하고 맞춤형 학습 지원을 제공합니다.
  • 데이터 분석: 사용자가 업로드한 데이터 파일을 분석하고 보고서를 생성하며 차트를 시각화합니다.
  • 개인화된 추천: 사용자의 과거 상호 작용에 기반한 맞춤형 제안 및 서비스를 제공합니다.

1.3 어시스턴트의 핵심 개념

어시스턴트 API의 핵심 객체에는 어시스턴트, 스레드 및 메시지가 포함됩니다. 이러한 객체 및 기능에 대한 자세한 소개는 다음과 같습니다:

어시스턴트

어시스턴트 객체는 OpenAI 모델 위에 구축되며 AI 어시스턴트 도구를 호출할 수 있습니다. 어시스턴트의 지시를 사용자 정의하여 그 성격과 기능을 맞출 수 있습니다. 예를 들어, "데이터 분석가"라는 어시스턴트를 생성하여 "code_interpreter" 도구를 사용하여 데이터를 분석하고 차트를 생성할 수 있습니다.

스레드

스레드 객체는 사용자와 어시스턴트 간의 대화 세션을 나타냅니다. 각 사용자마다 스레드를 생성하고 사용자가 어시스턴트와 상호 작용할 때 메시지를 추가할 수 있습니다. 스레드 객체는 효율적으로 메시지 기록을 저장하고 필요할 때 모델의 컨텍스트 길이 제한을 준수하기 위해 메시지를 줄입니다.

메시지

메시지 객체는 사용자 또는 어시스턴트가 생성할 수 있습니다. 메시지에는 텍스트, 이미지 및 기타 파일이 포함될 수 있습니다. 메시지는 스레드에 목록으로 저장됩니다. 실제 API 사용에서 개발자는 사용자 메시지를 스레드에 추가하고 필요에 따라 어시스턴트의 응답을 트리거할 수 있습니다.

실행

Run 객체는 어시스턴트 요청의 실행을 나타내며 Thread의 메시지 내용에 기초하여 어시스턴트를 호출합니다. 어시스턴트는 구성 및 스레드의 메시지를 활용하여 모델과 도구를 호출하여 작업을 실행합니다. 실행의 일부로 어시스턴트는 스레드에 메시지를 추가합니다.

2. 어시스턴트 API의 개발 프로세스

2.1 어시스턴트 생성

어시스턴트를 생성하려면 지침, 모델 이름 및 도구 구성을 포함하여 API에 요청을 보내어야 합니다. 다음은 개인적인 수학 교사 어시스턴트를 생성하는 간단한 예제입니다:

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "당신은 개인 수학 교사입니다. 코드를 작성하고 실행하여 수학 문제에 답하세요.",
    "name": "Math Tutor",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4"
  }'

API 파라미터:

  • instructions - 어시스턴트에게 할 일을 알려주는 시스템 지침입니다.
  • name - 어시스턴트의 이름입니다.
  • tools - 어시스턴트가 사용할 도구를 정의합니다. 각 어시스턴트마다 최대 128개의 도구를 가질 수 있습니다. 현재 도구 유형은 code_interpreter, retrieval 또는 function입니다.
  • model - 어시스턴트가 사용할 모델은 무엇인가요?

어시스턴트를 성공적으로 생성하면 어시스턴트 ID를 받게 됩니다.

2.2 세션 스레드 생성

Thread은 대화를 나타내며 사용자가 대화를 시작할 때마다 각 사용자를 위해 세션 스레드를 만드는 것을 권장합니다. 스레드는 다음과 같이 만들 수 있습니다:

curl https://api.openai.com/v1/threads \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d ''

스레드를 만든 후에는 스레드 ID를 받게 됩니다.

2.3 스레드에 메시지 추가하기

특정 스레드에 메시지를 추가할 수 있습니다. 이 메시지는 텍스트를 포함하고 선택적으로 사용자가 업로드한 파일을 허용할 수 있습니다. 예를 들어:

curl https://api.openai.com/v1/threads/{thread_id}/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
      "role": "user",
      "content": "`3x + 11 = 14`란 방정식을 풀어야 해요. 도와주실 수 있을까요?"
    }'

API 파라미터:

  • thread_id - 대화 스레드 ID를 나타내며, 스레드 생성 시에 얻을 수 있습니다.

API 요청 본문은 일반적으로 사용자의 질문을 나타내는 사용자 메시지로, 대화 모델의 메시지 구조와 유사합니다.

2.4 어시스턴트 실행하여 응답 생성하기

사용자 메시지에 어시스턴트가 응답하려면 Run을 생성해야 합니다. 이를 통해 어시스턴트는 스레드를 읽고 도구를 사용할지 (사용 가능한 경우) 또는 단순히 모델을 사용하여 쿼리에 가장 잘 대답할지를 결정합니다.

참고: 이 시점까지 어시스턴트는 사용자의 질문에 응답하지 않았습니다. Run API를 호출할 때에만 AI 어시스턴트가 사용자의 질문에 응답합니다.

curl https://api.openai.com/v1/threads/{thread_id}/runs \
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "assistant_id": "assistant_id",
    "instructions": "사용자를 Jane Doe로 지칭하세요. 사용자는 프리미엄 계정입니다."
  }'

API 파라미터:

  • thread_id - 대화 스레드 ID를 나타내며, 스레드 생성 시에 얻을 수 있습니다.
  • assistant_id - 어시스턴트 ID를 나타내며, 어시스턴트 생성 시에 얻을 수 있습니다.
  • instructions - 어시스턴트 지침으로, 어시스턴트 생성 시 설정한 지침을 무시할 수 있습니다.

성공적인 API 요청은 Run ID를 반환합니다.

2.5 어시스턴트 실행 상태 확인하기

어시스턴트에서 작업(Run)을 시작한 후, 작업 실행은 비동기적으로 이루어집니다. 이는 Run의 상태를 정기적으로 확인하여 완료되었는지 여부를 결정해야 한다는 것을 의미합니다. Run의 상태를 확인하기 위해 CURL을 사용하여 HTTP 요청을 수행할 수 있습니다. 아래에 이 과정에 대한 구체적인 소개가 있습니다.

CURL 요청 예시:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

API 파라미터 설명:

  • https://api.openai.com/v1/threads/thread_abc123/runs/run_abc123: 이것은 API의 요청 URL로, thread_abc123은 스레드(Thread)의 고유 식별자이며, run_abc123은 Run의 고유 식별자입니다.

응답 본문 예시:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "completed",
  "created_at": 1699073585,
  ...
}

API 응답 파라미터 설명:

  • id: Run의 고유 식별자
  • object: 반환된 객체의 유형을 나타내며, 여기서는 thread.run입니다.
  • status: Run의 상태로, queued, in_progress, completed, requires_action, failed 등의 가능한 값이 있습니다.
  • created_at: Run이 생성된 타임스탬프입니다.

2.6 어시스턴트 응답 결과 가져오기

어시스턴트 Run이 완료된 후, 스레드(Thread)에 추가된 메시지를 확인하여 어시스턴트의 응답 결과를 읽을 수 있습니다. CURL을 사용하여 요청하는 방법과 API 파라미터의 상세 설명이 아래에 있습니다.

팁: 어시스턴트와의 대화와 유사하게, 어시스턴트가 사용자의 쿼리를 처리를 마치면, 어시스턴트는 대화 스레드(Thread)에 메시지를 추가합니다. 따라서 우리는 단순히 대화 스레드(Thread)의 최신 메시지를 조회하여 어시스턴트의 응답을 얻을 수 있습니다.

CURL 요청 예시:

curl https://api.openai.com/v1/threads/thread_abc123/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1"

API 파라미터 설명:

  • https://api.openai.com/v1/threads/thread_abc123/messages: API의 요청 URL입니다. 여기서 thread_abc123은 쓰레드(Thread)의 고유 식별자입니다.
  • 이전에 실행 상태를 확인하는 데 사용된 요청 헤더와 동일하게, 인증 정보와 API 버전 정보를 포함합니다.

어시스턴트 응답 예시:

이 예시에서 사용자가 수학 문제를 어시스턴트에게 물어보고, 어시스턴트가 처리한 후 쓰레드에 응답 메시지를 추가했습니다.

사용자: `3x + 11 = 14`라는 방정식을 풀어야 해. 도와줄래?
어시스턴트: 물론이죠, Jane Doe. 방정식 `(3x + 11 = 14)`을 풀려면, 방정식의 한 쪽에 `(x)`를 고립시켜야 해요. `(x)`의 값을 계산해 드릴게요.
어시스턴트: 방정식 `(3x + 11 = 14)`의 해는 `(x = 1)`입니다.

어시스턴트로부터 응답 결과를 얻은 후, 사용자에게 제공하여 어시스턴트가 제공하는 서비스를 더 잘 이해하고 활용할 수 있도록 도와줄 수 있습니다.

3. 도구: OpenAI에서 제공하는 내장 도구

3.1 코드 해석기 도구

코드 해석기 도구를 통해 Assistants API는 Python 코드를 작성하고 실행할 수 있는 격리된 실행 환경에서 작업할 수 있습니다. 이 도구는 다양한 데이터 및 파일 형식을 처리하고 데이터 및 그래픽 이미지 파일을 생성할 수 있습니다. 코드 해석기는 어시스턴트가 복잡한 코딩 및 수학 문제를 해결하기 위해 코드를 반복적으로 실행할 수 있도록 합니다. 어시스턴트가 작성한 코드가 실행에 실패할 경우, 실행이 성공할 때까지 다양한 코드를 시도하여 코드를 반복할 수 있습니다.

코드 해석기 활성화하기

코드 해석기를 활성화하려면 Assistant 객체를 생성할 때 tools 매개변수에 code_interpreter를 전달하십시오:

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "당신은 개인 수학 가르치기입니다. 수학 문제가 제기되면 코드를 작성하고 실행하세요.",
    "tools": [
      { "type": "code_interpreter" }
    ],
    "model": "gpt-4-turbo-preview"
  }'

그럼 모델은 사용자의 요청의 특성에 따라 실행 중에 코드 해석기를 호출할지 여부를 결정하게 됩니다. 이 동작을 Assistant의 instructions (예: "이 문제를 해결하기 위해 코드를 작성하세요")를 통해 용이하게 할 수 있습니다.

코드 해석기를 사용하여 파일 처리하기

코드 해석기는 파일에서 데이터를 파싱할 수 있습니다. 이 기능은 어시스턴트에 대량의 데이터를 제공하거나 사용자가 자체 파일을 업로드하여 분석하도록 허용하고자 할 때 유용합니다. 코드 해석기에 업로드된 파일은 검색을 위해 색인화되지 않습니다. 검색을 위해 파일을 색인화하는 방법에 대한 자세한 정보는 아래의 검색 도구 섹션을 참조하십시오.

Assistant 수준에서 전달된 파일은 이 Assistant와 관련된 모든 Run에서 액세스할 수 있습니다:

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/mydata.csv"

curl https://api.openai.com/v1/assistants \
  -u :$OPENAI_API_KEY \
  -H 'Content-Type: application/json' \
  -H 'OpenAI-Beta: assistants=v1' \
  -d '{
    "instructions": "당신은 개인 수학 가르치기입니다. 수학 문제가 제기되면 코드를 작성하고 실행하세요.",
    "tools": [{"type": "code_interpreter"}],
    "model": "gpt-4-turbo-preview",
    "file_ids": ["file_123abc456"]
  }'

코드 해석기에서 생성된 이미지 및 파일 읽기

코드 해석기는 API에서 이미지 차트, CSV 및 PDF 파일을 생성하는 등 파일을 출력할 수도 있습니다. 생성된 파일에는 이미지와 데이터 파일(예: Assistant에 의해 생성된 데이터가 포함된 CSV 파일) 두 가지 유형이 있습니다.

코드 해석기가 이미지를 생성하면, Assistant Message 응답의 file_id 필드에서 이 파일을 찾고 다운로드할 수 있습니다:

{
    "id": "msg_abc123",
    "object": "thread.message",
    "created_at": 1698964262,
    "thread_id": "thread_abc123",
    "role": "assistant",
    "content": [
    {
      "type": "image_file",
      "image_file": {
        "file_id": "file-abc123"
      }
    }
  ]
  // ...
}

3.2 검색 도구

검색 도구는 Assistant의 기능을 향상시켜 모델 외부(예: 독점 제품 정보 또는 사용자 제공 문서)에서 지식을 추가합니다. 파일을 업로드하고 Assistant에 전달하면 OpenAI는 문서를 자동으로 분할하여 색인화하고 임베딩을 저장한 뒤 사용자의 쿼리에 대한 관련 콘텐츠를 검색하기 위해 벡터 검색을 구현합니다.

검색 활성화

Assistant의 tools 매개변수에서 검색을 활성화하려면 retrieval을 전달하세요:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "고객 지원 챗봇입니다. 지식 베이스를 사용하여 고객 쿼리에 효과적으로 응답하세요.",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview"
  }'

검색용 파일 업로드

코드 해석기와 마찬가지로, 파일은 Assistant 수준 또는 개별 Message 수준에서 업로드할 수 있습니다.

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="assistants" \
  -F file="@/path/to/knowledge.pdf"

curl "https://api.openai.com/v1/assistants" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "고객 지원 챗봇입니다. 지식 베이스를 사용하여 고객 쿼리에 효과적으로 응답하세요.",
    "name": "수학 과외",
    "tools": [{"type": "retrieval"}],
    "model": "gpt-4-turbo-preview",
    "file_ids": ["file_123abc456"]
  }'

3.3 함수 호출 도구

채팅 완성 API와 마찬가지로, Assistants API는 함수 호출을 지원합니다. 함수 호출을 통해 Assistant에 함수를 설명하고 해당 함수 및 매개변수를 지능적으로 반환할 수 있습니다. 함수 호출이 실행되면 Assistants API는 실행을 일시 중단하고 함수 호출의 결과를 제공한 후 실행을 계속할 수 있습니다.

함수 정의

어시스턴트를 생성할 때 어시스턴트가 호출할 함수 집합을 정의할 수 있습니다. 이러한 함수는 어시스턴트 객체를 만들 때 명시적으로 지정해야 합니다. 각 함수는 고유한 이름, 설명 및 매개변수 사양을 가져야 합니다.

다음 코드는 어시스턴트를 생성할 때 curl 명령어를 사용하여 두 개의 함수를 정의하는 방법을 보여줍니다:

curl https://api.openai.com/v1/assistants \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "instructions": "날씨 예보 봇입니다. 제공된 함수를 사용하여 질문에 답하세요.",
    "tools": [{
      "type": "function",
      "function": {
        "name": "getCurrentWeather",
        "description": "특정 위치의 날씨 상황 가져오기",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "도시 및 주, 예: 샌프란시스코, 캘리포니아"},
            "unit": {"type": "string", "enum": ["c", "f"]}
          },
          "required": ["location"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "getNickname",
        "description": "도시의 별명 가져오기",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string", "description": "도시 및 주, 예: 샌프란시스코, 캘리포니아"}
          },
          "required": ["location"]
        }
      }
    }],
    "model": "gpt-4-turbo-preview"
  }'

어시스턴트에 의해 호출된 함수 읽기

사용자가 어시스턴트에 메시지를 제출하고 메시지 내용이 함수 호출을 유발하는 경우이 함수 호출의 정보를 읽어야합니다. 이 과정에서 어시스턴트는 requires_action 상태 실행을 생성합니다. 이때 Run 객체를 검색하여 함수 호출에 대한 자세한 정보를 얻을 수 있습니다.

다음은 Run 객체를 검색하는 예시로 함수 호출 정보를 얻는 방법을 보여줍니다:

{
  "id": "run_abc123",
  "object": "thread.run",
  "status": "requires_action",
  "required_action": {
    "type": "submit_tool_outputs",
    "submit_tool_outputs": {
      "tool_calls": [
        {
          "id": "call_abc123",
          "type": "function",
          "function": {
            "name": "getCurrentWeather",
            "arguments": "{\"location\":\"San Francisco\"}"
          }
        },
        {
          "id": "call_abc456",
          "type": "function",
          "function": {
            "name": "getNickname",
            "arguments": "{\"location\":\"Los Angeles\"}"
          }
        }
      ]
    }
  },
  ...
}

tool_calls 매개변수에는 함수 호출 정보가 포함되어 있고, 여기서는 로컬 프로그램에서 해당 함수를 호출하기만 하면 됩니다.

함수 출력 제출

로컬에서 함수 호출을 실행하고 결과를 얻은 후에는 이러한 결과를 Assistants 어시스턴트에 제출하여 어시스턴트가 사용자의 요청을 계속 처리할 수 있도록해야 합니다. 함수 출력을 제출할 때, 출력물이 원래의 함수 호출과 관련되도록해야 합니다.

다음은 함수 출력 결과를 제출하는 방법에 대한 예시 코드입니다:

curl https://api.openai.com/v1/threads/thread_abc123/runs/run_123/submit_tool_outputs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "OpenAI-Beta: assistants=v1" \
  -d '{
    "tool_outputs": [
      {
        "tool_call_id": "call_abc123",
        "output": "{\"temperature\": \"22\", \"unit\": \"celsius\"}"
      }, 
      {
        "tool_call_id": "call_abc456",
        "output": "{\"nickname\": \"LA\"}"
      }
    ]
  }'

매개변수 설명:

  • thread_abc123은 대화 스레드 ID를 나타냅니다
  • run_123은 Run 객체의 ID를 나타냅니다
  • tool_call_id는 이전의 tool_calls 매개변수에서 얻은 특정 함수 호출의 ID를 나타냅니다.

모든 함수 출력을 성공적으로 제출한 경우, Run 객체의 상태가 다시 업데이트되고 어시스턴트는 계속 처리하고 최종 응답을 사용자에게 반환합니다.