1.MCP入门-大模型函数调用的概念

137 阅读3分钟

大模型函数调用示例

一. 大模型函数调用的流程

函数调用流程.drawio.png

二、函数调用

2.1 Function call 功能

函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。

需要注意的是,大模型的 Function call 不会执行任何函数调用,仅返回调用函数所需要的参数。开发者可以利用模型输出的参数在应用中执行函数调用。 执行。 但研读了DEEKSEEK 的 Function call 之后,发现不是这样的

2.2 DEEKSEEK 是如何进行函数调用的

假设我们要创建一个具备查询航班功能的聊天机器人

2.2.1 定义外部函数

我们定义如下两个外部函数供模型选择调用:

    1. 查询两地之间某日航班号函数:get_flight_number(departure: str, destination: str, date: str)
    1. 查询某航班某日票价函数:get_ticket_price(flight_number: str, date: str)

为了向模型描述外部函数库,需要向 tools 字段传入可以调用的函数列表。参数如下表:

参数名称类型是否必填参数说明
typeString设置为function
functionObject
nameString函数名称
descriptionString用于描述函数功能。模型会根据这段描述决定函数调用方式。
parametersObjectparameters字段需要传入一个 Json Schema 对象,以准确地定义函数所接受的参数。若调用函数时不需要传入参数,省略该参数即可。
 required指定哪些属性在数据中必须被包含。

三.相关代码

import json
from openai import OpenAI

def get_flight_number(date:str , departure:str , destination:str):
    flight_number = {
        "北京":{
            "上海" : "1234",
            "广州" : "8321",
        },
        "上海":{
            "北京" : "1233",
            "广州" : "8123",
        }
    }
    return { "flight_number":flight_number[departure][destination] }
def get_ticket_price(date:str , flight_number:str):
    return {"ticket_price": "1000"}



tools = [
    {
        "type": "function",
        "function": {
            "name": "get_flight_number",
            "description": "根据始发地、目的地和日期,查询对应日期的航班号",
            "parameters": {
                "type": "object",
                "properties": {
                    "departure": {
                        "description": "出发地",
                        "type": "string"
                    },
                    "destination": {
                        "description": "目的地",
                        "type": "string"
                    },
                    "date": {
                        "description": "日期",
                        "type": "string",
                    }
                },
                "required": [ "departure", "destination", "date" ]
            },
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_ticket_price",
            "description": "查询某航班在某日的票价",
            "parameters": {
                "type": "object",
                "properties": {
                    "flight_number": {
                        "description": "航班号",
                        "type": "string"
                    },
                    "date": {
                        "description": "日期",
                        "type": "string",
                    }
                },
                "required": [ "flight_number", "date"]
            },
        }
    },
]


client = OpenAI(
    api_key="sk-apikey",
    base_url="https://api.deepseek.com",
)


def parse_function_call(model_response,messages):
    # 处理函数调用结果,根据模型返回参数,调用对应的函数。
    # 调用函数返回结果后构造tool message,再次调用模型,将函数结果输入模型
    # 模型会将函数调用结果以自然语言格式返回给用户。
    if model_response.choices[0].message.tool_calls:
        tool_call = model_response.choices[0].message.tool_calls[0]
        args = tool_call.function.arguments
        function_result = {}
        if tool_call.function.name == "get_flight_number":
            function_result = get_flight_number(**json.loads(args))
        if tool_call.function.name == "get_ticket_price":
            function_result = get_ticket_price(**json.loads(args))
        messages.append({
            "role": "tool",
            "content": f"{json.dumps(function_result)}",
            "tool_call_id":tool_call.id
        })
        response = client.chat.completions.create(
            model="deepseek-chat",  # 填写需要调用的模型名称
            messages=messages,
            tools=tools,
        )
        print(response.choices[0].message)
        messages.append(response.choices[0].message.model_dump())

# 清空对话
messages = []

messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"})
messages.append({"role": "user", "content": "帮我查询1月23日,北京到广州的航班"})

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=messages,
    tools=tools
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())

parse_function_call(response,messages)