Function calling - how to get dict as return type

I want to have GPT4 output a dict through the function calling API. For example, if I have a list ["a", "b", "c"] I want GPT4 to output a dict {"a": 1, "b": 2, "c": 3}.

For example:

NUMBER_LETTERS = {
    "name": "number_letters",
    "description": "You will receive a list of letters as input. Please return a dict where each value is one of"
        " the letters received, and the corresponding value is the index of that letter in the alphabet. Any input"
        " other than a lowercase letter should get value -1. Here are some examples:"
        "\nexample 1: input = ['a', 'b', 'c'] --> output = {'a': 1, 'b': 2, 'c': 3}"
        "\nexample 2: input = ['a', 'A', 'bla'] --> output = {'a': 1, 'A': -1, 'bla': -1}"
        "\nexample 3: input = ['abc', 'z', 'y'] --> output = {'abc': -1, 'z': 26, 'y': 25}",
    "parameters": {
        "type": "object",
        "properties": {
            "output": {
                "type": "array",
                "description": "a dict where each input letter is a key, and its index in the alphabet is the value.",
                "items": {
                    "type": "object",
                    "patternProperties": {
                        "^.*$": {"type": "integer"},
                    },
                    "additionalProperties": False
                }
            }
        },
        "required": ["output"]
    }
}

This gives me:

{'input': ['a', 'b', 'c']}

as output. How can I get it to output a dict correctly?

1 Like

You did not mention which model you are using. I tried this on 3.5 and 4+
THe performance on 3.5 is dubious as expected but 4 does not seem to have a problem with it

1 Like

Welcome @willemvdb42

First you have to understand that this isn’t a valid type. You can either have an array of dictionaries or a single dictionary to have values.

I’d prefer a single dictionary, if it suits your requirements, as it’d save tokens. It’d look like:

{"a": 1, "b": 2, "c": 3}

Then this "type" has to be set to "dict" instead of array.

1 Like

I tried it on GPT4, did you try my function as I defined it in the example above? What output did you get?

1 Like

That is not correct. “dict” is not a valid JSON type. Remember: the function specification should be a valid JSON format. JSON does uses “object” instead of “dict”.

If you replace the “object” with “dict” in my example above you get the following error message:

BadRequestError: Error code: 400 - {‘error’: {‘message’: “Invalid schema for function ‘number_letters’: ‘dict’ is not valid under any of the given schemas”, ‘type’: ‘invalid_request_error’, ‘param’: None, ‘code’: None}}

1 Like

The output of a function can only be particular JSON types: string, number, boolean, array (of numbers or strings). It is also limited by the AI pretraining and understanding.

Thus, if you want to receive a dictionary, you would need to have the AI compose that as a string. You can use strong hints in a parameter name like python_dictionary_of_letter_encodings, and a description “produce a JSON data object that can be translated to dictionary by json.loads()”

Then when you receive the argument, expect it to look like:

{
 "id": "call_123456123456123",
 "function": {
  "arguments": "{\n  \"python_dictionary_of_letter_encodings\": \" {'abc': -1, 'z': 26, 'y': 25}\",\n}",
  "name": "job_output"
 },
 "type": "function"
}

Then in your function handler for that type of function and argument name, actually run json.loads() on the string.

dictionary = json.loads(api_response_argument)

1 Like

I did exactly your thing in the playground and I used the Assistants. Below example is using GPT-4. Using 3.5 it does not work reliably

Huh, that’s interesting. Did you change anything at all in the function description? Did you set a random seed?

I don’t think there is a place to set a seed - I just made up the input list myself.
And the input text for the assistant is your literal instruction with three examples included.