Avalonia是什么?

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

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

SemanticKernel是什么?

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

硅基流动介绍

硅基流动致力于打造大模型时代的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)
{
// 这里是你要修改的 URL
Scheme = "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>

界面效果如下所示:

构建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制作完成一个简易的小工具了。

动手学Avalonia:基于SemanticKernel与硅基流动构建AI聊天与翻译工具的更多相关文章

  1. 【Datawhale】动手学数据分析

    动手学数据分析 第一章:数据载入及初步观察 载入数据 任务一:导入numpy和pandas import numpy as np import pandas as pd 任务二:载入数据 train_ ...

  2. 对比《动手学深度学习》 PDF代码+《神经网络与深度学习 》PDF

    随着AlphaGo与李世石大战的落幕,人工智能成为话题焦点.AlphaGo背后的工作原理"深度学习"也跳入大众的视野.什么是深度学习,什么是神经网络,为何一段程序在精密的围棋大赛中 ...

  3. 【动手学深度学习】Jupyter notebook中 import mxnet出错

    问题描述 打开d2l-zh目录,使用jupyter notebook打开文件运行,import mxnet 出现无法导入mxnet模块的问题, 但是命令行运行是可以导入mxnet模块的. 原因: 激活 ...

  4. 小白学习之pytorch框架(2)-动手学深度学习(begin-random.shuffle()、torch.index_select()、nn.Module、nn.Sequential())

    在这向大家推荐一本书-花书-动手学深度学习pytorch版,原书用的深度学习框架是MXNet,这个框架经过Gluon重新再封装,使用风格非常接近pytorch,但是由于pytorch越来越火,个人又比 ...

  5. 基于echarts的带流动光效的折线图-lowline-for-echarts使用记录

    起源 在技术群看到有人问这个react插件,带着好奇心看了一下. 标题:基于echarts的带流动光效的折线图 - 掘金 网址:https://juejin.cn/post/7090566240233 ...

  6. 基于tcp和多线程的多人聊天室-C语言

    之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...

  7. 基于jersey和Apache Tomcat构建Restful Web服务(二)

    基于jersey和Apache Tomcat构建Restful Web服务(二) 上篇博客介绍了REST以及Jersey并使用其搭建了一个简单的“Hello World”,那么本次呢,再来点有趣的东西 ...

  8. 基于jersey和Apache Tomcat构建Restful Web服务(一)

    基于jersey和Apache Tomcat构建Restful Web服务(一) 现如今,RESTful架构已然成为了最流行的一种互联网软件架构,它结构清晰.符合标准.易于理解.扩展方便,所以得到越来 ...

  9. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  10. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

随机推荐

  1. tomcat(2)- tomcat目录结果和配置文件

    目录 1 Tomcat目录结构 2 Tomcat的配置文件 2.1 server.xml配置文件 2.2 server.xml配置文件结构 2.3 WEB应用自动部署 2.4 配置文件各个组件的关联 ...

  2. fastposter v2.9.2 最简海报生成器

    fastposter v2.9.2 程序员必备海报生成器 fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像)即可生成海报. 点击 ...

  3. Linux(三):Linux的目录及相关作用

    使用 Linux,不仅限于学习各种命令,了解整个 Linux 文件系统的目录结构以及各个目录的功能同样至关重要.使用 Linux 时,通过命令行输入 ls -l / 可以看到,在 Linux 根目录( ...

  4. Clear Code for Minimal API

    我在写MinimalAPI的时候,发现不能最清晰的看到每个API,原因就是:WebAPI中不断增长逻辑处理过程 于是我在想如何简化API至一行,在一点一点想办法中,发现了简化DotNET Minima ...

  5. Java基础 韩顺平老师的 常用类 的部分笔记

    459,八大Wrapper类 包装类的分类 1) 针对八种基本数据类型相应的引用类型-包装类 2) 有了类的特点, 就可以调用类中的方法. 460,装箱和拆箱 package com.hspedu.W ...

  6. win10激活方法

    slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX slmgr /skms zh.us.to slmgr /ato

  7. SuperSocket AppServer.NewRequestReceived 不触发 接受不到字节

    SuperSocket AppServer.NewRequestReceived 不触发 接受不到字节 针对.netframework版本 1.6.* 使用 FixedHeaderReceiveFil ...

  8. [NOIP2001 提高组] 数的划分

    个人博客传送锚点:https://www.acwing.com/blog/content/55495/ 传送锚点:https://www.luogu.com.cn/problem/P1025 题目描述 ...

  9. Django——启动项目时报错mysqlclient

    报错内容如下: Watching for file changes with StatReloader Exception in thread django-main-thread: Tracebac ...

  10. golang 无向简单图邻接多重表

    package main import "fmt" type MultipleEdgeNode struct { iVex int iLink *MultipleEdgeNode ...