界面控件DevExpress Blazor中文教程:AI聊天 - 如何实现函数调用?

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。

现代AI驱动的应用程序需要与外部系统或内部应用程序组件无缝交互,许多AI服务提供商现在支持函数调用(也称为工具调用),这允许AI模型在运行时触发函数。这种功能对于AI需要执行诸如获取数据、调用API或在应用程序中启动任务(从安排约会和修改数据库信息到更新应用程序的外观)等操作的代理工作流/应用程序特别有价值。

获取DevExpress v24.2正式版下载

本文实例中的整个流程是这样的:模型不是回复用户消息,而是请求一个带有指定参数的函数调用,然后聊天客户端调用该函数并将结果返回给LLM。此时,LLM根据函数返回的值构造一个响应。

在本指南中,我们将探索如何在DevExpress Blazor DxAiChat组件中启用函数调用:

  • 来自Microsoft.Extensions.AI库的IChatClient接口
  • 来自Microsoft语义内核的插件
开始

要开始,您必须首先将DxAiChat组件集成到应用程序中(请参阅我们的官方指南以获取更多信息):Add AI Chat to a Project。

接下来注册您的AI服务,在这个例子中我们将使用Azure OpenAI。下面是一个示例Program.cs设置:

using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
var builder = WebApplication.CreateBuilder(args);
...
// Replace with your endpoint, API key, and deployed AI model name
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = string.Empty;
...
var azureChatClient = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey));IChatClient chatClient = azureChatClient.AsChatClient(deploymentName);builder.Services.AddDevExpressBlazor();
builder.Services.AddChatClient(chatClient);
builder.Services.AddDevExpressAI();

运行项目来确认您可以发送消息和接收AI响应。

使用IChatClient调用工具

首先,定义一个简单的函数来检索指定城市的天气信息。在本例中,这是GetWeatherTool。为了帮助AI理解如何调用GetWeatherTool函数,请使用方法及其参数的System.ComponentModel.Description属性。LLM使用参数找出最合适的方法调用,并规划调用顺序:

using System.ComponentModel;
using Microsoft.Extensions.AI;public class CustomAIFunctions
{
public static AIFunction GetWeatherTool => AIFunctionFactory.Create(GetWeather);
[Description("Gets the current weather in the city")]
public static string GetWeather([Description("The name of the city")] string city)
{
switch (city)
{
case "Los Angeles":
case "LA":
return GetTemperatureValue(20);
case "London":
return GetTemperatureValue(15);
default:
return $"The information about the weather in {city} is not available.";
}
}
static string GetTemperatureValue(int value)
{
var valueInFahrenheits = value * 9 / 5 + 32;
return $"{valueInFahrenheits}\u00b0F ({value}\u00b0C)";
}
}

修改聊天客户端注册,如下所示,来提供可用函数列表,并允许客户端在回答用户问题时调用函数。确保首先配置聊天客户端选项,因为这里的方法调用顺序至关重要:

using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
...
IChatClient chatClient = new ChatClientBuilder(azureChatClient)
.ConfigureOptions(opt =>
{
opt.Tools = [CustomAIFunctions.GetWeatherTool];
})
.UseFunctionInvocation()
.Build();builder.Services.AddChatClient(chatClient);

此时当用户向AI服务询问天气时,该服务将自动触发GetWeatherTool函数并将结果添加到其响应中。

界面控件DevExpress Blazor中文教程

集成语义内核插件

Microsoft语义内核允许开发人员将高级AI功能整合到应用程序中(包括推理、工作流编排和动态提示工程),Microsoft的框架通过允许应用程序与插件交互和更有效地管理内存来增强AI解决方案。

首先,将以下NuGet包添加到项目中:

  • Microsoft.SemanticKernel
  • Microsoft.SemanticKernel.Plugins.Core
  • Microsoft.SemanticKernel.Connectors.OpenAI (或为您的AI提供商提供适当的连接器)

如果您已经在应用程序中使用语义内核,并且熟悉插件的概念,可以很容易地将它连接到DevExpress Blazor DxAiChat控件。

由于DevExpress AI驱动的API使用IChatClient接口与llm一起操作,您需要手动实现接口并从语义内核调用IChatCompletionService方法:

using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
...
public class SemanticKernelPluginCallingChatClient : IChatClient {
private IChatCompletionService _chatCompletionService;
private Kernel _kernel;
private OpenAIPromptExecutionSettings _executionSettings;
public SemanticKernelPluginCallingChatClient(Kernel kernel)
{
_kernel = kernel;
_chatCompletionService = _kernel.GetRequiredService();
_executionSettings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
}public async Task GetResponseAsync(IEnumerable chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
{
var history = GetChatHistory(chatMessages);
ChatMessageContent message = await _chatCompletionService.GetChatMessageContentAsync(history, _executionSettings, _kernel, cancellationToken);
return new ChatResponse(new ChatMessage(ChatRole.Assistant, message.Content));
}public async IAsyncEnumerable GetStreamingResponseAsync(IEnumerable chatMessages, ChatOptions? options = null, CancellationToken cancellationToken = default)
{
var history = GetChatHistory(chatMessages);
await foreach(var item in _chatCompletionService.GetStreamingChatMessageContentsAsync(history, _executionSettings, _kernel, cancellationToken)) {
yield return new ChatResponseUpdate(ChatRole.Assistant, item.Content);
}
}AuthorRole GetRole(ChatRole chatRole) {
if(chatRole == ChatRole.User) return AuthorRole.User;
if(chatRole == ChatRole.System) return AuthorRole.System;
if(chatRole == ChatRole.Assistant) return AuthorRole.Assistant;
if(chatRole == ChatRole.Tool) return AuthorRole.Tool;
throw new Exception();
}private ChatHistory GetChatHistory(IEnumerable chatMessages)
{
var history = new ChatHistory(chatMessages.Select(x => new ChatMessageContent(GetRole(x.Role), x.Text)));
return history;
}
...
}

实现一个类似于前面函数的语义内核插件,但是用Microsoft.SemanticKernel.KernelFunction属性修饰main函数方法:

using Microsoft.SemanticKernel;
using System.ComponentModel;
...public class WeatherPlugin {
[KernelFunction]
[Description("Gets the current weather in the city")]
public static string GetWeather([Description("The name of the city")] string city) {
switch(city) {
case "Los Angeles":
case "LA":
return GetTemperatureValue(20);
case "London":
return GetTemperatureValue(15);
default:
return $"The information about the weather in {city} is not available.";
}
}
static string GetTemperatureValue(int value)
{
var valueInFahrenheits = value * 9 / 5 + 32;
return $"{valueInFahrenheits}\u00b0F ({value}\u00b0C)";
}
}

最后,在应用程序启动时注册语义内核和聊天客户端:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Plugins.Core;
...var semanticKernelBuilder = Kernel.CreateBuilder();
semanticKernelBuilder.AddAzureOpenAIChatCompletion(
deploymentName,
azureOpenAIEndpoint,
azureOpenAIKey);// Add plugins from Microsoft.SemanticKernel.Plugins.Core
#pragma warning disable SKEXP0050
semanticKernelBuilder.Plugins.AddFromType<TimePlugin>(); // this is a built-in plugin
semanticKernelBuilder.Plugins.AddFromType<WeatherPlugin>(); // this is our custom plugin
#pragma warning restore SKEXP0050var globalKernel = semanticKernelBuilder.Build();
builder.Services.AddChatClient(new SemanticKernelPluginCallingChatClient(globalKernel));builder.Services.AddDevExpressAI();

一旦配置好,您的应用程序将使用Semantic Kernel插件来智能地处理请求:

界面控件DevExpress Blazor中文教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88459.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

github 上的php项目

github 上的php项目 项目的网址 &#xff08;Loong1996/LikeGirlSite: 情侣网站、情侣网页、恋爱记录网站&#xff09; # 修改 # admin/Config_DB.php//localhost 为数据库地址 一般使用默认的即可 或&#xff08;127.0.0.1&#xff09; $db_address "mysql_php";/…

区间求最值问题高效解决方法

对于区间求最值场景&#xff0c;如果区间不定长度的&#xff0c;可以使用稀疏表进行求解&#xff0c;如果区间是固定长度的&#xff0c;则可以使用分块的思想&#xff08;与稀疏表原理类似&#xff09;&#xff0c;都是通过压缩状态个数&#xff0c; 1 关于稀疏表的原理详见&a…

Linux程序设计:什么时候选择开发内核模块?

最近看一个CPU使用率高的问题,从perf里看,是下面的一个占用的比较多是下面一个 Overhead Source:Line Symbol Shared Object - 8.48% [vdso][1129] 0x1129 B [.] 0x0000000000001129

OpenCV CUDA模块设备层-----欧几里得距离函数hypot()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于计算两个无符号字符向量&#xff08;uchar1&#xff09;的欧几里得距离&#xff08;即直角三角形的斜边长度&#xff09;&#xff0c;…

惠普HP LaserJet Pro P1106 打印机信息

基本信息 产品类型&#xff1a;黑白激光打印机。上市时间&#xff1a;2011 年。最大打印幅面&#xff1a;A4。网络打印&#xff1a;不支持网络打印。双面打印&#xff1a;手动双面打印。 性能参数 打印速度&#xff1a;黑白打印速度&#xff08;ISO&#xff0c;A4&#xff09;正…

通义灵码智能体模式在企业级开发中的应用:以云效DevOps自动化流程为例

一、智能体模式的核心能力 通义灵码的智能体模式区别于传统代码补全工具&#xff0c;具备&#xff1a; 语义级理解&#xff1a;解析业务需求、代码上下文及错误日志。自主任务闭环&#xff1a;从问题诊断→ 代码生成→ 测试覆盖→ 文档生成全流程自动化。环境感知&#xff1a…

SQL学习笔记2

DDL、DML、DQL、DCL基础语法 1、DDL 查询 查询所有数据库&#xff1a;show databases; show databases; 查询当前数据库&#xff1a;select database(); select database(); 数据库创建 创建数据库:create database [if not exist(若存在重名数据库&#xff0c;则不创建…

VScode常用快捷键【个人总结】

注&#xff1a;快捷键以 Windows/Linux 为主&#xff0c;Mac 用户将 Ctrl 替换为 Cmd&#xff0c;Alt 替换为 Option。 1. 编辑相关 快速复制与剪切 Alt Shift ↓&#xff1a;复制当前行到下方Alt Shift ↑&#xff1a;复制当前行到上方Ctrl X&#xff1a;剪切整行&…

数据结构与算法:线性表-顺序表(顺序存储)

一、线性表的定义&#xff08;逻辑结构&#xff09; 线性表是由 n (n > 0) 个相同数据类型的数据元素组成的有限序列&#xff0c;其中 n 为线性表的表长&#xff0c;当 n 0 时&#xff0c;线性表为空表。如果用 L 命名线性表&#xff0c;那么一般表示为&#xff1a;L (a1…

从源码到实践:Java集合框架面试核心知识点全解析

在Java开发中&#xff0c;集合框架&#xff08;Java Collections Framework&#xff09;是最基础也最常用的工具集。无论是处理业务逻辑时的数据暂存&#xff0c;还是高性能场景下的算法优化&#xff0c;集合的使用都贯穿始终。因此&#xff0c;Java集合相关的面试题几乎是所有…

【深度学习新浪潮】空间计算的医疗应用技术分析(简要版)

空间计算是一种通过融合计算机视觉、传感器技术与三维渲染,将虚拟内容精准锚定到物理空间,实现数字世界与现实世界无缝交互的技术体系。其核心在于让计算机理解真实环境的结构、位置和动态,从而支持自然交互(如手势、语音、眼动)和沉浸式体验。例如,苹果Vision Pro通过实…

win电脑没有xcode怎么上传ipa

在上架IOS项目的时候&#xff0c;遇到一个问题&#xff0c;如下图&#xff0c;在app store connect上架的时候&#xff0c;需要选择一个构建版本&#xff0c;然后它在下方提示&#xff0c;点击查看上传工具后&#xff0c;会发现需要下载xcode或mac命令行等工具来上传编译后的文…

相机标定与3D重建技术通俗讲解

一、什么是相机标定&#xff1f;能解决什么问题&#xff1f; 相机标定是计算机视觉中的基础技术&#xff0c;简单来说&#xff0c;就是确定相机从3D世界拍摄到2D图像时的"转换规则"。具体解决两个核心问题&#xff1a; 相机内部属性&#xff1a;如焦距&#xff08;…

DeepSeek-Reasoner推理模型示例

《DEEPSEEK原生应用与智能体开发实践 王晓华 书籍 图书》【摘要 书评 试读】- 京东图书 在之前讲解的示例中&#xff08;指这个示例&#xff1a;通过Prompt提示构建思维链-CSDN博客&#xff09;&#xff0c;无论是进行日常对话还是调用特定工具&#xff0c;我们所依赖的底层技…

常说的电源芯片到底指什么?

电源芯片是电子系统中用于管理、转换和分配电能的集成电路&#xff0c;根据功能和应用场景的不同&#xff0c;主要分为以下几类&#xff1a; 一、线性稳压器&#xff08;LDO, Low Dropout Regulator&#xff09; LDO内部的基本电路情况如下&#xff1a; LDO内部主要分为四大部…

【大模型学习】项目练习:套壳DeepSeek

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;AI入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 &#x1f4…

笔记03:布线-过孔的调用与添加

布线-过孔的调用与添加 &#xff08;1&#xff09;在进行PCB设计时&#xff0c;都必须使用到过孔&#xff0c;对走线进行换层处理。在走线进行打过孔之前&#xff0c;必须先要添加过孔&#xff0c;这样在PCB布线时才可以使用过孔。 &#xff08;2&#xff09;需要使用pad des…

在vscode中,Python程序的内置对象、关键字、自定义函数名/类名、字符串进行着色,说明分别是什么颜色?

在 VS Code 中&#xff0c;Python 代码的着色完全取决于你当前使用的主题。不同主题&#xff08;如 Dark, Monokai, Solarized Dark, Light, Quiet Light 等&#xff09;对不同类型的代码元素会使用不同的颜色。 一、Default Dark&#xff08;默认的深色主题&#xff09; impo…

Visual Studio 中使用 AddressSanitizer 指南

Visual Studio 中使用 AddressSanitizer 指南 基于 Microsoft Visual Studio 2022&#xff0c;支持 MSVC 和 Clang 编译器链&#xff0c;本文详细说明如何在 VS 中配置和使用 AddressSanitizer&#xff0c;用于检测内存误用&#xff0c;如消息释放后访问、超界读写等类型错误。…

Flink Sink函数深度解析:从原理到实践的全流程探索

在Flink的数据流处理体系中&#xff0c;Sink函数作为数据处理的最终出口&#xff0c;肩负着将处理后的数据写入外部存储引擎的关键使命。它如同数据旅程的终点站&#xff0c;决定着数据的最终归宿与应用价值。深入理解Sink函数的工作原理、核心概念及实现方式&#xff0c;对构建…