You can call external functions and APIs from Gemini using Tool Use, which lets Gemini access real-world data and trigger actions.

Let’s see it in action. Imagine you have a service that can fetch stock prices. We’ll define a tool for Gemini to use this service.

import google.generativeai as genai
from google.generativeai.types import Tool, FunctionDeclaration, Schema, Type

# Configure your API key
genai.configure(api_key="YOUR_API_KEY")

# Define the tool for fetching stock prices
stock_price_tool = Tool(
    function_declarations=[
        FunctionDeclaration(
            name="getStockPrice",
            description="Gets the current stock price for a given ticker symbol.",
            parameters=Schema(
                type=Type.OBJECT,
                properties={
                    "ticker": Schema(type=Type.STRING, description="The stock ticker symbol (e.g., AAPL, GOOG).")
                },
                required=["ticker"]
            ),
        )
    ]
)

# Initialize the Gemini model with the tool
model = genai.GenerativeModel(model_name="gemini-1.5-flash", tools=[stock_price_tool])

# Simulate a function that Gemini can call
def get_stock_price(ticker: str) -> dict:
    # In a real scenario, this would call an actual stock API
    prices = {"AAPL": 170.50, "GOOG": 2800.75, "MSFT": 300.20}
    return {"price": prices.get(ticker, "N/A")}

# --- Example 1: Gemini decides to call the tool ---
prompt1 = "What is the stock price of Apple?"
response1 = model.generate_content(prompt1)

print("--- Response 1 ---")
print(response1.text)
print("--- Tool Calls 1 ---")
print(response1.candidates[0].content.parts)

# Gemini will output a tool call request. You need to execute this call.
# Let's simulate executing the tool call:
tool_call1 = response1.candidates[0].content.parts[0].function_call
if tool_call1:
    function_name = tool_call1.name
    args = tool_call1.args
    if function_name == "getStockPrice":
        result1 = get_stock_price(ticker=args["ticker"])
        # Now, send the result back to Gemini
        response1_tool_result = model.generate_content(
            [
                prompt1, # Pass the original prompt
                response1.candidates[0].content, # Pass Gemini's tool call
                genai.protos.ToolCallResult(
                    tool_call_id=tool_call1.call_id, # Use the call_id from the tool call
                    function_response=genai.protos.FunctionResponse(
                        name=function_name,
                        response={"content": result1}
                    )
                )
            ]
        )
        print("\n--- Response 1 (after tool execution) ---")
        print(response1_tool_result.text)

# --- Example 2: Gemini needs more information ---
prompt2 = "Tell me about the price of a tech stock."
response2 = model.generate_content(prompt2)

print("\n--- Response 2 ---")
print(response2.text)

# Gemini might ask clarifying questions if the tool input is ambiguous.
# If it asks for a ticker, you'd then proceed to call the tool with the user's input.

In this example, Gemini acts as an orchestrator. You define what capabilities are available (the getStockPrice function), and Gemini decides when and how to use them based on the user’s prompt. The core mechanism is the FunctionDeclaration within the Tool object. This declaration tells Gemini the name of the function, what it does (description), and what arguments it expects, along with their types and descriptions.

When Gemini determines that calling a tool is the best way to answer a prompt, it doesn’t execute the function itself. Instead, it outputs a structured request, typically a function_call object, specifying the function name and the arguments it wants to pass. Your application then receives this request, executes the corresponding Python function (e.g., get_stock_price), and sends the result back to Gemini. Gemini then uses this result to formulate a natural language response.

The key to this process is the tools parameter when initializing the GenerativeModel. By passing a list of Tool objects, you make those tools discoverable by the model. Each Tool can contain one or more FunctionDeclaration objects. The Schema within FunctionDeclaration uses Type.OBJECT, Type.STRING, Type.NUMBER, Type.BOOLEAN, and Type.ARRAY to define the expected parameters. The required list ensures that essential arguments are always provided.

The most surprising thing about this system is that Gemini doesn’t know how to execute your Python code directly. It only understands the interface of your functions – their names, descriptions, and parameter schemas. When it generates a function_call, it’s essentially saying, "I need the result of calling getStockPrice with ticker='AAPL'." Your code is responsible for bridging that gap by actually running the getStockPrice function and returning its output.

When Gemini needs to call a tool, it returns a Tool object containing a FunctionCall. This FunctionCall has a name and args. Your code then looks up the function by name, executes it with the provided args, and constructs a ToolCallResult object. This ToolCallResult must include the tool_call_id from the original FunctionCall to correlate the result with the request. You then send this ToolCallResult back to the model, often as part of a new generate_content call, along with the original prompt and Gemini’s previous tool call.

The next concept you’ll likely encounter is handling multiple tool calls simultaneously or dealing with situations where a tool call fails.

Want structured learning?

Take the full Gemini-api course →