YouTip LogoYouTip

Ai Agent Function Calling

Function Calling (function calling) is the core mechanism that allows LLMs to use external tools. Function Calling enables the model to decide when to call a tool, which tool to call, and what parameters to pass. ### Why Do We Need Function Calling? Imagine an LLM as a smart but handless consultant. It knows a lot of knowledge, but cannot: * Get real-time information (such as current weather, stock prices) * Perform calculations (such as complex mathematical operations) * Operate external systems (such as sending emails, reading/writing files) Function Calling gives the LLM hands, allowing it to break through its own limitations and perform actual tasks. ### How Function Calling Works The basic process of Function Calling is as follows: !(#) ### Core Concepts * **Tool Definition**: Describes a tool's functionality, parameters, and return values * **Tool Selection**: The LLM chooses the appropriate tool based on the user's question * **Parameter Extraction**: The LLM extracts the parameters needed by the tool from the question * **Result Processing**: Integrates the tool execution results into the final response ### Example Explanation Suppose we have a weather query tool. When a user asks, "What's the weather like in Beijing today?", here's what happens: 1. The LLM identifies that it needs to call the weather query tool 2. Extracts parameters from the question: `city="Beijing"`, `date="Today"` 3. Calls the weather API to fetch data 4. Integrates the weather data into a friendly response and returns it to the user * * * ## Tool Definition and Description Writing To let the LLM correctly use tools, we first need to clearly define them. A good tool definition should be like a clear manual, helping the LLM understand: * What does this tool do? * When should it be used? * What parameters are needed? * What format should the parameters be in? ### Structure of Tool Definitions A complete tool definition usually includes the following parts: ## Example # Example Structure of Tool Definition weather_tool ={ "name": "get_weather",# Tool name "description": "Get weather information for a specified city",# Tool description "parameters": {# Parameter definitions "type": "object", "properties": { "city": { "type": "string", "description": "City name, e.g., 'Beijing', 'Shanghai'" }, "date": { "type": "string", "description": "Date, format 'YYYY-MM-DD', or 'today', 'tomorrow'", "enum": ["Today","Tomorrow","Day after tomorrow"] } }, "required": # Required parameters } } ### Writing High-Quality Tool Descriptions #### 1. Descriptions Should Be Clear and Specific * **Poor Description**: Query weather * **Good Description**: Retrieve weather information for a specific city on a particular date, including temperature, humidity, wind speed, and weather conditions (sunny, rainy, cloudy, etc.) #### 2. Parameter Descriptions Should Be Detailed **Poor Parameter Description**: "city": {"type": "string"} **Good Parameter Description:** "city": { "type": "string", "description": "Full city name, e.g., 'BeijingCity', 'ShanghaiCity'. Do not use abbreviations or pinyin."} #### 3. Use Enumerations to Limit Options For limited options, use enums (enumeration) to help the LLM understand: "unit": { "type": "string", "description": "Temperature unit", "enum": ["celsius", "fahrenheit"], "default": "celsius"} #### 4. Provide Example Values Provide examples in descriptions to help the LLM understand the format: "date": { "type": "string", "description": "Date, format should be 'YYYY-MM-DD', e.g., '2024-06-15'"} ### Practical Tool Definition Examples #### 1. Calculator Tool calculator_tool = { "name": "calculate", "description": "Perform mathematical calculations, supporting basic operations such as addition, subtraction, multiplication, division, and exponentiation", "parameters": { "type": "object", "properties": { "expression": { "type": "string", "description": "Mathematical expression, e.g., '2 + 3 * 4', 'sqrt(16)', 'sin(30)'" } }, "required": }} #### [](#)2. Search Tool search_tool = { "name": "search_web", "description": "Search for the latest information on the internet", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search keywords, preferably specific and clear" }, "num_results": { "type": "integer", "description": "Number of results to return, default is 5", "default": 5, "minimum": 1, "maximum": 10 } }, "required": }} #### 3. File Operation Tool file_tool = { "name": "read_file", "description": "Read the content of a specified file", "parameters": { "type": "object", "properties": { "file_path": { "type": "string", "description": "Complete file path, e.g., '/home/user/document.txt'" }, "encoding": { "type": "string", "description": "File encoding, default is 'utf-8'", "default": "utf-8" } }, "required": }} ### Best Practices for Tool Definitions * **Clear and Concise Names**: Start with verbs, e.g., `get_`, `calculate_`, `search_` * **Complete and Detailed Descriptions**: Explain the tool’s purpose, applicable scenarios, and limitations * **Thorough Parameter Validation**: Define parameter types, ranges, and format requirements * **Provide Default Values**: Offer reasonable defaults for optional parameters * **Consider Error Scenarios**: Describe possible errors and limitations in the description ### Validating Tool Definitions After defining a tool, validation testing should be performed: def validate_tool_definition(tool_def): """Validate whether the tool definition is complete""" required_fields = ["name", "description", "parameters"] for field in required_fields: if field not in tool_def: return False, f"Missing required field: {field}" # Check parameter structure if "properties" not in tool_def: return False, "Missing properties field in parameter definition" return True, "Tool definition is complete"# Test validation is_valid, message = validate_tool_definition(weather_tool)print(f"Validation result: {is_valid}, message: {message}") * * * ## Parameter Extraction and Validation After the LLM extracts parameters from the user's question, these parameters need to be validated and processed to ensure the tool can execute correctly. ### Parameter Extraction Process When the LLM decides to call a tool, it analyzes the user input and extracts the parameters required by the tool: User Input: "Query the weather temperature in Beijing tomorrow" Tool: get_weather Extracted Parameters: {"city": "Beijing", "date": "Tomorrow"} ### Challenges in Parameter Extraction Parameter extraction may encounter the following issues: * **Missing Information**: The user did not provide all necessary information * **Format Mismatch**: The provided format does not match the tool's requirements * **Ambiguous Interpretation**: The same information might have multiple interpretations * **Context Dependency**: Parameters require understanding from conversation history ### Methods for Parameter Validation #### 1. Type Validation Ensure parameter types meet the requirements: def validate_parameters(params, tool_def): """Validate parameter types""" errors = [] for param_name, param_def in tool_def.items(): if param_name in params: param_value = params expected_type = param_def.get("type") # Type check if expected_type == "string" and not isinstance(param_value, str): errors.append(f"Parameter '{param_name}' should be string type") elif expected_type == "integer" and not isinstance(param_value, int): errors.append(f"Parameter '{param_name}' should be integer type") elif expected_type == "number" and not isinstance(param_value, (int, float)): errors.append(f"Parameter '{param_name}' should be number type") elif expected_type == "boolean" and not isinstance(param_value, bool): errors.append(f"Parameter '{param_name}' should be boolean type") return errors #### 2. Range Validation Check if parameter values fall within allowed ranges: def validate_range(params, tool_def): """Validate parameter ranges""" errors = [] for param_name, param_def in tool_def.items(): if param_name in params: param_value = params # Check minimum value if "minimum" in param_def and param_value param_def: errors.append(f"Parameter '{param_name}' cannot be greater than {param_def['maximum']}") # Check enum values if "enum" in param_def and param_value not in param_def: errors.append(f"Parameter '{param_name}' must be one of {param_def['enum']}") return errors #### 3. Required Parameter Validation Ensure all required parameters are provided: def validate_required(params, tool_def): """Validate required parameters""" errors = [] required_params = tool_def.get("required", []) for param_name in required_params: if param_name not in params: errors.append(f"Missing required parameter: {param_name}") return errors ### Complete Parameter Validation System ## Example class ParameterValidator: """Parameter Validator""" def __init__ (self, tool_def): self.tool_def= tool_def def validate(self, params): """Execute full parameter validation""" all_errors =[] # Check required parameters required_errors =self.validate_required(params) all_errors.extend(required_errors) # Check parameter types type_errors =self.validate_type(params) all_errors.extend(type_errors) # Check parameter ranges range_errors =self.validate_range(params) all_errors.extend(range_errors) # Check extra parameters (undefined parameters) extra_errors =self.validate_extra(params) all_errors.extend(extra_errors) return len(all_errors)==0, all_errors def validate_required(self, params): """Validate required parameters""" errors =[] required_params =self.tool_def.get("required",[]) for param_name in required_params: if param_name not in params or paramsis None: errors.append(f"Missing required parameter: {param_name}") return errors def validate_type(self, params): """Validate parameter types""" errors =[] for param_name, param_value in params.items(): if param_name in self.tool_def: param_def =self.tool_def expected_type = param_def.get("type") if expected_type =="string"and not isinstance(param_value,str): errors.append(f"Parameter '{param_name}' should be string type, actual is {type(param_value).__name__}") elif expected_type =="integer"and not isinstance(param_value,int): errors.append(f"Parameter '{param_name}' should be integer type, actual is {type(param_value).__name__}") elif expected_type =="number"and not isinstance(param_value,(int,float)): errors.append(f"Parameter '{param_name}' should be number type, actual is {type(param_value).__name__}") elif expected_type =="boolean"and not isinstance(param_value,bool): errors.append(f"Parameter '{param_name}' should be boolean type, actual is {type(param_value).__name__}") return errors def validate_range(self, params): """Validate parameter ranges""" errors =[] for param_name, param_value in params.items(): if param_name in self.tool_def: param_def =self.tool_def # Check minimum value if"minimum"in param_def and param_value param_def: errors.append(f"Parameter '{param_name}' cannot be greater than {param_def['maximum']}") # Check enum values if"enum"in param_def and param_value not in param_def: errors.append(f"Parameter '{param_name}' must be one of {param_def['enum']}") return errors def validate_extra(self, params):
← Ai Agent Python SetupAi Agent Working Principle β†’