pythonopenai-apichatgpt-apigpt-4

OpenAI Chat Completions API: How do I use a function to store conversation memory?


I am trying to make a chatbot using OpenAI Function Calling. I have taken the basic example of getting the current weather condition, which was given in the documentation.

What I want to implement is to have a memory with it.

I tried to append into the message, but what I want is when I have a new message, so instead of calling the function, how can it get the response from memory if it's already asked?

My code is like this:

def get_current_weather(location, unit="fahrenheit"):
    print("IT RAN>>>>>>>>>>")
    weather_info = {
        "location": location,
        "temperature": "72",
        "unit": unit,
        "forecast": ["sunny", "windy"],
    }
    return json.dumps(weather_info)


messages = []


def run_conversation(input_message):
    messages.append({"role": "user", "content": f"{input_message}"})
    functions = [
        {
            "name": "get_current_weather",
            "description": "Get the details about a drug/medication",
            "parameters": {
                "type": "object",
                "properties": {
                    "definition": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        }
    ]
    print("MESSAGE 1", messages)
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=messages,
        functions=functions,
        # function_call="auto",
    )
    response_message = response["choices"][0]["message"]
    print("RESPONSE MSG", response_message)

    if response_message.get("function_call"):
        available_functions = {"get_current_weather": get_current_weather}
        function_name = response_message["function_call"]["name"]
        function_to_call = available_functions[function_name]
        function_args = json.loads(response_message["function_call"]["arguments"])
        function_response = function_to_call(
            location=function_args.get("location"),
            unit=function_args.get("unit"),
        )

        # messages.append(response_message)
        messages.append(
            {"role": "function", "name": function_name, "content": function_response}
        )
        print("MESSAGE 2", messages)
        second_response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo-0613",
            messages=messages,
        )
        print("SECOND RESPONSE", second_response['choices'][0]['message'].to_dict())
        messages.append(second_response['choices'][0]['message'].to_dict())
        print("MESSAGE 3", messages)
        return second_response

It always runs the function even if I ask the same question

Output:

RESPONSE MSG {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\n  \"definition\": \"Boston, MA\",\n  \"unit\": \"celsius\"\n}"
  }
}
IT RAN>>>>>>>>>>
MESSAGE 2 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}]
SECOND RESPONSE {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Celsius.'}
MESSAGE 3 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}]
MESSAGE 1 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}]
RESPONSE MSG {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\"location\": \"New York\"}"
  }
}
IT RAN>>>>>>>>>>
MESSAGE 2 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"locati
on": "New York", "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}]
SECOND RESPONSE {'role': 'assistant', 'content': 'The temperature in New York is 72 degrees. Please note that I did not specify the temperature unit, as i
t is missing in the response.'}
MESSAGE 3 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"locati
on": "New York", "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in New York is 72
 degrees. Please note that I did not specify the temperature unit, as it is missing in the response.'}]
MESSAGE 1 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"locati
on": "New York", "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in New York is 72
 degrees. Please note that I did not specify the temperature unit, as it is missing in the response.'}, {'role': 'user', 'content': 'what is the temperatu
re in Boston?'}]
RESPONSE MSG {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\"definition\": \"Boston\"}"
  }
}
IT RAN>>>>>>>>>>
MESSAGE 2 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"locati
MESSAGE 3 [{'role': 'user', 'content': 'what is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degree
s Celsius.'}, {'role': 'user', 'content': 'what is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"locati
on": "New York", "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in New York is 72
 degrees. Please note that I did not specify the temperature unit, as it is missing in the response.'}, {'role': 'user', 'content': 'what is the temperatu
re in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location": null, "temperature": "72", "unit": null, "forecast": ["sunny
", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees. Please note that the unit of temperature is missing in the resp
onse.'}]
MESSAGE 1 [{'role': 'user', 'content': 'What is the temperature in Boston?'}]
RESPONSE MSG {        
  "role": "assistant",
  "content": null,    
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\n  \"definition\": \"Boston, MA\"\n}"
  }
}
IT RAN>>>>>>>>>>
MESSAGE 2 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}]
SECOND RESPONSE {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fahrenheit.'}
MESSAGE 3 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fah
renheit.'}]
MESSAGE 1 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fah
renheit.'}, {'role': 'user', 'content': 'What is the temperature in NewYork?'}]
RESPONSE MSG {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\"location\": \"New York\", \"unit\": \"celsius\"}"
  }
}
IT RAN>>>>>>>>>>
MESSAGE 2 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fah
renheit.'}, {'role': 'user', 'content': 'What is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location
": "New York", "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}]
SECOND RESPONSE {'role': 'assistant', 'content': 'The temperature in New York is 72 degrees Celsius.'}
MESSAGE 3 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fah
renheit.'}, {'role': 'user', 'content': 'What is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location
": "New York", "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in New York is
 72 degrees Celsius.'}]
MESSAGE 1 [{'role': 'user', 'content': 'What is the temperature in Boston?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location":
 null, "temperature": "72", "unit": null, "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in Boston is 72 degrees Fah
renheit.'}, {'role': 'user', 'content': 'What is the temperature in NewYork?'}, {'role': 'function', 'name': 'get_current_weather', 'content': '{"location
": "New York", "temperature": "72", "unit": "celsius", "forecast": ["sunny", "windy"]}'}, {'role': 'assistant', 'content': 'The temperature in New York is
 72 degrees Celsius.'}, {'role': 'user', 'content': 'What is the temperature in Boston?'}]
RESPONSE MSG {
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\"location\": \"Boston\"}"
  }
is 72 degrees.'}]

Solution

  • Using the OpenAI API function to store conversation memory is not the right approach because of the possibility that the model may generate invalid JSON or hallucinate parameters.

    People are already having problems with that.

    If you take a look at the official OpenAI documentation, you can see that OpenAI transparently states:

    The basic sequence of steps for function calling is as follows:

    1. Call the model with the user query and a set of functions defined in the functions parameter.
    2. The model can choose to call a function; if so, the content will be a stringified JSON object adhering to your custom schema (note: the model may generate invalid JSON or hallucinate parameters).
    3. Parse the string into JSON in your code, and call your function with the provided arguments if they exist.
    4. Call the model again by appending the function response as a new message, and let the model summarize the results back to the user.