Function Calling

Build AI agents that can use tools and take actions

Overview

Function calling (also called tool use) allows AI models to call functions you define, enabling agents that can query databases, call APIs, execute code, and take real-world actions.

Authentication: API Key or OAuth token
Required Scopes (OAuth): ai:chat

Capabilities

  • External APIs - Weather, search, databases, third-party services
  • Code Execution - Run calculations and data processing
  • Actions - Send emails, create tasks, update records
  • Real-time Data - Access current information beyond training cutoff
  • Multi-step Agents - Chain multiple tool calls for complex workflows

Supported Models

ModelQuality
anthropic/claude-3.5-sonnetExcellent
anthropic/claude-3-opusExcellent
openai/gpt-4oExcellent
openai/gpt-4o-miniGood
google/gemini-proGood

Define and Call Functions

Create a chat completion with available tools.

Endpoint: POST /api/v1/chat/completions

import OpenAI from 'openai'
 
const client = new OpenAI({
  apiKey: process.env.GATEWAY_API_KEY,
  baseURL: 'https://hypery.ai/api/v1'
})
 
// Step 1: Define tools
const tools = [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Get current weather for a city',
      parameters: {
        type: 'object',
        properties: {
          location: {
            type: 'string',
            description: 'City name (e.g., "Paris, FR")'
          },
          unit: {
            type: 'string',
            enum: ['celsius', 'fahrenheit']
          }
        },
        required: ['location']
      }
    }
  }
]
 
// Step 2: Ask the model
const response = await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [
    { role: 'user', content: 'What is the weather in Paris?' }
  ],
  tools
})
 
// Step 3: Check for tool calls
const toolCall = response.choices[0].message.tool_calls?.[0]
 
if (toolCall) {
  const args = JSON.parse(toolCall.function.arguments)
  console.log('Calling:', toolCall.function.name, args)
  
  // Step 4: Execute your function
  const weather = await getWeather(args.location)
  
  // Step 5: Send result back
  const final = await client.chat.completions.create({
    model: 'anthropic/claude-3.5-sonnet',
    messages: [
      { role: 'user', content: 'What is the weather in Paris?' },
      response.choices[0].message,
      {
        role: 'tool',
        tool_call_id: toolCall.id,
        content: JSON.stringify(weather)
      }
    ],
    tools
  })
  
  console.log(final.choices[0].message.content)
}

Input Parameters

ParameterTypeRequiredDescription
modelstringYesModel ID supporting function calling
messagesarrayYesConversation messages
toolsarrayYesAvailable functions
tool_choicestring | objectNoControl tool selection (default: auto)

Tool Definition

Each tool must include:

FieldTypeRequiredDescription
typestringYesAlways function
function.namestringYesFunction identifier
function.descriptionstringYesWhat the function does
function.parametersobjectYesJSON Schema for parameters

Response when function is called:

{
  "id": "chatcmpl-123",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"location\":\"Paris\",\"unit\":\"celsius\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

Output Fields

FieldTypeDescription
tool_callsarrayFunctions the model wants to call
tool_calls[].idstringUnique tool call ID (use in response)
tool_calls[].typestringAlways function
tool_calls[].function.namestringFunction to call
tool_calls[].function.argumentsstringJSON arguments for function
finish_reasonstringtool_calls when function requested

Tool Choice

Control whether and how the model uses tools.

// Auto (default) - Model decides
await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [{ role: 'user', content: 'Hello' }],
  tools,
  tool_choice: 'auto'
})
 
// Required - Must call a tool
await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [{ role: 'user', content: 'Get weather' }],
  tools,
  tool_choice: 'required'
})
 
// None - Never call tools
await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [{ role: 'user', content: 'Just chat' }],
  tools,
  tool_choice: 'none'
})
 
// Specific function
await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [{ role: 'user', content: 'Search' }],
  tools,
  tool_choice: {
    type: 'function',
    function: { name: 'search_web' }
  }
})

Tool Choice Options

ValueBehavior
autoModel decides whether to call tools (default)
requiredModel must call at least one tool
noneModel will not call any tools
{type: "function", function: {name: "..."}}Force specific function call

Multiple Tools

Define multiple tools and let the model choose:

const tools = [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Get weather for a location',
      parameters: {
        type: 'object',
        properties: {
          location: { type: 'string' }
        },
        required: ['location']
      }
    }
  },
  {
    type: 'function',
    function: {
      name: 'search_web',
      description: 'Search the web',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string' }
        },
        required: ['query']
      }
    }
  },
  {
    type: 'function',
    function: {
      name: 'calculate',
      description: 'Perform math calculations',
      parameters: {
        type: 'object',
        properties: {
          expression: { type: 'string' }
        },
        required: ['expression']
      }
    }
  }
]
 
const response = await client.chat.completions.create({
  model: 'anthropic/claude-3.5-sonnet',
  messages: [
    { role: 'user', content: 'What is the weather in Tokyo and 42 * 17?' }
  ],
  tools
})
 
// Model may call multiple tools
for (const toolCall of response.choices[0].message.tool_calls || []) {
  console.log(`Calling: ${toolCall.function.name}`)
}

Agent Loop

Build autonomous agents that call multiple tools:

async function runAgent(userMessage) {
  const messages = [{ role: 'user', content: userMessage }]
  const maxIterations = 10
  
  for (let i = 0; i < maxIterations; i++) {
    const response = await client.chat.completions.create({
      model: 'anthropic/claude-3.5-sonnet',
      messages,
      tools
    })
    
    const message = response.choices[0].message
    messages.push(message)
    
    // Check if model called tools
    if (message.tool_calls?.length > 0) {
      // Execute all tool calls
      for (const toolCall of message.tool_calls) {
        const args = JSON.parse(toolCall.function.arguments)
        const result = await executeFunction(toolCall.function.name, args)
        
        messages.push({
          role: 'tool',
          tool_call_id: toolCall.id,
          content: JSON.stringify(result)
        })
      }
    } else {
      // No more tools, return final answer
      return message.content
    }
  }
  
  throw new Error('Max iterations reached')
}
 
async function executeFunction(name, args) {
  switch (name) {
    case 'get_weather':
      return await getWeather(args.location)
    case 'search_web':
      return await searchWeb(args.query)
    case 'calculate':
      return { result: eval(args.expression) }
    default:
      throw new Error(`Unknown function: ${name}`)
  }
}
 
// Use it
const answer = await runAgent('What is the weather in Paris and Rome?')
console.log(answer)

Parameter Schema

Define parameters using JSON Schema:

{
  type: 'object',
  properties: {
    location: {
      type: 'string',
      description: 'City name and country (e.g., "Paris, FR")'
    },
    unit: {
      type: 'string',
      enum: ['celsius', 'fahrenheit', 'kelvin'],
      description: 'Temperature unit'
    },
    include_forecast: {
      type: 'boolean',
      description: 'Include 5-day forecast'
    }
  },
  required: ['location']  // Required parameters
}

Supported Types

TypeExampleDescription
string"Paris"Text values
number42Numeric values (int or float)
booleantrueTrue or false
array["a", "b"]Lists of values
object{key: "value"}Nested objects

Best Practices

Write Clear Descriptions

// ❌ Bad
{
  name: 'get_data',
  description: 'Gets data'
}
 
// ✅ Good
{
  name: 'get_weather',
  description: 'Get current weather conditions including temperature, humidity, wind speed, and forecast for a specific city'
}

Use Enums for Limited Options

{
  unit: {
    type: 'string',
    enum: ['celsius', 'fahrenheit', 'kelvin'],
    description: 'Temperature unit'
  }
}

Validate Arguments

const toolCall = response.choices[0].message.tool_calls?.[0]
if (toolCall) {
  try {
    const args = JSON.parse(toolCall.function.arguments)
    
    // Validate types and required fields
    if (!args.location || typeof args.location !== 'string') {
      throw new Error('Invalid location parameter')
    }
    
    const result = await getWeather(args.location)
  } catch (error) {
    console.error('Function call error:', error)
  }
}

Provide Examples in Descriptions

{
  location: {
    type: 'string',
    description: 'City and country code (e.g., "London, UK" or "Tokyo, JP")'
  }
}

Common Use Cases

Database Query

{
  type: 'function',
  function: {
    name: 'query_customers',
    description: 'Search customer database by email or name',
    parameters: {
      type: 'object',
      properties: {
        email: { type: 'string', description: 'Customer email' },
        name: { type: 'string', description: 'Customer name' }
      }
    }
  }
}

API Integration

{
  type: 'function',
  function: {
    name: 'create_ticket',
    description: 'Create a support ticket',
    parameters: {
      type: 'object',
      properties: {
        title: { type: 'string' },
        priority: {
          type: 'string',
          enum: ['low', 'medium', 'high', 'urgent']
        }
      },
      required: ['title']
    }
  }
}

File Operations

{
  type: 'function',
  function: {
    name: 'read_file',
    description: 'Read file contents from workspace',
    parameters: {
      type: 'object',
      properties: {
        path: {
          type: 'string',
          description: 'File path relative to workspace root'
        }
      },
      required: ['path']
    }
  }
}

Next Steps