【译】融入人工智能的 eShop – 全面的智能应用示例

原文 | Jeremy Likness

翻译 | 郑子铭

人工智能 (AI) 是一种强大的工具,它可以增强您的应用程序,提供更好的个性化定制体验,满足客户的独特需求,同时提高内部运营的质量和效率。虽然简单的演示应用程序通常是快速采用新技术的简单方法,但"现实世界"要复杂得多,您希望看到更多使用 AI 的强大、现实启发场景的示例。为了帮助回答不仅仅是"什么是 AI?"这个问题,而且是"如何在我的应用程序中使用 AI?",我们创建了一个应用程序来说明如何将 AI 融入典型的业务线应用程序中。

介绍 eShop"AI 支持"版本

AI 增强型 eShopSupport 应用程序是一个支持站点,客户可使用它来查询产品。eShop 员工有一个工作流程来跟踪这些查询、与客户交谈以及对这些查询进行分类并最终关闭这些查询。通过各种功能,此示例超越了流行的"聊天机器人"场景,说明了 AI 可以提高开发人员工作效率的几种方式,同时提高您能够提供的个性化客户支持水平。

此演示说明了如何使用 AI 来增强现有业务线应用程序中的各种功能,而不仅仅是"绿地"或新应用程序。例如,为什么不使用语义搜索来增强您的搜索功能,即使用户没有输入准确的短语或使用正确的拼写,它也可以找到内容?您是否需要向您的应用程序添加新语言?大型语言模型 (LLM) 能够处理多种语言的输入和输出。您是否需要筛选大量数据来寻找趋势?使用 LLM 来帮助汇总您的数据。如果进入管道,请考虑自动分类和情感分析。

该演示还使用 .NET Aspire 来利用其跨服务、数据存储、容器甚至技术进行编排的能力。Python 是数据科学领域的一种流行语言,但这并不意味着您必须将所有内容都切换到 Python,甚至将 Python 转换为 C#。此示例展示了一种互操作性方法,并使用 .NET Aspire 托管 Python 微服务。

功能

示例中与 AI 相关的功能包括:

功能 描述 代码实现
语义搜索 无需知道确切的短语或描述,甚至无需知道正确的拼写即可查找内容 src / Backend / Services / SemanticSeach
总结 避免"陷入困境"而重新阅读历史以获取背景信息,只需关注相关部分 src / Backend / Services / TicketSummarizer
分类 自动化工作流程,无需人工干预 src / PythonInference / routers / classifier
情感评分 帮助对反馈和讨论进行分类和优先排序,以了解产品或活动的接受程度 src / Backend / Services / TicketSummarizer
内部问答机器人 帮助员工回答技术、业务相关问题,并提供引证,自动生成回复草稿 src / ServiceDefaults / Clients / Backend / StaffBackendClient
测试数据生成 根据您提供的规则生成大量数据 seeddata / DataGenerator / Generators
评估工具 根据准确性、速度和成本客观地对您的机器人/代理的行为进行评分,并随着时间的推移系统地改进它们 src / Evaluator / Program
E2E 测试 当产品本身不确定时提供确定性测试门的示例(实验)方法 test / E2ETest

.NET Aspire 用于管理 LLM 和数据库等资源。Microsoft.Extensions.AI 是一组用于智能应用的通用构建块和原语。开发人员可以使用一组标准 API 来执行常见任务,而库和框架提供商可以在这些通用的标准接口和类的基础上进行构建,以在整个 .NET 生态系统中提供一致的体验。正如 Semantic Kernel 团队 在其博客中宣布的那样,Microsoft.Extensions.AI 版本不会取代 Semantic Kernel。相反,它提供了一组抽象、API 和原语构建块,这些将由 Semantic Kernel 实现,以及语义分块等附加功能。

本地克隆和运行说明

智能应用示例通常需要比典型演示更多的资源和强大的环境才能运行。您可以阅读运行示例的最低要求,并使用最新的分步说明在 eShopSupport 存储库上本地克隆和运行示例。

代码之旅

应用程序背后的"大脑"是用于生成响应的大型语言模型 (LLM)。虽然将 LLM 视为聊天或助手是一种普遍趋势,但此示例演示了如何使用它们来增强业务线应用程序中的各种功能。LLM 用于生成摘要、提供问题的答案、建议回复客户查询,甚至生成测试数据。使用 Microsoft.Extensions.AI 提供的标准原语,您可以使用相同的代码与 LLM 交互,无论它是 Ollama 托管的本地模型还是云中的 Azure OpenAI 服务资源。

选择您的模型

现在您知道可以交换模型,让我们来看看执行此操作的代码。以下代码使用 Microsoft.Extensions.AI 抽象与客户端交互,本地和远程模型之间的唯一区别在于配置方式。您配置的服务和模型将传递到依赖项注入,并使用 Microsoft.Extensions.AI 提供的标准接口进行注册。使用此功能,您可以轻松地从使用 Ollama 等工具的本地模型切换到云托管的 OpenAI 模型。

AppHost 项目中打开 Program.cs,查看模型的配置方式和注入应用程序的方式。例如,要使用 Ollama,您可以按如下方式配置服务:

var chatCompletion = builder.AddOllama("chatcompletion").WithDataVolume();

测试完成,准备部署了吗?没问题。在 appSettings.json 配置中设置 OpenAI 键,然后将调用更改为:

var chatCompletion = builder.AddConnectionString("chatcompletion");

请注意,尽管连接方式不同,但两个实例中的服务名称相同("chatcompletion")。现在,无论您使用哪种模型,代码都是相同的:

var client = services.GetRequiredService<IChatClient>();
var response = await ChatClient.CompleteAsync(
    prompt,
    new ChatOptions ());

ChatOptions 类允许您指定参数,例如要生成的最大令牌数、温度或"创造力"等。它提供了合理的开箱即用默认值,但您可以根据需要对其进行自定义。

生成测试数据

seeddata 文件夹包含用于创建测试数据的 DataGenerator。各种生成器位于 Generators 文件夹中。提示如下所示:

  1. 有多少条记录
  2. 字段创建规则和业务逻辑
  3. 数据的架构(在本例中,提供了一个 JSON 示例)

这种构造提示的方法不仅对数据生成有用。只要您希望以众所周知的结构或格式接收响应,就可以使用该模式,以便对其进行解析。这是自动化某些工作流程和任务的关键。

以下是生成类别的示例提示:

Generate 100 product category names for an online retailer of high-tech outdoor adventure goods and related clothing/electronics/etc.
Each category name is a single descriptive term, so it does not use the word 'and'.
Category names should be interesting and novel, e.g., "Mountain Unicycles", "AI Boots", or "High-volume Water Filtration Plants", not simply "Tents".
This retailer sells relatively technical products.
Each category has a list of up to 8 brand names that make products in that category. 
All brand names are purely fictional. 
Brand names are usually multiple words with spaces and/or special characters, e.g. "Orange Gear", "Aqua Tech US", "Livewell", "E & K", "JAXⓇ".
Many brand names are used in multiple categories. Some categories have only 2 brands.

The response should be a JSON object of the form: 
{ 
    "categories"": [
        {
            "name":"Tents", 
            "brands": [
                "Rosewood", 
                "Summit Kings"]
        }]
}

然后,响应很容易被反序列化并插入到数据库中。

评估模型

LLM 模型不是确定性的,因此使用完全相同的输入可能会产生不同的结果。这带来了一些挑战。您需要一种方法来测试您的提示是否生成了预期的响应,以便您可以通过评估响应的质量来迭代改进提示。您还需要一个基线,当您由于应用程序的更改而遇到回归时,您可以根据该基线进行自动化和分类。

代码提供了"评估"的示例,评估是一组客观问题,用于询问模型并确定其是否扎根。分数基于模型的答案与预期答案的接近程度。完美的分数必须包括手册提供的所有事实,并且没有错误、不相关的陈述或矛盾。问题由基于产品手册的模型生成,并将答案与预期答案进行比较。

这种方法可以帮助您和您的团队确信模型更新或提示调整将实现预期结果。

总结和分类信息

LLM 的一项功能可以节省大量时间并提高效率和生产力,那就是总结和分类信息的能力。假设您是一名客户支持代表,每天收到数百个请求。您需要对每个请求进行分类,以便能够优先处理不满意的客户和关键请求。LLM 可以通过总结和分类请求来提供帮助。它还可以提供情绪分数。情绪、总结和分类都提供了正确的背景信息,让您"一目了然"地对工单进行适当的优先排序。您可以随时阅读原始工单以进行澄清或仔细检查 LLM 的工作。

最好的部分是:所有这些都可以通过一次调用 LLM 来实现。以下是总结、分类和分析工单情绪的提示示例:

You are part of a customer support ticketing system.
Your job is to write brief summaries of customer support interactions. 
This is to help support agents understand the context quickly so they can help the customer efficiently.
Here are details of a support ticket.

Product: "Television Set"
Brand: "Contoso"

The message log so far is:

(customer feedback goes here, such as: "my TV won't turn on" or "it's stuck on a channel that plays nothing but 80s sitcoms")                

Write these summaries:

1. A longer summary that is up to 30 words long, condensing as much distinctive information as possible. Do NOT repeat the customer or product name, since this is known anyway. Try to include what SPECIFIC questions/info were given, not just stating in general that questions/info were given. Always cite specifics of the questions or answers. For example, if there is pending question, summarize it in a few words. FOCUS ON THE CURRENT STATUS AND WHAT KIND OF RESPONSE (IF ANY) WOULD BE MOST USEFUL FROM THE NEXT SUPPORT AGENT.

2. A shorter summary that is up to 8 words long. This functions as a title for the ticket, so the goal is to distinguish what's unique about this ticket.

3. A 10-word summary of the latest thing the CUSTOMER has said, ignoring any agent messages. Then, based ONLY on that summary, score the customer's satisfaction using one of the following phrases ranked from worst to best: (insert list of terms like "angry" to "ecstatic" here) Pay particular attention to the TONE of the customer's messages, as we are most interested in their emotional state.

Both summaries will only be seen by customer support agents.

Respond as JSON in the following form: 
{
    "LongSummary": "string",
    "ShortSummary": "string",
    "TenWordsSummarizingOnlyWhatCustomerSaid": "string",
    "CustomerSatisfaction": "string"
}

如您所见,结果再次是一个可解析的 JSON 对象,可用于更新数据库中的票证。

语义搜索

语义搜索使用语义排名来提供更相关的结果。当您拥有大量项目数据库,并且用户可能不知道他们正在寻找的确切单词或短语时,这尤其有用。 LLM 可以通过根据搜索词的含义提供更相关的搜索结果来提供帮助。搜索的工作原理是将搜索文本转换为"嵌入",即表示文本含义的数字向量。它可以根据含义的对齐方式提供短语之间的"距离"。例如,考虑一个包含以下内容的产品目录:

  • 显微镜 - 强大的 200 倍放大倍率可揭示世界上最微小的奇迹
  • 望远镜 - 焦距为 2,350 毫米,足以观察遥远的星系
  • 手套 - 不要让您的手太冷

在传统搜索中,如果客户输入"micrscope"(故意拼写错误),则搜索不会返回任何结果,因为没有完全匹配。使用语义搜索,搜索将认为此字符串与显微镜的条目最接近。同样,如果用户搜索"skiing",它会选择"gloves"条目作为更接近的匹配项,而不是"microscope"或"telescope"的条目,即使拼写没有相似之处。

repo 包含几个类,它们在 Services 文件夹中提供语义搜索的实现。

关于端到端测试的说明

为确保完整性,我们引入了一种端到端测试方法。eShop 支持中的示例完全是实验性的,不应视为生产指南。对智能应用进行自动化测试面临许多挑战,从资源限制和成本控制到模型不确定的事实。提供的示例是一种控制模型变化并确保应用行为与预期结果一致的方法。

结论

智能应用时代已经到来,.NET 提供了将 AI 驱动的功能集成到项目中所需的工具。持续评估 AI 的负责任使用至关重要。例如,不要假设 AI 总是正确的。这就是为什么应用程序的设计使得实际客户响应不是自动的。会生成建议的响应,但仍需人工审核和发送。AI 加速了这一过程,但人类仍在掌控之中。

类似地,自动化支持工单的工作流程会对某个类别做出"最佳猜测",但如果猜测不正确,人类可以随时推翻这一猜测。该应用还会量化响应的质量,以便您可以系统地改进响应。这些只是 AI 如何与人类合作(而不是取代人类)以增强您的应用体验并提高生产力的几个例子。

如需深入了解,请查看 Jason Haley 的 eShopSupport 博客系列

来吧,它已经为您准备好了!下载 eShopSupport 智能 .NET 应用示例并立即开始探索代码!

原文链接

eShop infused with AI -- a comprehensive intelligent app sample

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com)