> ## Documentation Index
> Fetch the complete documentation index at: https://genai.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool Use & Function Calling

> Understand the function calling API contract and bind custom python tools to Chat Models

Large Language Models cannot directly execute python code or fetch URL contents. Instead, they use **Function Calling** (Tool Binding), where the model outputs a structured JSON request indicating *which* tool to run and *what* arguments to pass. The client application executes the code locally and returns the result to the model.

## 1. The Function Calling Lifecycle

The function calling loop operates as a communication contract between the application client and the LLM API:

```text theme={null}
1. Client sends Query + Tool Schemas (JSON) ──> [ LLM ]
2. LLM decides to call tool ──> Returns Tool Call JSON Request {"name": "get_stock", "args": {"ticker": "AAPL"}}
3. Client runs get_stock("AAPL") locally ──> Returns result: "$240.50"
4. Client sends result to LLM ──> [ LLM ] ──> Generates conversational response: "Apple stock is currently $240.50."
```

> \[!IMPORTANT]
> **LLMs do not run your tools.** The model only generates the JSON arguments specifying *how* you should run them. Your Python script is responsible for executing the function and feeding the text result back to the model.

## 2. Defining & Binding Tools in LangChain

In LangChain, you convert any standard Python function into a tool using the **`@tool`** decorator. The decorator automatically generates the JSON schema description based on your function name, docstring, and type hints.

### 2.1 Python Implementation

Below is a working script demonstrating tool binding. The model evaluates a user question and outputs a structured tool call request.

```python theme={null}
import os
from dotenv import load_dotenv
from langchain_core.tools import tool
from langchain.chat_models import init_chat_model

load_dotenv()

# 1. Define a tool using the @tool decorator
# The docstring is critical: it tells the LLM when to call this tool
@tool
def calculate_salary_bonus(years_of_service: int, performance_score: float) -> float:
    """Calculates the end-of-year salary bonus for an employee based on tenure and score."""
    base_bonus = 1000.0
    return base_bonus + (years_of_service * 200.0) * performance_score

# 2. Initialize the Chat Model
llm = init_chat_model("gemini-2.5-flash", model_provider="google_genai")

# 3. Bind the tool to the LLM
# This registers the tool schema with the model during call configuration
llm_with_tools = llm.bind_tools([calculate_salary_bonus])

# 4. Invoke the model
query = "How much bonus does a worker with 5 years of service and a 1.5 performance score get?"
print(f"Query: '{query}'")

response = llm_with_tools.invoke(query)

# 5. Inspect the response
# The model will not return conversational text; it returns a tool call request
print("\n--- Model Response Metadata ---")
print(f"AIMessage content: {response.content}")
print(f"Tool Calls requested: {response.tool_calls}")
```

**Output:**

```text theme={null}
Query: 'How much bonus does a worker with 5 years of service and a 1.5 performance score get?'

--- Model Response Metadata ---
AIMessage content: 
Tool Calls requested: [{'name': 'calculate_salary_bonus', 'args': {'years_of_service': 5, 'performance_score': 1.5}, 'id': '...', 'type': 'tool_call'}]
```

## 3. Practice Exercises

### Practice 1: Binding Multiple Tools

Create a second tool called `get_current_weather(city_name: str)` that returns a mock weather string (e.g. `"22°C and sunny"`). Bind **both** `calculate_salary_bonus` and `get_current_weather` to your model. Query `"What is the weather in London?"` and verify the correct tool call is returned.

**Instructions:**

1. Write the `get_current_weather` tool with a docstring.
2. Call `llm.bind_tools([calculate_salary_bonus, get_current_weather])`.
3. Invoke the query and print `response.tool_calls`.

<Accordion title="Solution">
  ```python theme={null}
  from langchain_core.tools import tool
  from langchain.chat_models import init_chat_model

  @tool
  def get_current_weather(city_name: str) -> str:
      """Fetches the current weather description for a given city."""
      return f"The weather in {city_name} is currently 22°C and sunny."

  llm = init_chat_model("gemini-2.5-flash", model_provider="google_genai")

  # Bind both tools
  llm_with_tools = llm.bind_tools([calculate_salary_bonus, get_current_weather])

  # Query weather
  response = llm_with_tools.invoke("What is the weather in London?")
  print(response.tool_calls)
  ```
</Accordion>
