Large Language Models (LLMs) are historically static—they can only output text based on their pre-trained parameters. **Tool Calling (or Function Calling)** transforms LLMs from passive text engines into active system controllers. By enabling models to query databases, invoke APIs, and run local computations, we connect artificial intelligence to the real world.
In a traditional chat interaction, the model answers queries purely from memory. If you ask, *"What is the balance of account ACC-992?"*, the model must guess or hallucinate because it lacks access to dynamic account data.
With Tool Calling, the developer provides the LLM with a catalog of tools (functions) described in structural JSON Schema format. Instead of answering directly, the model evaluates the user query, determines that it needs external information, and returns astructured JSON payload specifying which function to run and with what exact arguments. The host application executes the function, collects the result, sends it back to the model, and allows the model to summarize the final response.
function_call payload (e.g., { "name": "get_balance", "args": { "account_id": "ACC-992" } }) instead of natural language.{ "status": "success", "balance": 1450.75 }).To let the model know what tools exist, we define their signatures using a sub-specification of JSON Schema. The description of the function and its arguments is critical: the model relies on these descriptions as semantic instructions to decide when and how to call the function.
# Declarative representation of a tool schema sent to the API
db_tool_schema = {
"name": "query_database",
"description": "Fetch user record by ID from the internal Postgres database.",
"parameters": {
"type": "OBJECT",
"properties": {
"user_id": {
"type": "INTEGER",
"description": "The unique 6-digit employee identification number."
},
"fields": {
"type": "ARRAY",
"items": {"type": "STRING"},
"description": "Specific columns to fetch, e.g., ['email', 'salary']."
}
},
"required": ["user_id"]
}
}Modern SDKs (such as Gemini's google-generativeai or OpenAI's client) support automatic schema generation by using Python's type hinting and docstrings (type-reflection). Here is a complete execution sequence:
import google.generativeai as genai
# 1. Define the actual local tool with strict type annotations and detailed docstrings
def get_weather(location: str, unit: str = "celsius") -> str:
"""Get the current weather forecast for a given city.
Args:
location: The city and state, e.g. San Francisco, CA
unit: Temperature unit, either 'celsius' or 'fahrenheit'
"""
# In a real app, this queries an external weather API.
return f"The weather in {location} is 22 degrees {unit}, sunny."
# 2. Configure the client and pass the function reference directly as a tool
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel(
model_name="gemini-1.5-pro",
tools=[get_weather] # Automatically generates the JSON Schema!
)
# 3. Start a stateful chat session
chat = model.start_chat(enable_automatic_function_calling=True)
# 4. Prompt the model. The SDK automatically intercepts the model's call instruction,
# executes get_weather("Seattle, WA"), sends the result back, and gives the final answer.
response = chat.send_message("Should I wear a jacket in Seattle today?")
print(response.text)
Navigate to the code editor on the right. You need to implement manual function extraction and feedback injection using Python dictionary calls. This reinforces understanding of what the SDK does under the hood.
query_database(user_id: int) -> dict that returns a hardcoded mock record: { 'id': user_id, 'name': 'Alice Smith', 'role': 'Lead Researcher' }.query_database, specifying the user_id as a required integer.tools list configuration parameter.function_call returned from the model response, run the local function, and return the result using a structural multi-turn API request.Once you've completed these tasks and verified the execution flow in the terminal, proceed to the next lesson, where we will tie multiple tool invocations together into autonomous, multi-step ReAct Planning Loops!