AABBbaby

导航

DevExpress WinForms中文教程 - 如何在Grid控件中集成语义相似性搜索?

许多用户都知道Microsoft的Daniel Roth和Steve Sanderson引入的.NET智能组件——AI驱动的UI控件,许多人都喜欢这个控件原因归结为以下几点:

  • 由于它的简单性,开发人员可以在本地“驾驭AI”,而无需获得Azure或OpenAI PhD - 智能功能使用单个NuGet包即可使用。
  • “智能搜索”是通过本地嵌入实现的,它的优点在于能够在本地运行,而不需要外部人工智能服务。
  • 相关的使用场景很有意义——许多业务线(LOB)应用程序可以立即从这个实现中受益。以语义相似度搜索为例:终端用户可以在使用DevExpress Data Grid、Lookup或其他数据感知控件时搜索“furniture”这个词,并且实现足够智能,可以返回“chair”、“table”、“sofa”、"wardrobe"等记录。

P.S:DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!

获取DevExpress WinForms v24.1正式版下载

DevExpress技术交流群10:532598169      欢迎一起进群讨论

问题/使用场景

上面提到的例子采用ASP. NET Core Blazor和MVC/Razor集成,在本文中我们将演示如何使用DevExpress WinForms数据网格轻松引入“智能搜索”,其他数据感知DevExpress UI控件的集成也类似——您只需要使用适当的事件来实现期望的结果。

DevExpress WinForms中文教程图集
实现细节

1. Microsoft的 SmartComponents.LocalEmbeddings NuGet(作为一个实验性的GitHub仓库)是我们“智能搜索”实现的核心——只是把它和DevExpress.Win.Grid包一起添加到WinForms项目中。

DevExpress WinForms中文教程图集

让我们仔细看看Microsoft的GitHub repo本地嵌入:

嵌入用于语义相似度搜索,自然语言字符串被转换成称为嵌入的数字向量。两个字符串在概念上越相关,它们的向量就越接近。虽然您可以使用外部AI服务来计算嵌入,但在许多情况下,可以简单地再服务器上本地计算它们(不需要GPU - CPU就可以正常工作)。SmartComponents.LocalEmbeddings是一个简化此操作的包,使用它您可以在一毫秒内计算嵌入,并在一位数毫秒内对数十万个候选项执行语义搜索。

SmartComponents.LocalEmbeddings NuGet包实际上不包含任何ML模型,但它被配置为在您第一次构建应用程序时下载一个模型,您可以配置下载哪个模型。

有关这方面的更多信息,请查看了解Understand embeddings in Azure OpenAI Service在web上搜索类似的文章。ONNX嵌入模型(由Microsoft.ML.OnnxRuntime.dll提供支持)会自动从SmartComponents.LocalEmbeddings NuGet包中添加到Bin文件夹中 - 它的大小为16MB。

DevExpress WinForms中文教程图集

2. 被绑定到一个Item记录的集合(ID, Name, Description),测试数据是人工智能生成的(节省时间)。我们处理网格的ColumnView.CustomRowFilter 事件来确定搜索字符串行的可见性(基于条目文本相似度—在本例中为Name和Description,可选),当处理键盘输入或更改搜索选项(如相似性阈值)时,也会触发过滤例程。

void OnCustomRowFilter(object sender, RowFilterEventArgs e) {
Item? item = ((ColumnView)sender).DataController.GetRowByListSourceIndex(e.ListSourceRow) as Item;
if(item == null)
return;
string filter = teFilter.Text;
if(string.IsNullOrEmpty(filter))
return;
float threshold = (float)tbThreshold.Value / 100;
e.Visible = SmartFilterProvider.IsSimilarTo(filter, item.Name, threshold);
if(!e.Visible && cbIncludeDescription.Checked)
e.Visible = SmartFilterProvider.IsSimilarTo(filter, item.Description, threshold);
e.Handled = true;
}

3. “智能搜索”是由SmartFilterProvider类实现的——它调用了SmartComponents. LocalEmbeddings API基于GitHub repo中发布的文档。

namespace SmartAIFilter.Provider {
using SmartComponents.LocalEmbeddings;

public static class SmartFilterProvider {
readonly static LocalEmbedder Embedder = new LocalEmbedder(caseSensitive: false);
readonly static ConcurrentDictionary<string, EmbeddingF32> cache =
new ConcurrentDictionary<string, EmbeddingF32>(StringComparer.OrdinalIgnoreCase);
public static bool IsSimilarTo(string filter, string text, float threshold = 0.75f) {
EmbeddingF32 eText = cache.GetOrAdd(text, x => Embedder.Embed(x));
EmbeddingF32 eFilter = cache.GetOrAdd(filter, x => Embedder.Embed(x));
return eFilter.Similarity(eText) > threshold;
}
}
}

上面的LocalEmbedder类使用ONNX运行时——它可以执行许多不同的CPU或GPU嵌入模型(通常,CPU对于这样小的模型工作得更快)。

SmartComponents.LocalEmbeddings NuGet包实际上不包含任何ML模型,但它被配置为在您第一次构建应用程序时下载一个模型。如前所述,您可以配置下载哪个模型。

作为一名开发人员,您可以根据特定用例场景/项目需求来调整这个示例。例如,您可以根据需要使用在线(OpenAI, Azure等)或离线模型(Ollama, ONNX)。

posted on 2024-07-09 09:57  AABBbaby  阅读(2)  评论(0编辑  收藏  举报