Function calling doesn't work for me

Function calling is just not working for me. functions = [
{
‘name’: ‘print_text’,
‘description’: ‘Prints text using a printer.’,
‘parameters’: {
‘type’: ‘object’,
‘properties’: {
‘body’: {
‘type’: ‘string’,
‘description’: ‘The text to print.’
}

        }
    }
}

]

I’m building a chatbot, and I’ve put a real function above the definition:
def
print_text(body):
os.system(f’echo “{body}” | lp’)
print(“printed”)

Whenever I ask the AI to print something, I’m assuming it’s trying to; its response just says “None”, but never calls the function.

1 Like

Hello @inventing2022 ,
I would need more information. Anyway, I tried to do some tests.

Using your function definition and a prompt like “some test to print” the result was:

function call: yes
function name: print_text
function args: {
  "body": "This is a test message."
}

But the arg "body": is different from user prompt. So I added a system message like “Your task is to always return text delimited by three hash as function argument” and I used a prompt like “###Whiskers of snow, purrs bring joy and quiet solace.###”. Using your function definition, the result was:

function call: yes
function name: print_text
function args: {
  "body": "Whiskers of snow, purrs bring joy and quiet solace."
}

So, a first advice could be to use a system message. This help the model to better understand the task.

But what differ from my tests and your function definition is the definition itself. Beginning from November, older function definition are deprecated. The payload structure is changed. Now functions are array of tools.
The following is my working JSON payload. Try to print your payload and compare if there are any difference:

{
  "response_format": {
    "type": "text"
  },
  "tools": [
    {
      "function": {
        "parameters": {
          "type": "object",
          "properties": {
            "body": {
              "description": "The text to print.",
              "type": "string"
            }
          }
        },
        "name": "print_text",
        "description": "Prints text using a printer."
      },
      "type": "function"
    }
  ],
  "messages": [
    {
      "role": "system",
      "content": "Your task is to always return text delimited by three hash as function argument"
    },
    {
      "role": "user",
      "content": "###Whiskers of snow, purrs bring joy and quiet solace.###"
    }
  ],
  "model": "gpt-3.5-turbo",
  "tool_choice": "auto",
  "temperature": 0,
  "top_p": 1,
  "presence_penalty": 0,
  "frequency_penalty": 0,
  "n": 1,
  "max_tokens": 1000,
  "stream": false,
  "logprobs": false
}

Here some documentation about tools API: https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools

Using JSONlist.com to check for syntax error. (You need to use double quotes not single),
And you need to add the “required” parameter.

So correct syntax is:

{
  "name": "print_text",
  "parameters": {
    "type": "object",
    "properties": {
      "body": {
        "type": "string",
        "description": "The text to print."
      }
    },
    "required": [
      "body"
    ]
  },
  "description": "Prints text using a printer."
}```

Hightly recommend use the back end in the beginning - on the dashboard you can see the assitant and use the + button to add a function. It will refuse to add the function if the JSON is incorrect.  Unfortunately it does NOT tell you what is wrong :)
1 Like

When printing the response, it returns:
ChatCompletion(id=‘chatcmpl-8WqLKoBmHoCGjvFPhyB2wXaquk1Kv’, choices=[Choice(finish_reason=‘tool_calls’, index=0, message=ChatCompletionMessage(content=None, role=‘assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=‘call_GT5nP68OqC46aaKfYmWQjmCP’, function=Function(arguments=‘{\n “text”: “Hello, world!”\n}’, name=‘print_text’), type=‘function’)]), logprobs=None)], created=1702838394, model=‘gpt-3.5-turbo-0613’, object=‘chat.completion’, system_fingerprint=None, usage=CompletionUsage(completion_tokens=17, prompt_tokens=133, total_tokens=150))

But It never calls the function!

You will have to call the function when you receive the ‘tool_calls’ status… Many examples - here is post that I wrote a few weeks ago.

Openai docs have an example as well
https://platform.openai.com/docs/assistants/tools/code-interpreter

Oh, I’m not using the assistant api, just the normal GPT-3.5 Turbo-0613.

Its’ mostly the same mechanism.

Ok, but could you provide me with some sample code for that? The Function calling Api refence is a bit confusing to me.

Check out this cookbook?

1 Like

In your provided response the model choose to call function. You must check finish_reason key. In your response finish_reason='tool_calls'. It means model choose to call function.
The older, and deprecated, function_call key is equal to None, but only because is deprecated.
So, first you must check that finish_reason='tool_calls'. If finish_reason is equal to tool_calls, then you can extract function arguments.

I take it for granted that you put response in a variable, such as 'chat_response'.
First extract assistant message:

message = chat_response.json()["choices"][0]["message"]['tool_calls']

Now message must contain:

[{'id': 'call_BEvTzOZ8V4jTA3cT3qd3o2Lz', 'type': 'function', 'function': {'name': 'print_test', 'arguments': '{\n  "text": "Hello, world!"\n}'}}]

Then extract "text" argument:

text = json.loads(message[0]["function"]["arguments"])["text"]
print(text)
# 'Hello, world!'

Calling your application function:

def print_text(body):
    os.system(f’echo “{body}” | lp’)
    print(“printed”)

print_text(text)

Hope it help.

1 Like

I noticed this morning that you now get a JSON error with line number when trying to save invalid JSON in the functions in the backend.

1 Like