第五章 推断

推断任务可以看作是模型接收文本作为输入,并执行某种分析的过程。其中涉及提取标签、提取实体、理解文本情感等等。如果你想要从一段文本中提取正面或负面情感,在传统的机器学习工作流程中,需要收集标签数据集、训练模型、确定如何在云端部署模型并进行推断。这样做可能效果还不错,但是执行全流程需要很多工作。
而且对于每个任务,如情感分析、提取实体等等,都需要训练和部署单独的模型。
LLM 的一个非常好的特点是,对于许多这样的任务,你只需要编写一个 Prompt 即可开始产出结果,而不需要进行大量的工作。这极大地加快了应用程序开发的速度。你还可以只使用一个模型和一个 API 来执行许多不同的任务,而不需要弄清楚如何训练和部署许多不同的模型。

环境配置

参考第二章的 环境配置小节内容即可。

情感推断与信息提取

情感分类

以电商平台关于一盏台灯的评论为例,可以对其传达的情感进行二分类(正向/负向)。


    //评论示例
    private String review = "我需要一盏漂亮的卧室灯,这款灯具有额外的储物功能,价格也不算太高。\n" +
            "我很快就收到了它。在运输过程中,我们的灯绳断了,但是公司很乐意寄送了一个新的。\n" +
            "几天后就收到了。这款灯很容易组装。我发现少了一个零件,于是联系了他们的客服,他们很快就给我寄来了缺失的零件!\n" +
            "在我看来,Lumina 是一家非常关心顾客和产品的优秀公司!";


现在让我们来编写一个 Prompt 来分类这个评论的情感。如果我想让系统告诉我这个评论的情感是什么,只需要编写 “以下产品评论的情感是什么” 这个 Prompt ,加上通常的分隔符和评论文本等等。
然后让我们运行一下。结果显示这个产品评论的情感是积极的,这似乎是非常正确的。虽然这盏台灯不完美,但这个客户似乎非常满意。这似乎是一家关心客户和产品的伟大公司,可以认为积极的情感似乎是正确的答案。


        String prompt = "以下用三个反引号分隔的产品评论的情感是什么?\n" +
                "评论文本: ```{" + review + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative1:\n{}", message);

情感是积极的。

如果你想要给出更简洁的答案,以便更容易进行后处理,可以在上述 Prompt 基础上添加另一个指令:用一个单词回答:「正面」或「负面」。这样就只会打印出 “正面” 这个单词,这使得输出更加统一,方便后续处理。


        String prompt = "以下用三个反引号分隔的产品评论的情感是什么?\n" +
                "    用一个单词回答:「正面」或「负面」。\n" +
                "    评论文本: ```{" + review + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative2:\n{}", message);

正面

识别情感类型

仍然使用台灯评论,我们尝试另一个 Prompt 。这次我需要模型识别出评论作者所表达的情感,并归纳为列表,不超过五项。

        String prompt = "识别以下评论的作者表达的情感。包含不超过五个项目。将答案格式化为以逗号分隔的单词列表。\n" +
                "    评论文本: ```{" + review + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative3:\n{}", message);

满意,感激,积极,赞赏,信任

大型语言模型非常擅长从一段文本中提取特定的东西。在上面的例子中,评论所表达的情感有助于了解客户如何看待特定的产品.

识别愤怒

对于很多企业来说,了解某个顾客是否非常生气很重要。所以产生了下述分类问题:以下评论的作者是否表达了愤怒情绪?因为如果有人真的很生气,那么可能值得额外关注,让客户支持或客户成功团队联系客户以了解情况,并为客户解决问题。


    String prompt = "以下评论的作者是否表达了愤怒?评论用三个反引号分隔。给出是或否的答案。\n" +
                "    评论文本: ```{" + review + "}```";
        String message = this.getCompletion(prompt);
        log.info("iterative4:\n{}", message);
    

上面这个例子中,客户并没有生气。注意,如果使用常规的监督学习,如果想要建立所有这些分类器,不可能在几分钟内就做到这一点。我们鼓励大家尝试更改一些这样的 Prompt ,也许询问客户是否表达了喜悦,
或者询问是否有任何遗漏的部分,并看看是否可以让 Prompt 对这个灯具评论做出不同的推论。

商品信息提取

接下来,让我们从客户评论中提取更丰富的信息。信息提取是自然语言处理(NLP)的一部分,与从文本中提取你想要知道的某些事物相关。因此,在这个 Prompt 中,我要求它识别以下内容:购买物品和制造物品的公司名称。
同样,如果你试图总结在线购物电子商务网站的许多评论,对于这些评论来说,弄清楚是什么物品、谁制造了该物品,弄清楚积极和消极的情感,有助于追踪特定物品或制造商收获的用户情感趋势。
在下面这个示例中,我们要求它将响应格式化为一个 JSON 对象,其中物品和品牌作为键。

        String prompt = "从评论文本中识别以下项目:\n" +
        " - 评论者购买的物品\n" +
        " - 制造该物品的公司\n" +
        "    评论文本用三个反引号分隔。将你的响应格式化为以 “物品” 和 “品牌” 为键的 JSON 对象。\n" +
        "    如果信息不存在,请使用 “未知” 作为值。\n" +
        "    让你的回应尽可能简短。\n" +
        "    评论文本: ```{" + review + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative5:\n{}", message);
{
  "物品": "卧室灯",
  "品牌": "Lumina"
}

如上所示,它会说这个物品是一个卧室灯,品牌是 Luminar.

综合完成任务

提取上述所有信息使用了 3 或 4 个 Prompt ,但实际上可以编写单个 Prompt 来同时提取所有这些信息。

        String prompt = "从评论文本中识别以下项目:\n" +
                "- 情绪(正面或负面)\n" +
                "- 审稿人是否表达了愤怒?(是或否)\n" +
                "- 评论者购买的物品\n" +
                "- 制造该物品的公司\n" +
                
                "评论用三个反引号分隔。将您的响应格式化为 JSON 对象,以 “Sentiment”、“Anger”、“Item” 和 “Brand” 作为键。\n" +
                "如果信息不存在,请使用 “未知” 作为值。\n" +
                "让你的回应尽可能简短。\n" +
                "将 Anger 值格式化为布尔值。\n" +
                "评论文本: ```{" + review + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative6:\n{}", message);
{
  "Sentiment": "正面",
  "Anger": false,
  "Item": "卧室灯",
  "Brand": "Lumina"
}

这个例子中,我们告诉它将愤怒值格式化为布尔值,然后输出一个 JSON。您可以自己尝试不同的变化,或者甚至尝试完全不同的评论,看看是否仍然可以准确地提取这些内容。

主题推断

大型语言模型的另一个很酷的应用是推断主题。给定一段长文本,这段文本是关于什么的?有什么话题?以以下一段虚构的报纸报道为例。



推断讨论主题

上面是一篇虚构的关于政府工作人员对他们工作机构感受的报纸文章。我们可以让它确定五个正在讨论的主题,用一两个字描述每个主题,并将输出格式化为逗号分隔的列表。


        String prompt = "确定以下给定文本中讨论的五个主题。\n" +
                "每个主题用1-2个单词概括。\n" +
                "输出时用逗号分割每个主题。\n" +
                "给定文本: ```{" + story + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative7:\n{}", message);

主题1: NASA满意度高
主题2: 社会保障管理局满意度低
主题3: NASA员工对工作感到自豪
主题4: 政府承诺解决员工问题
主题5: 政府努力提高工作满意度

为特定主题制作新闻提醒

假设我们有一个新闻网站或类似的东西,这是我们感兴趣的主题:NASA、地方政府、工程、员工满意度、联邦政府等。假设我们想弄清楚,针对一篇新闻文章,其中涵盖了哪些主题。
可以使用这样的prompt:确定以下主题列表中的每个项目是否是以下文本中的主题。以 0 或 1 的形式给出答案列表。


        String prompt = "判断主题列表中的每一项是否是给定文本中的一个话题,\n" +
                "    以列表的形式给出答案,每个主题用 0 或 1。\n" +
                "    主题列表:美国航空航天局、当地政府、工程、员工满意度、联邦政府\n" +
                "    给定文本: ```{" + story + "}```";

        String message = this.getCompletion(prompt);

        log.info("iterative9:\n{}", message);
[1, 0, 0, 1, 0]

有结果可见,这个故事是与关于 NASA 、员工满意度、联邦政府有关,而与当地政府的、工程学无关。这在机器学习中有时被称为 Zero-Shot (零样本)学习算法,因为我们没有给它任何标记的训练数据。仅凭 Prompt ,它就能确定哪些主题在新闻文章中有所涵盖。

这就是关于推断的全部内容了,仅用几分钟时间,我们就可以构建多个用于对文本进行推理的系统,而以前则需要熟练的机器学习开发人员数天甚至数周的时间。这非常令人兴奋,无论是对于熟练的机器学习开发人员,还是对于新手来说,都可以使用 Prompt 来非常快速地构建和开始相当复杂的自然语言处理任务。

10-03 10:12