OpenAI 工具调用示例
以下示例展示如何使用OpenAI兼容接口进行Function Calling(工具调用),让AI能够调用外部函数来获取信息或执行操作。快速开始
只需要替换<API-KEY> 为你的实际API密钥即可运行。
curl -X POST "https://api.tokenops.ai/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"
}'
import requests
import json
# 配置API密钥和基础URL
API_KEY = "<API-KEY>"
BASE_URL = "https://api.tokenops.ai/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)
const axios = require('axios');
// 配置API密钥和基础URL
const API_KEY = '<API-KEY>';
const BASE_URL = 'https://api.tokenops.ai/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);
}
})();
工具调用的工作流程
- 定义工具: 在请求中定义可用的函数及其参数
- AI决策: AI根据用户输入决定是否需要调用工具
- 函数调用: AI生成函数调用请求
- 执行函数: 客户端执行相应的函数
- 返回结果: 将函数结果发送回AI
- 生成回复: AI基于函数结果生成最终回复
工具定义格式
{
"type": "function",
"function": {
"name": "function_name",
"description": "函数的描述",
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "参数1的描述"
}
},
"required": ["param1"]
}
}
}
应用场景
- 信息查询: 天气、股票、新闻等实时信息
- 数据计算: 数学计算、数据分析
- 系统操作: 文件操作、数据库查询
- 外部API: 调用第三方服务
- 业务逻辑: 执行特定的业务流程
最佳实践
- 清晰的函数描述: 提供准确的函数和参数描述
- 参数验证: 在函数中进行输入参数验证
- 错误处理: 妥善处理函数执行中的错误
- 安全考虑: 避免执行危险的操作
- 性能优化: 对于耗时操作考虑异步处理
注意事项
- 工具调用需要两次API请求(决策+生成回复)
- 确保函数执行的安全性,避免恶意代码注入
- 合理设置
tool_choice参数控制工具使用 - 函数返回结果应该是JSON可序列化的格式