找回密码
 立即注册
首页 业界区 业界 使用Semantic Kernel框架和C#.NET 实现大模型Function C ...

使用Semantic Kernel框架和C#.NET 实现大模型Function Calling

毋峻舷 4 天前
最近研究Function Call,总结了一篇文章,分享给大家
一、GPT-4中实现函数调用功能
定义函数:首先,开发一个函数。例如,一个获取天气信息的函数可能如下:
  1. def get_current_weather(location, unit='Celsius'):
  2.     # 此处实现获取天气信息的逻辑
  3.     return {"location": location, "temperature": "22", "unit": unit, "description": "晴朗"}
复制代码
描述函数:为GPT-4提供函数的描述,包括函数名称、功能描述以及参数信息。这有助于模型理解函数的用途和如何调用它。
  1. function_descriptions = [
  2.     {
  3.         "name": "get_current_weather",
  4.         "description": "获取指定地点的当前天气信息",
  5.         "parameters": {
  6.             "type": "object",
  7.             "properties": {
  8.                 "location": {
  9.                     "type": "string",
  10.                     "description": "地点名称"
  11.                 },
  12.                 "unit": {
  13.                     "type": "string",
  14.                     "enum": ["Celsius", "Fahrenheit"],
  15.                     "description": "温度单位,默认为摄氏度"
  16.                 }
  17.             },
  18.             "required": ["location"]
  19.         }
  20.     }
  21. ]
复制代码
与GPT-4交互:将用户输入、函数描述以及模型名称传递给GPT-4。模型将根据用户输入和函数描述,决定是否需要调用函数,并返回相应的响应。
  1. import openai
  2. import json
  3. openai.api_key = 'YOUR_OPENAI_API_KEY'
  4. def chat_with_gpt(messages, functions):
  5.     response = openai.ChatCompletion.create(
  6.         model="gpt-4-0613",
  7.         messages=messages,
  8.         functions=functions,
  9.         function_call="auto"  # 模型将根据需要决定是否调用函数
  10.     )
  11.     return response
  12. # 用户输入
  13. user_message = {"role": "user", "content": "请告诉我北京的当前天气。"}
  14. # 与模型交互
  15. response = chat_with_gpt([user_message], function_descriptions)
复制代码
处理模型响应:检查模型的响应,确定是否需要调用函数。如果模型返回了函数调用信息,则提取函数名称和参数,并调用相应的函数。
  1. response_message = response["choices"][0]["message"]
  2. if "function_call" in response_message:
  3.     # 提取函数名称和参数
  4.     function_name = response_message["function_call"]["name"]
  5.     function_args = json.loads(response_message["function_call"]["arguments"])
  6.     # 调用相应的函数
  7.     if function_name == "get_current_weather":
  8.         function_response = get_current_weather(
  9.             location=function_args.get("location"),
  10.             unit=function_args.get("unit", "Celsius")
  11.         )
  12.         # 将函数响应传递回模型,获取最终的回答
  13.         messages = [
  14.             user_message,
  15.             response_message,  # 包含函数调用信息
  16.             {
  17.                 "role": "function",
  18.                 "name": function_name,
  19.                 "content": json.dumps(function_response)
  20.             }
  21.         ]
  22.         final_response = chat_with_gpt(messages, function_descriptions)
  23.         answer = final_response["choices"][0]["message"]["content"]
  24.         print(answer)
  25. else:
  26.     # 模型直接提供了回答
  27.     answer = response_message["content"]
  28.     print(answer)
复制代码
GPT-4并不会直接执行函数调用,而是根据提供的函数描述,生成包含函数名称和参数的JSON对象。然后,我们需要在应用程序中解析该对象,并实际调用相应的函数。
根据函数返回的结果,放到Prompt中,调用大模型API,生成新的内容返回给用户。
二、使用Semantic Kernel框架和C#.NET 实现Function Calling
Semantic Kernel 框架中,大模型可以通过 Function Calling(函数调用)来执行插件(Plugins)中的功能。以下示例,展示如何在 Semantic Kernel 中让大模型调用一个 插件函数(Function Call)
设计一个计算插件,包含一个 add_numbers 方法,让大模型可以调用它来执行加法运算。
首先安装Semantic Kernel Nuget包
dotnet add package Microsoft.SemanticKernel
在 Semantic Kernel 中,插件就是一个包含方法的 C# 类,并使用 [KernelFunction] 进行标注。
  1. using Microsoft.SemanticKernel;
  2. using System.Threading.Tasks;
  3. public class CalculatorPlugin
  4. {
  5.     [KernelFunction("add_numbers")]
  6.     public int AddNumbers(int a, int b)
  7.     {
  8.         return a + b;
  9.     }
  10. }
复制代码
在 Program.cs 或 Main 方法中,初始化 Semantic Kernel 并注册这个插件。
  1. using System;
  2. using System.Threading.Tasks;
  3. using Microsoft.SemanticKernel;
  4. using Microsoft.SemanticKernel.Connectors.OpenAI;
  5. class Program
  6. {
  7.     static async Task Main(string[] args)
  8.     {
  9.         // 1. 创建 Kernel 实例
  10.         var kernel = Kernel.CreateBuilder()
  11.             .AddOpenAIChatCompletion(
  12.                 "gpt-4-turbo",  // OpenAI 模型名称
  13.                 "your-openai-api-key") // 替换为你的 API Key
  14.             .Build();
  15.         // 2. 加载插件(CalculatorPlugin)
  16.         var plugin = kernel.ImportPluginFromObject(new CalculatorPlugin(), "Calculator");
  17.         // 3. 让大模型调用 `add_numbers`
  18.         var result = await kernel.InvokeAsync("Calculator", "add_numbers", new()
  19.         {
  20.             { "a", 5 },
  21.             { "b", 10 }
  22.         });
  23.         Console.WriteLine($"Function Call Result: {result}");
  24.     }
  25. }
复制代码
执行 dotnet run,输出结果:Function Call Result: 15
代码执行原理说明

  • Semantic Kernel 提供了 插件(Plugins) 机制,让大模型可以调用 .NET 代码中的方法。
  • [KernelFunction("add_numbers")] 让大模型知道这个函数可以被调用。
  • kernel.ImportPluginFromObject(new CalculatorPlugin(), "Calculator") 把 CalculatorPlugin 作为插件加载到 Semantic Kernel 里。
  • kernel.InvokeAsync("Calculator", "add_numbers", new() { { "a", 5 }, { "b", 10 } }) 让大模型调用 add_numbers 并传入参数。
 
周国庆
2025/3/18
 
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册