Guide

Function & Tool Calling

Give language models access to external databases, search APIs, and internal functions using standard OpenAI JSON Schema tool definitions.

Overview

InfinityRouter passes your tools definitions to capable models (such as Claude 3.5 Sonnet, GPT-4o, and DeepSeek-V3). When the model decides to invoke a tool, it returns a tool_calls array containing the function name and parsed JSON arguments.

1. Defining Tools

Tools are specified as an array of JSON Schema objects inside the tools parameter:

jsonTool Schema Definition
[
  {
    "type": "function",
    "function": {
      "name": "get_stock_quote",
      "description": "Fetch real-time ticker price and market cap for a stock symbol",
      "parameters": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "description": "Stock ticker symbol, e.g. NVDA, AAPL"
          },
          "currency": {
            "type": "string",
            "enum": ["USD", "EUR"],
            "default": "USD"
          }
        },
        "required": ["symbol"]
      }
    }
  }
]

2. Complete Multi-Turn Tool Execution Loop (Python)

Here is a complete, self-contained Python script showing the request, the tool call interception, executing the local function, and returning the result for final synthesis:

pythontool_agent.py
import json
import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ.get("INFINITY_BASE_URL", "https://infinityrouter.qd.je/v1"),
    api_key=os.environ.get("INFINITY_API_KEY"),
)

# 1. Define local Python tool
def get_stock_quote(symbol: str, currency: str = "USD") -> str:
    mock_prices = {"NVDA": 132.50, "AAPL": 224.10, "GOOGL": 178.90}
    price = mock_prices.get(symbol.upper(), 100.00)
    return json.dumps({"symbol": symbol.upper(), "price": price, "currency": currency})

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_quote",
            "description": "Fetch real-time ticker price for a stock symbol",
            "parameters": {
                "type": "object",
                "properties": {
                    "symbol": {"type": "string", "description": "Stock ticker symbol"},
                    "currency": {"type": "string", "enum": ["USD", "EUR"], "default": "USD"}
                },
                "required": ["symbol"]
            }
        }
    }
]

messages = [
    {"role": "user", "content": "What is the current stock price of NVDA and AAPL?"}
]

# 2. First call: Model determines tool calls
response = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=messages,
    tools=tools,
    tool_choice="auto",
)

assistant_message = response.choices[0].message
messages.append(assistant_message)

# 3. Process each tool call requested by the model
if assistant_message.tool_calls:
    for tool_call in assistant_message.tool_calls:
        fn_name = tool_call.function.name
        fn_args = json.loads(tool_call.function.arguments)
        
        if fn_name == "get_stock_quote":
            result = get_stock_quote(**fn_args)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result,
            })

    # 4. Final call: Model synthesizes tool output into natural response
    final_response = client.chat.completions.create(
        model="claude-sonnet-5",
        messages=messages,
    )
    print(final_response.choices[0].message.content)