Skip to content

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

  1. Clear Descriptions: Write detailed function descriptions
  2. Specific Parameters: Use specific parameter types and constraints
  3. Required Fields: Mark essential parameters as required
  4. Validation: Implement proper parameter validation
  5. Error Handling: Provide meaningful error messages

Performance Optimization

  1. Efficient Functions: Keep function execution fast
  2. Caching: Cache function results when appropriate
  3. Async Operations: Use async functions for I/O operations
  4. Rate Limiting: Implement rate limiting for external APIs
  5. Timeout Handling: Set appropriate timeouts

Security Considerations

  1. Input Validation: Always validate function inputs
  2. Access Control: Implement proper authorization
  3. Sanitization: Sanitize inputs to prevent injection attacks
  4. Audit Logging: Log function calls for security monitoring
  5. 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

  1. Invalid JSON: Ensure function arguments are valid JSON
  2. Missing Parameters: Check all required parameters are provided
  3. Type Mismatches: Verify parameter types match the schema
  4. Function Not Found: Ensure function names match exactly
  5. Timeout Errors: Implement proper timeout handling

Debugging Tips

  1. Log Function Calls: Log all function calls and responses
  2. Validate Schemas: Use JSON schema validation
  3. Test Incrementally: Test functions individually first
  4. Monitor Performance: Track function execution times
  5. 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!

基于 DeepSeek AI 大模型技术