minimaxir / simpleaichat

Python package for easily interfacing with chat apps, with robust features and minimal code complexity.
MIT License
3.43k stars 224 forks source link

Big Fix (To support OpenAI's responses, allow control characters in the content) #44

Closed keyboardAnt closed 1 year ago

keyboardAnt commented 1 year ago

OpenAI's responses could include control characters in the content. To reproduce the bug:

class LongStory(BaseModel):
    """This class represent a long story."""
    text: str = Field(min_length=int(10**6))

ai = AIChat(system="You are an AI writer.", model="gpt-4-0613", params={"temperature": 0}, api_key=OPENAI_API_KEY, save_messages=True)
ai("Generate a long story with one million words", output_schema=LongStory)

(Note: I used black and isort for the formatting)

minimaxir commented 1 year ago

What is the error you get in the current version? I do not have access to GPT-4 so can't verify what exactly is wrong here.

The issue does not reproduce with gpt-3.5-turbo-0613

keyboardAnt commented 1 year ago

What is the error you get in the current version? I do not have access to GPT-4 so can't verify what exactly is wrong here.

The issue does not reproduce with gpt-3.5-turbo-0613

The error is JSONDecodeError: Extra data: line 25 column 1 (char 3138). Now that I tried again, I could only reproduce it if save_messages=True, as in:

ai = AIChat(system="You are an AI writer.", model="gpt-4-0613", params={"temperature": 0}, api_key=OPENAI_API_KEY, save_messages=True)

With gpt-3.5-turbo-0613 I couldn't reproduce regardless of save_messages.

minimaxir commented 1 year ago

Now that I coincidentally got access to GPT-4, I tested out the code using the raw openai library to ensure it's not something simpleaichat is doing, and output seems normal. Therefore, since it's possible a fluke, I'm closing as Not Reproducible.

Additionally, it's unlikely switching to json from orjson would be the fix for a relevant issue anyways.

keyboardAnt commented 1 year ago

@minimaxir, I checked again and was able to reproduce the error. It is tricky though. I'm executing the minimal example mentioned above in a Jupyter Notebook. First, I reset the kernel and execute the example. The cell runs with no exception and returns the value {'text': 'Once upon a time, in a land far, far away...'}. However, all my tries to rerun this cell reproduce the JSONDecodeError exception.

keyboardAnt commented 1 year ago

I have the same issue when r["choices"][0]["finish_reason"] == "length", which is understood. However, the current implementation could be improved by indicating the "length" finish reason as the cause for failing to parse the JSON.