Function calling (also called "tool use") is the most powerful feature in modern AI APIs. It lets your application delegate real-world actions to AI models: querying databases, calling APIs, performing calculations, and interacting with external services. This guide covers function calling with Chinese AI models through TokenEase's unified API.
What is Function Calling?
Function calling allows an AI model to decide when to invoke a predefined function based on the conversation context. Instead of just generating text, the model outputs structured JSON that your application can parse and execute.
Which Chinese Models Support Function Calling?
| Model | Function Calling | Parallel Tools | Notes |
|---|---|---|---|
| deepseek DeepSeek-V4 | Yes | Yes | Excellent reasoning, complex multi-step tool chains |
| zhipu GLM-5.1 | Yes | Yes | Strong Chinese function understanding |
| qwen Qwen-Plus | Yes | Yes | Alibaba's tool-use optimized variant |
| kimi Kimi-K3 | Yes | Yes | Long-context tool chains (200K tokens) |
| doubao Doubao-Pro | Yes | Limited | ByteDance's enterprise tool use |
Setting Up Your First Function Call
All Chinese models on TokenEase use the OpenAI-compatible tools parameter. Here's a complete working example:
Step 1: Define Your Tools
import requests
API_KEY = "your-tokenease-api-key"
BASE_URL = "https://tokenease.io/v1"
# Define available functions
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name in English or Chinese"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_product",
"description": "Search product catalog by keyword",
"parameters": {
"type": "object",
"properties": {
"keyword": {
"type": "string",
"description": "Product search term"
},
"max_results": {
"type": "integer",
"description": "Maximum results to return",
"default": 5
}
},
"required": ["keyword"]
}
}
}
]
Step 2: Send Request with Tools
messages = [
{"role": "system", "content": "You are a helpful assistant. Use tools when needed."},
{"role": "user", "content": "北京今天天气怎么样?顺便帮我找一下蓝牙耳机。"}
]
response = requests.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={
"model": "deepseek",
"messages": messages,
"tools": tools,
"tool_choice": "auto"
}
)
result = response.json()
message = result["choices"][0]["message"]
Step 3: Handle Tool Calls
# Check if model wants to call functions
if message.get("tool_calls"):
for tool_call in message["tool_calls"]:
function_name = tool_call["function"]["name"]
arguments = json.loads(tool_call["function"]["arguments"])
print(f"Model wants to call: {function_name}")
print(f"With arguments: {arguments}")
# Execute the actual function
if function_name == "get_weather":
result = get_weather_api(**arguments)
elif function_name == "search_product":
result = search_product_db(**arguments)
# Add tool result to conversation
messages.append({
"role": "tool",
"tool_call_id": tool_call["id"],
"content": str(result)
})
# Send follow-up to get final answer
final_response = requests.post(
f"{BASE_URL}/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "deepseek",
"messages": messages,
"tools": tools
}
)
print(final_response.json()["choices"][0]["message"]["content"])
Advanced Patterns
1. Forcing Tool Use
Sometimes you want the model to always use a specific tool:
# Force a specific tool
json={
"model": "deepseek",
"messages": messages,
"tools": tools,
"tool_choice": {"type": "function", "function": {"name": "get_weather"}}
}
# Or force ANY tool (model must pick one)
json={
"model": "deepseek",
"messages": messages,
"tools": tools,
"tool_choice": "required"
}
2. Parallel Tool Calls
Modern models can call multiple tools at once. DeepSeek-V4 and Kimi-K3 excel at this:
# The model might return multiple tool_calls in one response
# Handle them concurrently for better performance
import concurrent.futures
def execute_tool(tool_call):
name = tool_call["function"]["name"]
args = json.loads(tool_call["function"]["arguments"])
return {"id": tool_call["id"], "result": TOOL_REGISTRY[name](**args)}
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(execute_tool, tc) for tc in message["tool_calls"]]
results = [f.result() for f in futures]
3. Multi-Turn Tool Chains
For complex workflows, models can chain multiple tool calls across turns:
# Example: "Find me the cheapest flight to Shanghai next week"
# Turn 1: search_flights(city="Shanghai", date="next_week")
# Turn 2: get_price_details(flight_id="CA1234")
# Turn 3: book_flight(flight_id="CA1234", passenger_info={...})
# Each turn adds tool results back to messages and re-calls the API
Real-World Use Cases
Tools: search_products, check_inventory, calculate_shipping, place_order
Models: qwen or zhipu for Chinese product understanding
Tools: run_sql_query, generate_chart, export_to_csv
Models: deepseek for complex reasoning and SQL accuracy
Tools: lookup_customer, check_ticket_status, create_refund, schedule_callback
Models: kimi for handling long conversation history
Tools: search_flights, search_hotels, check_visa_requirements, get_exchange_rate
Models: deepseek for multi-step itinerary planning
Best Practices
- Clear descriptions matter. The model decides which tool to use based on your
descriptionfield. Be specific: "Get weather by city name" beats "Weather function." - Use enums for constrained choices. If a parameter has limited valid values, always use
enuminstead of free-form strings. - Validate tool outputs. Always validate and sanitize the model's generated arguments before executing functions. Never trust raw JSON for database writes or API calls.
- Handle errors gracefully. If a tool fails, return the error message as the tool result content. The model can often recover and try a different approach.
- Keep tool schemas small. Each tool consumes tokens. For cost efficiency, only include tools relevant to the current conversation context.
- Name parameters descriptively. Use
destination_cityinstead ofparam1. The model reads parameter names, not just descriptions.
deepseek to zhipu to kimi without changing your tool definitions or handling code. One API, every model.
Error Handling Pattern
def safe_tool_executor(tool_call):
try:
name = tool_call["function"]["name"]
args = json.loads(tool_call["function"]["arguments"])
# Validate against schema
if name not in TOOL_REGISTRY:
raise ValueError(f"Unknown tool: {name}")
# Execute
result = TOOL_REGISTRY[name](**args)
return {"role": "tool", "tool_call_id": tool_call["id"], "content": json.dumps(result)}
except Exception as e:
# Return error so model can recover
return {
"role": "tool",
"tool_call_id": tool_call["id"],
"content": f"Error executing {name}: {str(e)}. Please try a different approach."
}
Performance Comparison
| Model | Tool Accuracy | Latency | Best For |
|---|---|---|---|
| DeepSeek-V4 | 97% | Fast | Complex multi-step chains |
| GLM-5.1 | 94% | Fast | Chinese-language tool interactions |
| Qwen-Plus | 95% | Very Fast | E-commerce, structured data |
| Kimi-K3 | 96% | Medium | Long-context tool sequences |
Conclusion
Function calling transforms AI models from text generators into action-taking agents. With TokenEase, you get unified access to all major Chinese models' tool-use capabilities through a single OpenAI-compatible API. Start with simple tools, handle errors gracefully, and scale to complex multi-turn agent workflows.
Start Building with Function Calling
Get $1 free API credit to test function calling with all 6 Chinese AI models.
Claim Free Credits