> ## Documentation Index
> Fetch the complete documentation index at: https://docs-model.skyengine.com.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI 工具调用示例

> 使用OpenAI接口进行Function Calling工具调用的完整示例代码

# OpenAI 工具调用示例

以下示例展示如何使用OpenAI兼容接口进行Function Calling（工具调用），让AI能够调用外部函数来获取信息或执行操作。

## 快速开始

只需要替换 `<API-KEY>` 为你的实际API密钥即可运行。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://model-api.skyengine.com.cn/v1/chat/completions" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <API-KEY>" \
    -d '{
      "model": "gpt-5-2025-08-07",
      "messages": [
        {
          "role": "user",
          "content": "北京今天的天气怎么样？"
        }
      ],
      "tools": [
        {
          "type": "function",
          "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
              "type": "object",
              "properties": {
                "city": {
                  "type": "string",
                  "description": "城市名称"
                },
                "unit": {
                  "type": "string",
                  "enum": ["celsius", "fahrenheit"],
                  "description": "温度单位"
                }
              },
              "required": ["city"]
            }
          }
        }
      ],
      "tool_choice": "auto"
    }'
  ```

  ```python Python theme={null}
  import requests
  import json

  # 配置API密钥和基础URL
  API_KEY = "<API-KEY>"
  BASE_URL = "https://model-api.skyengine.com.cn/v1"

  # 定义可调用的工具函数
  def get_weather(city, unit="celsius"):
      """模拟获取天气信息"""
      weather_data = {
          "北京": {"temperature": 22, "condition": "晴天", "humidity": 45},
          "上海": {"temperature": 25, "condition": "多云", "humidity": 60},
          "广州": {"temperature": 28, "condition": "小雨", "humidity": 75},
          "深圳": {"temperature": 27, "condition": "晴天", "humidity": 55}
      }
      
      if city in weather_data:
          data = weather_data[city]
          temp = data["temperature"]
          if unit == "fahrenheit":
              temp = temp * 9/5 + 32
          return {
              "city": city,
              "temperature": f"{temp}°{'C' if unit == 'celsius' else 'F'}",
              "condition": data["condition"],
              "humidity": f"{data['humidity']}%"
          }
      else:
          return {"error": f"没有找到{city}的天气信息"}

  def get_stock_price(symbol):
      """模拟获取股票价格"""
      stock_data = {
          "AAPL": {"price": 150.25, "change": "+2.30", "change_percent": "+1.55%"},
          "GOOGL": {"price": 2750.80, "change": "-15.20", "change_percent": "-0.55%"},
          "TSLA": {"price": 245.67, "change": "+8.90", "change_percent": "+3.76%"}
      }
      
      symbol = symbol.upper()
      if symbol in stock_data:
          return stock_data[symbol]
      else:
          return {"error": f"没有找到股票代码{symbol}的信息"}

  def calculate(expression):
      """安全的数学计算"""
      try:
          # 简单的安全检查
          allowed_chars = set('0123456789+-*/.() ')
          if not all(c in allowed_chars for c in expression):
              return {"error": "表达式包含不允许的字符"}
          
          result = eval(expression)
          return {"expression": expression, "result": result}
      except Exception as e:
          return {"error": f"计算错误: {str(e)}"}

  # 工具函数映射
  AVAILABLE_FUNCTIONS = {
      "get_weather": get_weather,
      "get_stock_price": get_stock_price,
      "calculate": calculate
  }

  def chat_with_tools(message):
      url = f"{BASE_URL}/chat/completions"
      headers = {
          "Content-Type": "application/json",
          "Authorization": f"Bearer {API_KEY}"
      }
      
      # 定义可用的工具
      tools = [
          {
              "type": "function",
              "function": {
                  "name": "get_weather",
                  "description": "获取指定城市的天气信息",
                  "parameters": {
                      "type": "object",
                      "properties": {
                          "city": {
                              "type": "string",
                              "description": "城市名称"
                          },
                          "unit": {
                              "type": "string",
                              "enum": ["celsius", "fahrenheit"],
                              "description": "温度单位"
                          }
                      },
                      "required": ["city"]
                  }
              }
          },
          {
              "type": "function",
              "function": {
                  "name": "get_stock_price",
                  "description": "获取股票的当前价格",
                  "parameters": {
                      "type": "object",
                      "properties": {
                          "symbol": {
                              "type": "string",
                              "description": "股票代码，如AAPL, GOOGL等"
                          }
                      },
                      "required": ["symbol"]
                  }
              }
          },
          {
              "type": "function",
              "function": {
                  "name": "calculate",
                  "description": "执行数学计算",
                  "parameters": {
                      "type": "object",
                      "properties": {
                          "expression": {
                              "type": "string",
                              "description": "要计算的数学表达式"
                          }
                      },
                      "required": ["expression"]
                  }
              }
          }
      ]
      
      messages = [
          {
              "role": "user",
              "content": message
          }
      ]
      
      data = {
          "model": "gpt-5-2025-08-07",
          "messages": messages,
          "tools": tools,
          "tool_choice": "auto"
      }
      
      response = requests.post(url, headers=headers, json=data)
      
      if response.status_code != 200:
          return f"错误: {response.status_code} - {response.text}"
      
      result = response.json()
      message = result['choices'][0]['message']
      
      # 检查是否需要调用工具
      if message.get('tool_calls'):
          messages.append(message)  # 添加助手的消息
          
          # 处理每个工具调用
          for tool_call in message['tool_calls']:
              function_name = tool_call['function']['name']
              function_args = json.loads(tool_call['function']['arguments'])
              
              print(f"调用工具: {function_name}")
              print(f"参数: {function_args}")
              
              # 执行函数调用
              if function_name in AVAILABLE_FUNCTIONS:
                  function_response = AVAILABLE_FUNCTIONS[function_name](**function_args)
              else:
                  function_response = {"error": f"未知的函数: {function_name}"}
              
              # 添加函数调用结果到消息历史
              messages.append({
                  "tool_call_id": tool_call['id'],
                  "role": "tool",
                  "name": function_name,
                  "content": json.dumps(function_response, ensure_ascii=False)
              })
          
          # 使用工具调用结果重新请求
          data["messages"] = messages
          second_response = requests.post(url, headers=headers, json=data)
          
          if second_response.status_code == 200:
              final_result = second_response.json()
              return final_result['choices'][0]['message']['content']
          else:
              return f"二次请求错误: {second_response.status_code} - {second_response.text}"
      else:
          return message['content']

  # 使用示例
  if __name__ == "__main__":
      # 天气查询示例
      print("=== 天气查询 ===")
      weather_response = chat_with_tools("北京今天的天气怎么样？")
      print(weather_response)
      
      print("\n=== 股票价格查询 ===")
      stock_response = chat_with_tools("AAPL的股价是多少？")
      print(stock_response)
      
      print("\n=== 数学计算 ===")
      calc_response = chat_with_tools("帮我计算 25 * 4 + 10")
      print(calc_response)
      
      print("\n=== 复合查询 ===")
      complex_response = chat_with_tools("北京的天气如何？另外帮我算一下100除以3等于多少？")
      print(complex_response)
  ```

  ```javascript JavaScript/Node.js theme={null}
  const axios = require('axios');

  // 配置API密钥和基础URL
  const API_KEY = '<API-KEY>';
  const BASE_URL = 'https://model-api.skyengine.com.cn/v1';

  // 定义可调用的工具函数
  function getWeather(city, unit = 'celsius') {
      const weatherData = {
          '北京': { temperature: 22, condition: '晴天', humidity: 45 },
          '上海': { temperature: 25, condition: '多云', humidity: 60 },
          '广州': { temperature: 28, condition: '小雨', humidity: 75 },
          '深圳': { temperature: 27, condition: '晴天', humidity: 55 }
      };
      
      if (weatherData[city]) {
          const data = weatherData[city];
          let temp = data.temperature;
          if (unit === 'fahrenheit') {
              temp = temp * 9/5 + 32;
          }
          return {
              city: city,
              temperature: `${temp}°${unit === 'celsius' ? 'C' : 'F'}`,
              condition: data.condition,
              humidity: `${data.humidity}%`
          };
      } else {
          return { error: `没有找到${city}的天气信息` };
      }
  }

  function getStockPrice(symbol) {
      const stockData = {
          'AAPL': { price: 150.25, change: '+2.30', change_percent: '+1.55%' },
          'GOOGL': { price: 2750.80, change: '-15.20', change_percent: '-0.55%' },
          'TSLA': { price: 245.67, change: '+8.90', change_percent: '+3.76%' }
      };
      
      symbol = symbol.toUpperCase();
      if (stockData[symbol]) {
          return stockData[symbol];
      } else {
          return { error: `没有找到股票代码${symbol}的信息` };
      }
  }

  function calculate(expression) {
      try {
          // 简单的安全检查
          const allowedChars = /^[0-9+\-*/.() ]+$/;
          if (!allowedChars.test(expression)) {
              return { error: '表达式包含不允许的字符' };
          }
          
          const result = eval(expression);
          return { expression: expression, result: result };
      } catch (error) {
          return { error: `计算错误: ${error.message}` };
      }
  }

  // 工具函数映射
  const AVAILABLE_FUNCTIONS = {
      get_weather: getWeather,
      get_stock_price: getStockPrice,
      calculate: calculate
  };

  async function chatWithTools(message) {
      const url = `${BASE_URL}/chat/completions`;
      const headers = {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${API_KEY}`
      };
      
      // 定义可用的工具
      const tools = [
          {
              type: 'function',
              function: {
                  name: 'get_weather',
                  description: '获取指定城市的天气信息',
                  parameters: {
                      type: 'object',
                      properties: {
                          city: {
                              type: 'string',
                              description: '城市名称'
                          },
                          unit: {
                              type: 'string',
                              enum: ['celsius', 'fahrenheit'],
                              description: '温度单位'
                          }
                      },
                      required: ['city']
                  }
              }
          },
          {
              type: 'function',
              function: {
                  name: 'get_stock_price',
                  description: '获取股票的当前价格',
                  parameters: {
                      type: 'object',
                      properties: {
                          symbol: {
                              type: 'string',
                              description: '股票代码，如AAPL, GOOGL等'
                          }
                      },
                      required: ['symbol']
                  }
              }
          },
          {
              type: 'function',
              function: {
                  name: 'calculate',
                  description: '执行数学计算',
                  parameters: {
                      type: 'object',
                      properties: {
                          expression: {
                              type: 'string',
                              description: '要计算的数学表达式'
                          }
                      },
                      required: ['expression']
                  }
              }
          }
      ];
      
      let messages = [
          {
              role: 'user',
              content: message
          }
      ];
      
      const data = {
          model: 'gpt-5-2025-08-07',
          messages: messages,
          tools: tools,
          tool_choice: 'auto'
      };
      
      try {
          const response = await axios.post(url, data, { headers });
          const responseMessage = response.data.choices[0].message;
          
          // 检查是否需要调用工具
          if (responseMessage.tool_calls) {
              messages.push(responseMessage); // 添加助手的消息
              
              // 处理每个工具调用
              for (const toolCall of responseMessage.tool_calls) {
                  const functionName = toolCall.function.name;
                  const functionArgs = JSON.parse(toolCall.function.arguments);
                  
                  console.log(`调用工具: ${functionName}`);
                  console.log(`参数:`, functionArgs);
                  
                  // 执行函数调用
                  let functionResponse;
                  if (AVAILABLE_FUNCTIONS[functionName]) {
                      functionResponse = AVAILABLE_FUNCTIONS[functionName](...Object.values(functionArgs));
                  } else {
                      functionResponse = { error: `未知的函数: ${functionName}` };
                  }
                  
                  // 添加函数调用结果到消息历史
                  messages.push({
                      tool_call_id: toolCall.id,
                      role: 'tool',
                      name: functionName,
                      content: JSON.stringify(functionResponse)
                  });
              }
              
              // 使用工具调用结果重新请求
              data.messages = messages;
              const secondResponse = await axios.post(url, data, { headers });
              return secondResponse.data.choices[0].message.content;
          } else {
              return responseMessage.content;
          }
      } catch (error) {
          return `错误: ${error.response?.status} - ${error.response?.data || error.message}`;
      }
  }

  // 使用示例
  (async () => {
      try {
          console.log('=== 天气查询 ===');
          const weatherResponse = await chatWithTools('北京今天的天气怎么样？');
          console.log(weatherResponse);
          
          console.log('\n=== 股票价格查询 ===');
          const stockResponse = await chatWithTools('AAPL的股价是多少？');
          console.log(stockResponse);
          
          console.log('\n=== 数学计算 ===');
          const calcResponse = await chatWithTools('帮我计算 25 * 4 + 10');
          console.log(calcResponse);
      } catch (error) {
          console.error('错误:', error.message);
      }
  })();
  ```
</CodeGroup>

## 工具调用的工作流程

1. **定义工具**: 在请求中定义可用的函数及其参数
2. **AI决策**: AI根据用户输入决定是否需要调用工具
3. **函数调用**: AI生成函数调用请求
4. **执行函数**: 客户端执行相应的函数
5. **返回结果**: 将函数结果发送回AI
6. **生成回复**: AI基于函数结果生成最终回复

## 工具定义格式

```json theme={null}
{
  "type": "function",
  "function": {
    "name": "function_name",
    "description": "函数的描述",
    "parameters": {
      "type": "object",
      "properties": {
        "param1": {
          "type": "string",
          "description": "参数1的描述"
        }
      },
      "required": ["param1"]
    }
  }
}
```

## 应用场景

* **信息查询**: 天气、股票、新闻等实时信息
* **数据计算**: 数学计算、数据分析
* **系统操作**: 文件操作、数据库查询
* **外部API**: 调用第三方服务
* **业务逻辑**: 执行特定的业务流程

## 最佳实践

1. **清晰的函数描述**: 提供准确的函数和参数描述
2. **参数验证**: 在函数中进行输入参数验证
3. **错误处理**: 妥善处理函数执行中的错误
4. **安全考虑**: 避免执行危险的操作
5. **性能优化**: 对于耗时操作考虑异步处理

## 注意事项

* 工具调用需要两次API请求（决策+生成回复）
* 确保函数执行的安全性，避免恶意代码注入
* 合理设置 `tool_choice` 参数控制工具使用
* 函数返回结果应该是JSON可序列化的格式
