# Function Calling

Function calling lets Arcee models connect to external tools like user-defined functions or APIs. This integration helps build applications for specific use cases. In this section, we defined three functions for getting stock prices and company information, enabling answers to stock market queries. In this example, we used the Caller model, our specialized SLM trained for tool use and function calling, and Virtuoso Large, for final output generation via LLM reasoning.&#x20;

Here are the four steps to do function calling with Arcee Models:

You should first define the tools and then, pass the user prompt alongside the list of tools to the model.

<figure><img src="/files/dtRafw889iecC97YYr5y" alt=""><figcaption></figcaption></figure>

Then, the model will detect the required function and extract the function arguments from the user query. &#x20;

<figure><img src="/files/fcOIy05ZQDH70f6VN7ZV" alt=""><figcaption></figcaption></figure>

Next, the model will call the tool to get the relevant information.

<figure><img src="/files/44hqMwPiU4WdX7gTpDOT" alt=""><figcaption></figcaption></figure>

Finally, the model will integrate the output of function calling in the final response.

<figure><img src="/files/mCrPiaAxRD3sXpRzBIX0" alt=""><figcaption></figcaption></figure>

Here, you can find the step-by-step implementation of an example pipeline showing how to use Yahoo Finance API using the function calling and tool use capability of the Arcee models.&#x20;

### Step 1: Installing Required Libraries

```python
pip install -qU httpx[http2] yfinance openai
```

This command installs and upgrades three essential Python libraries:

1. **`httpx[http2]`**:
   * `httpx` is an HTTP client for Python that provides asynchronous support.
   * The `[http2]` extra enables HTTP/2 support, which improves efficiency in communication with APIs.
2. **`yfinance`**:
   * A Python library that allows easy access to stock market data from Yahoo Finance.
   * Useful for retrieving historical stock prices, company financials, and real-time data.
3. **`openai`**:
   * The OpenAI API client library is required for making API requests to Arcee models.

The `-qU` flag:

* `-q` (quiet) suppresses unnecessary output.
* `-U` (upgrade) ensures that the latest versions of the packages are installed.

This setup ensures that all dependencies required for function calling, stock data retrieval, and HTTP requests are available in your environment.

### Step 2: Importing Required Libraries

```notebook-python
import httpx
import json
import pprint
import yfinance
from openai import OpenAI
```

* **`httpx`**: Used for making HTTP requests, particularly with HTTP/2 support.
* **`json`**: Standard Python library for handling JSON data.
* **`pprint`**: Pretty Print module to display data in a structured and readable format.
* **`yfinance`**: Library for fetching stock market data from Yahoo Finance.
* **`OpenAI`**: OpenAI client library to interact with the Arcee Model APIs.

### Step 3: Setting Up API Endpoint and Key

```python
endpoint="https://conductor.arcee.ai/v1"
api_key="YOUR API KEY GOES HERE"
```

* `endpoint`: The base URL for the API that will be used for function calling.
* `api_key`: The API key required to authenticate requests.&#x20;

{% hint style="info" %}
Note! Make sure not to expose API keys in production environments for security reasons.
{% endhint %}

### Step 4: Initializing the Client

```python
client = OpenAI(
    base_url=endpoint,
    api_key=api_key,
    http_client=httpx.Client(http2=True)
)
```

* **`OpenAI()`**: Creates an OpenAI client instance to interact with the model.
* **`base_url=endpoint`**: Specifies the endpoint where API requests will be sent.
* **`api_key=api_key`**: Provides authentication for accessing the API.
* **`http_client=httpx.Client(http2=True)`**:
  * Configures the HTTP client with HTTP/2 support for faster, more efficient communication.

At this stage, the client is ready to send API requests.

### Step 5: Defining  the Functions for Stock Market Research

This section defines three functions that use `yfinance` to fetch stock prices, CEO names, and company summary information.

```python
def get_stock_price(company_name, stock_symbol):
    stock = yfinance.Ticker(stock_symbol)
    price = stock.history(period="1d")["Close"].values[0]
    return f"The last closing price of {company_name} ({stock_symbol}) was ${price:.2f}."

def get_ceo_name(company_name, stock_symbol):
    stock = yfinance.Ticker(stock_symbol)
    info = stock.info
    ceo = info['companyOfficers'][0]['name']
    return f"The CEO of {company_name} is {ceo}. The full job title is {info['companyOfficers'][0]['title']}."

def get_company_information(company_name, stock_symbol):
    stock = yfinance.Ticker(stock_symbol)
    summary = stock.info['longBusinessSummary']
    return summary
```

<figure><img src="/files/qbk0daGrZoBLQCTOpmgL" alt=""><figcaption></figcaption></figure>

### Step 6: Defining Tools for Function Calling

This section defines a list of tools that will be available for function calling via the Model Engine API.

````python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "Use this function to get the last price of a stock",
            "parameters": {
                "type": "object",
                "properties": {
                    "company_name": {
                        "type": "string",
                        "description": "A company name (e.g., Mc Donalds)",
                    },
                    "stock_symbol": {
                        "type": "string",
                        "description": "A company stock ticker (e.g., MCD)",
                    },
                },
                "required": ["company_name", "stock_symbol"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_ceo_name",
            "description": "Use this function to get the name of a company's CEO",
            "parameters": {
                "type": "object",
                "properties": {
                    "company_name": {
                        "type": "string",
                        "description": "A company name (e.g., Mc Donalds)",
                    },
                    "stock_symbol": {
                        "type": "string",
                        "description": "A company stock ticker (e.g., MCD)",
                    },
                },
                "required": ["company_name", "stock_symbol"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_company_summary",
            "description": "Use this function to describe a company's activities, products, services, and customers",
            "parameters": {
                "type": "object",
                "properties": {
                    "company_name": {
                        "type": "string",
                        "description": "A company name (e.g., Mc Donalds)",
                    },
                    "stock_symbol": {
                        "type": "string",
                        "description": "A company stock ticker (e.g., MCD)",
                    },
                },
                "required": ["company_name", "stock_symbol"],
            },
        },
    }
]
```
````

### Step 7 - Defining `call_tool`

This function **`call_tool`** is responsible for:

1. Sending a **user prompt** to the Caller model.
2. Automatically determining if a function call is needed.
3. Extracting the function and arguments from the API response.
4. Dynamically calling the corresponding function.

````python
def call_tool(user_prompt, max_tokens=128):
    response = client.chat.completions.create(
        model="caller",
        messages=[

            {
                "role": "user",
                "content": user_prompt
            }
        ],
        tools=tools,
        tool_choice="auto",
        max_tokens=max_tokens,
    )

    tool_calls = response.choices[0].message.tool_calls

    # Check if there are any tool calls
    if tool_calls:
        # Extract the first tool call (assuming there's at least one)
        first_tool_call = tool_calls[0]

        # Extract function name and arguments
        function_name = first_tool_call.function.name
        arguments_json = first_tool_call.function.arguments
        arguments_dict = json.loads(arguments_json)

        ## Assuming the function is in the current namespace or imported
        if function_name in globals():
            # Get the function object based on its name
            function_to_call = globals()[function_name]

            print(f"Calling {function_name} with arguments: {arguments_dict}")

            # Call the function with unpacked keyword arguments
            result = function_to_call(**arguments_dict)
            return result
        else:
            print(f"Function {function_name} not found in the global namespace.")
            return None
    else:
        # No tool call: print the generated response
        print("No tool call")
        return None

```
````

### Step 8 - Defining `call_tool_and_invoke_model`

The function **`call_tool_and_invoke_model`** extends `call_tool` by:

1. Calling the function using OpenAI’s **function calling** mechanism.
2. Passing the tool result to the Arcee model, **`virtuoso-large`**.
3. Generating a **final response** that intelligently uses the tool’s output.

This approach combines function calling with LLM reasoning, ensuring accuracy and context-aware responses. If function calling fails, the model still provides a meaningful answer.

```python
def call_tool_and_invoke_model(user_prompt, max_tokens=1024):
    tool_result = call_tool(user_prompt)

    response = client.chat.completions.create(
        model="virtuoso-large",
        messages=[
            {
                "role": "system",
                "content": "You are a helpful and knowledgeable assistant giving sharp answers. Use a business-oriented tone."
            },
            {
                "role": "user",
                "content": f"""Answer the following question: {user_prompt} using the tool result: {tool_result}.
                If the tool result is empty or not useful, say it is not useful and answer the question without using the information.
                If the tool result is useful, you can complement it with your own knowledge as long as it's not contradictory.
                """
            }
        ],
        max_tokens=max_tokens
    )
    return response.choices[0].message.content
```

<figure><img src="/files/4Q0b4efebtGE9poLMMxa" alt=""><figcaption></figcaption></figure>

## Example Workflow

#### User Input

```
user_prompt = "What's the last closing price of Chipotle stock?"
```

#### Step 1 - Function Call Execution

```python
response = call_tool(user_prompt)
pprint.pprint(response)
```

#### Step 2 - Function Output

```
Calling get_stock_price with arguments: {'company_name': 'Chipotle', 'stock_symbol': 'CMG'} 'The last closing price of Chipotle (CMG) was $58.35.'
```

#### Step 3 - Function Call and Response Generation

```python
response = call_tool_and_invoke_model(user_prompt)
pprint.pprint(response)
```

#### Step 4 - Model Output

```
Calling get_stock_price with arguments: {'company_name': 'Chipotle', 'stock_symbol': 'CMG'} ('The last closing price of Chipotle (CMG) was $58.35. This price reflects the ' "most recent trading day's closing value for the company's stock. It's " 'important to note that stock prices can fluctuate based on market ' 'conditions, company performance, and broader economic factors, so this ' 'figure may change with new trading sessions.')
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.arcee.ai/arcee-conductor/arcee-small-language-models/model-capabilities/function-calling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
