Skip to main content
Version: Next

Function Calling with ASI-1 Mini

Function calling in ASI1 allows models to go beyond text generation by invoking external functions with the right parameters. This enables integration with APIs, tools, or your own code to retrieve live data, perform tasks, or trigger actions based on user input.

Overview

Function calling enables you to integrate your custom code with the Chat Completion API in ASI1. When given access to defined tools, the model can choose to call them based on the conversation context. After the function is called, you execute the corresponding code, return the results, and the model incorporates the output into its final reply. This guide provides instructions for connecting ASI1 models to your custom functions to retrieve data or perform specific actions.

Here's a basic example of how function calling works with ASI1:

import requests
import json

# ASI1 API settings
API_KEY = "your_api_key"
BASE_URL = "https://api.asi1.ai/v1"

headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}

# Define the get_weather tool
get_weather_tool = {
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current temperature for a given location (latitude and longitude).",
"parameters": {
"type": "object",
"properties": {
"latitude": {"type": "number"},
"longitude": {"type": "number"}
},
"required": ["latitude", "longitude"]
}
}
}

# Initial message setup
initial_message = [
{
"role": "system",
"content": "You are a weather assistant. When a user asks for the weather in a location, use the get_weather tool with the appropriate latitude and longitude for that location."
},
{
"role": "user",
"content": "What's the current weather like in New York right now?"
}
]

# First call to model
payload = {
"model": "asi1-mini",
"messages": [initial_message],
"tools": [get_weather_tool],
"temperature": 0.7,
"max_tokens": 1024
}

response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)

Example Response

When you make a function call request, the model will respond with a structured output that includes the function call details. Here's an example response:

{
"id": "id_t0m4Pzm0KDbMg0WaX",
"model": "asi1-mini",
"executable_data": [],
"conversation_id": null,
"thought": [],
"choices": [
{
"index": 0,
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"content": "",
"reasoning": null,
"tool_calls": [
{
"id": "call_WzB5g",
"index": 0,
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"latitude\":40.7128,\"longitude\":-74.006}"
}
}
]
}
}
],
"usage": {
"prompt_tokens": 36,
"completion_tokens": 8,
"total_tokens": 44
}
}

Sample function

Let's look at the steps to allow a model to use a real get_weather function defined below:

Sample get_weather function implemented in your codebase

import requests

def get_weather(latitude, longitude):
response = requests.get(f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m")
data = response.json()
return data['current']['temperature_2m']
async function getWeather(latitude, longitude) {
const response = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m`);
const data = await response.json();
return data.current.temperature_2m;
}

Complete Tool Execution Cycle

Let's walk through the complete cycle of executing a function call with ASI1, using the weather example:

Step 1: Initial Request with Tools

First, we make a request to the model with the function definition and user message:

# Define the get_weather tool
get_weather_tool = {
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current temperature for a given location (latitude and longitude).",
"parameters": {
"type": "object",
"properties": {
"latitude": {"type": "number"},
"longitude": {"type": "number"}
},
"required": ["latitude", "longitude"]
}
}
}

# User's question
initial_message = {
"role": "user",
"content": "What's the current weather like in London right now?"
}

# First call to model
payload = {
"model": "asi1-mini",
"messages": [initial_message],
"tools": [get_weather_tool],
"temperature": 0.7,
"max_tokens": 1024
}

first_response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload
)
Step 2: Parse Tool Calls from Response

The model responds with a function call that we need to parse:

first_response.raise_for_status()
first_response_json = first_response.json()

tool_calls = first_response_json["choices"][0]["message"].get("tool_calls", [])
messages_history = [
initial_message,
first_response_json["choices"][0]["message"]
]
Step 3: Execute Tools and Format Results

Next, we execute the function and format the results:

# Simulate execution of get_weather tool
def get_weather(lat, lon):
response = requests.get(
f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}&current=temperature_2m,wind_speed_10m"
)
data = response.json()
return data['current']['temperature_2m']

# Process tool call
for tool_call in tool_calls:
function_name = tool_call["function"]["name"]
arguments = json.loads(tool_call["function"]["arguments"])

if function_name == "get_weather":
latitude = arguments["latitude"]
longitude = arguments["longitude"]
temperature = get_weather(latitude, longitude)
result = {
"temperature_celsius": temperature,
"location": f"lat: {latitude}, lon: {longitude}"
}
else:
result = {"error": f"Unknown tool: {function_name}"}

# Tool result message
tool_result_message = {
"role": "tool",
"tool_call_id": tool_call["id"],
"content": json.dumps(result)
}
messages_history.append(tool_result_message)
Step 4: Send Results Back to Model

Now we send the function results back to the model:

# Final call to model with tool results
final_payload = {
"model": "asi1-mini",
"messages": messages_history,
"temperature": 0.7,
"max_tokens": 1024
}

final_response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=final_payload
)
Step 5: Receive Final Answer

Finally, we get the model's response incorporating the function results:

final_response.raise_for_status()
final_response_json = final_response.json()

# Final result
print(final_response_json["choices"][0]["message"]["content"])

Tool Result Handling in ASI1

Here are key guidelines to ensure correct behavior and prevent common errors.


Preserving Tool Call IDs

Each tool call comes with a unique id that must be preserved when sending results back.

# Correct
tool_result_message = {
"role": "tool",
"tool_call_id": tool_call.id, # Use the exact ID from the tool call
"content": json.dumps(result)
}

# Incorrect - Don't make up IDs
tool_result_message = {
"role": "tool",
"tool_call_id": "my_custom_id", # This will cause an error
"content": json.dumps(result)
}
Message History Order

The message history must maintain this exact order:

  • Original user message
  • Assistant message with tool_calls (content should be null or empty)
  • Tool result messages (one for each tool_call, identified by tool_call_id)
Content Formatting

Tool results must be JSON-stringified within the content field.

# Correct
"content": json.dumps({"key": "value"})

# Incorrect - Don't send raw objects
"content": {"key": "value"} # This will cause an error
Error Handling

If a tool fails, send back a result message indicating the error.

try:
# Execute tool
result = execute_tool(function_name, arguments)
content_to_send = json.dumps(result)
except Exception as e:
# Send error as tool result content
error_content = {
"error": f"Tool execution failed: {str(e)}",
"status": "failed"
}
content_to_send = json.dumps(error_content)

tool_result_message = {
"role": "tool",
"tool_call_id": tool_call.id, # Still use the original tool_call.id
"content": content_to_send
}
messages_history.append(tool_result_message)

Function Definition

Functions are specified using the tools parameter in each API request, where each tool is described as a function object.

Each function is defined using a schema that tells the model what the function does and what input arguments it requires. The schema includes the following key fields:

  • name (string) : A unique, descriptive identifier for the function (e.g., get_weather_forecast, send_email). Use underscores or camelCase formatting. Avoid spaces or special characters.

  • description (string) : A detailed explanation of what the function does and when it should be used. Clear, specific descriptions improve the model's ability to use the function correctly.

  • parameters (object) : Defines the input parameters the function expects.

    • type (string) : Usually set to "object" to represent structured input.

    • properties (object) : Lists each input parameter and its details:

      • type (string): The data type (e.g., string, integer, boolean, array).
      • description (string): A clear explanation of the parameter's purpose and expected format.
        Example: "City and country, e.g., 'Paris, France'"
      • enum (optional): An array of allowed values, useful when inputs must be restricted.
        Example: "enum": ["celsius", "fahrenheit"]
    • required (array of strings) : Lists the parameter names that must be included when calling the function.

Example Function Schema
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Retrieves current weather for the given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country e.g. Bogotá, Colombia"
},
"units": {
"type": "string",
"enum": [
"celsius",
"fahrenheit"
],
"description": "Units the temperature will be returned in."
}
},
"required": [
"location",
"units"
],
"additionalProperties": false
},
"strict": true
}
}

Additional Configurations

ASI1 provides several options to control how and when tools are called, as well as how strictly the model adheres to your function schemas.

Tool Choice

By default, the model determines when and how many tools to use. You can control this behavior with the tool_choice parameter:

  • Auto (default): The model may call zero, one, or multiple functions.
    "tool_choice": "auto"
  • Required: The model must call at least one function.
    "tool_choice": "required"
  • Forced Function: Force the model to call a specific function.
    "tool_choice": {
    "type": "function",
    "function": { "name": "get_weather" }
    }
  • None: Prevent the model from calling any functions.
    "tool_choice": "none"

Parallel Function Calling

By default, the model may call multiple functions in a single turn. To restrict this and ensure only one (or zero) tool is called per turn, set:

"parallel_tool_calls": false

Note: If parallel tool calls are enabled, strict mode may be disabled for those calls.

Strict Mode

Setting strict to true ensures the model strictly follows your function schema. This is recommended for most use cases.

Requirements for strict mode:

  1. additionalProperties must be set to false for each object in the parameters.
  2. All fields in properties must be listed in required.

Example with strict mode enabled:

{
"type": "function",
"function": {
"name": "get_weather",
"description": "Retrieves current weather for the given location.",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country e.g. Bogotá, Colombia"
},
"units": {
"type": ["string", "null"],
"enum": ["celsius", "fahrenheit"],
"description": "Units the temperature will be returned in."
}
},
"required": ["location", "units"],
"additionalProperties": false
}
}
}

Example with strict mode disabled:

{
"type": "function",
"function": {
"name": "get_weather",
"description": "Retrieves current weather for the given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country e.g. Bogotá, Colombia"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Units the temperature will be returned in."
}
},
"required": ["location"]
}
}
}

Tip: We recommend enabling strict mode for reliable function calling.