Skip to main content

Tool Calling

Tool Calling (Function Calling / Tool Use) allows large models to invoke custom functions, extending model capabilities for scenarios like information retrieval, database operations, and external API calls.

How It Works

The CloudBase AI SDK automatically handles the above workflow — developers only need to define and register tools.

Prerequisites

Before using tool calling, initialize the CloudBase AI instance:

const cloudbase = require("@cloudbase/node-sdk");

const app = cloudbase.init({
env: "<ENV_ID>"
});

const ai = app.ai();

Steps

1. Define a Tool

const getWeatherTool = {
name: "get_weather",
description: "Query weather information for a specified city",
fn: async ({ city }) => {
// In practice, call a weather API
return `${city}: 26°C, Sunny`;
},
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "City name"
}
},
required: ["city"]
}
};

2. Register the Tool

ai.registerFunctionTool(getWeatherTool);

3. Call the Model

const model = ai.createModel("cloudbase");

const result = await model.generateText({
model: "deepseek-v4-flash",
tools: [getWeatherTool],
messages: [{ role: "user", content: "What's the weather in Beijing?" }]
});

console.log(result.text);
// Output: Beijing is 26°C today, sunny, great for outdoor activities.

Tool Definition

FunctionTool Type

interface FunctionTool {
name: string; // Tool name, unique identifier
description: string; // Tool description, helps model understand purpose
fn: Function; // Execution function
parameters: object; // Parameter definition (JSON Schema format)
}

Parameter Definition (JSON Schema)

{
type: "object",
properties: {
// String parameter
city: {
type: "string",
description: "City name"
},
// Number parameter
limit: {
type: "number",
description: "Number of results to return"
},
// Boolean parameter
detailed: {
type: "boolean",
description: "Whether to return detailed information"
},
// Enum parameter
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "Temperature unit"
}
},
required: ["city"] // Required parameters
}

Multiple Tools Example

// Weather query tool
const getWeatherTool = {
name: "get_weather",
description: "Query city weather",
fn: async ({ city }) => `${city}: 26°C, Sunny`,
parameters: {
type: "object",
properties: {
city: { type: "string", description: "City name" }
},
required: ["city"]
}
};

// Time query tool
const getTimeTool = {
name: "get_time",
description: "Query current time for a specified city",
fn: async ({ city }) => {
const now = new Date();
return `Current time in ${city}: ${now.toLocaleTimeString()}`;
},
parameters: {
type: "object",
properties: {
city: { type: "string", description: "City name" }
},
required: ["city"]
}
};

// Register multiple tools
ai.registerFunctionTool(getWeatherTool);
ai.registerFunctionTool(getTimeTool);

// Pass all tools when calling
const result = await model.generateText({
model: "deepseek-v4-flash",
tools: [getWeatherTool, getTimeTool],
messages: [{ role: "user", content: "What time is it in Beijing? How's the weather?" }]
});

Advanced Configuration

toolChoice

Control how the model selects tools:

const result = await model.generateText({
model: "deepseek-v4-flash",
tools: [getWeatherTool],
toolChoice: "auto", // Model decides whether to use tools
messages: [{ role: "user", content: "What's the weather in Beijing?" }]
});
ValueDescription
"auto"Model decides automatically (default)
"none"Disable tool usage
"custom"Force use of a specific tool

maxSteps

Limit the maximum number of tool calls:

const result = await model.generateText({
model: "deepseek-v4-flash",
tools: [getWeatherTool],
maxSteps: 3, // Maximum 3 tool calls
messages: [{ role: "user", content: "Compare the weather in Beijing and Shanghai" }]
});

onStepFinish

Listen for each tool call completion:

const result = await model.generateText({
model: "deepseek-v4-flash",
tools: [getWeatherTool],
onStepFinish: ({ toolCall, toolResult, text }) => {
if (toolCall) {
console.log("Tool called:", toolCall.function.name);
console.log("Tool result:", toolResult);
}
if (text) {
console.log("Generated text:", text);
}
},
messages: [{ role: "user", content: "What's the weather in Beijing?" }]
});

Streaming

Tool calling also supports streaming output:

const result = await model.streamText({
model: "deepseek-v4-flash",
tools: [getWeatherTool],
messages: [{ role: "user", content: "What's the weather in Beijing?" }]
});

for await (const text of result.textStream) {
console.log(text);
}

Practical Examples

Database Query

const queryDatabaseTool = {
name: "query_database",
description: "Query user information from the database",
fn: async ({ userId }) => {
const db = app.database();
const result = await db.collection("users").doc(userId).get();
return JSON.stringify(result.data);
},
parameters: {
type: "object",
properties: {
userId: { type: "string", description: "User ID" }
},
required: ["userId"]
}
};

External API Call

const searchWebTool = {
name: "search_web",
description: "Search the web for latest information",
fn: async ({ query }) => {
const response = await fetch(`https://api.example.com/search?q=${query}`);
const data = await response.json();
return JSON.stringify(data.results.slice(0, 3));
},
parameters: {
type: "object",
properties: {
query: { type: "string", description: "Search keywords" }
},
required: ["query"]
}
};

Calculator

const calculatorTool = {
name: "calculator",
description: "Perform mathematical calculations",
fn: ({ expression }) => {
try {
// Note: In production, use a safe expression parsing library
return String(eval(expression));
} catch {
return "Calculation error";
}
},
parameters: {
type: "object",
properties: {
expression: { type: "string", description: "Math expression, e.g. 2+2*3" }
},
required: ["expression"]
}
};

Type Definitions

IOnStepFinish

interface IOnStepFinish {
messages: ChatModelMessage[]; // Current message list
text?: string; // Generated text
toolCall?: ToolCall; // Tool call information
toolResult?: unknown; // Tool execution result
finishReason?: string; // Finish reason
stepUsage?: Usage; // Current step token usage
totalUsage?: Usage; // Cumulative token usage
}

ToolCall

interface ToolCall {
id: string;
type: string;
function: {
name: string;
arguments: string; // JSON string
};
}

Best Practices

  1. Clear tool descriptions - Help the model accurately understand tool purpose
  2. Complete parameter specs - Include type, description, and required status
  3. Error handling - Tool functions should handle exceptions
  4. Limit call count - Use maxSteps to prevent infinite loops
  5. Async functions - Tool functions can be asynchronous