Skip to main content

Function Calling & Tools

Enable AI models to call external functions and APIs using the modern tools parameter.

Tool calling is the modern standard for function calling, with support for parallel tool execution and extensible tool types. ModelPilot uses the tools parameter internally for all providers.

Industry Standard

The tools parameter is the current standard across all major AI providers (OpenAI, Anthropic, etc.). The legacy functions parameter is deprecated by OpenAI and never supported by Anthropic.

Parallel Tool Execution

Multiple Tools at Once
Execute multiple tools in parallel for better performance
javascript
import ModelPilot from 'modelpilot';

const client = new ModelPilot({
  apiKey: process.env.MODELPILOT_API_KEY,
  routerId: process.env.MODELPILOT_ROUTER_ID,
});

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: 'get_news',
      description: 'Get latest news for a location',
      parameters: {
        type: 'object',
        properties: {
          location: { type: 'string' }
        },
        required: ['location']
      }
    }
  }
];

const completion = await client.chat.completions.create({
  messages: [{
    role: 'user',
    content: 'What\'s the weather and latest news in Boston?'
  }],
  tools: tools,
});

const message = completion.choices[0].message;

// Model may call multiple tools at once
if (message.tool_calls) {
  console.log(`Model called ${message.tool_calls.length} tools`);
  
  // Execute all tools in parallel
  const results = await Promise.all(
    message.tool_calls.map(async (toolCall) => {
      const args = JSON.parse(toolCall.function.arguments);
      
      if (toolCall.function.name === 'get_weather') {
        return await getWeather(args.location);
      } else if (toolCall.function.name === 'get_news') {
        return await getNews(args.location);
      }
    })
  );
}

Complete Tool Pattern

End-to-End Example
javascript
async function chatWithTools(userMessage) {
  const messages = [{ role: 'user', content: userMessage }];
  
  const tools = [
    {
      type: 'function',
      function: {
        name: 'search_database',
        description: 'Search product database',
        parameters: {
          type: 'object',
          properties: {
            query: { type: 'string' },
            limit: { type: 'number' }
          },
          required: ['query']
        }
      }
    }
  ];
  
  // Initial request
  let completion = await client.chat.completions.create({
    messages: messages,
    tools: tools,
  });
  
  let responseMessage = completion.choices[0].message;
  messages.push(responseMessage);
  
  // Handle tool calls
  while (responseMessage.tool_calls) {
    // Execute all tool calls
    const toolResults = await Promise.all(
      responseMessage.tool_calls.map(async (toolCall) => {
        const functionName = toolCall.function.name;
        const functionArgs = JSON.parse(toolCall.function.arguments);
        
        // Execute the function
        let result;
        if (functionName === 'search_database') {
          result = await searchDatabase(functionArgs);
        }
        
        return {
          role: 'tool',
          tool_call_id: toolCall.id,
          content: JSON.stringify(result),
        };
      })
    );
    
    // Add all tool results to messages
    messages.push(...toolResults);
    
    // Get next response
    completion = await client.chat.completions.create({
      messages: messages,
      tools: tools,
    });
    
    responseMessage = completion.choices[0].message;
    messages.push(responseMessage);
  }
  
  return responseMessage.content;
}

// Usage
const response = await chatWithTools('Find laptops under $1000');
console.log(response);

Tool Types

Function Tools
Currently the only supported tool type

The tools API is designed to be extensible. Currently, only type: "function" is supported, but future versions may support additional tool types.

javascript
const tools = [
  {
    type: 'function',  // Required
    function: {
      name: 'tool_name',
      description: 'What this tool does',
      parameters: {
        // JSON Schema
      }
    }
  }
];

Error Handling

Graceful Tool Failures
javascript
async function executeToolCallSafely(toolCall) {
  try {
    const functionName = toolCall.function.name;
    const functionArgs = JSON.parse(toolCall.function.arguments);
    
    // Execute function
    const result = await executeTool(functionName, functionArgs);
    
    return {
      role: 'tool',
      tool_call_id: toolCall.id,
      content: JSON.stringify({ success: true, data: result }),
    };
  } catch (error) {
    // Return error to model
    return {
      role: 'tool',
      tool_call_id: toolCall.id,
      content: JSON.stringify({
        success: false,
        error: error.message
      }),
    };
  }
}

Best Practices

  • Use parallel execution

    Execute independent tool calls concurrently with Promise.all

  • Include tool_call_id in responses

    Always include the tool_call_id when returning results

  • Return structured data

    Use JSON objects for tool results, not plain strings

  • Handle timeouts

    Set reasonable timeouts for long-running tools

  • Validate arguments

    Always validate and sanitize tool arguments

Next Steps