【项目记录】QLLMChat(模型对话客户端 代码 - 输出+渲染)
这是什么
https://github.com/quxingbai/QLLMChat
示例
可以手动选择由IMultiChatTypes接口实现后的方法所提供的多种模型。
然后可以选择提示词副本 也就是 身份,每次发消息都会在后面追加一条system,也就是这个身份文件带的内容。
测试下来Coder模型更好用一些

使用
目前支持直接输出WPF UI 也可以切换到源代码查看
如果无法渲染会直接把错误信息渲染成Element放出来

前提是模型输出的内容是正确的。
它们训练可能使用了大量的Html,然后让它输出WPF控件的时候就很容易搞混某些属性,圆角 或者默认显示的问题本之类的。
它的原理就是通过提示词 让模型必须输出那些指定的格式
就像这样 它每次输出需要渲染的Xaml代码都会被 QLLMRender 包裹,然后Type指定代码类型


比如说到一些难实现的功能,它就有很大概率失败...

因为代码是这么写的....

就因为提示词里的这一句。所以说目前的难点在于提示词的作用

所以很多时候都需要一些模板来约束输出的内容
就像个颜色输出模板
不过模板多了又会消耗上下文的Token数量...

具体实现上
由于模型输出都是Markdown,所以引用了 Markdig.Wpf.MarkdownViewer 的Markdown渲染。
但是由于需要渲染WPF 或者其他的什么东西,所以就得重写某一部分功能。
这里的重写后的主体代码是Copilot写的 很好用,稍微有些细节 渲染失败后怎么办,渲染出来的东西如何放置稍微改一下就跑起来了。
private string HandleMarkdownChanged(string markdown)
{
CancelPendingInject();
if (markdown is null)
markdown = string.Empty;
// 匹配所有完整的 <QLLMRender ...>...</QLLMRender> 块
var matches = Regex.Matches(markdown, @"<QLLMRender\b([^>]*)>(.*?)</QLLMRender>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
var renderItems = new List<(string Id, RenderItem Item)>();
var sanitizedBuilder = markdown;
int indexShift = 0; // not strictly needed since we do Replace with Regex later
int idCounter = 0;
foreach (Match match in matches)
...
配置
在APP的Startup里进行了依赖注入,实现几个关键接口就能替换目前的数据源
protected override void OnStartup(StartupEventArgs e)
{
var service = new ServiceCollection();
//这里是数据库的注入,可以根据需要替换成其他数据库实现
//比如目前除了Json还有一个内存数据库MemoryDatabase,后续也可以添加其他数据库实现
service.AddSingleton<IChatDataBase, JsonDatabase>(p =>
{
return new JsonDatabase("./chatdata.json");
});
//这里是聊天模型的注入,可以根据需要替换成其他聊天模型实现,实现了IMultiChatTypes接口的聊天模型会在界面上显示不同的模型,
// public class OllamaChat : IChatModel, IMultiChatTypes
service.AddSingleton<IChatModel, OllamaChat>();
service.AddSingleton<IDispatcherProvider, AppDispatcher>();
service.AddTransient<MainWindowViewModel>();
service.AddTransient<MainChatPageViewModel>();
service.AddTransient<MainWindow>();
ServiceProvider serviceProvider = service.BuildServiceProvider();
var window = serviceProvider.GetRequiredService<MainWindow>();
window.Show();
base.OnStartup(e);
}
提示词文件
提示词会放在执行目录下的Roles/中,每层都是一个文件夹,文件夹名会被识别为提示词的组名,然后内容中的Main.txt将会读取为system提示词。



浙公网安备 33010602011771号