How to use ResponseSchema and StructuredOutputParser with OpenAI Assistant

39 Views Asked by At

I have created an Assistant in OpenAI as shown below

enter image description here

It returns the JSON formatted result while testing it on OpenAI's playground.

{
    "code": {
        "block": "def calculate_sum(num1, num2):\n    return num1 + num2\n\n# Taking input from user\nnum1 = int(input('Enter first number: '))\nnum2 = int(input('Enter second number: '))\n\n# Calculating and printing the sum\nresult = calculate_sum(num1, num2)\nprint('The sum is:', result)",
        "lang": "python",
        "explain": "This code defines a function calculate_sum that takes two parameters (num1 and num2) and returns their sum. It then prompts the user to enter two numbers, calculates the sum using the calculate_sum function, and prints the result."
    }
}

Now, I want to get the same result using a simple python program that uses the OpenAI Python SDK

def _langchain_outputs(outputs, structured_output_parser):
        struct_output = structured_output_parser.parse(
            outputs[-1].content[-1].text.value
        )
        block = struct_output["code"]["block"]
        lang = struct_output["code"]["lang"]
        explain = struct_output["code"]["explain"]
        st.write(f"> Code in {lang}")
        st.code(block, language=lang, line_numbers=True)
        st.write(explain)

def polling_run_routine(client, thread, run):
    run_status = "in_progress"
    start_time_seconds = time.time()
    interval_ms = 500   # Try every 0.5 seconds
    timeout_ms = 30000  # Timeout set to 30 seconds

    while time.time() - start_time_seconds < timeout_ms / 1000:
        if run_status == "completed":
            # Code to execute when condition is met
            return run_status
        else:
            time.sleep(interval_ms / 1000)  # Convert milliseconds to seconds
            try:
                run = client.beta.threads.runs.retrieve(
                    thread_id=thread.id,
                    run_id=run.id
                )
                print(f"Timestamp: {time.time()}, Run status update: {run.status}.")
                run_status = run.status
            except Exception as e:
                print(f"Error retrieving run status: {e}")

    else:
        # Code to execute when the timeout is reached
        print(f"Timeout reached after {timeout_ms} milliseconds, condition not met.")
        return "expired"

structured_output_parser = StructuredOutputParser.from_response_schemas(
    [
        ResponseSchema(
            name="code",
            description="""A code snippet block, programming language name and explaination:
                    { "block": string // the code block,  "lang": string // programming langauge name, "explain": string // explaination of the code}
                    """,
            type="string",
        ),
    ]
) 

assistant = client.beta.assistants.create(
    name="AI Programmer",
    instructions=instructions + "\n\n" + f"The output format instructions is {structured_output_parser.get_format_instructions()}",
    tools=[{"type": "code_interpreter"}],
    model="gpt-3.5-turbo"
)


# Create a thread and send a message
thread = client.beta.threads.create()

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Can you write a program in python which would take 2 inputs and print the sum?"
)

# Create a run
run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Please address the user as Jane Doe. The user has a premium account."
)

# Check the result of the polling routine
if polling_run_routine(client, thread, run) == "completed":
    messages = client.beta.threads.messages.list(
        thread_id=thread.id,
    )
    _langchain_outputs(messages.data[0], structured_output_parser)
else:
    print("Timeout occurred, please try again later")  

It looks like "messages.data[0].content[0].value" is just a plain text but not a JSON formatted data, so it throws the following error

TypeError: 'Message' object is not subscriptable
0

There are 0 best solutions below