当前位置:   article > 正文

深入了解openai的Function Calling(通俗易懂-可跑nodejs代码)_openai function call

openai function call

相信来看这个的小伙伴已经有openai的api使用经验
这个api可以使用的模型: gpt-3.5-turbo-0613和gpt-4-0613

之前的对话是(nodejs语句)

  body: JSON.stringify({
     model: "gpt-3.5-turbo-0613",
     messages: messages,
 })
  • 1
  • 2
  • 3
  • 4

使用function calling是

  body: JSON.stringify({
     model: "gpt-3.5-turbo-0613",
     messages: messages,
     functions: functions,
     function_call: function_call
 })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

不难看出添加了functions和function_call两块内容,这两块内容的参数怎么写呢?

    const functions = [
        {
            name: "get_current_weather",//这个名字需要调用的函数名一致
            description: "获取当前地点的天气",  //描述需要做什么事情
            parameters: { 
                type: "object",
                properties: {  //需要从对话中抽取的关键信息,这里有两个参数,1地点,2温度单位
                    location: {
                        type: "string",
                        description: "城市地点",
                    },
                    unit: { type: "string", enum: ["摄氏度", "华氏度"] }, //
                },
                required: ["地点"], //定义哪些参数是必须的,只有匹配到必须的参数才认为这是一个函数实例
            },
        }
    ];

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

funtion_call的内容可以写如下三个:

  1. function_call: {“name”: “”}
  2. function_call: “none” 来强制模型生成面向用户的消息
  3. 默认行为function_call: "auto"是让模型自行决定是否调用函数

下面分3步来简单说明一下这个接口的常规操作

  1. 既然我们用这个接口,就乖乖按规定跟着写好了呗,就写上那些functions参数,发给gpt
  2. 发送请求完得到response回复,如果响应消息中存在函数调用信息,这个信息里面大概率已经存在了我们想要的数据了。他将字符串解析为了JSON。
  3. 那它咋回复我想要的内容呢,通过将函数响应作为新消息附加,再次调用模型,让模型向用户总结结果。(具体内容代码内有详细解释)

通过以上三点,我们一步步用nodejs代码实现。我给出两段不同的代码可以更好的理解。

场景假设:获取当前的天气信息,下面代码设置好自己的地址和apiKey后,可以直接跑通~


// 定义获取天气信息的异步函数 get_current_weather
async function get_current_weather(location, unit = "摄氏度") {
    // 模拟天气信息
    const weather_info = {
        location: location,
        temperature: "32摄氏度",
        unit: unit,
        forecast: ["暴雨", "阴天"],
    };
    return JSON.stringify(weather_info);
}

// 定义主要逻辑的异步函数 runConversation
async function runConversation() {
    const apiKey = 'test'; 
    const messages = [{ role: "user", content: "北京的天气怎么样?有多少摄氏度?" }];
    
    // 定义要传递给模型的函数信息
    const functions = [
        {
            name: "get_current_weather",
            description: "获取当前地点的天气",
            parameters: {
                type: "object",
                properties: {
                    location: {
                        type: "string",
                        description: "城市地点",
                    },
                    unit: { type: "string", enum: ["摄氏度", "华氏度"] },
                },
                required: ["地点"],
            },
        }
    ];

    const function_call = "auto"; // auto 是默认值,但我们会显式指定
    const headers = {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKey}`
    };

    // 发送请求给 GPT-3.5 Turbo API
    const response = await fetch('xxxxx/release/v1/chat/completions', {
        method: 'POST',
        headers: headers,
        body: JSON.stringify({
            model: "gpt-3.5-turbo-0613",
            messages: messages,
            functions: functions,
            function_call: function_call
        })
    });

    // 解析响应为 JSON 格式
    const data = await response.json();
    const responseMessage = data.choices[0].message;
   	console.log(responseMessage)

    // {
    //     role: 'assistant',
    //     content: null,
    //     function_call: {
    //       name: 'get_current_weather',
    //       arguments: '{\n  "location": "北京"\n}'
    //     }
    //   }

    if (responseMessage.function_call) {
        // 定义可用的函数映射
        const available_functions = {
            get_current_weather: get_current_weather
        };

        // 提取函数调用信息
        const functionName = responseMessage.function_call.name;
        const functionToCall = available_functions[functionName];
        const functionArgs = JSON.parse(responseMessage.function_call.arguments);
        
        // 调用函数并获取响应
        const functionResponse = await functionToCall(functionArgs.location, functionArgs.unit);

        // 更新消息列表,添加函数调用结果
		//这里需要注意的是messages里面的信息都有什么
		// 1. 第一步调用接口时push的user信息
		// 2. 第一步调用接口后返回的responseMessage信息
		// 3. 增加role: 'function'的接口,里面的内容是模拟返回的天气信息
        messages.push(responseMessage);
        messages.push({
            role: "function",
            name: functionName,
            content: functionResponse
        });
    	console.log(messages)


        // [
        //     { role: 'user', content: '北京的天气怎么样?' },
        //     {
        //       role: 'assistant',
        //       content: null,
        //       function_call: {
        //         name: 'get_current_weather',
        //         arguments: '{\n  "location": "北京"\n}'
        //       }
        //     },
        //     {
        //       role: 'function',
        //       name: 'get_current_weather',
        //       content: '{"location":"北京","temperature":"32摄氏度","unit":"fahrenheit","forecast":["暴雨","阴天"]}'
        //     }
        //   ]

        // 再次调用 GPT-3.5 Turbo API,附加函数响应作为新消息
        const secondResponse = await fetch('xxxxx/release/v1/chat/completions', {
            method: 'POST',
            headers: headers,
            body: JSON.stringify({
                model: "gpt-3.5-turbo-0613",
                messages: messages
            })
        });

        // 解析第二次响应并显示结果
        const result = await secondResponse.json();
        console.log(result); // 显示最终响应
           // {
        //     id: 'chatcmpl-7lDCNrAhnMNi3iXMwGatnlrtiXa6l',
        //     object: 'chat.completion',
        //     created: 1691486507,
        //     model: 'gpt-3.5-turbo-0613',
        //     choices: [ { index: 0, message: [Object], finish_reason: 'stop' } ],
        //     usage: { prompt_tokens: 72, completion_tokens: 46, total_tokens: 118 }
        //   }
        
        console.log(result.choices[0].message.content)//北京的天气目前是32摄氏度,预计会有暴雨和阴天。请注意天气变化,并做好相应的准备。

    } else {
        console.log(data); // 如果没有函数调用,显示响应信息
    }
}

// 调用主函数以开始对话
runConversation();


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147

场景模拟:我们公司正在招聘设计师和工程师,并且也有对外合作的意向,有意向的留下邮箱信息,我们可以给您发送信息保持后续联系



async function get_email_send_message(email, type = "求职") {
    //模拟发送邮箱
    const user_info = {
        user_email: email,
        type: type,
        is_send: true,
        send_email:'aaa.@qq.com'
    };
    return JSON.stringify(user_info);
}

// 我们公司正在招聘设计师和工程师,并且也有对外合作的意向,有意向的留下邮箱信息
async function runConversation() {
    const apiKey = 'test'; 
    const apiUrl = 'xxx'; //写入api的地址
    const messages = [{ role: "user", content: "我想在本公司担任工程师工作,我的邮箱是747012622@qq.com,希望您能联系我" }];
    const functions = [
        {
            name: "get_email_send_message",
            description: "获取邮箱地址,获取是求职还是合作,如果求职获取期望岗位",
            parameters: {
                type: "object",
                properties: {
                    email: {
                        type: "string",
                        description: "邮箱地址",
                    },
                    type: { type: "string", enum: ["求职", "合作"] },
                    position: { type: "string", enum: ["工程师", "设计师"] },
                },
                required: ["邮箱地址"],
            },
        }
    ];

    const function_call = "auto"; // auto is default, but we'll be explicit
    const headers = {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKey}`
    };

    const response = await fetch(apiUrl, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify({
            model: "gpt-3.5-turbo-0613",
            messages: messages,
            functions: functions,
            function_call: function_call
        })
    });

    const data = await response.json();
    const responseMessage = data.choices[0].message;

    if (responseMessage.function_call) {
        const available_functions = {
            get_email_send_message: get_email_send_message
        };

        const functionName = responseMessage.function_call.name;
        const functionToCall = available_functions[functionName];
        const functionArgs = JSON.parse(responseMessage.function_call.arguments);
        const functionResponse = await functionToCall(functionArgs.email, functionArgs.type);

        // console.log(responseMessage,'responsemessage')
        messages.push(responseMessage);
        messages.push({
            role: "function",
            name: functionName,
            content: functionResponse
        });

        console.log(messages)


   

        const secondResponse = await fetch(apiUrl, {
            method: 'POST',
            headers: headers,
            body: JSON.stringify({
                model: "gpt-3.5-turbo-0613",
                messages: messages
            })
        });

        const result = await secondResponse.json();
        console.log(result); // Display the final response
        console.log(result.choices[0].message.content)

    } else {
        console.log(data); // Display the response if no function call is made
    }
}

runConversation()


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

function-calling的api地址:function-calling

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/200072
推荐阅读
相关标签
  

闽ICP备14008679号