动手学Avalonia:基于SemanticKernel与硅基流动构建AI聊天与翻译工具

Avalonia是什么?

Avalonia是一个跨平台的UI框架,专为.NET开发打造,提供灵活的样式系统,支持Windows、macOS、Linux、iOS、Android及WebAssembly等多种平台。它已成熟并适合生产环境,被Schneider Electric、Unity、JetBrains和GitHub等公司采用。

许多人认为Avalonia是WPF的继任者,它为XAML开发人员提供了一种熟悉且现代的跨平台应用开发体验。尽管与WPF相似,但Avalonia并非完全复制,而包含了许多改进。

image-20240703120741584

SemanticKernel是什么?

Semantic Kernel是一个SDK,它可以将大型语言模型(如OpenAI、Azure OpenAI和Hugging Face)与常规编程语言(如C#、Python和Java)整合。特殊之处在于,Semantic Kernel通过允许定义和链式调用插件,能够自动调度并组合这些AI模型。其功能是,用户可以向LLM提出个性化目标,由Semantic Kernel的规划器生成实现目标的计划,然后由系统自动执行这份计划。

image-20240703121053734

硅基流动介绍

硅基流动致力于打造大模型时代的AI基础设施,通过算法、系统和硬件的协同创新,跨数量级降低大模型应用成本和开发门槛,加速AGI普惠人类。

SiliconCloud是集合主流开源大模型的一站式云服务平台,为开发者提供更快、更便宜、更全面、体验更丝滑的模型API。

目前,SiliconCloud已上架包括DeepSeek-Coder-V2、Stable Diffusion 3 Medium、Qwen2、GLM-4-9B-Chat、DeepSeek V2、SDXL、InstantID在内的多种开源大语言模型、图片生成模型,支持用户自由切换符合不同应用场景的模型。同时,SiliconCloud提供开箱即用的大模型推理加速服务,为生成式AI应用带来更高效的用户体验。

我们知道在国内使用OpenAI不太方便同时成本也比较高。现在已经有很多开源的大模型了,但是对于个人开发者而言,部署它们的一大难点是硬件资源。没有显卡,也能部署一些参数少一些的开源大模型,但是推理速度肯定是很慢的,这里选择硅基流动的原因是第一,之前注册送了42元的额度,该额度不会过期,可以一直使用,第二,试了一下推理速度真的很快,第三(也是最重要的一点)(白嫖),硅基流动宣布:SiliconCloud平台的Qwen2(7B)、GLM4(9B)、Yi1.5(9B)等顶尖开源大模型免费使用。

构建什么样的工具

最近在学习Avalonia,动手做一个小工具实现自己的需求是一个很好的开始。同时对SemanticKernel也比较感兴趣,所以选择从最基本的制作一个基于大模型的聊天应用开始。个人对大模型的一大需求就是翻译,在查看英文网站时,遇到不太理解的地方,总喜欢问大模型,将某某某翻译为中文。因此选择构建解决自己这个需求的Avalonia练手小工具。该工具的效果如下所示:

聊天

英译中

中译英

开始实践

在SemanticKernel中使用SiliconCloud提供的API服务

要解决的第一个问题就是如何在SemanticKernel中使用SiliconCloud提供的服务。

SemanticKernel中并没有告诉我们如何连接其他的大模型,但由于SiliconCloud提供的接口是与OpenAI兼容的,因此可以通过在发送请求时,改变发送请求的地址来实现。

添加OpenAIHttpClientHandler类:

public class OpenAIHttpClientHandler : HttpClientHandler
{protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){UriBuilder uriBuilder;switch (request.RequestUri?.LocalPath){case "/v1/chat/completions":uriBuilder = new UriBuilder(request.RequestUri){// 这里是你要修改的 URLScheme = "https",Host = "api.siliconflow.cn",Path = "v1/chat/completions",};request.RequestUri = uriBuilder.Uri;break;}HttpResponseMessage response = await base.SendAsync(request, cancellationToken);return response;}
}

kernel通过这种方式构建:

var handler = new OpenAIHttpClientHandler();
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(modelId: "Qwen/Qwen1.5-7B-Chat",apiKey: "你的apikey",httpClient: new HttpClient(handler));
_kernel = builder.Build();

_kernel为全局私有变量:

private Kernel _kernel;

构建页面

axaml如下所示:

<Window xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:vm="using:AvaloniaChat.ViewModels"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:views="clr-namespace:AvaloniaChat.Views"mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"x:Class="AvaloniaChat.Views.MainWindow"Icon="/Assets/avalonia-logo.ico"Title="AvaloniaChat"><Design.DataContext><!-- This only sets the DataContext for the previewer in an IDE,to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) --><vm:MainViewModel /></Design.DataContext><StackPanel><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*" /><ColumnDefinition Width="*" /></Grid.ColumnDefinitions><Grid Grid.Column="0"><StackPanel><StackPanel Orientation="Horizontal"><Button Content="问AI" Margin="10"Command="{Binding AskCommand}"></Button><!--<Button Content="翻译为:"></Button>--><Label Content="翻译为:"HorizontalAlignment="Center"VerticalAlignment="Center"></Label><ComboBox ItemsSource="{Binding Languages}"SelectedItem="{Binding SelectedLanguage}"HorizontalAlignment="Center"VerticalAlignment="Center"></ComboBox><Button Content="翻译" Margin="10"Command="{Binding TranslateCommand}"></Button></StackPanel>	   <TextBox Height="300" Margin="10"Text="{Binding AskText}"TextWrapping="Wrap"AcceptsReturn="True"></TextBox></StackPanel>    </Grid><Grid Grid.Column="1"><StackPanel><Button Content="AI回答" Margin="10"></Button><TextBox Height="300" 					 Margin="10"Text="{Binding ResponseText}"TextWrapping="Wrap"></TextBox></StackPanel>    </Grid>
</Grid>		</StackPanel>
</Window>

界面效果如下所示:

image-20240703134726518

构建ViewModel

ViewModel如下所示:

public partial class MainViewModel : ViewModelBase
{  private Kernel _kernel;[ObservableProperty]private string askText;[ObservableProperty]private string responseText;[ObservableProperty]private string selectedLanguage;public string[] Languages { get; set; }public MainViewModel(){var handler = new OpenAIHttpClientHandler();var builder = Kernel.CreateBuilder().AddOpenAIChatCompletion(modelId: "Qwen/Qwen1.5-7B-Chat",apiKey: "你的apikey",httpClient: new HttpClient(handler));_kernel = builder.Build();AskText = " ";ResponseText = " ";SelectedLanguage = " ";Languages = new string[] { "中文","英文"};}[RelayCommand]private async Task Ask(){   if(ResponseText != ""){ResponseText = "";}await foreach (var update in _kernel.InvokePromptStreamingAsync(AskText)){ResponseText += update.ToString();         }     }[RelayCommand]private async Task Translate(){string skPrompt =   """{{$input}}将上面的输入翻译成{{$language}},无需任何其他内容""";if (ResponseText != ""){ResponseText = "";}await foreach (var update in _kernel.InvokePromptStreamingAsync(skPrompt, new() { ["input"] = AskText,["language"] = SelectedLanguage })){ResponseText += update.ToString();}}
}

使用流式返回

[RelayCommand]
private async Task Ask()
{   if(ResponseText != ""){ResponseText = "";}await foreach (var update in _kernel.InvokePromptStreamingAsync(AskText)){ResponseText += update.ToString();         }     
}

实现效果如下:

写提示

当我们需要翻译功能的时候,只需要翻译文本,其他的内容都不要,简易的模板如下:

 string skPrompt =   """{{$input}}将上面的输入翻译成{{$language}},无需任何其他内容""";

{{$input}}{{$language}}是模板里的参数,使用时会被替换,如下所示:

 await foreach (var update in _kernel.InvokePromptStreamingAsync(skPrompt, new() { ["input"] = AskText,["language"] = SelectedLanguage })){ResponseText += update.ToString();}

通过以上这几个步骤,我们就使用Avalonia制作完成一个简易的小工具了。

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

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

相关文章

如何使用缓存提升SpringBoot性能(EhCache和Redis方式)

一、简介 缓存是通过将频繁访问的数据存储在内存中来提高Web应用程序性能的重要策略&#xff0c;从而减少对数据库等较慢的存储系统的重复进行数据检索操作的需求。在这里将介绍如何使用流行的缓存实现&#xff08;如EhCache和Redis等&#xff09;&#xff0c;专门为Spring Bo…

使用 Smart-doc 记录 Spring REST API

如果您正在使用 Spring Boot 开发 RESTful API&#xff0c;您希望让其他开发人员尽可能容易地理解和使用您的 API。文档是必不可少的&#xff0c;因为它为将来的更新提供了参考&#xff0c;并帮助其他开发人员与您的 API 集成。很长一段时间以来&#xff0c;记录 REST API 的方…

java设计模式(十二)享元模式(Flyweight Pattern)

1、模式介绍&#xff1a; 享元模式是一种结构型设计模式&#xff0c;旨在通过共享对象来有效支持大量细粒度的对象。它通过将对象的状态分为内部状态&#xff08;可共享&#xff09;和外部状态&#xff08;不可共享&#xff09;来减少内存消耗和提高性能。内部状态存储在享元对…

苏东坡传-读书笔记九

我们论到苏东坡&#xff0c;我们就不能避免“气”这个字。因为每个文学批评家综括苏东坡的个性&#xff0c;必用孟子所说的这个“气”字。 在《孟子》里&#xff0c;“气”是哲学的概念&#xff0c;类似柏格森所说的“生气勃勃”&#xff0c;是人格上的“元气”。使伟人和匹夫显…

419. 甲板上的战舰

419. 甲板上的战舰 题目链接&#xff1a;419. 甲板上的战舰 代码如下&#xff1a; class Solution { public:int countBattleships(vector<vector<char>>& board) {int res0;int rowboard.size(),colboard[0].size();for(int i0;i<row;i){for(int j0;j&l…

深度学习中的Logits处理:InvalidScoreLogitsProcessor详解

深度学习中的Logits处理&#xff1a;InvalidScoreLogitsProcessor详解 基础概念InvalidScoreLogitsProcessor为什么需要这个处理器&#xff1f;使用示例进阶&#xff1a;自定义LogitsProcessor结论 在自然语言处理(NLP)任务中,特别是在使用大型语言模型(LLM)进行文本生成时,我们…

【 2024!深入了解 大语言模型(LLM)微调方法(总结)】

引言 众所周知&#xff0c;大语言模型(LLM)正在飞速发展&#xff0c;各行业都有了自己的大模型。其中&#xff0c;大模型微调技术在此过程中起到了非常关键的作用&#xff0c;它提升了模型的生成效率和适应性&#xff0c;使其能够在多样化的应用场景中发挥更大的价值。 那么&…

《C++20设计模式》桥接模式经验分享

文章目录 一、前言二、探讨一个类有多个抽象父类的情况&#xff08;为什么会有桥接&#xff09;三、桥接模式3.1 UML类图3.2 实现 四、最后 一、前言 怎么判断你是否理解桥接模式了呢&#xff1f;&#x1f9d0; 试着回答下面这个问题吧&#xff01;&#x1f60b; 桥接模式到底…

Current request is not a multipart request

看了许多博客的解决方法&#xff0c;感觉还是不太懂&#xff0c;看了这个解决了问题。 从源码角度详细解析

【数据库】范式

文章目录 1. 第一范式&#xff08;1NF&#xff09;2. 第二范式&#xff08;2NF&#xff09;3. 第三范式&#xff08;3NF&#xff09;4. 巴斯-科德范式&#xff08;BCNF&#xff09;5. 第四范式&#xff08;4NF&#xff09;6. 第五范式&#xff08;5NF&#xff0c;又称完美范式&…

heic格式转化jpg有没有免费软件?2024年顶尖的7款heic转jpg工具请收好!

heic格式转化jpg有没有免费软件&#xff1f;heic格式虽然在分辨率上优于jpg&#xff0c;但由于并非所有设备的默认图片格式&#xff0c;许多用户并不太喜欢它。这并不奇怪&#xff0c;因为在非苹果设备上打开HEIC文件可能会遇到困难。因此&#xff0c;人们更倾向于寻找能够免费…

FlinkSQL 开发经验分享

作者&#xff1a;汤包 最近做了几个实时数据开发需求&#xff0c;也不可避免地在使用 Flink 的过程中遇到了一些问题&#xff0c;比如数据倾斜导致的反压、interval join、开窗导致的水位线失效等问题&#xff0c;通过思考并解决这些问题&#xff0c;加深了我对 Flink 原理与机…

监控与安全服务

kali 系统 nmap扫描 网段的扫描 使用脚本扫描 使用john破解密码 哈希算法是一种单向加密的算法&#xff0c;也就是将原始数据生成一串“乱码”只能通过原始数据&#xff0c;生成这串“乱码”&#xff0c;但是不能通过“乱码”回推出原始数据相同的原始数据&#xff0c;生成的乱…

sql优化-单表优化

文章目录 0、索引优化原则1、在docker内部连接mysql2、数据准备3、创建表 dept 和 emp4、插入50万数据到 emp 表中4.1、创建函数4.2、存储过程4.3、调用存储过程 5、查找姓名以"abc"开头的员工信息5.1、执行计划 select * from emp where name like abc%;5.2、sql优化…

React+TS前台项目实战(二十四)-- 全局常用绘制组件Qrcode封装

文章目录 前言Qrcode组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示(pc端 / 移动端) 总结 前言 今天要封装的Qrcode 组件&#xff0c;是通过传入的信息&#xff0c;绘制在二维码上&#xff0c;可用于很多场景&#xff0c;如区块链项目中的区块显示交易地址时就可以用到…

无线领夹麦克风哪个品牌好,推荐口碑最好的麦克风品牌

在5G网络普及的浪潮下&#xff0c;短视频平台的兴起带动了一股全民创作的热潮。无论是城市街头还是乡间小径&#xff0c;人们纷纷拿起手机&#xff0c;记录生活中的点点滴滴。领夹式麦克风凭借其精准的拾音特性和稳定的信号传输&#xff0c;无论是在静止状态还是在移动过程中&a…

Android什么是OSD层图形?

在Android开发中&#xff0c;OSD&#xff08;On-Screen Display&#xff09;层图形指的是在屏幕上直接显示特定信息的技术&#xff0c;这些信息可以是文字、图标、进度条等&#xff0c;主要用于展示应用程序状态、提示信息、操作指引等。从技术难点、面试官关注点以及回答吸引力…

制作一个静态库

1. 准备工作 # 目录结构 add.c div.c mult.c sub.c -> 算法的源文件, 函数声明在头文件 head.h # main.c中是对接口的测试程序, 制作库的时候不需要将 main.c 算进去 . ├── add.c ├── div.c ├── include │ └── head.h ├── main.c ├── mult.c └── s…

Node.js适合什么场景下使用

Node.js是一个基于Chrome V8 JavaScript引擎构建的开源运行时环境&#xff0c;它允许开发者使用JavaScript在服务器端运行代码。Node.js具有高性能、轻量级、事件驱动和非阻塞I/O等特性&#xff0c;这些特性使得它在多种场景下具有广泛的应用。以下是Node.js适合使用的几个主要…