探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用

semantic,kernel,conversationsummaryplugin · 浏览次数 : 0

小编点评

前言 在前几章中,我们已经了解了Semantic Kernel插件的概念,并学习了如何基于Prompts构造语义插件和基于本地方法构建原生插件。本章将介绍Semantic Kernel中的一些内置插件,以避免重复劳动。 内置插件 Semantic Kernel提供了许多预定义插件,以满足通用业务需求。这些插件分为多个类库,每个类库都包含一组相关功能的插件SDK。其中,Plugins.Core提供了常用插件集合。以下是Plugins.Core中的一些插件: 1. ConversationSummaryPlugin:对话总结插件 2. FileIOPlugin:读写文件插件 3. HttpPlugin:HTTP请求功能插件 4. MathPlugin:数学计算插件 5. TextPlugin:字符串操作插件 6. TimePlugin:获取当前时间和日期插件 7. WaitPlugin:等待插件 实战 在本节中,我们将通过一个实战练习来展示如何使用Semantic Kernel内置插件。首先,我们需要安装Nuget包。然后,我们将注册插件,并使用插件功能对对话进行摘要和提取行动项。 1. 安装Nuget包 使用Visual Studio的包管理器安装Microsoft.SemanticKernel.Plugins.Core包,并勾选预览发行版。 2. 注册插件 ```csharp var conversationSummaryPlugin = kernel.ImportPluginFromType(); var customCustomConversationSummaryPlugin = kernel.ImportPluginFromType(); ``` 3. 使用插件功能 a. 总结会话内容 ```csharp FunctionResult summary = await kernel.InvokeAsync(conversationSummaryPlugin["SummarizeConversation"], new() { ["input"] = chatTranscript }); Console.WriteLine($"Generated Summary:{summary.ToString()}"); ``` b. 提取会话行动项 ```csharp FunctionResult actionItems = await kernel.InvokeAsync(conversationSummaryPlugin["GetConversationActionItems"], new() { ["input"] = chatTranscript }); Console.WriteLine($"Generated Action Items:{summary.ToString()}"); ``` c. 提取会话主题 ```csharp FunctionResult topics = await kernel.InvokeAsync(conversationSummaryPlugin["GetConversationTopics"], new() { ["input"] = chatTranscript }); Console.WriteLine($"Generated Topics:{summary.ToString()}"); ``` 通过以上示例,我们可以看到Semantic Kernel内置插件在对话摘要、行动项提取和主题提取方面的实用价值。这些插件可以帮助我们更高效地进行聊天记录管理和任务跟踪。

正文

前言

经过前几章的学习我们已经熟悉了Semantic Kernel 插件的概念,以及基于Prompts构造的Semantic Plugins和基于本地方法构建的Native Plugins。本章我们来讲解一下在Semantic Kernel 中内置的一些插件,让我们避免重复造轮子。

内置插件

Semantic Kernel 有非常多的预定义插件,作为解决通用业务的相关能力。Plugins 地址

image

这里面每一个类库都是一组相关功能的插件SDK,其中Plugins.Core 里面提供的使我们高频使用的插件集合。

Plugins.Core

image

可以看到Plugins.Core 内有以下几个插件:

  • ConversationSummaryPlugin: 对话总结插件
  • FileIOPlugin: 读写文件插件
  • HttpPluginHttp请求功能的插件
  • MathPluginMath 计算插件
  • TextPlugin:字符串操作插件
  • TimePlugin:获取当前时间和日期插件
  • WaitPluginWaitPlugin提供了一组函数,在进行其余操作之前等待。

实战

我们来对Semantic Kernel中提供的内置插件来做一个实战练习

第一步需要安装Nuget

NuGet\Install-Package Microsoft.SemanticKernel.Plugins.Core -Version 1.14.1-alpha

该包目前只有预览版本,如果用 VS 的包管理器安装,那需要勾选包括预览发行版

ConversationSummaryPlugin

这是一个对话总结插件,以提示词构造的Semantic Plugins,插件内定义了三个Kernel Function分别是:

  • SummarizeConversation :给定一段长的对话记录,总结谈话内容
  • GetConversationActionItems:给定一段长的对话记录,识别出其中的行动项。
  • GetConversationTopics:给定一段长的对话记录,识别出值得记住的主题
SummarizeConversation

我们先定义一个对话用户我们测试的对话数据


string chatTranscript = @"
A: 你好,最近工作很忙碌,我们需要安排下周的会议时间,你觉得周几比较合适?
B: 嗯,我明白,工作确实很忙。周三或周四应该比较合适,因为那时候大家的日程相对空闲一些。
A: 好的,周三或周四都可以,我们再确认一下其他同事的时间表。
B: 对,最好再和大家核实一下,免得出现时间冲突。
A: 我今天会发邮件询问大家的意见,然后我们再做最终决定。
B: 好的,我也会在群里提醒大家留意邮件。

A: 大家好,关于下周的会议安排,我建议定在周四下午两点,在会议室A举行,大家觉得怎么样?
C: 周四下午两点可以,我在日历上已经标注了。
D: 对不起,周四下午我有其他安排,能否改到周三下午呢?
A: 好的,我们尽量照顾大家的时间,那就改到周三下午两点吧,地点仍然是会议室A。
B: 没问题,我会通知其他同事,让大家知道时间的变动。

";

Kernel注册插件:

var conversationSummaryPlugin = kernel.ImportPluginFromType<ConversationSummaryPlugin>();

总结会话内容

Console.WriteLine("SamplePlugins - Conversation Summary Plugin - Summarize");
{
    FunctionResult summary = await kernel.InvokeAsync(
        conversationSummaryPlugin["SummarizeConversation"], new() { ["input"] = chatTranscript });

    Console.WriteLine($"Generated Summary:{summary.ToString()}");
}

OutPut:

Generated Summary:In the conversation, A and B discuss scheduling a meeting for the following week, considering Wednesday or Thursday as potential dates due to lighter schedules. A decides to send an email to confirm the availability of all colleagues. Later, A proposes holding the meeting on Thursday at 2 PM in Conference Room A, but D requests a change due to a scheduling conflict. A agrees to reschedule the meeting to Wednesday at 2 PM in the same room, and B confirms that they will inform the rest of the team about the change.

Semantic Kernel的这个插件我用了GPT-4oKimi都回复的是英文,我感觉这个内置的这个Semantic Kernel 插件还是不够完善。

我们可以看一下SummarizeConversation方法的Prompts定义

BEGIN CONTENT TO SUMMARIZE:
{{$INPUT}}

END CONTENT TO SUMMARIZE.

Summarize the conversation in 'CONTENT TO SUMMARIZE', identifying main points of discussion and any conclusions that were reached.
Do not incorporate other general knowledge.
Summary is in plain text, in complete sentences, with no markup or tags.

BEGIN SUMMARY:

简要理解一下这个提示词:

  • 开始标记:BEGIN CONTENT TO SUMMARIZE: 这个标记清晰地指示了摘要内容的开始。

  • 输入占位符:{{$INPUT}} 这是一个占位符,用于插入需要被摘要的对话或文本内容。

  • 结束标记:END CONTENT TO SUMMARIZE. 这个标记同样清晰地指示了摘要内容的结束。

  • 摘要指导:提供了对摘要的具体要求,包括识别对话的主要讨论点和结论,并且强调不要包含外部的一般知识。

  • 格式要求:指出摘要应该是纯文本,用完整的句子表达,不包含任何标记或标签。

  • 摘要开始标记:BEGIN SUMMARY: 这个标记指示了摘要部分的开始。

针对上述我们发现的问题:会话摘要全部是中文的问题 我觉得可以进行提示词的优化

优化的第一点内容是:总结应选择最切合内容的语言in the language that best fits the content.

@"BEGIN CONTENT TO SUMMARIZE:
{{$INPUT}}

END CONTENT TO SUMMARIZE.

Please summarize the conversation, highlighting the main points and any conclusions reached, in the language that best fits the content. Do not incorporate any external general knowledge. The summary should be in plain text, in complete sentences, without any markup or tags.

BEGIN SUMMARY:

我们自定义一个插件测试一下,创建一个CustomConversationSummaryPlugin的插件,这个和原生SummarizeConversation插件只有Prompts有区别

    private const int MaxTokens = 1024;

    private readonly KernelFunction _summarizeConversationFunction;
    public CustomConversationSummaryPlugin()
    {


        PromptExecutionSettings settings = new()
        {
            ExtensionData = new Dictionary<string, object>()
            {
                { "Temperature", 0.1 },
                { "TopP", 0.5 },
                { "MaxTokens", MaxTokens }
            }
        };

        this._summarizeConversationFunction = KernelFunctionFactory.CreateFromPrompt(
            CustomConversationSummaryPlugin.SummarizeConversationDefinition,
            description: "Given a section of a conversation transcript, summarize the part of the conversation.",
            executionSettings: settings);
    }

    /// <summary>
    /// Given a long conversation transcript, summarize the conversation.
    /// </summary>
    /// <param name="input">A long conversation transcript.</param>
    /// <param name="kernel">The <see cref="Kernel"/> containing services, plugins, and other state for use throughout the operation.</param>
    [KernelFunction, Description("Given a long conversation transcript, summarize the conversation.")]
    public Task<string> SummarizeConversationAsync(
        [Description("A long conversation transcript.")] string input,
        Kernel kernel) =>
        ProcessAsync(this._summarizeConversationFunction, input, kernel);
    private static async Task<string> ProcessAsync(KernelFunction func, string input, Kernel kernel)
    {
        List<string> lines = TextChunker.SplitPlainTextLines(input, MaxTokens);
        List<string> paragraphs = TextChunker.SplitPlainTextParagraphs(lines, MaxTokens);

        string[] results = new string[paragraphs.Count];

        for (int i = 0; i < results.Length; i++)
        {
            // The first parameter is the input text.
            results[i] = (await func.InvokeAsync(kernel, new() { ["input"] = paragraphs[i] }).ConfigureAwait(false))
                .GetValue<string>() ?? string.Empty;
        }

        return string.Join("\n", results);
    }

Kernel对象注册自定义插件

var customCustomConversationSummaryPlugin = kernel.ImportPluginFromType<CustomConversationSummaryPlugin>();

新跑一边测试一下:

Generated Summary:在这段对话中,A和B讨论了安排下周会议的时间。B建议周三或周四比较合适,因为那时大家的日程相对空闲。A决定通过邮件询问其他同事的意见,然后做出最终决定 。在邮件中,A提议将会议安排在周四下午两点,地点是会议室A。然而,D表示周四下午有其他安排,请求将会议改到周三下午。A同意了D的请求,将会议时间调整为周三下午两点,地点仍然是会议室A。B表示会通知其他同事关于时间变动的情况。

可以看到满足我们的需求了,根据我们输入生成的摘要信息没有问题了。

这个插件对于我们的聊天会话也是十分有用,对话历史记录随着不断聊天,消息越来越多,那每次对话消耗的 token 也是不断增加,此时 ConversationSummaryPlugin 插件的就可以帮助我们对聊天记录进行摘要总结,提高聊天效率。

提取会话行动项

识别对话记录中的动作项(action items)是一种重要的沟通技巧,它有助于提高效率、确保任务的完成和促进团队协作。

使用场景包括:

  • 会议记录:在会议结束后,快速生成包含所有动作项的摘要,便于团队成员执行和跟踪。
  • 项目管理:在项目讨论中,识别和记录关键的里程碑和任务,确保项目按时进展。
  • 客户服务:在客户沟通中,记录客户的请求和需要采取的行动,以提供更好的服务和支持。
  • 团队协作工具:集成到团队协作平台中,帮助团队成员共享和协调任务。
  • 个人生产力:个人使用该插件来管理自己的任务和待办事项,提高个人效率。
  • 法律和合规性:在需要确保对话内容符合特定法规或标准的情况下,识别必要的行动以确保合规。

要完成这个需要用到ConversationSummaryPlugin插件的GetConversationActionItems方法

Console.WriteLine("======== SamplePlugins - Conversation Summary Plugin - Action Items ========");
{

    FunctionResult summary = await kernel.InvokeAsync(
        conversationSummaryPlugin["GetConversationActionItems"], new() { ["input"] = chatTranscript });

    Console.WriteLine($"Generated Action Items:{summary.ToString()}");
    Console.WriteLine(summary.GetValue<string>());

}

输出:

{
    "actionItems": [
        {
            "owner": "A",
            "actionItem": "发邮件询问大家的意见",
            "dueDate": "",
            "status": "Open",
            "notes": "今天会发"
        },
        {
            "owner": "B",
            "actionItem": "在群里提醒大家留意邮件",
            "dueDate": "",
            "status": "Open",
            "notes": ""
        },
        {
            "owner": "B",
            "actionItem": "通知其他同事时间的变动",
            "dueDate": "",
            "status": "Open",
            "notes": "让大家知道时间的变动"
        }
    ]
}

提取会话的主题

用于对话摘要的工具或插件,它的作用是帮助用户快速识别和总结对话中的主要话题。

使用场景可能包括但不限于:

  • 企业内部会议的快速摘要和信息整理。
  • 客户服务对话的分析,以识别服务改进点。
  • 社交媒体或论坛讨论的监控和摘要。
  • 教育环境中的课堂讨论摘要。
  • 法律咨询或案件讨论的记录和审查。

要完成这个功能需要用到ConversationSummaryPlugin插件的GetConversationTopics方法

使用:

    Console.WriteLine("======== SamplePlugins - Conversation Summary Plugin - Topics ========");

    FunctionResult summary = await kernel.InvokeAsync(
        conversationSummaryPlugin["GetConversationTopics"], new() { ["input"] = chatTranscript });

    Console.WriteLine($"Generated Topics:{summary.ToString()}");

输出:

Generated Topics:
{
  "topics": [
    "Work busy",
    "Schedule meeting",
    "Wednesday or Thursday",
    "Confirm colleagues' availability",
    "Email for opinions",
    "Meeting reschedule",
    "Thursday 2 PM",
    "Change to Wednesday 2 PM",
    "Notify colleagues"
  ]
}

最后

剩下的插件我们后续章节在讲解吧,本章重点讲解了ConversationSummaryPlugin 会话总结插件的使用。

示例代码

本文源代码

与探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用相似的内容:

探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用

前言 经过前几章的学习我们已经熟悉了Semantic Kernel 插件的概念,以及基于Prompts构造的Semantic Plugins和基于本地方法构建的Native Plugins。本章我们来讲解一下在Semantic Kernel 中内置的一些插件,让我们避免重复造轮子。 内置插件 Sem

探索Semantic Kernel内置插件:深入了解HttpPlugin的应用

前言 上一章我们熟悉了Semantic Kernel中的内置插件和对ConversationSummaryPlugin插件进行了实战,本章我们讲解一下另一个常用的内置插件HttpPlugin的应用。 上一章对ConversationSummaryPlugin总结进行了调整之后,顺便给Semantic

探索Semantic Plugins:开启大模型的技能之门

前言 在之前的章节中我们或多或少的已经接触到了 Semantic Kernel 的 Plugins,本章我们讲详细介绍如何使用插件。 Semantic Kernel 的一大特点是拥有强大的插件,通过结合自定义/预定义的插件解决智能业务的问题。让传统的代码和智能插件一起工作灵活地接入到应用场景简化传统

探索 SK 示例 -- GitHub 存储库中的机器人

微软 3月22日 一篇文章“Semantic-kernel 嵌入和记忆:使用聊天UI探索GitHub Repos”[1] ,文章中进行了展示了嵌入,该文章解释了他们如何帮助开发人员提出有关GitHub存储库的问题或使用自然语言查询探索GitHub存储库。与嵌入一起,这是在SK存储器[2](嵌入集合)

探索Native Plugins:开启大模型的技能之门

前言 上一章节我们了解了一下Semantic Kernnel中Plugins插件的概念以及学习了的 Semantic Kernel 模板插件的创建,本章节我们来学习 Native Plugins 原生函数插件使用。 通过函数定义插件 在之前的章节中我们介绍过在在 Semantic Kernel 中应

.NET周报 【4月第1期 2023-04-02】

国内文章 探索 SK 示例 -- GitHub 存储库中的机器人 https://www.cnblogs.com/shanyou/p/17280627.html 微软 3月22日 一篇文章“Semantic-kernel 嵌入和记忆:使用聊天UI探索GitHub Repos”[1] ,文章中进行了展

文章《Semantic Kernel -- LangChain 的替代品?》的错误和疑问 探讨

微信公众号文章 Semantic Kernel —— LangChain 的替代品?[1] ,它使用的示例代码是Python ,他却发了这么一个疑问:支持的语言对比(因为 Semantic Kernel 是用 C#开发的,所以它对 C#比较支持)如上所示。不清楚 Semantic Kernel 为什

[转帖]探索惊群 ①

https://wenfh2020.com/2021/09/25/thundering-herd/ 惊群比较抽象,类似于抢红包 😁。它多出现在高性能的多进程/多线程服务中,例如:nginx。 探索惊群 系列文章将深入 Linux (5.0.1) 内核,透过 多进程模型 去剖析惊群现象、惊群原理、惊

探索贪心算法:解决优化问题的高效策略

贪心算法是一种在每一步选择中都采取当前最佳选择的算法,以期在整体上达到最优解。它广泛应用于各种优化问题,如最短路径、最小生成树、活动选择等。本文将介绍贪心算法的基本概念、特点、应用场景及其局限性。 贪心算法的基本概念 贪心算法的核心思想是局部最优策略,即在每一步选择中都选择当前看起来最优的选项,希望

《探索Python Requests中的代理应用与实践》

本文详细介绍了如何在Python的requests库中使用高匿代理和隧道代理,以及如何部署一个简易的代理IP池来提高爬虫的稳定性和匿名性。同时,文章还深入探讨了野生代理的来源及其潜在的安全风险和使用限制。这篇文章适合希望进一步了解代理技术及其在网络爬虫开发中应用的读者。