My very simple GPT Assistant Walk-Thru

Video: https://youtu.be/miRjd8D8PnA

This is my take on a simple GPT Assistant program I created while trying to learn the Assistants API. I used the OpenAI Assistants documentation, and also got a lot of help from some other YouTube videos about assistants. They are linked below. This video may be helpful for this particular approach, and for those using PyCharm vs. some of the more advanced development environments in the other videos.

One observation when using the Assistants API is that when asking questions where the answer is not contained within the document, sometimes it responds that the information isn’t available in the document. However, sometimes it responds with an answer created from its general knowledge base - and it doesn’t explain that it didn’t get the answer from the document. This is somewhat concerning.

Despite that, I am actually finding this program somewhat useful. While it is much easier to just upload a document to ChatGPT and ask questions there, for cases where I don’t want the document or the questions to be retained by OpenAI, I use the API.

Any thoughts on the above would be welcome!

OpenAI Assistants documentation: https://platform.openai.com/docs/assistants/overview
Dave Ebbelaar’s Assistants Tutorial: https://youtu.be/0h1ry-SqINc?si=Lpi-Wehmb9c4LpGR
AssemblyAI’s Assistants Tutorial: https://youtu.be/5rcjGjgJNQc?si=9D2OPGyO5_qkHHkA

My code: GitHub - GEScott71/GPT_Assistant: This Python program uses OpenAI tools to create a very simple ChatGPT assistant to answer questions about a document.

# This Python program uses OpenAI tools to create a very simple ChatGPT assistant to answer questions about a document.
# It takes a text file as an input, queries the user for questions, and displays the responses to the user.
#
# First, it uploads a document to ChatGPT
# Next, it creates a ChatGPT assistant that references that document
# Then it creates a thread
# Then it starts a loop asking the user for questions.  When a question is entered,
# It creates a message with the question, adds it to the thread, and runs the assistant on the thread
# Finally, it displays the response from ChatGPT and starts the loop again

# Input: a document such as a text file, and user-entered questions
# Output: displays responses to the questions about the document

import openai
from openai import OpenAI
import time # used in function to periodically check assistant status

openai.api_key = open(r"C:\Users\GESco\Documents\key.txt", "r").read().strip('\n') # My OpenAI API key location / path
client = OpenAI(
    api_key=openai.api_key
)

def upload_file(path):  # Upload a file to OpenAI with an "assistants" purpose
    file = client.files.create(
        file=open(path, "rb"),
        purpose="assistants"
    )
    return file


def create_assistant(file): # Create an assistant with OpenAI with instructions and a file to reference
    assistant = client.beta.assistants.create(
        name="Meeting Analyzer",
        instructions="You are a helpful and highly skilled AI assistant trained in language comprehension and summarization. Answer questions about the document provided:",
        tools=[{"type": "retrieval"}],
        model="gpt-4-turbo-preview",
        file_ids = [file.id]
    )
    return assistant

def run_assistant(message_body): # Create a message, run the assistant on it, monitor it for completion, and display the output
    # Create a message in an existing thread
    message = client.beta.threads.messages.create(
        thread_id = thread.id,
        role="user",
        content=message_body,
    )

    # Run the existing assistant on the existing thread
    run = client.beta.threads.runs.create(
        thread_id=thread.id,
        assistant_id=assistant.id,
    )

    # Monitor the assistant and report status
    while run.status != "completed":
        run = openai.beta.threads.runs.retrieve(
            thread_id=thread.id,
            run_id=run.id
        )
        print(run.status)
        time.sleep(2)

    # Extract the messages from the thread
    messages = client.beta.threads.messages.list(
        thread_id=thread.id
    )

    # Display the output
    print("\nOutput:")
    for message in reversed(messages.data):
        print(message.role + ": " + message.content[0].text.value)

    return messages

if __name__ == '__main__':

    # *** Run these if creating a new assistant with a new file
    # file = upload_file(r'Data/unp_Q4_2023_earnings_call_transcript_2024-01-26.txt')
    # assistant = create_assistant(file)

    ## *** Run these if using an existing assistant:
    # saved_assistant_id = 'asst_GUjvBwaOxfHJFdb9qgDddRDn' # Meeting analyzer with UNP Q3 earnings call transcript
    saved_assistant_id = 'asst_Td0UqBTDjsmu6uwWVSybaSGc' # Meeting analyzer with UNP Q4 earnings call transcript
    assistant = client.beta.assistants.retrieve(saved_assistant_id)

    thread = client.beta.threads.create() # Create a new thread

    # As the user for input and run the assistant on it. Loop until the user types 'exit'
    while True:
        user_input = input("Enter a question, or type 'exit' to end: ").strip().lower()
        if user_input == 'exit':
            break

        else:
            run_assistant(user_input)
2 Likes

What are you paying for the use? Last I checked the Assistants API is super expensive to use. Especially since as you note, it has occasional random output. Not super useful in my opinion.

Cost doesn’t seem to be prohibitive for this example use case; about 10 cents per run. I get that from my usage today shows $.34, and I ran the code 3-4 times today while creating the video. That is much cheaper than when I was using the same file (70kb of meeting transcript text) a few weeks ago with the chat completions API to create meeting minutes. I got into several $ very quickly. Not sure if this is cheaper now because the rates have changed, or if the Assistant is cheaper. I guess there were many more tokens (words of output) when creating meeting minutes; maybe its entirely due to that.

Right on, well if you see anything of note, feel free to update. I stopped using Assistant because chat was far more reasonable. Assistant requires so much more data to be pulled and it is unclear how that is being charged or not.

1 Like

thanks very much for your work. your script was exactly the intro to the Assistant API i was lookig for.

Since this got a bump and I hadn’t seen it before, I should note that the nomenclature used here and within the un-updated code is very confused. See this mish-mash:

These incorrect statements and misuse of terms throughout will rather be a hindrance to learning.

1 Like

thanks very much for your work, Scott. Thanks to you I"ve got a document searcher working in v2 of the Assistant API and am on my way to creating a database manager Assistant.

if you want to re-use an assistant, you have to retrieve both assistant and thread. if you instead create a new thread, the assistant will not remember the previous discussion.