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