Gemini Function Calling: Building Tool-Using Agents with Google's AI
Master Gemini's function calling capabilities to build agents that use external tools. Learn tool definitions, function declarations, automatic execution, and multi-turn tool use patterns.
What Is Function Calling in Gemini
Function calling is the mechanism that transforms a language model from a text generator into an agent capable of taking actions. When you give Gemini a set of tool definitions, it can decide when to call those tools, what arguments to pass, and how to incorporate the results into its response.
Unlike simple prompt engineering where you ask the model to output JSON matching a tool schema, Gemini's function calling is a native capability. The model outputs structured FunctionCall objects that your code executes, then you feed the results back as FunctionResponse objects. This creates a reliable agent loop.
Defining Tools with Function Declarations
Tools are defined as Python functions with type hints. The SDK automatically converts these into the schema Gemini expects:
flowchart TD
USER(["User message"])
LLM["LLM call<br/>with tools schema"]
DECIDE{"Model wants<br/>to call a tool?"}
EXEC["Execute tool<br/>sandboxed runtime"]
RESULT["Append tool_result<br/>to messages"]
GUARD{"Output passes<br/>guardrails?"}
DONE(["Final reply"])
BLOCK(["Refuse and log"])
USER --> LLM --> DECIDE
DECIDE -->|Yes| EXEC --> RESULT --> LLM
DECIDE -->|No| GUARD
GUARD -->|Yes| DONE
GUARD -->|No| BLOCK
style LLM fill:#4f46e5,stroke:#4338ca,color:#fff
style EXEC fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
style DONE fill:#059669,stroke:#047857,color:#fff
style BLOCK fill:#dc2626,stroke:#b91c1c,color:#fff
import google.generativeai as genai
import os
genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
def get_weather(city: str, unit: str = "celsius") -> dict:
"""Get the current weather for a given city.
Args:
city: The city name, e.g. 'San Francisco'.
unit: Temperature unit, either 'celsius' or 'fahrenheit'.
"""
# In production, call a real weather API here
weather_data = {
"San Francisco": {"temp": 18, "condition": "foggy"},
"New York": {"temp": 25, "condition": "sunny"},
"London": {"temp": 14, "condition": "rainy"},
}
result = weather_data.get(city, {"temp": 20, "condition": "unknown"})
if unit == "fahrenheit":
result["temp"] = result["temp"] * 9 / 5 + 32
return result
def search_restaurants(location: str, cuisine: str, max_results: int = 3) -> list:
"""Search for restaurants in a given location.
Args:
location: The city or neighborhood to search in.
cuisine: Type of cuisine, e.g. 'italian', 'japanese'.
max_results: Maximum number of results to return.
"""
return [
{"name": f"Best {cuisine.title()} Place", "rating": 4.5},
{"name": f"{cuisine.title()} Garden", "rating": 4.2},
]
The docstring format matters. Gemini uses the function description and argument descriptions to decide when and how to call each tool.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
Passing Tools to the Model
Create the model with your tools attached:
model = genai.GenerativeModel(
"gemini-2.0-flash",
tools=[get_weather, search_restaurants],
)
chat = model.start_chat()
response = chat.send_message("What's the weather in San Francisco?")
print(response.candidates[0].content.parts)
When the model decides to use a tool, the response contains a FunctionCall part instead of text. You need to execute the function and send the result back.
The Manual Function Calling Loop
Here is the complete agent loop that handles function calls:
import json
def run_agent(user_message: str, model, chat):
response = chat.send_message(user_message)
while response.candidates[0].content.parts[0].function_call:
fc = response.candidates[0].content.parts[0].function_call
function_name = fc.name
function_args = dict(fc.args)
# Dispatch to the actual function
available_functions = {
"get_weather": get_weather,
"search_restaurants": search_restaurants,
}
result = available_functions[function_name](**function_args)
# Send the result back to Gemini
response = chat.send_message(
genai.protos.Content(
parts=[genai.protos.Part(
function_response=genai.protos.FunctionResponse(
name=function_name,
response={"result": result},
)
)]
)
)
return response.text
This loop continues until Gemini returns a text response rather than another function call, allowing the model to chain multiple tool calls in sequence.
Automatic Function Calling
For simpler agents, the SDK supports automatic function calling that handles the loop for you:
model = genai.GenerativeModel(
"gemini-2.0-flash",
tools=[get_weather, search_restaurants],
)
# Enable automatic function calling
chat = model.start_chat(enable_automatic_function_calling=True)
# The SDK automatically executes functions and feeds results back
response = chat.send_message(
"What's the weather in London and find me Italian restaurants there?"
)
# response.text contains the final answer with tool results incorporated
print(response.text)
Automatic mode is convenient for prototyping but gives you less control. In production agents, the manual loop lets you add logging, validation, and error handling around each tool call.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
Parallel Function Calling
Gemini can request multiple function calls in a single turn. Handle this by checking all parts:
def run_agent_parallel(user_message: str, model, chat):
response = chat.send_message(user_message)
function_calls = [
part.function_call
for part in response.candidates[0].content.parts
if part.function_call.name
]
if function_calls:
results = []
available_functions = {
"get_weather": get_weather,
"search_restaurants": search_restaurants,
}
for fc in function_calls:
result = available_functions[fc.name](**dict(fc.args))
results.append(
genai.protos.Part(
function_response=genai.protos.FunctionResponse(
name=fc.name,
response={"result": result},
)
)
)
response = chat.send_message(
genai.protos.Content(parts=results)
)
return response.text
FAQ
How many tools can I give Gemini at once?
Gemini supports up to 128 function declarations in a single request. However, performance is best with fewer, well-described tools. If you have more than 20 tools, consider grouping them into categories and using a routing agent to select the relevant subset.
Does function calling work with streaming?
Yes. When streaming is enabled, the function call appears as soon as the model decides to use a tool, before the full response is generated. This allows your agent to start executing tools earlier in the response cycle.
What happens if my function raises an exception?
If your function fails, you should catch the exception and return an error message as the function response. Gemini will then attempt to recover, either by trying different arguments or explaining the failure to the user.
#GoogleGemini #FunctionCalling #AIAgents #ToolUse #Python #AgenticAI #LearnAI #AIEngineering
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.