Chat completion ai returning Content as None and finish_reason as "tool_call"

I am using GPT-4o and sometimes completion api returns content None which has finish_reason “tool_call”.
I also tried changing temperature from 0.2 to 0.7
Here’s the Complete code:


    def get_completion(self, user_messages: list[dict[str, str]]) -> ChatCompletion:
        messages = self.messages + user_messages
        completion = self.client.chat.completions.create(
            model=self.json_config["trained_model"],
            messages=messages,
            temperature=0.7,
            tools=self.json_config["tools_config"],
            tool_choice="auto",
            parallel_tool_calls=False,
        )
        return completion

    def generate_response(
        self,
        session_id: str,
        msg_service: MessageService,
        user_messages: list[dict[str, str]],
    ) -> Dict:
        completion_response = self.get_completion(user_messages)
        tool_calls = completion_response.choices[0].message.tool_calls

        if tool_calls:
            user_messages.append(completion_response.choices[0].message)
            for tool_call in tool_calls:
                function_name = tool_call.function.name
                function_args = json.loads(tool_call.function.arguments)
                # Simulate function execution
                if function_name:
                    result = self.get_function_mapping(session_id, msg_service)[
                        function_name
                    ](**function_args)
                    if not isinstance(result, str):
                        result = json.dumps(result)
                    user_messages.append(
                        {
                            "role": "tool",
                            "tool_call_id": tool_call.id,
                            "name": function_name,
                            "content": result,
                        }
                    )
                    # Get final response after function execution
            resp = self.get_completion(user_messages)
            resp = resp.model_dump()
            return resp
        completion_response = completion_response.model_dump()
        return completion_response


Here’s the complete response of chat completion api:


ChatCompletion(id='chatcmpl-BEv5u7q3BPGBk78Cwa3YPBvDGx3n7', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content=None, refusal=None, role='assistant', audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_o4naaB4sn5z2XQfHlRSR2Xv1', function=Function(arguments='{"location_name":"Mangwon station"}', name='check_if_location_is_inside_japan'), type='function')], annotations=[]))], created=1742895762, model='ft:gpt-4o-2024-08-06:mkbus:all-data-v11:BEV14QSX', object='chat.completion', service_tier='default', system_fingerprint='fp_0937e35264', usage=CompletionUsage(completion_tokens=23, prompt_tokens=3871, total_tokens=3894, completion_tokens_details=CompletionTokensDetails(accepted_prediction_tokens=0, audio_tokens=0, reasoning_tokens=0, rejected_prediction_tokens=0), prompt_tokens_details=PromptTokensDetails(audio_tokens=0, cached_tokens=3712)))

Thank you for your help :person_bowing:

You are placing tools we don’t see.

If the AI invokes a tool call, sent to your code to fulfill, you will typically get no content for user display.

You are asked to return the value from processing this tool call:

check_if_location_is_inside_japan("location_name":"Mangwon station")

Your job then, if that is a real function (if not, in your mapping, it would likely raise a ValueError), is to send the assistant call and tool result, appended to the list of chat messages, back to the API to get another response. You need your own code that can answer the tool output.

Also, you must understand the paradigm that the AI can repeatedly emit to tools despite a tool return, and that you must continue iterating and performing them until there is no more tool call, only “content” as a result.

Thanks, your edit “Also, you must understand the paradigm that the AI can repeatedly emit to tools despite a tool return, and that you must continue iterating and performing them until there is no more tool call, only “content” as a result.” gave me the answer. I appreciate it :person_bowing:
Marking your answer as the solution

Ai didn’t returned all the tool calls at once inside tools, instead it was providing tools one by one.

1 Like