Tool Calling#
Tool calling (also known as function calling) enables models to interact with external tools and APIs. Furiosa-LLM supports tool calling for models trained with this capability.
Tool Calling Parsers#
The system converts model outputs into the OpenAI response format through a designated parser implementation. Tool calling parsers are model-dependent, as different models use different formats for tool calls.
Currently, Furiosa-LLM supports the following tool calling parsers:
hermes: For models using the Hermes tool calling format (e.g., EXAONE-4.0, Qwen3 series)llama3_json: For Llama series models (e.g., Llama 3.1, Llama 3.2)openai: For models using the OpenAI tool calling format (e.g., gpt-oss-20b, gpt-oss-120b)
When starting the server, specify the appropriate parser using the --tool-call-parser option.
Tool Choice Options#
The tool_choice parameter controls how the model selects tools to call. Furiosa-LLM supports the following options:
auto(default): The model decides whether to call a tool or respond directly based on the conversation context.required: Forces the model to call at least one tool. The model cannot respond without making a tool call.{"type": "function", "function": {"name": "<function_name>"}}: Forces the model to call a specific named function.
For more details on the tool calling specification, refer to the OpenAI Chat API documentation.
Online Example with Named Function Calling#
import json
import os
from openai import OpenAI
base_url = os.getenv("OPENAI_BASE_URL", "http://localhost:8000/v1")
api_key = os.getenv("OPENAI_API_KEY", "EMPTY")
client = OpenAI(base_url=base_url, api_key=api_key)
def get_weather(location: str, unit: str):
return f"Getting the weather for {location} in {unit}..."
def get_time(timezone: str):
return f"Getting the current time in {timezone}..."
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City and state, e.g., 'San Francisco, CA'"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location", "unit"]
}
}
},
{
"type": "function",
"function": {
"name": "get_time",
"description": "Get the current time in a given timezone",
"parameters": {
"type": "object",
"properties": {
"timezone": {"type": "string", "description": "Timezone, e.g., 'America/Los_Angeles'"}
},
"required": ["timezone"]
}
}
}
]
# The user asks for both weather and time, but ``tool_choice`` forces the
# model to call ``get_weather`` only. The response is constrained to
# ``get_weather``'s schema, so the model cannot smuggle a ``timezone``
# argument (which belongs to ``get_time``) into the call.
response = client.chat.completions.create(
model=client.models.list().data[0].id,
messages=[{"role": "user", "content": "What's the weather and time in San Francisco?"}],
tools=tools,
tool_choice={"type": "function", "function": {"name": "get_weather"}}, # Force specific function
temperature=0.0,
)
tool_call = response.choices[0].message.tool_calls[0].function
print(f"Function called: {tool_call.name}")
print(f"Arguments: {tool_call.arguments}")
assert tool_call.name == "get_weather", f"Expected 'get_weather' but got '{tool_call.name}'"
print(f"Result: {get_weather(**json.loads(tool_call.arguments))}")