Function Calling Guide
Learn how to use DeepSeek's powerful function calling capabilities to create structured outputs and integrate with external tools and APIs.
Overview
Function calling allows DeepSeek models to generate structured outputs and interact with external tools by calling predefined functions. This enables:
- Structured Data Generation: Generate JSON outputs with specific schemas
- API Integration: Connect with external services and databases
- Tool Usage: Leverage external tools and calculations
- Workflow Automation: Create complex multi-step processes
- Dynamic Responses: Adapt responses based on real-time data
Basic Function Calling
Defining Functions
Functions are defined using JSON Schema format:
json
{
"name": "get_weather",
"description": "Get current weather information for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit to use"
}
},
"required": ["location"]
}
}
Making Function Calls
Python Example
python
import json
from deepseek import DeepSeek
client = DeepSeek(api_key="your-api-key")
# Define the function
functions = [
{
"name": "get_weather",
"description": "Get current weather information",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
]
# Make the request
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "What's the weather like in Tokyo?"}
],
functions=functions,
function_call="auto"
)
# Check if a function was called
if response.choices[0].message.function_call:
function_call = response.choices[0].message.function_call
print(f"Function: {function_call.name}")
print(f"Arguments: {function_call.arguments}")
JavaScript Example
javascript
import DeepSeek from 'deepseek-js';
const client = new DeepSeek({
apiKey: 'your-api-key'
});
const functions = [
{
name: 'get_weather',
description: 'Get current weather information',
parameters: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name'
},
unit: {
type: 'string',
enum: ['celsius', 'fahrenheit']
}
},
required: ['location']
}
}
];
const response = await client.chat.completions.create({
model: 'deepseek-chat',
messages: [
{ role: 'user', content: "What's the weather like in Tokyo?" }
],
functions: functions,
function_call: 'auto'
});
if (response.choices[0].message.function_call) {
const functionCall = response.choices[0].message.function_call;
console.log(`Function: ${functionCall.name}`);
console.log(`Arguments: ${functionCall.arguments}`);
}
Function Call Parameters
function_call Parameter
Controls how the model uses functions:
"auto"
: Model decides whether to call a function"none"
: Model will not call any functions{"name": "function_name"}
: Force call a specific function
python
# Auto mode - model decides
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "What's the weather?"}],
functions=functions,
function_call="auto"
)
# Force specific function
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "Tell me about the weather"}],
functions=functions,
function_call={"name": "get_weather"}
)
# Disable function calling
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "What's the weather?"}],
functions=functions,
function_call="none"
)
Advanced Function Calling
Multiple Functions
Define multiple functions for complex workflows:
python
functions = [
{
"name": "get_weather",
"description": "Get current weather information",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
},
{
"name": "get_news",
"description": "Get latest news for a topic",
"parameters": {
"type": "object",
"properties": {
"topic": {"type": "string"},
"limit": {"type": "integer", "minimum": 1, "maximum": 10}
},
"required": ["topic"]
}
},
{
"name": "calculate",
"description": "Perform mathematical calculations",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string"},
"precision": {"type": "integer", "minimum": 1, "maximum": 10}
},
"required": ["expression"]
}
}
]
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "What's the weather in Paris and calculate 15 * 23?"}
],
functions=functions,
function_call="auto"
)
Function Chaining
Execute multiple function calls in sequence:
python
def execute_function_call(function_call):
"""Execute the actual function call"""
function_name = function_call.name
arguments = json.loads(function_call.arguments)
if function_name == "get_weather":
# Call your weather API
return get_weather_api(arguments["location"], arguments.get("unit", "celsius"))
elif function_name == "calculate":
# Perform calculation
return eval(arguments["expression"]) # Note: Use safe evaluation in production
# Add more function implementations
def chat_with_functions(user_message, functions):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
functions=functions,
function_call="auto"
)
message = response.choices[0].message
if message.function_call:
# Execute the function
function_result = execute_function_call(message.function_call)
# Add function call and result to conversation
messages.append({
"role": "assistant",
"content": None,
"function_call": {
"name": message.function_call.name,
"arguments": message.function_call.arguments
}
})
messages.append({
"role": "function",
"name": message.function_call.name,
"content": str(function_result)
})
else:
# No function call, return the response
return message.content
# Usage
result = chat_with_functions(
"What's the weather in London and what's 25 + 17?",
functions
)
print(result)
Real-World Examples
Database Query Function
python
database_functions = [
{
"name": "query_database",
"description": "Query the customer database",
"parameters": {
"type": "object",
"properties": {
"table": {
"type": "string",
"enum": ["customers", "orders", "products"]
},
"filters": {
"type": "object",
"properties": {
"customer_id": {"type": "string"},
"status": {"type": "string"},
"date_range": {
"type": "object",
"properties": {
"start": {"type": "string"},
"end": {"type": "string"}
}
}
}
},
"limit": {"type": "integer", "minimum": 1, "maximum": 100}
},
"required": ["table"]
}
}
]
def query_database(table, filters=None, limit=10):
# Implement your database query logic
# This is a simplified example
if table == "customers":
return [{"id": "1", "name": "John Doe", "email": "john@example.com"}]
elif table == "orders":
return [{"id": "101", "customer_id": "1", "total": 99.99}]
# Add more table handling
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "Show me the last 5 customer orders"}
],
functions=database_functions,
function_call="auto"
)
Email Sending Function
python
email_functions = [
{
"name": "send_email",
"description": "Send an email to specified recipients",
"parameters": {
"type": "object",
"properties": {
"to": {
"type": "array",
"items": {"type": "string"},
"description": "Email addresses of recipients"
},
"subject": {"type": "string"},
"body": {"type": "string"},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"],
"default": "normal"
}
},
"required": ["to", "subject", "body"]
}
}
]
def send_email(to, subject, body, priority="normal"):
# Implement your email sending logic
print(f"Sending email to {to}")
print(f"Subject: {subject}")
print(f"Body: {body}")
print(f"Priority: {priority}")
return {"status": "sent", "message_id": "msg_123"}
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "Send a follow-up email to john@example.com about our meeting tomorrow"}
],
functions=email_functions,
function_call="auto"
)
File Operations Function
python
file_functions = [
{
"name": "file_operations",
"description": "Perform file operations",
"parameters": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["read", "write", "list", "delete"]
},
"path": {"type": "string"},
"content": {"type": "string"},
"encoding": {
"type": "string",
"default": "utf-8"
}
},
"required": ["operation", "path"]
}
}
]
def file_operations(operation, path, content=None, encoding="utf-8"):
import os
if operation == "read":
with open(path, 'r', encoding=encoding) as f:
return f.read()
elif operation == "write":
with open(path, 'w', encoding=encoding) as f:
f.write(content)
return f"File written to {path}"
elif operation == "list":
return os.listdir(path)
elif operation == "delete":
os.remove(path)
return f"File {path} deleted"
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "Read the contents of config.json file"}
],
functions=file_functions,
function_call="auto"
)
Error Handling
Function Call Validation
python
def validate_and_execute_function(function_call):
try:
function_name = function_call.name
arguments = json.loads(function_call.arguments)
# Validate function exists
if function_name not in available_functions:
return {"error": f"Function {function_name} not found"}
# Validate required parameters
function_def = get_function_definition(function_name)
required_params = function_def.get("parameters", {}).get("required", [])
for param in required_params:
if param not in arguments:
return {"error": f"Missing required parameter: {param}"}
# Execute function
result = available_functions[function_name](**arguments)
return {"success": True, "result": result}
except json.JSONDecodeError:
return {"error": "Invalid JSON in function arguments"}
except Exception as e:
return {"error": f"Function execution error: {str(e)}"}
# Usage in conversation loop
if message.function_call:
result = validate_and_execute_function(message.function_call)
if "error" in result:
# Handle error
messages.append({
"role": "function",
"name": message.function_call.name,
"content": json.dumps(result)
})
else:
# Handle success
messages.append({
"role": "function",
"name": message.function_call.name,
"content": json.dumps(result["result"])
})
Best Practices
Function Design
- Clear Descriptions: Write detailed function descriptions
- Specific Parameters: Use specific parameter types and constraints
- Required Fields: Mark essential parameters as required
- Validation: Implement proper parameter validation
- Error Handling: Provide meaningful error messages
Performance Optimization
- Efficient Functions: Keep function execution fast
- Caching: Cache function results when appropriate
- Async Operations: Use async functions for I/O operations
- Rate Limiting: Implement rate limiting for external APIs
- Timeout Handling: Set appropriate timeouts
Security Considerations
- Input Validation: Always validate function inputs
- Access Control: Implement proper authorization
- Sanitization: Sanitize inputs to prevent injection attacks
- Audit Logging: Log function calls for security monitoring
- Resource Limits: Limit resource usage and execution time
Streaming with Function Calls
Function calls work with streaming responses:
python
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
functions=functions,
function_call="auto",
stream=True
)
function_call_data = {"name": "", "arguments": ""}
for chunk in response:
delta = chunk.choices[0].delta
if delta.function_call:
if delta.function_call.name:
function_call_data["name"] += delta.function_call.name
if delta.function_call.arguments:
function_call_data["arguments"] += delta.function_call.arguments
if chunk.choices[0].finish_reason == "function_call":
# Function call is complete
print(f"Function: {function_call_data['name']}")
print(f"Arguments: {function_call_data['arguments']}")
Testing Function Calls
Unit Testing
python
import unittest
from unittest.mock import patch
class TestFunctionCalls(unittest.TestCase):
def test_weather_function_call(self):
with patch('deepseek.DeepSeek') as mock_client:
# Mock the response
mock_response = {
"choices": [{
"message": {
"function_call": {
"name": "get_weather",
"arguments": '{"location": "Tokyo", "unit": "celsius"}'
}
}
}]
}
mock_client.return_value.chat.completions.create.return_value = mock_response
# Test function call
result = make_weather_request("What's the weather in Tokyo?")
self.assertEqual(result["function_name"], "get_weather")
self.assertEqual(result["location"], "Tokyo")
def test_function_validation(self):
# Test parameter validation
result = validate_function_call("get_weather", {})
self.assertIn("error", result)
self.assertIn("location", result["error"])
if __name__ == "__main__":
unittest.main()
Troubleshooting
Common Issues
- Invalid JSON: Ensure function arguments are valid JSON
- Missing Parameters: Check all required parameters are provided
- Type Mismatches: Verify parameter types match the schema
- Function Not Found: Ensure function names match exactly
- Timeout Errors: Implement proper timeout handling
Debugging Tips
- Log Function Calls: Log all function calls and responses
- Validate Schemas: Use JSON schema validation
- Test Incrementally: Test functions individually first
- Monitor Performance: Track function execution times
- Error Tracking: Implement comprehensive error tracking
Next Steps
- Explore API Reference for detailed parameter documentation
- Check out Use Cases for more function calling examples
- Visit SDKs for language-specific implementations
- Join our Community for support and discussions
Function calling opens up endless possibilities for creating intelligent, interactive applications. Start building today and transform how your applications interact with data and external services!