Skip to main content
Let LLMs call your functions to interact with external systems, databases, and APIs.

Prerequisites

  • An Auriko API key
  • Python 3.10+ with auriko SDK installed (pip install auriko)
    • OR Node.js 18+ with @auriko/sdk installed (npm install @auriko/sdk)
  • A model that supports tool calling (e.g., GPT-4o, Claude 3.5 Sonnet)

Define tools

Define tools as JSON schemas describing the function signature:
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "The city name"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "Temperature unit"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

Call tools

Send a request with tools and check the response:
import os
from auriko import Client
import json

client = Client(
    api_key=os.environ["AURIKO_API_KEY"],
    base_url="https://api.auriko.ai/v1"
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Paris?"}],
    tools=tools
)

if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    print(f"Function: {tool_call.function.name}")
    print(f"Arguments: {json.loads(tool_call.function.arguments)}")

Execute tool calls

After receiving tool calls, execute them and send the results back:
import json

def get_weather(city: str) -> str:
    # Your actual implementation here
    return f"Weather in {city}: 72°F, sunny"

# Step 1: Initial request
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Paris?"}],
    tools=tools
)

# Step 2: Check for tool calls
message = response.choices[0].message
if message.tool_calls:
    # Build message history
    messages = [
        {"role": "user", "content": "What's the weather in Paris?"},
        message.model_dump(),  # Assistant message with tool_calls
    ]
    
    # Execute each tool call
    for tool_call in message.tool_calls:
        args = json.loads(tool_call.function.arguments)
        
        if tool_call.function.name == "get_weather":
            result = get_weather(args["city"])
        
        # Add tool result
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": result
        })
    
    # Step 3: Get final response
    final_response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=tools
    )
    
    print(final_response.choices[0].message.content)

Use multiple tools

Define multiple tools in the same request:
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_web",
            "description": "Search the web for information",
            "parameters": {
                "type": "object",
                "properties": {"query": {"type": "string"}},
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "send_email",
            "description": "Send an email",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string"},
                    "subject": {"type": "string"},
                    "body": {"type": "string"}
                },
                "required": ["to", "subject", "body"]
            }
        }
    }
]

Use parallel tool calls

Models can request multiple tool calls in parallel:
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{
        "role": "user",
        "content": "What's the weather in Paris and Tokyo?"
    }],
    tools=tools
)

# May return two tool calls
if response.choices[0].message.tool_calls:
    for tool_call in response.choices[0].message.tool_calls:
        print(f"{tool_call.function.name}: {tool_call.function.arguments}")

Control tool choice

Control which tools the model can use:
# Let model decide
response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto"  # default
)

# Force tool use
response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="required"
)

# Force specific tool
response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice={"type": "function", "function": {"name": "get_weather"}}
)

# Disable tools
response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="none"
)

Stream tool calls

Accumulate streamed tool call fragments:
stream = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Paris?"}],
    tools=tools,
    stream=True
)

tool_calls = {}
for chunk in stream:
    if not chunk.choices:
        continue
    delta = chunk.choices[0].delta
    
    if delta.tool_calls:
        for tc in delta.tool_calls:
            idx = tc.index
            if idx not in tool_calls:
                tool_calls[idx] = {"id": tc.id, "function": {"name": "", "arguments": ""}}
            if tc.function and tc.function.name:
                tool_calls[idx]["function"]["name"] += tc.function.name
            if tc.function and tc.function.arguments:
                tool_calls[idx]["function"]["arguments"] += tc.function.arguments

print(list(tool_calls.values()))
See Streaming Guide for full streaming patterns including error handling and metadata access.

Convert legacy functions

Auriko auto-converts the deprecated functions/function_call parameters to the modern tools/tool_choice format:
Legacy parameterConverted toCondition
functionstoolsOnly if tools is absent
function_call: "auto"tool_choice: "auto"Only if tool_choice is absent
function_call: "none"tool_choice: "none"Only if tool_choice is absent
function_call: {name: "fn"}tool_choice: {type: "function", function: {name: "fn"}}Only if tool_choice is absent
Conversion only runs when the legacy field is present and the modern field is absent. If both are present, the modern field takes precedence. Use tools/tool_choice for new code. Auriko supports the legacy format for backward compatibility.
Provider compatibility: Most major providers support function calling (tools / tool_choice), but subfeatures such as parallel_tool_calls vary by provider. Auriko filters out providers that don’t support tool calling at all, but doesn’t guarantee every provider-specific tool subfeature. Check /v1/directory/models for current capability details.

Best practices

Clear Descriptions

Write clear, specific function descriptions so the model knows when to use them.

Validate Arguments

Always validate tool call arguments before executing.

Error Handling

Return helpful error messages in tool results when execution fails.

Limit Tools

Only include relevant tools to reduce confusion and latency.