Function Calling‌是一种允许开发者通过API方式实现类似于ChatGPT插件的数据交互能力。它允许用户在使用模型处理特定问题时,定制并调用专有的函数,这些函数可以是专门为处理特定任务(如数据分析、图像处理等)而设计的代码块,从而让Chat Completion模型可以调用外部函数获取信息,并对输出进行格式化‌1。

Function Calling的背景和历史

Function Calling是OpenAI在2023年6月13日发布在Chat Completions API中的新能力。这一功能的主要目的是帮助开发者更高效地使用外部工具和API,以完成一些基础大模型无法完成的推理任务‌。

Function Calling的应用场景和优势

Function Calling的应用场景非常广泛,包括但不限于:

  • 调用本地函数‌:实现特定的计算或逻辑处理。
  • 多函数调用‌:处理复杂问题,需要多个函数协同工作。
  • 获取JSON结构‌:通过函数调用获取结构化数据。
  • 查询数据库‌:调用数据库函数进行数据查询和处理。
  • 实现多表查询‌:在处理涉及多个数据表的信息时,通过函数调用实现复杂查询。
  • Stream模式‌:处理流式数据时,通过函数调用实现实时数据处理‌2。

Function Calling的原理和实现方式

Function Calling的原理是通过API调用外部函数,这些函数可以是用户自定义的,也可以是第三方提供的。开发者可以在模型中嵌入这些函数,模型在处理问题时可以调用这些函数来获取所需的信息和数据,从而增强模型的功能和准确性‌

一、定义工具函数

定义各个工具函数,也就是具体要是实现的业务等信息。

#天气
def get_weather(city):
    return f'{city}的天气是多云'

#温度
def get_humidity(city):
    return f'{city}的湿度是70%'

#温度
def get_temperature(city):
    return f'{city}的温度是-10度'

# 国旗的长和宽
def get_flag_area(width,length):
    return f'旗帜面积是{width * length}'

二、定义functions

定义模型以及提示词

client = OpenAI(
    api_key = "XXXXXXX",
    base_url = "XXXXXXXXX"
)

messages = [
    {
        "role": "system",
        "content": "你是一个天气查询小助手,你可以查询天气、湿度、温度"
    },
    {
        "role": "user",
        "content": "一个旗帜的长是10.21cm,长度是20.23cm,面积说多少呢?"
    }
]

定义function,对应每一个函数,其中有函数名称,参数,参数类型等信息。

functions = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "查询天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名"
                    }
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_temperature",
            "description": "查询温度",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名"
                    }
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_humidity",
            "description": "查询湿度",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名"
                    }
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_flag_size",
            "description": "查询旗帜的面积",
            "parameters": {
                "type": "object",
                "properties": {
                    "width": {
                        "type": "number",
                        "description": "宽"
                    },
                    "length": {
                        "type": "number",
                        "description": "长"
                    }
                },
                "required": ["width","length"]
            }
        }
    }
]

三、定义模型请求函数

进行第一个模型调用,并获取返回中的请求信息。例如function的name、arguments等信息

# 定义模型请求函数
def response_message(messages):
    try:
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages = messages,
            tools = functions,
            tool_choice = "auto",
            temperature = 0.7
        )
        return response.choices[0].message
    except Exception as e:
        print(f"模型处理数据异常:{str(e)}")

# 第一次请求
first_response = response_message(messages)
tool_calls = first_response.tool_calls[0]
tool_name = tool_calls.function.name
tool_args = json.loads(tool_calls.function.arguments)

# 第一次的结果塞入
messages.append(first_response)

四、封装数据,请求模型

对三中的数据,塞入到messages中,作为提示词和问题一起塞给模型,并让模型进行最终答复。

def get_fun_name(tool_name,tool_args):
    if tool_name == "get_weather":
        return get_weather(tool_args["city"])
    elif tool_name == "get_temperature":
        return get_temperature(tool_args["city"])
    elif tool_name == "get_humidity":
        return get_humidity(tool_args["city"])
    elif tool_name == "get_flag_size":
        return get_flag_area(tool_args["width"],tool_args["length"])
    else:
        return "未知函数"
 
# 解析后的结果塞入
messages.append({
    "role": "tool",
    "content": get_fun_name(tool_name,tool_args),
    "tool_call_id": tool_calls.id
})

# 第二次请求
second_response = response_message(messages)
print(second_response)

五、运行试例

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐