Function Calling
Function (tool) calling allows models to invoke predefined functions and APIs so they can take actions, fetch real-time data, and interact with external systems. This is useful for assistants, chat applications, and agentic systems that must act on user input.
Tools or functions expose specific capabilities through a name, description, and parameter schema. When tools are included in a request, the model can decide when to call them.
Tool Calls
A tool call is produced when the model determines that using one of the available tools is required. Here are key parameters to pass when calling the model related to function/tool calling:
toolsDefines the functions the model can call, including their names, descriptions, and parameter schemas.tool_choiceControls whether the model should decide when to call a tool. The supported value isauto, which lets the model choose based on the prompt
Tool Call Outputs
After your system executes the tool with the model-provided arguments, the result is returned to the model to generate the final response.
tool_callsContains the list of tool calls returned by the model. Each entry includes the tool name, the arguments the model generated, and an ID used to link your tool output back to the call.function.nameThe name of the tool or function the model selected.function.argumentsA JSON string with the arguments the model generated for the tool.idUnique identifier for the tool call, used to match tool outputs to the corresponding request.
Example: Function Calling with Custom Python Functions
This example demonstrates how to use function calling with an OpenAI-compatible model to fetch real-time financial data using the yfinance library. The model can retrieve stock prices, CEO names, and business summaries for publicly traded companies by invoking custom Python functions.
Before running the example, make sure the following Python packages are installed:
pip install -qU httpx[http2] yfinance openaihttpxis an HTTP client for Python that provides asynchronous support.The
[http2]extra enables HTTP/2 support, which improves efficiency in communication with APIs.
Initializing the Client - Optimizing with Httpx
endpoint = "https://api.arcee.ai/api/v1"
model = "YOUR_MODEL_NAME"
api_key="API_KEY"
client = OpenAI(
base_url=endpoint,
api_key=api_key,
http_client=httpx.Client(http2=True)
)http_client=httpx.Client(http2=True):Configures the HTTP client with HTTP/2 support for faster, more efficient communication.
Custom functions for stock research
def get_stock_price(company_name: str, stock_symbol: str) -> dict:
try:
stock = yf.Ticker(stock_symbol)
hist = stock.history(period="1d")
if hist.empty:
return {"error": f"No price data found for {company_name} ({stock_symbol})."}
return {"price": float(hist["Close"].iloc[-1])}
except Exception as e:
return {"error": str(e)}def get_ceo_name(company_name: str, stock_symbol: str) -> dict:
try:
info = yf.Ticker(stock_symbol).info
officers = info.get("companyOfficers", [])
if not officers:
return {"error": "No officer data available."}
ceo = officers[0]
return {
"ceo": ceo.get("name", "Unknown"),
"title": ceo.get("title", "Unknown")
}
except Exception as e:
return {"error": str(e)}def get_company_summary(company_name: str, stock_symbol: str) -> dict:
try:
info = yf.Ticker(stock_symbol).info
summary = info.get("longBusinessSummary")
if not summary:
return {"error": "No summary available."}
return {"summary": summary}
except Exception as e:
return {"error": str(e)}
Register the functions as tools
tools = [
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "Get the last closing price of a company's stock",
"parameters": {
"type": "object",
"properties": {
"company_name": {"type": "string"},
"stock_symbol": {"type": "string"}
},
"required": ["company_name", "stock_symbol"]
}
}
},
{
"type": "function",
"function": {
"name": "get_ceo_name",
"description": "Get the CEO of the company",
"parameters": {
"type": "object",
"properties": {
"company_name": {"type": "string"},
"stock_symbol": {"type": "string"}
},
"required": ["company_name", "stock_symbol"]
}
}
},
{
"type": "function",
"function": {
"name": "get_company_summary",
"description": "Get a company's business summary",
"parameters": {
"type": "object",
"properties": {
"company_name": {"type": "string"},
"stock_symbol": {"type": "string"}
},
"required": ["company_name", "stock_symbol"]
}
}
}
]
Step 5: Creating the Initial Model Call (Function Calling)
By setting tool_choice="auto", the model will decide whether to call a tool and which to call, or answer directly.
user_prompt = "What's the last closing price of Chipotle stock?"
response = client.chat.completions.create(
model=model,
messages=[
{"role": "user", "content": user_prompt}
],
tools=tools,
tool_choice="auto"
)At this stage, the model responds either with:
a function/tool call including arguments, or
a normal text response (if no function is needed).
Handling Tool Calls and Returning a Response
After the user prompt is sent, the model may respond with one or more tool calls. This step processes those tool calls, executes the corresponding functions locally, and sends the results back to the model to complete the conversation.
# Prepare message history
message = response.choices[0].message
messages = [{"role": "user", "content": user_prompt}, message]
# Execute tool calls if present
if message.tool_calls:
for tool_call in message.tool_calls:
args = json.loads(tool_call.function.arguments)
if isinstance(args, str): # Handle double-encoding
args = json.loads(args)
# Dispatch the correct tool
if tool_call.function.name == "get_stock_price":
result = get_stock_price(args.get("company_name"), args.get("stock_symbol"))
elif tool_call.function.name == "get_ceo_name":
result = get_ceo_name(args.get("company_name"), args.get("stock_symbol"))
elif tool_call.function.name == "get_company_summary":
result = get_company_summary(args.get("company_name"), args.get("stock_symbol"))
else:
result = {"error": f"Unknown function: {tool_call.function.name}"}
messages.append({
"role": "tool",
"content": json.dumps(result, ensure_ascii=False),
"tool_call_id": tool_call.id
})
# Final completion with tool results
final_response = client.chat.completions.create(
model=model,
messages=messages,
tools=tools,
tool_choice="auto"
)
print(final_response.choices[0].message.content)
else:
# If no tools were called, return model response directly
if message.content:
print(message.content)
else:
print("No content in response")Example Output
Calling get_stock_price with arguments: {'company_name': 'Chipotle', 'stock_symbol': 'CMG'}
Tool result: {'price': 31.0}
Final output: The last closing price of Chipotle stock was **$31.0**.Last updated


