Responses API returns message + function_call

Hello All,
I am building a chatbot using the responses API and am having a problem when GPT-4.1-mini returns both message and function_call. See the example below:

  "output": [{
      "id": "msg_685434d722c8819b807abcdc03cc9cc80ed0eb9962f32640",
      "role": "assistant",
      "type": "message",
      "status": "completed",
      "content": [{
          "text": "{\"assistant_message\":\"Please provide your email address used for the order so I can check the delivery status for you.\",\"assistant_quick_replies\":[]}",
          "type": "output_text",
          "annotations": []
        }
      ]
    },
	... 7 similar message cut here ...
    {
      "id": "fc_685434df74d4819b93276af011d65ede0ed0eb9962f32640",
      "name": "check_delivery_status",
      "type": "function_call",
      "status": "completed",
      "call_id": "call_HdtDqdWf9jqaKmAPLPJi2iJm",
      "arguments": "{\"email\":\"user@example.com\"}"
    }
  ],

Actually, here I have 3 problems:

  • message is mixed with function_call, which one should I choose? Should I show the message or call the function? (In my example, showing the message is the right thing to do, as the LLM has not collected the user’s email yet)
  • I have 8 similar messages. ??? Okay, I can pick up the first one, but I don’t want to pay for all eight. I read and added “Please return one complete response and then stop.” instruction, but as you can see, it does not work.
  • The email address in the function call argument is hallucinated (user@example.com)

To give you more context, I am using structured output like the following:

"model": "gpt-4.1-mini",
"text": {
	"format": {
	  "type": "json_schema",
	  "name": "assistant_response",
	  "schema": {
		"type": "object",
		"properties": {
		  "assistant_message": {
			"type": "string",
			"description": "Assistant's response"
		  },
		  "assistant_quick_replies": {
			"type": "array",
			"description": "List of suggested quick replies buttons for the user. May contain user's email if mentioned previously. Populated ONLY when returned by a function call (assistant_quick_replies field), otherwise it is [].",
			"items": {
			  "type": "string",
			  "description": "Short text for a quick reply button."
			}
		  }
		},
		"required": [
		  "assistant_message",
		  "assistant_quick_replies"
		],
		"additionalProperties": false
	  },
	  "strict": true
	}
}

Did anyone face these issues with the response API?
I mostly interested in handling mix of message and function_call

1 Like

Can I see your tool descriptions and system prompt if you have one? I’ve 4.1-mini give me a message and function_call too but the message was just its reason for needing to call the tool.

1 Like

Here are 2 function definitions I use. I cut 2 other functions to make the JSON smaller

{
  "type": "function",
  "name": "check_delivery_status",
  "description": "Check the status of the user's shipment like expected delivery date, current tracking info, etc.",
  "strict": true,
  "parameters": {
    "type": "object",
    "properties": {
      "email": {
        "type": "string",
        "description": "Valid user's email address",
        "format": "email"
      }
    },
    "required": [
      "email"
    ],
    "additionalProperties": false
  }
}, {
  "type": "function",
  "name": "main_menu",
  "description": "Shows the main menu. Restarts the conversation",
  "strict": true,
  "parameters": {
    "type": "object",
    "required": [],
    "properties": {},
    "additionalProperties": false
  }
}

BTW, "format": "email" in the function property did not work for me, I had many times the model accepting incomplete emails like “dm@test”. I believe it is only supposed to be used in the structured output. Can someone from OpenAI comment on this?

hmm, i never had a message that desribes a reason for function call, for me it is always variations of the same text “Please provide your email address…”

1 Like

The responses output list reminds me of the choices of the completion API, the model generates some variations of its responses, and the function call comes as one of the variants.

It also seems to me that the order of output items is important. The first item is the most important one, so taking only output[0] into account and ignoring everything else can be a good strategy for now, until OpenAI provides more guidelines.

Note that when you are using the file_search tool, it seems to always insert its output into the 1st element. That aligns with my idea of the priority of output items; the model considers the file search results to be the most reliable. So in that case, your output[0] strategy should be changed to: get the first element while ignoring the file_search_call element.

Can someone from OpenAI comment on this? Please!

The AI has always been able to write text and then also call a function in the same output, before it finally finishes.

Responses API endpoint just makes this more annoying to handle and pass back, by making the same assistant AI generation split into two different output objects, equivalent also to out-of-band array items like reasoning summary or code interpreter inputs.

Can you try changing the email description to this: “Valid user’s email address. This should be provided by the user. If the user hasn’t provided an email yet then ask the user before using this tool.”

Not sure what your system instructions are but there is nothing in your tool description that explicitly tells the model where the email should come from. You are expecting it to assume that it should be provided by the user but it is better to explicitly tell it that.

If your tools are clear then you should be able to safely ignore any messages in the output if there is a tool call since the message should only ever be reasoning about calling a tool if anything.

here is the sys prompt part concerning collecting email

## Function calling
- Call "check_delivery_status" when the customer asks about order status, tracking info, etc.
- Always collect the customer's email address and make sure it is valid before calling "check_delivery_status"

Ah ok, there it is. Can you still try moving that to the tool description and see if that resolves your issue. Even just appending it to the overall check_delivery_status description as “Always collect the customer’s email address and make sure it is valid before calling this tool.”

And I know this is annoying but what does the email being “valid” mean? Does it mean formatted as an email or a valid company email? If it’s a valid company email then does the model have a tool to validate the email? I’m not trying to be difficult, just trying to remove all ambiguity since there is something here obviously tripping up the model.

Also, I’ve never seen the format field for a tool definition. I’m not sure why the api isn’t giving you an error for sending it. Try removing that as well.

That is for structured output, where text → format → JSON Schema on the Responses endpoint replaces Chat Completions’ “response_format” parameter.

This is not a tool call specification - this is the only output format the AI can write to the user in.

Yes I keep getting the same errors when using API in my script

Agree, "format": "email" for strings is described in the structured output article. It did not work for me in the function parameter. Despite it would be great to have it there.

Let’s stick to the main topic of this thread, which is why Responses API returns messages and function_calls in the same output. What should we do when we see both? Show message or call the function?

Some new info.
After I added 2 new functions, check_delivery_status stopped working.
Now Responses generate:

  1. message “I will check the delivery status for your order. Please hold on a moment.”
  2. function_call check_delivery_status with correctly extracted email

It breaks my approach, where I believe the 1st message more. What to do?

See both? Do both.

You’ll get a stream of delta events for content that can be displayed immediately.
Then you’ll have a collection of tool calls you must satisfy and return.

Your handler must not discard one, but instead, be written so it always services and collects both.

I don’t think he is using streaming here. So it wouldn’t really make sense to output the tool reasoning messages at the same time as the final response.

If the API/Model is performing correctly it should be safe to discard any message if there are any function_call present. The original issue you were seeing is something that should not happen if your system, tool, and parameter prompts are clear and applied appropriately.

In my case, it is true when output has 1 message followed by 1 function_call. However, when the output contains 3-8 messages followed by 1 function_call, that function call always contains a hallucinated email address. That is how I came up with the idea that items of output are sorted by priority, so the 1st one is most reliable.

I agree that it is not normal. It would be nice to hear some comments from OpenAi

I’m running into a similar issue when using the agents sdk (wrapping the responses API). See the github issue here: Agent run with previous_response_id fails - No tool output found for function call call_WdnUUKXKvwy3jk.... · Issue #1061 · openai/openai-agents-python · GitHub. As far as I can tell, this combined message + function_tool response breaks the agents-sdk.

1 Like

We are having the same issue with @markns .

Please see toolUseBehavior: run_llm_again (default) doesn't work · Issue #180 · openai/openai-agents-js · GitHub