How to use function calling with Azure OpenAI in Microsoft Foundry Models
If one or more functions are included in your request, the model determines if any of the functions should be called based on the context of the prompt. When the model determines thatodel a function should be called, it responds with a JSON object including the arguments for the function. The models formulate API calls and structure data outputs, all based on the functions you specify. It’s important to note that while the models can generate these calls, it’s up to you to execute them, ensuring you remain in control. At a high level, you can break down working with functions into three steps:- Call the chat completions API with your functions and the user’s input
- Use the model’s response to call your API or function
- Call the chat completions API again, including the response from your function to get a final response
Prerequisites
- An Azure OpenAI model deployed
- For Microsoft Entra ID authentication:
- A custom subdomain configured. For more information, see Custom subdomain names.
- Packages:
pip install openai azure-identity.
Single tool/function calling example
First demonstrate a toy function call that can check the time in three hardcoded locations with a single tool/function defined. We have added print statements to help make the code execution easier to follow:tool_calls array, each with a unique id. If you wanted to respond to these function calls, you would add three new messages to the conversation, each containing the result of one function call, with a tool_call_id referencing the id from tool_calls.
To force the model to call a specific function, set tool_choice to a named tool object, for example: tool_choice={"type": "function", "function": {"name": "get_current_time"}}. To force a user-facing message, set tool_choice="none".
The default behavior (
tool_choice: "auto") is for the model to decide on its own if it should call a function and if so which function to call.Parallel function calling with multiple functions
Now we demonstrate another toy function calling example this time with two different tools/functions defined.The JSON response might not always be valid so you need to add additional logic to your code to be able to handle errors. For some use cases you may find you need to use fine-tuning to improve function calling performance.
Prompt engineering with functions
When you define a function as part of your request, the details are injected into the system message using specific syntax that the model has been trained on. This means that functions consume tokens in your prompt and that you can apply prompt engineering techniques to optimize the performance of your function calls. The model uses the full context of the prompt to determine if a function should be called including function definition, the system message, and the user messages.Improving quality and reliability
If the model isn’t calling your function when or how you expect, there are a few things you can try to improve the quality.Provide more details in your function definition
It’s important that you provide a meaningfuldescription of the function and provide descriptions for any parameter that might not be obvious to the model. For example, in the description for the location parameter, you could include extra details and examples on the format of the location.
Provide more context in the system message
The system message can also be used to provide more context to the model. For example, if you have a function calledsearch_hotels you could include a system message like the following to instruct the model to call the function when a user asks for help with finding a hotel.
Instruct the model to ask clarifying questions
In some cases, you want to instruct the model to ask clarifying questions to prevent making assumptions about what values to use with functions. For example, withsearch_hotels you would want the model to ask for clarification if the user request didn’t include details on location. To instruct the model to ask a clarifying question, you could include content like the next example in your system message.
Reducing errors
Another area where prompt engineering can be valuable is in reducing errors in function calls. The models are trained to generate function calls matching the schema that you define, but the models produce a function call that doesn’t match the schema you defined or try to call a function that you didn’t include. If you find the model is generating function calls that weren’t provided, try including a sentence in the system message that says"Only use the functions you have been provided with.".
Using function calling responsibly
Like any AI system, using function calling to integrate language models with other tools and systems presents potential risks. It’s important to understand the risks that function calling could present and take measures to ensure you use the capabilities responsibly. Here are a few tips to help you use functions safely and securely:- Validate Function Calls: Always verify the function calls generated by the model. This includes checking the parameters, the function being called, and ensuring that the call aligns with the intended action.
- Use Trusted Data and Tools: Only use data from trusted and verified sources. Untrusted data in a function’s output could be used to instruct the model to write function calls in a way other than you intended.
- Follow the Principle of Least Privilege: Grant only the minimum access necessary for the function to perform its job. This reduces the potential impact if a function is misused or exploited. For example, if you’re using function calls to query a database, you should only give your application read-only access to the database. You also shouldn’t depend solely on excluding capabilities in the function definition as a security control.
- Consider Real-World Impact: Be aware of the real-world impact of function calls that you plan to execute, especially those that trigger actions such as executing code, updating databases, or sending notifications.
- Implement User Confirmation Steps: Particularly for functions that take actions, we recommend including a step where the user confirms the action before execution.
The
functions and function_call parameters have been deprecated with the release of the 2023-12-01-preview version of the API. The replacement for functions is the tools parameter. The replacement for function_call is the tool_choice parameter.Function calling support
Parallel function calling
gpt-4(2024-04-09)gpt-4o(2024-05-13)gpt-4o(2024-08-06)gpt-4o(2024-11-20)gpt-4o-mini(2024-07-18)gpt-4.1(2025-04-14)gpt-4.1-mini(2025-04-14)gpt-5(2025-08-07)gpt-5-mini(2025-08-07)gpt-5-nano(2025-08-07)gpt-5-codex(2025-09-11)gpt-5.1(2025-11-13)gpt-5.1-chat(2025-11-13)gpt-5.1-codex(2025-11-13)gpt-5.1-codex-mini(2025-11-13)gpt-5.1-codex-max(2025-12-04)gpt-5.2(2025-12-11)gpt-5.2-chat(2025-12-11)gpt-5.2-codex(2026-01-14)
2023-12-01-preview
Basic function calling with tools
- All the models that support parallel function calling
gpt-5-pro(2025-10-06)codex-mini(2025-05-16)o3-pro(2025-06-10)o4-mini(2025-04-16)o3(2025-04-16)gpt-4.1-nano(2025-04-14)o3-mini(2025-01-31)o1(2024-12-17)
The
tool_choice parameter is now supported with o3-mini and o1. For more information, see the reasoning models guide.Tool/function descriptions are currently limited to 1,024 characters with Azure OpenAI. We’ll update this article if this limit is changed.
Next steps
- Learn more about Azure OpenAI.
- For more examples on working with functions, check out the Azure OpenAI Samples GitHub repository