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.
Online Example
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?" }]
});
| Value | Description |
|---|---|
"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
- Clear tool descriptions - Help the model accurately understand tool purpose
- Complete parameter specs - Include type, description, and required status
- Error handling - Tool functions should handle exceptions
- Limit call count - Use
maxStepsto prevent infinite loops - Async functions - Tool functions can be asynchronous