1. 使用场景

Function Calling 功能让模型能够调用外部工具,来增强自身能力。 该能力可以通过外部工具,通过大模型作为大脑调用外部工具(如搜索外部知识、查阅行程、或者某些特定领域工具),有效解决模型的幻觉、知识时效性等问题。

2. 使用方式

2.1 通过 REST API 添加 tools 请求参数

在请求体中添加

"tools": [
    {
        'type': 'function',
        'function': {
            'name': '对应到实际执行的函数名称',
            'description': '此处是函数相关描述',
            'parameters': {
                '_comments': '此处是函数参数相关描述'
            },
        }
    },
    {
        '_comments': '其他函数相关说明'
    }
]

比如完整的 payload 信息:

payload = {
    "model": "deepseek-ai/DeepSeek-V2-Chat",
    "messages": [
        {
            "role": "user",
            "content": "SiliconCloud推出分层速率方案与免费模型RPM提升10倍,对于整个大模型应用领域带来哪些改变?"
        }
    ],
    "tools": [
    {
        'type': 'function',
        'function': {
            'name': '对应到实际执行的函数名称',
            'description': '此处是函数相关描述',
            'parameters': {
                '_comments': '此处是函数参数相关描述'
            },
        }
    },
    {
        '_comments': '其他函数相关说明'
    }
    ]
    '_comments': '其他函数列表'
}

2.2 通过 OpenAI 库请求

该功能和openai兼容,在使用 OpenAI 的库时,对应的请求参数中添加tools=[对应的 tools] 比如:

response = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V2.5",
    messages = messages,
    tools=[
        {
            'type': 'function',
            'function': {
                'name': '对应到实际执行的函数名称',
                'description': '此处是函数相关描述',
                'parameters': {
                    // 此处是函数参数相关描述
                },
            }
        },
        {
            // 其他函数相关说明
        }
    ]
    // chat.completions 其他参数
)

3. 支持模型列表

目前支持的模型列表有:

  • Deepseek 系列:

    • deepseek-ai/DeepSeek-V2.5
  • 书生系列:

    • internlm/internlm2_5-20b-chat
    • internlm/internlm2_5-7b-chat
    • Pro/internlm/internlm2_5-7b-chat
  • Qwen系列:

    • Qwen/Qwen2.5-72B-Instruct
    • Qwen/Qwen2.5-32B-Instruct
    • Qwen/Qwen2.5-14B-Instruct
    • Qwen/Qwen2.5-7B-Instruct
    • Pro/Qwen/Qwen2.5-7B-Instruct
  • GLM 系列:

    • THUDM/glm-4-9b-chat
    • Pro/THUDM/glm-4-9b-chat
注意:支持的模型列表在不断调整中,请查阅本文档了解最新支持的模型列表。

4. 使用示例

4.1. 示例 1:通过function calling 来扩展大语言模型的数值计算能力

本代码输入 4 个函数,分别是数值的加、减、比较大小、字符串中重复字母计数四个函数 来演示通过function calling来解决大语言模型在tokens 预测不擅长的领域的执行问题。


from openai import OpenAI

client = OpenAI(
    api_key="您的 APIKEY", # 从https://cloud.siliconflow.cn/account/ak获取
    base_url="https://api.siliconflow.cn/v1"
)

def add(a: float, b: float):
    return a + b

def mul(a: float, b: float):
    return a * b

def compare(a: float, b: float):
    if a > b:
        return f'{a} is greater than {b}'
    elif a < b:
        return f'{b} is greater than {a}'
    else:
        return f'{a} is equal to {b}'

def count_letter_in_string(a: str, b: str):
    string = a.lower()
    letter = b.lower()
    
    count = string.count(letter)
    return(f"The letter '{letter}' appears {count} times in the string.")


tools = [
{
    'type': 'function',
    'function': {
        'name': 'add',
        'description': 'Compute the sum of two numbers',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'int',
                    'description': 'A number',
                },
                'b': {
                    'type': 'int',
                    'description': 'A number',
                },
            },
            'required': ['a', 'b'],
        },
    }
}, 
{
    'type': 'function',
    'function': {
        'name': 'mul',
        'description': 'Calculate the product of two numbers',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'int',
                    'description': 'A number',
                },
                'b': {
                    'type': 'int',
                    'description': 'A number',
                },
            },
            'required': ['a', 'b'],
        },
    }
},
{
    'type': 'function',
    'function': {
        'name': 'count_letter_in_string',
        'description': 'Count letter number in a string',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'str',
                    'description': 'source string',
                },
                'b': {
                    'type': 'str',
                    'description': 'letter',
                },
            },
            'required': ['a', 'b'],
        },
    }
},
{
    'type': 'function',
    'function': {
        'name': 'compare',
        'description': 'Compare two number, which one is bigger',
        'parameters': {
            'type': 'object',
            'properties': {
                'a': {
                    'type': 'float',
                    'description': 'A number',
                },
                'b': {
                    'type': 'float',
                    'description': 'A number',
                },
            },
            'required': ['a', 'b'],
        },
    }
}
]

def function_call_playground(prompt):
    messages = [{'role': 'user', 'content': prompt}]
    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V2.5",
        messages = messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools)

    # print(response)
    func1_name = response.choices[0].message.tool_calls[0].function.name
    func1_args = response.choices[0].message.tool_calls[0].function.arguments
    func1_out = eval(f'{func1_name}(**{func1_args})')
    # print(func1_out)

    messages.append(response.choices[0].message)
    messages.append({
        'role': 'tool',
        'content': f'{func1_out}',
        'tool_call_id': response.choices[0].message.tool_calls[0].id
    })
    # print(messages)
    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V2.5",
        messages=messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools)
    return response.choices[0].message.content
  
prompts = [
    "用中文回答:strawberry中有多少个r?", 
    "用中文回答:9.11和9.9,哪个小?"
]

for prompt in prompts:
    print(function_call_playground(prompt))

模型将输出:

strawberry中有3个r。
9.119.9 小。

4.2. 示例 2:通过function calling 来扩展大语言模型对外部环境的理解

本代码输入 1 个函数,通过外部 API 来查询外部信息

import requests
from openai import OpenAI

client = OpenAI(
    api_key="您的 APIKEY", # 从https://cloud.siliconflow.cn/account/ak获取
    base_url="https://api.siliconflow.cn/v1"
)

# 使用 WeatherAPI 的天气查询函数
def get_weather(city: str):
    # 使用 WeatherAPI 的 API 来获取天气信息
    api_key = "您的WeatherAPI APIKEY"  # 替换为你自己的 WeatherAPI APIKEY
    base_url = "http://api.weatherapi.com/v1/current.json"
    params = {
        'key': api_key,
        'q': city,
        'aqi': 'no'  # 不需要空气质量数据
    }
    
    # 调用天气 API
    response = requests.get(base_url, params=params)
    
    if response.status_code == 200:
        data = response.json()
        weather = data['current']['condition']['text']
        temperature = data['current']['temp_c']
        return f"The weather in {city} is {weather} with a temperature of {temperature}°C."
    else:
        return f"Could not retrieve weather information for {city}."

# 定义 OpenAI 的 function calling tools
tools = [
    {
        'type': 'function',
        'function': {
            'name': 'get_weather',
            'description': 'Get the current weather for a given city.',
            'parameters': {
                'type': 'object',
                'properties': {
                    'city': {
                        'type': 'string',
                        'description': 'The name of the city to query weather for.',
                    },
                },
                'required': ['city'],
            },
        }
    }
]

# 发送请求并处理 function calling
def function_call_playground(prompt):
    messages = [{'role': 'user', 'content': prompt}]
    
    # 发送请求到 OpenAI API
    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V2.5",
        messages=messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools
    )

    # 处理 API 返回的工具调用请求
    func1_name = response.choices[0].message.tool_calls[0].function.name
    func1_args = response.choices[0].message.tool_calls[0].function.arguments
    func1_out = eval(f'{func1_name}(**{func1_args})')

    # 将结果添加到对话中并返回
    messages.append(response.choices[0].message)
    messages.append({
        'role': 'tool',
        'content': f'{func1_out}',
        'tool_call_id': response.choices[0].message.tool_calls[0].id
    })
    
    # 返回模型响应
    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V2.5",
        messages=messages,
        temperature=0.01,
        top_p=0.95,
        stream=False,
        tools=tools
    )
    
    return response.choices[0].message.content

# 示例使用
prompt = "how is the weather today in beijing?"
print(function_call_playground(prompt))

模型将输出:

The weather in Beijing today is sunny with a temperature of 21.4°C.