본문 바로가기
파이썬

챗봇 만들기 PDF chatbot 챗봇 GPT. openAI Assistant API

by 진심블로그 2024. 3. 8.

openAI chatGPT assistant api 사용방법의 글에 이어서 작성합니다.

 

openAI의 어시스턴트 api를 이용하여 pdf 챗봇을 만드는 방법을 알아봅니다.

 

- 본 글은 파이썬 고급레벨 이상이 읽어보기에 적합합니다

 

이제 4번째 단계까지 왔습니다.

my_run = client.beta.threads.runs.create(
  thread_id=my_thread.id,
  assistant_id=my_assistant.id,
  instructions="Please address the user as pysin."
)
print(f"This is the run object: {my_run} \n")

 

메시지를 담고 있는 쓰레드까지 만든 후에,

해당 쓰레드를 동작시키는 쓰레드를 다시 만듭니다.

 

복잡하게 보이지만, 다음의 순서대로 만듭니다.

 

1. 비어 있는 쓰레드 객체 생성,

2. 메시지 쓰레드 객체를 생성하고, 비어 있는 쓰레드에 연동,

3. 최종 쓰레드인 run쓰레드를 만들어서 1번에서 만든 쓰레드와 어시스턴트와 연동

 

이제 신경 써야 할 쓰레드 객체는 3가지에서 2가지로 줄어듭니다.

 

메시지 쓰레드 객체와 run쓰레드 객체입니다.

 

run쓰레드가 동작하면서 메시지쓰레드에 새로운 메시지가 있는지를

계속해서 확인하고,

run쓰레드가 내부적으로 해당 메시지를 어떻게 처리할지를 다루는 구조입니다.

 

이제 실제로 run쓰레드를 동작시켜 보겠습니다.

 

5번째 단계입니다.

while my_run.status in ["queued", "in_progress"]:
    keep_retrieving_run = client.beta.threads.runs.retrieve(
        thread_id=my_thread.id,
        run_id=my_run.id
    )
    
    print(f"Run status: {keep_retrieving_run.status}")

    if keep_retrieving_run.status == "completed":
        print("\n")

 

run쓰레드가 queud상태, 즉 기다리는 상태에서 while안의 동작들을 실행합니다.

 

또는 in_progress 상태에서 기다립니다.

 

.....runs.retrieve()를 통해서 동작을 유지합니다.

 

실제로 동작을 시켜 보면, Run status : in_progress가 계속 출력됩니다.

 

사용자가 던진 질문에 대답을 하기 위해 동작하는 동안,

계속해서 in_progress가 출력된다는 뜻입니다.

 

그러다가 어시스턴트의 상태가 completed로 바뀌면,

 

다음과 같이 어떤 동작을 할지 아래에서 정하게 됩니다.

 

이제 6번째 단계입니다.

        all_messages = client.beta.threads.messages.list(
            thread_id=my_thread.id
        )

        print("------------------------------------------------------------ \n")

        print(f"User: {my_thread_message.content[0].text.value}")
        print(f"Assistant: {all_messages.data[0].content[0].text.value}")

 

결과물도 메시지 객체로 전달됩니다.

 

결과물이 나왔으니, 출력을 해서 확인해 봅니다.

 

openAI의 GPT4기준, 어시스턴트 API에서 기본으로 제공하는 도구는,

code-interpreter와 retrieval인데,

추가적으로, 프로그래머가 만든 function을 사용할 수 있습니다.

 

해당 function을 여기서 사용합니다.

 

동기/비동기에 따라 코딩방식에 다소 차이가 있겠지만,

기본적으로는 여기서 이용한다고 생각하면 됩니다.

 

어시스턴트가 메시지 쓰레드 객체를 통해 전달한 메시지의 값에 따라

프로그래머의 추가적인 코딩을 여기서 할 수 있다는 뜻입니다.

 

    break
    elif keep_retrieving_run.status == "queued" or keep_retrieving_run.status == "in_progress":
        pass
    else:
        print(f"Run status: {keep_retrieving_run.status}")
        break

 

나머지 코드는 위와 같습니다.

 

메시지가 완료된 상태가 아니라면 쓰레드가 계속 동작하게 만드는 것뿐입니다.

 

이제 5번째와 6번째 코드를 전체적으로 보겠습니다.

 

while my_run.status in ["queued", "in_progress"]:
    keep_retrieving_run = client.beta.threads.runs.retrieve(
        thread_id=my_thread.id,
        run_id=my_run.id
    )
    
    print(f"Run status: {keep_retrieving_run.status}")

    if keep_retrieving_run.status == "completed":
        print("\n")
        
        all_messages = client.beta.threads.messages.list(
            thread_id=my_thread.id
        )

        print("------------------------------------------------------------ \n")

        print(f"User: {my_thread_message.content[0].text.value}")
        print(f"Assistant: {all_messages.data[0].content[0].text.value}")

        break
    elif keep_retrieving_run.status == "queued" or keep_retrieving_run.status == "in_progress":
        pass
    else:
        print(f"Run status: {keep_retrieving_run.status}")
        break

 

출력 결과는 다음과 같습니다.

 

 

데이터 양에 따라 다르지만, 몇 분에서 몇 시간이 걸릴 수도 있습니다.

작업 중이라고 계속 나오다가,

 

최종 결과가 다음과 같이 나옵니다. 

이 부분은 결과물의 내용이 길어서, 텍스트로 대신합니다.

 

User: 전체 문서에서 "파이신"이라는 글자가 몇번이나 나와?

Assistant: 문서에서 "파이신"이라는 글자가 나타난 위치를 확인한 결과, 적어도 3번 이상 나타났습니다【9†source】. 그러나 문서 전체에서 정확히 몇 번 나오는지 파악하기 위해 더 많은 검색을 시도했으나, 도구의 한계로 인해 전체 빈도수를 정확하게 계산할 수 없습니다. 검색 결과에서 "파이신"이라는 텍스트는 글의 저자로 여러 번 언급되었으며, 이는 단지 확인한 부분에서의 결과입니다. 문서의 나머지 부분에 대해서는 검색 도구의 한계로 인해 정확한 횟수를 제공하기 어렵습니다. 필요한 경우 문서를 직접 검토하여 더 정확한 수치를 얻을 수 있습니다.

 

위에서 어시스턴트가 대답한 내용을 꼼꼼하게 읽어보기 바랍니다.

 

이전 글에서 언급한 것처럼 gpt는 db가 아닙니다. 

 

위와 같은 질문은 프롬프트가 잘못되었다고 생각할 수 있지만,

그렇지 않습니다.

 

gpt가 db는 아니지만, AI를 db처럼 사용할 수 있습니다.

 

위의 코드는 어시스턴트 api를 세팅하고 이용하는 기초 작업일 뿐입니다.

 

다음 글들에서 위의 질문에도 정확하게 대답하는 코드를 다루어 보고,

 

또, 그에 맞도록 업로드 자료를 구성하는 데이터 모델링에 관해서도 

 

다루어 보겠습니다.