(Click di pikshua we dey up dia for watch video of dis lesson)
Tools dey interesting because dem dey allow AI agents make dem get more plenty tins dem fit do. Instead make di agent get only few actions e fit do, if you add tool, e fit do plenty actions now. For dis chapter, we go look di Tool Use Design Pattern, wey dey show how AI agents fit use special tools take achieve dia goals.
For dis lesson, we wan find answer to these questions:
After you finish dis lesson, you go fit:
Di Tool Use Design Pattern focus on make LLMs fit interact wit tools outside dem self to achieve exact goals. Tools be code wey agent fit run to do actions. Tool fit be simple function like calculator, or API call to third-party service like look stock price or weather forecast. For AI agents matter, tools dem dey designed make agents fit run dem when model generate function calls.
AI Agents fit take tools do complicated work, find information, or make decisions. Tool use design pattern dem dey use wella when you need make e interact well wit external things like database, web services, or code interpreters. Dis ability dey important for many use cases like:
All dis parts go allow AI agent do plenty tins. Make we check di main tins we need take build Tool Use Design Pattern:
Function/Tool Schemas: Detailed definition of tools wey dey, including function name, wetin e suppose do, wetin parameters e need, and wetin e go return. Dis schemas dey make LLM sabi which tools dey and how to create proper requests.
Function Execution Logic: Na dis one dey control when and how dem go call tools based on wetin user want and di gist context. E fit get planner modules, routing systems, or condition flows wey dey decide how to use tool.
Message Handling System: Tins wey dey manage di conversation flow between user input, LLM response, tool calls, and tool output.
Tool Integration Framework: Di system wey connect agents to different tools, whether na simple functions or big outside services.
Error Handling & Validation: Tins wey dey catch tool execution failure, check parameters, and manage surprise response.
State Management: Keep eye for conversation history, past tool usage, and data wey need to stay consistent for multi-turn interactions.
Next, make we check Function/Tool Calling well well.
Function calling na main way we take let Large Language Models (LLMs) fit interact wit tools. You fit see ‘Function’ and ‘Tool’ mean are same because ‘functions’ (blocks of reusable code) be di ‘tools’ wey agents dey use to do work. To make function code run, LLM must compare user request with function description. For dis one, schema wey get all function description go send to LLM. Then LLM go pick di best function for di work, return e name and arguments. Di chosen function go run, e response go come back to LLM, wey go use am answer user request.
For developer wen wan build function calling for agents, you go need:
Make we use example of find current time for city to explain:
Start LLM wey support function calling:
No all models support function calling, so make sure say di LLM wey you dey use get am. Azure OpenAI dey support function calling. We fit start by open OpenAI client for Azure OpenAI Responses API (stable /openai/v1/ endpoint — no api_version needed).
# Start di OpenAI client for Azure OpenAI (Responses API, v1 endpoint)
client = OpenAI(
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
api_key=os.environ["AZURE_OPENAI_API_KEY"],
)
deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT"]
Create Function Schema:
Next, we go define JSON schema wey get function name, description, and parameters name and description. We go pass dis schema to client wey we create before, plus user request say make e find time for San Francisco. Wetin important to know be say tool call be wetin you go get back, no na final answer to question. Like we talk before, LLM go return name of function wey e pick for task, and arguments wey e go use.
# Function tok say how di model go read (Responses API flat tool format)
tools = [
{
"type": "function",
"name": "get_current_time",
"description": "Get the current time in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco",
},
},
"required": ["location"],
},
}
]
# Initial user message
messages = [{"role": "user", "content": "What's the current time in San Francisco"}]
# First API call: Ask di model make e use di function
response = client.responses.create(
model=deployment_name,
input=messages,
tools=tools,
tool_choice="auto",
store=False,
)
# Di Responses API dey return tool calls as function_call items inside response.output.
# Add dem join di conversation make di model get complete context for di next turn.
messages += response.output
print("Model's response:")
print(response.output)
Model's response:
[ResponseFunctionToolCall(arguments='{"location":"San Francisco"}', call_id='call_pOsKdUlqvdyttYB67MOj434b', name='get_current_time', type='function_call')]
Function code wey go do di work:
Now say LLM don pick di function to run, e code wey go do di work must dey implement and run. We fit write code to find current time for Python. We also need write code to take name and arguments from response_message to get final result.
def get_current_time(location):
"""Get the current time for a given location"""
print(f"get_current_time called with location: {location}")
location_lower = location.lower()
for key, timezone in TIMEZONE_DATA.items():
if key in location_lower:
print(f"Timezone found for {key}")
current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
return json.dumps({
"location": location,
"current_time": current_time
})
print(f"No timezone data found for {location_lower}")
return json.dumps({"location": location, "current_time": "unknown"})
# Handle function calls
tool_calls = [item for item in response.output if item.type == "function_call"]
if tool_calls:
for tool_call in tool_calls:
if tool_call.name == "get_current_time":
function_args = json.loads(tool_call.arguments)
time_response = get_current_time(
location=function_args.get("location")
)
# Return the tool result as a function_call_output item
messages.append({
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": time_response,
})
else:
print("No tool calls were made by the model.")
# Second API call: Get the final response from the model
final_response = client.responses.create(
model=deployment_name,
input=messages,
tools=tools,
store=False,
)
return final_response.output_text
get_current_time called with location: San Francisco
Timezone found for san francisco
The current time in San Francisco is 09:24 AM.
Function Calling na di main ting for most agent tool use design, but building am from scratch fit be challenge sometimes. As we learn for Lesson 2 agentic frameworks dey give us pre-made building blocks to take use the tool use.
Here na some examples how you fit use Tool Use Design Pattern wit different agentic frameworks:
Microsoft Agent Framework na open-source AI framework to build AI agents. E make am easy to use function calling by allowing you define tools as Python functions wit @tool decorator. Di framework dey handle communication between di model and your code. E also give access to pre-made tools like File Search and Code Interpreter through FoundryChatClient.
Below diagram show how function calling dey work wit Microsoft Agent Framework:

For Microsoft Agent Framework, tools dey define as decorated functions. We fit turn get_current_time function we see earlier into tool by using @tool decorator. Di framework go automatically serialize di function and parameters, create schema to send to LLM.
import os
from agent_framework import tool
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential
@tool(approval_mode="never_require")
def get_current_time(location: str) -> str:
"""Get the current time for a given location"""
...
# Make di client
provider = FoundryChatClient(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
# Make one agent and run am wit di tool
agent = provider.as_agent(name="TimeAgent", instructions="Use available tools to answer questions.", tools=get_current_time)
response = await agent.run("What time is it?")
Microsoft Foundry Agent Service na recent agentic framework wey dey help developers build, deploy, and scale strong, extensible AI agents without wahala of managing di underlying compute and storage. E good for enterprise applications because na full managed service wit top level security.
Compared to direct LLM API development, Microsoft Foundry Agent Service get advantage like:
Tools wey dey Microsoft Foundry Agent Service fit divide into two:
Agent Service allow us to fit use all dis tools together as toolset. E also use threads wey go keep history of messages for each conversation.
Imagine say you be sales agent for company wey dem call Contoso. You wan build conversational agent we fit answer questions about your sales data.
Dis picture show how you fit take Microsoft Foundry Agent Service analyze your sales data:

To use any of these tools wit di service, we fit create client and define tool or toolset. To do am for real, we fit use dis Python code. LLM go fit check di toolset and decide to use user made function, fetch_sales_data_using_sqlite_query, or built-in Code Interpreter based on user request.
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from fetch_sales_data_functions import fetch_sales_data_using_sqlite_query # fetch_sales_data_using_sqlite_query function wey you fit find inside fetch_sales_data_functions.py file.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool
project_client = AIProjectClient.from_connection_string(
credential=DefaultAzureCredential(),
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)
# Start toolset
toolset = ToolSet()
# Start function calling agent wit the fetch_sales_data_using_sqlite_query function make e join the toolset
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset.add(fetch_data_function)
# Start Code Interpreter tool make e join the toolset.
code_interpreter = CodeInterpreterTool()toolset.add(code_interpreter)
agent = project_client.agents.create_agent(
model="gpt-4.1-mini", name="my-agent", instructions="You are helpful agent",
toolset=toolset
)
One common palava with SQL wey LLMs dey create dynamically be security, especially risk of SQL injection or malicious things like dropping or messing with database. Even though dis concerns dey real, you fit protect well by setting database access correctly. For most databases, e mean to set am as read-only. For PostgreSQL or Azure SQL, assign app read-only (SELECT) role.
Run di app for secure environment go also protect well. For enterprise setting, data dey usually come from operational systems turn read-only database or data warehouse wit easy-to-use schema. Dis way, data go dey safe, fast and easy to reach, plus app go only get small read-only access.
Join di Microsoft Foundry Discord to meet other learners, attend office hours and get your AI Agents questions answer.
After you don sabi how to deploy agents for Lesson 16, you fit smoke-test dis lesson TravelToolAgent (e still dey call im tools and answer?) wit tests/lesson-04-smoke-tests.json. See tests/README.md to sabi how to run am.
Understanding Agentic Design Patterns
Disclaimer: Dis document don translate wit AI translation service Co-op Translator. Even tho we dey try make am correct, abeg make you know say automated translation fit get errors or mistakes. Di original document for dia own language na im be di correct source. For important info, make person wey sabi human translation do am. We no go responsible for any misunderstanding or wrong understanding wey fit happen because of dis translation.