DLAI-LLMOps-自动测试笔记-全-

DLAI LLMOps 自动测试笔记(全)

001:课程介绍 🚀

在本节课中,我们将要学习LLMOps(大语言模型运维)中自动化测试的基础概念、重要性以及本课程的核心内容。我们将了解两种关键的评估方法,并预览如何将它们整合到自动化工作流中。

软件测试能帮助你识别应用程序中的缺陷和安全漏洞。自动化测试则能进一步解放你的时间和精力,让你可以专注于设计和构建应用程序的创新性工作。

在本课程中,你将学习专注于LLM应用实际开发和部署的现代软件工程测试实践。

两种LLM评估方法

以下是本课程中将实现的两种核心LLM评估方法。

  • 基于规则的评估:这类评估使用字符串或模式匹配,例如正则表达式匹配。它们运行速度快且成本效益高。当需要评估具有明确正确答案的输出时(例如分类任务,并且你拥有真实标签),我会使用这种方法。基于规则的评估运行迅速且成本低廉,因此你可以在每次提交代码更改时运行这些测试,以快速获取关于应用程序健康状况的反馈。
  • 模型评分评估:这类评估适用于存在多种可能的好或坏输出的应用场景。例如,如果你要求一个LLM为你撰写文本内容,可能会存在多个高质量的回答。在这种情况下,你可以提示一个评估用的LLM,让它来评估你的应用程序LLM的输出质量。换句话说,就是用一个LLM来评估另一个LLM的输出。模型评分评估需要更多时间和成本,但它们允许你评估更复杂的输出。

课程讲师介绍

现在,我很高兴向大家介绍本课程的讲师,Circle CI的首席技术官Rob Zuber。

Rob拥有数十年的工程团队领导经验,并且通过使流程可重复、可扩展和可靠,帮助客户扩展其软件交付实践。他将向你展示如何将这些理念应用于你的应用程序,并重点强调测试环节。

自动化测试工作流

上一节我们介绍了评估方法,本节中我们来看看如何将它们融入开发流程。

在你的软件开发过程中,你和你的团队成员可能每天多次提交代码更新或错误修复。在本课程中,你将学习设置触发器,以便在你或你的团队成员向代码仓库提交更改时,自动运行你的评估。

你的团队可能还会以更长的周期(例如每两周一次)发布应用程序的更新版本。在部署给用户之前,你还可以自动化更全面、更综合的预发布评估。

  • 对于每次提交的评估,你可以包含基于规则的评估,因为它们运行速度快且成本低。
  • 对于那些预发布评估,使用模型评分评估在部署前进行更彻底的测试可能会非常有帮助。

到课程结束时,你将把每次提交评估和预发布评估结合到一个自动化测试套件中。在本课程中,你将设计测试来检测LLM响应中的“幻觉”(即不准确或虚构的内容)。

致谢与课程展望

许多人共同努力使这门课程成为可能。我要感谢Circle CI方面的Michael Webster、Jacob Schmidt和Emmawe,以及DeepLearning.AI的Eddie Shu和Eshb Gagari,他们也为本课程做出了贡献。

第一课将快速概述持续集成术语和技术,我们将以此为基础构建我们的自动化LLM测试流水线。

当你完成这门课程时,这将真正证明你致力于构建优秀应用程序的决心。或者,如果你不确定会多大程度使用这些想法,你仍然可以尝试一下。

所以,让我们继续观看下一个视频,开始学习吧。


本节课中我们一起学习了:LLMOps自动化测试的重要性、基于规则和模型评分两种核心评估方法的区别与应用场景,以及如何将它们集成到自动化开发工作流(包括每次提交和预发布环节)中来构建可靠的LLM应用。

002:持续集成简介 🚀

在本节课中,我们将快速概览用于自动化LLM评估的技术——持续集成。我们将讨论什么是持续集成、它为何重要,这将为我们后续课程中构建的自动化工作流打下坚实基础。

让我们开始吧。

什么是持续集成?

简而言之,持续集成是一种开发实践,其核心在于对软件进行频繁的小规模更改,并与团队其他成员的更改一起进行彻底测试

换句话说,你持续地验证你的新功能和更新在与团队其他成员的代码集成后,是否按预期工作。这种方法使你能够在问题演变成你和团队更难解决的大麻烦之前,及早发现并修复它们。

持续集成在LLM应用中的运作

让我们看看这在LLM驱动的应用程序中是如何运作的。

想象你正在开发一个尖端的虚拟助手应用。在持续集成的流程中,每当你或团队成员进行代码更改(无论是优化LLM提示词还是更新数据集成),你都会将该更改合并到一个中央代码仓库。

现在,关键的一步来了。一旦代码被合并,CI平台就会启动。它会自动构建你的应用程序,模拟其在真实环境中的行为。接着,自动测试会运行,以确保你的LLM产生准确可靠的结果。这些测试涵盖从基本功能到更复杂问题(如幻觉或偏见输出)的方方面面。

持续集成的重要性

为什么这很重要?可以把它看作一个超级反馈循环。CI平台对你的更改提供近乎即时的反馈。如果检测到问题(例如模型产生了意外的输出),你会立刻收到警报。这种快速的反馈循环使你能够在开发周期的早期发现并解决问题。这样一来,有缺陷的代码就不会影响到团队成员正在构建的其他功能,更糟糕的是,也不会被部署给你的用户。

对开发者的益处

现在,让我们谈谈持续集成对作为开发者的你的好处。

持续集成显著减少了你在调试和故障排除上花费的时间和精力。这并不是说你的测试永远不会失败。但当测试确实失败时,你将获得可操作的信息,可以用来快速回到正轨,并继续创新。

CI使你能够快速迭代尝试新功能充满信心地进行改进

对团队的益处

但优势不仅限于个人开发者。对于团队而言,CI通过鼓励更小、更频繁的贡献来促进协作。代码冲突被最小化,使得管理和解决问题变得更加容易。共享的代码仓库成为一个可靠的单一事实来源,自动化测试确保每个人都在一个稳定的基础上进行构建。这营造了一种信任、协作和快速交付高质量软件的文化。

此外,持续集成为你在部署、监控和重新训练语言模型方面实现更多自动化奠定了基础,使你的团队能够迈向更敏捷、响应更迅速的开发实践。对于创新快速且持续的AI开发者来说,CI提供了取得成功所需的结构。

如果你对AI与持续集成的概念整合有更多兴趣,我们在播客中有一个迷你系列《The Confident Commit》,其中通过许多出色的嘉宾详细探讨了这一点。

本课程中的实践

在本课程的其余部分,你将使用CircleCI作为你的持续集成平台。在你探索测试和评估LLM应用的不同技术时,你将能够触发你的自动化评估,并在CircleCI用户界面中查看结果。

所有的设置工作都已为你完成,以便你可以专注于学习和应用课程中使用的策略。

在团队环境中,通常会有一位CI/CD专家负责设置和维护你的流水线。但如果你有兴趣了解更多幕后发生的事情,可以随时探索项目仓库中提供的配置文件。我们还在本课程末尾包含了一个可选实验,让你有机会逐步体验在CircleCI中设置工作流的过程。

总结

虽然这只是持续集成功能的冰山一角,但在整个课程中使用它将为你提供所需的知识和工具,开始将自动化测试作为你开发实践的核心部分。这些技能将使你的整个职业生涯受益,并为你遵循现代软件工程实践奠定基础,无论你的兴趣将你带向何方。

好了,让我们马上开始你的第一次评估,并设置它们在CircleCI中运行。

下节课见。

003:自动化评估概述 🧪

在本节课中,我们将学习如何为基于LLM的应用程序设置自动化评估。我们将从基于规则的评估开始,这种评估运行速度快、成本低,非常适合在开发的早期迭代阶段频繁运行。最终,我们将看到这些评估如何在持续集成管道中自动运行。

传统软件与基于LLM应用的差异

上一节我们介绍了自动化评估的目标,本节中我们来看看为何基于LLM的应用需要不同的测试方法。

与传统软件相比,基于LLM的应用有几个根本区别:

  • 行为模式:传统软件的行为通常是预定义的。我们知道输入是什么,也知道特定输入对应的输出是什么,测试相对直接。
  • 输出性质:在基于LLM的应用中,我们知道输入,但会得到一组可能的输出,其本质更具概率性。
  • 主观性与多样性:许多LLM应用基于自然语言,具有高度主观性。例如,对于一个总结任务,可能存在多个足够好、可被视为正确的结果,同时也存在许多错误的结果。
  • 评估挑战:LLM可能产生有害、有毒或冒犯性的回应,这为应用测试带来了新的挑战。

为了应对这些新的测试挑战,AI研究人员提出了评估的概念,用于评估LLM在特定任务上的表现。虽然存在MMLU、Hellaswag、HumanEval等针对不同任务的通用基准数据集,但当我们构建自己的应用时,更需要针对特定用例进行测试。

自动化评估的关注点与时机

既然我们已经理解了为何需要专门的评估,接下来我们探讨一下评估的具体内容和执行时机。

进行自动化评估时,我们主要关注以下四个领域:

  1. 上下文遵循性:LLM的回应是否与提供的上下文或指南一致。
  2. 上下文相关性:检索到的上下文是否与原始查询或提示相关。
  3. 正确性或准确性:LLM的输出是否与提供的标准答案和预期结果一致。
  4. 偏见与毒性:LLM应用中可能存在的负面倾向,包括对特定群体的偏见或使用有害、冒犯性的措辞。

关于评估时机:

  • 在传统软件模型中,我们通常在每次变更(如修复bug、更新功能、数据或模型变更)后进行测试。
  • 对于LLM应用,如果每次变更后都进行全面测试速度太慢,也可以将更全面的测试安排在特定节点,例如部署前(在推送到生产环境时)或部署后(软件在生产环境中运行时)。

实践项目:AI驱动的测验生成器

理论部分已经介绍完毕,现在让我们通过一个实践项目来应用这个框架。我们将构建一个AI驱动的测验生成器。

该应用的数据集包含艺术、科学和地理类别的事实。用户要求我们的机器人就给定主题编写测验,并得到一组问题。我们将编写评估来检查机器人是否正确使用了我们数据中的事实。

环境与数据准备

在开始构建之前,我们需要进行一些设置。本应用需要使用CircleCI、GitHub和OpenAI等第三方服务。相关密钥已预先配置好。我们还将使用一个为每位学员生成的独立GitHub分支,以避免冲突。

首先,我们创建测验的数据集。为了清晰展示,我们将数据存储在字符串中。在实际应用中,你更可能将数据放入文件或数据库。

# 示例:测验数据(部分)
quiz_data = {
    "art": ["达芬奇创作了《蒙娜丽莎》。", "梵高是《星夜》的作者。"],
    "science": ["水的化学式是H2O。", "地球围绕太阳公转。"],
    "geography": ["巴黎是法国的首都。", "亚马逊河是世界上流量最大的河流。"]
}

接下来,我们构建一个提示模板,用于请求生成特定测验,并确保生成的测验基于我们提供的数据。

# 提示模板示例
prompt_template = """
你是一个测验生成助手。请根据以下步骤生成一个测验:
1. 类别:用户询问的类别是:{category}(可选:地理、科学、艺术)。
2. 主题:从以下题库中选择最多两个相关主题:{quiz_bank}。
3. 生成测验:基于上述类别和主题,生成一个包含问题和答案的测验。
请使用以下格式:
问题1: [问题]
答案1: [答案]
...
"""

我们将使用LangChain工具包来构建这个提示模板,并连接到LLM(本例中使用OpenAI的GPT-3.5-turbo)。最后,我们将所有组件组合成一个可复用的链。

创建基于规则的评估

现在应用的核心功能已经就绪,本节中我们开始为其创建评估。首先,我们创建基于规则的评估,检查输出中是否包含预期的词语。

例如,当我们请求生成一个关于“科学”的测验时,我们预期在回应中看到“H2O”、“地球”等词语。我们编写一个函数来执行此检查。

def eval_expected_words(response, expected_words):
    """
    评估响应中是否包含预期词语。
    response: LLM的回应文本
    expected_words: 预期出现的词语列表
    """
    for word in expected_words:
        if word not in response:
            raise AssertionError(f"未在响应中找到预期词语:'{word}'")
    print("评估通过:所有预期词语均已找到。")
    return True

然后,我们执行一次评估:

  1. 请求助手生成一个关于“科学”的测验。
  2. 定义预期词语列表,例如 ["H2O", "地球"]
  3. 运行 eval_expected_words 函数检查响应。

如果所有预期词语都找到,评估通过;如果缺少任何一个,函数将抛出断言错误,表明评估失败。

测试失败场景与优化提示

为了确保应用的健壮性,我们还需要测试它如何处理未知请求。例如,当用户请求一个关于“罗马”(不在我们数据集中)的测验时,我们希望助手礼貌地拒绝,而不是编造信息。

最初,我们的提示模板可能没有包含相关限制,因此测试会失败。助手可能会生成一个关于罗马的虚构测验。我们的评估函数会检查响应中是否包含“抱歉”等词语,由于没有找到,评估失败。

为了解决这个问题,我们优化提示模板,添加明确的指令:

  1. 仅使用提供的事实列表中的信息。
  2. 如果用户询问的主题没有相关信息,则回复:“抱歉,我没有关于该主题的信息。”

优化提示后,再次运行关于“罗马”的测验请求,助手现在应该会礼貌拒绝,评估得以通过。

集成到持续集成(CI)管道

手动运行评估对于单个更改尚可,但在团队协作和频繁迭代中无法扩展。因此,我们需要将评估自动化,集成到CI/CD管道中。

我们将创建两个主要文件:

  1. app.py:包含应用的主要逻辑和优化后的提示。
  2. test_assistant.py:包含我们定义的评估函数(如 eval_expected_words)和具体的测试用例。

测试用例示例:

# test_assistant.py 中的测试用例
def test_science_quiz():
    response = assistant_chain.run(category="science", ...)
    expected = ["引力", "细胞"]
    assert eval_expected_words(response, expected) == True

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_7.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_8.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_9.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_10.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_11.png)

![](https://github.com/OpenDocCN/dsai-notes-pt1-zh/raw/master/docs/dlai-llmops-autotst/img/7316d081545fb41c2d114cbc32cf45f3_12.png)

def test_refusal_for_unknown_topic():
    response = assistant_chain.run(category="history", ...) # 'history' 不在数据中
    expected = ["抱歉"]
    assert eval_expected_words(response, expected) == True

我们使用Git将这两个文件推送到GitHub仓库。我们在项目中已经配置了CircleCI的配置文件(如 .circleci/config.yml),该文件定义了CI管道的步骤:设置环境、安装依赖、运行测试(使用 pytest test_assistant.py)。

当我们推送代码到GitHub时,会自动触发CircleCI管道。管道会拉取代码,在一个干净的环境中运行我们的所有评估测试。如果所有测试通过,管道显示成功;如果有任何测试失败,管道会停止并报告错误,通知开发者修复问题。

总结 🎯

本节课中我们一起学习了为基于LLM的应用实施自动化评估的基础。

  1. 我们首先理解了为何基于LLM的应用需要不同于传统软件的评估方法。
  2. 接着,我们通过构建一个AI测验生成器,实践了创建基于规则的评估,例如检查输出中是否包含预期关键词。
  3. 我们测试了应用在遇到未知请求时的行为,并通过优化提示工程使其能够正确处理。
  4. 最后,我们将这些评估集成到了持续集成管道中,实现了每次代码变更时的自动测试,从而确保软件质量,并支持团队高效协作。

在下一节课中,我们将学习如何使用LLM本身来进行模型评分评估,并将这些更高级的评估也引入我们的自动化管道。

004:模型评分评估的自动化

概述

在本节课中,我们将要学习一种更强大、更全面的评估方法——模型评分评估。我们将了解如何使用另一个大语言模型来评估我们的LLM应用,并学习如何将这种评估方法自动化,集成到持续集成/持续部署的测试流程中。

到目前为止,我们一直使用基于规则的快速评估方法,这种方法适合在开发阶段,每次代码提交时频繁运行。然而,在将应用部署给用户之前,更稳健和全面的评估方法能帮助我们更好地确保整体质量。模型评分评估就是这样一种方法,即使用一个LLM来评估另一个LLM应用。让我们来看看这种评估方式,以及如何将其自动化,作为测试流程的一部分。

从规则评估到模型评估

上一节我们介绍了基于规则的快速评估,用于确保模型遵循提示中的指导方针并忠实于提供的数据。本节中,我们来看看如何通过模型评分评估来确保模型生成高质量、符合语境的回答。

评估LLM的输出可能很棘手,因为对于一个查询的“好”回答是主观的。我们可以尝试像初始评估那样编写自定义规则,以确保输出中包含预期的数据。但随着应用的增长,这会变得越来越复杂和脆弱。检查LLM输出的一种方法是使用另一个LLM作为评分器,这被称为模型评分评估。

我们将展示一个简单的例子,以确保我们的模型确实以测验的形式输出内容。目前我们只关心格式,不关心内容质量。我们将在下一课中更仔细地研究输出的质量。因此,在本课中,我们将专注于判断响应是否符合期望的格式,下一课再研究幻觉和忠实度等问题。

构建模型评分评估链

让我们直接开始,编写一个通过测试用例和一个失败测试用例,看看这是如何工作的。首先,我们需要像上一课那样建立密钥。

为了添加模型评分评估,我们将继续使用上一课生成的应用。让我们再看一下,以回忆我们正在处理的内容。同样,如果你想在本地文件系统上查看这些文件的内容,可以使用cat命令,它们都包含在你现有的实验环境中。

现在,让我们看看如何构建一个模型评分评估。这将类似于我们构建测验助手的工作,但这次我们构建的是一个提示,告诉LLM去评估测验助手的输出。

以下是构建评估链的核心步骤:

  1. 定义评估提示:创建一个提示,明确指示LLM扮演评估者的角色,并给出具体的评估标准和输出格式。
  2. 选择评估模型:选择一个LLM作为评分器。
  3. 设置输出解析器:指定如何解析评分模型的输出。
# 示例:构建评估链的核心代码结构
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser

# 1. 定义评估提示模板
eval_prompt = ChatPromptTemplate.from_messages([...])

# 2. 选择评估模型
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# 3. 设置输出解析器
output_parser = StrOutputParser()

# 构建评估链
eval_chain = eval_prompt | llm | output_parser

你可以看到,我们给LLM提供了具体的指令,告诉它在评估测验助手工作时所扮演的角色。在评估实际的测验助手之前,我们将通过模拟一个LLM响应来进行测试,使用我们的评估链来判断该响应是否能通过我们设定的测试。

完整的评估提示会告诉LLM:根据上下文评估生成的测验,并判断它是否看起来像一个测验或测试。它不用于评估信息是否正确。然后,它被明确告知,如果响应是一个测验,则输出“Y”;如果响应看起来不像一个测验,则输出“N”。

测试评估链

现在,我们将使用LangChain构建一个熟悉的链,但这次是专门用于进行评估的链。首先,我们有之前构建的聊天提示模板。接下来,我们选择LLM,同样使用GPT-3.5 Turbo。最后,我们选择一个输出解析器,即StrOutputParser,以获取LLM的响应并生成一个基本字符串。

我们将这些部分链接在一起:获取评估提示,将其传递给LLM,然后将该响应传递给输出解析器,以得到我们想要的字符串。

现在,我们使用一个已知的良好LLM响应构建了一个基本的评估链。我们可以通过针对该已知文本调用评估链来证明我们得到了积极的结果。

# 调用评估链进行测试
known_good_response = "这是一个模拟的良好测验输出..."
result = eval_chain.invoke({"context": "...", "response": known_good_response})
print(result)  # 预期输出: 'Y'

如你所见,在这种情况下,我们得到了一个“Y”,这意味着我们输入的已知良好响应被LLM认为符合预期的测验格式。

然而,我们也需要确保当响应看起来不像测验时,评估会失败。为此,我们首先将所有评估链创建代码存储为一个工具函数,以便重复使用。接下来,我们存储一个已知的不良结果,以便将其传递给一个新的评估链。

# 测试失败案例
known_bad_response = "这只是一段普通的文本,不是测验。"
result = eval_chain.invoke({"context": "...", "response": known_bad_response})
print(result)  # 预期输出: 'N'

现在我们调用这个新的评估链,看到我们得到了正确的响应,即一个“N”,表明该文本看起来不像一个测验。

集成到CI/CD流程

现在,我们将把新创建的模型评分评估能力,整合到我们在持续集成管道中运行的测试中。实验环境中的文件系统上有两个用于测试的文件。第一个是test_assistant.py,这是我们之前运行的。第二个是test_release_evals.py,它汇总了我们刚刚完成的所有工作,展示了如何创建模型评分评估并针对OpenAI执行它。

现在我们已经有了发布评估(即模型评分评估),它们存储在test_release_evals.py文件中,连同我们之前拥有的文件:test_assistant.py和存储原始代码的app.py。我们将把所有内容推送到GitHub,然后推送到CircleCI,以便评估我们的应用程序,包括模型评分评估。

在这种特定情况下,我们对积极案例使用完整评估,但故意将已知的不良结果传递给消极案例,以展示在持续集成管道中出现失败时的样子。我们还只会在CircleCI上触发发布评估任务,这样我们就不会为此进行过多的测试。

我们通过函数trigger_release_evals来实现这一点,该函数使用传递给工作流的参数。你可以看到,唯一运行的任务是run_pre_release_evals,因为这是我们通过该参数特别选择的。

运行结果与总结

如你所见,我们在此次运行中执行了模型评分评估,并且确实遇到了失败,因为我们故意传递了已知的不良内容。

很好!你可以看到,当你将应用程序更改合并到主分支时,你的预发布评估就会运行。在实际的开发场景中,这将在你在开发分支上进行更改并运行每次提交的评估之后发生。我们正在建立一个系统,随着我们越来越接近向用户发布应用,逐步增加对应用程序的信心。

在本节课中,我们一起学习了:

  1. 模型评分评估的概念:使用一个LLM作为评分器来评估另一个LLM应用的输出。
  2. 构建评估链:如何通过定义提示、选择模型和解析输出来创建一个自动化的评估流程。
  3. 测试评估有效性:使用已知的良好和不良响应来验证评估链是否能正确判断格式。
  4. 集成到CI/CD:如何将模型评分评估作为预发布检查的一部分,集成到自动化测试管道中。

在下一课中,我们将探讨如何使预发布检查更加稳健,包括在多个数据点上运行评估、编写用于检测应用程序中幻觉的评估,以及在CI中存储评估结果以供人工审查。

005:全面的测试框架 🧪

在本节课中,我们将学习如何扩展和增强评估流程,为你的LLM应用构建一个全面的测试框架。你将学习如何编写评估来检测应用中的幻觉,如何在多个数据点上运行评估,以及如何在CI/CD中存储评估结果以供审查。


理解幻觉问题

上一节我们介绍了基础的模型评分评估。本节中,我们来看看一个LLM的常见问题:幻觉。

幻觉是指模型提供了虚假或错误的输出。这是当前LLM作为“下一个词预测器”的副作用。模型总是会提供统计上可能的输出,但无法内置地保证输出内容的正确性。

在我们的应用中,幻觉可能表现为智能体创建的测验包含了知识库中没有的事实。例如:

  • 不准确的回答:用户问“巴西的首都是哪里?”,得到“圣保罗”的答案,而正确答案是“巴西利亚”。
  • 不相关的回答:用户问“巴西的首都是哪里?”,得到“加拿大的首都是渥太华”的答案。这个陈述本身是事实正确的,但与用户问题无关。
  • 矛盾或无意义的回答:用户问“美国按人口从大到小排列的主要城市有哪些?”,得到“纽约、洛杉矶、芝加哥和纽约”的答案。

检测幻觉的一种方法是创建一个模型评分评估,它接受模型应该产生的基准事实数据,并将其与实际输出进行比较。

编写检测幻觉的评估并不能保证模型永不产生幻觉,但它是一个有用的工具,可以检测提示词是否缺乏“护栏”来防止模型在提供的上下文之外进行猜测。在我们的应用中,一个护栏的例子是修改提示词,要求模型告诉用户它无法为知识库中没有的主题创建测验。


实践:检测幻觉

让我们将上述理论付诸实践。首先,我们需要重新加载API密钥以使用第三方服务。

# 示例:加载API密钥
import os
os.environ["OPENAI_API_KEY"] = "your-api-key-here"

正如之前课程提到的,管理知识库更可持续的方式是将其放入文本文件或数据库中。这里我们使用一个文本文件,并在需要时将其加载到内存中。

为了演示幻觉检测,我们首先快速重建之前使用的测验生成器。

# 示例:重建测验生成器链
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI

quiz_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个测验生成助手。根据以下知识库生成测验。"),
    ("human", "知识库:{quizbank}\n\n请生成一个关于{subject}的测验。")
])
assistant_chain = quiz_prompt | ChatOpenAI(model="gpt-3.5-turbo")

现在,我们继续创建一个明确寻找幻觉的模型评分评估。

你可以看到,为了模型评分评估的目的,我们投入了大量精力来强调“测验必须只包含知识库中的事实”这一点的重要性。例如,提示词中写明:“主要关注点是确保只使用已有的事实,包含知识库之外事实的测验是糟糕的,对学生有害。” 下方再次强调:“记住,测验需要只包含助手已知的事实。允许编造事实是危险的。”

然后,类似于我们之前的评估,我们将输出“Y”(如果测验正确,即只包含知识库中的事实)和“N”(如果包含知识库之外的事实)。

现在,我们定义一个函数来测试我们的模型评分评估。

# 示例:测试幻觉检测评估的函数
def test_hallucination_eval(quizbank, subject):
    # 生成测验
    quiz = assistant_chain.invoke({"quizbank": quizbank, "subject": subject})
    # 调用幻觉检测评估链
    result = hallucination_eval_chain.invoke({"quiz": quiz, "quizbank": quizbank})
    return result

为了检查当出现幻觉时会发生什么,我们使用之前存储的知识库,将其传递给新的模型评分评估,并在模型评分评估测试函数中检查幻觉。

我们请求一个关于“书籍”的测验,这不在我们的知识库中。然而,LLM试图提供帮助,返回了一个关于书籍的测验。我们的模型评分评估知道它的工作是检测包含知识库之外信息的测验。因此,在这种情况下,我们得到了一个“N”,表明这是一个不可接受的测验。

是什么导致了这些幻觉?如果你回顾我们的提示词,我们告诉助手让测验“有趣”。这可能是测验的一个好属性(教育应该具有吸引力),但它导致我们的模型产生了幻觉。幸运的是,我们的评估检测到了这些幻觉,因此我们可以返回去修正提示词。在未来的提示词中,我们将移除要求“有趣事实”的部分。


使用数据集进行扩展测试

随着你的应用随时间增长和变化,你会希望为其添加新功能。对于我们的测验应用,这可能意味着支持新主题或为现有主题添加事实。

为此,我们可以创建已知模型应如何行为的问题数据集,并对数据集中的每个示例运行测试。让我们通过一个示例,使用我们的应用代码在数据集上进行测试。

我们将稍微更新应用代码以防止幻觉。到目前为止,我们已经将评估用作自动化测试套件。这是捕捉明显错误和回归并快速迭代应用的好方法。


人工评估与结果存储

但在处理AI模型时,习惯于手动检查和整理数据非常重要。我们合作过的AI/ML工程师表示,愿意深入研究数据是在该领域有效工作的关键。这有时被称为错误分析或性能审计。

在本示例中,我们将展示一种将评估结果作为工件存储在CI/CD中的方法,以便你可以审查并与团队分享,确保你的应用和测试套件完全按预期运行。

首先,我们将重建评估器,使其不仅提供响应或决定,还提供做出该决定的解释。

如这个版本的提示词所示,我们要求以特定格式分隔决定和解释。提示词中提供了一个示例,以确保我们获得后续人工评估所需的有用信息。

现在,我们已经用新提示词重建了聊天提示模板,并且我们将构建一个数据集,以便可以针对新提示词运行多个测试。

如你所见,这个测试数据集包含了来自用户的多个不同提示或输入,以及一些预期的响应。接下来,我们创建一个函数,循环遍历数据,调用测验生成器,并评估数据集中每个条目的响应。

然后,我们确保能够访问所有需要的函数,以便基于数据生成我们想要的报告。接着,我们编写你熟悉的包装器来创建将在所有评估中使用的评估链。

最后,我们利用pandas的一些工具,在所有评估结果中创建一个数据框,这将使我们能够轻松生成报告。

现在,你可以看到一个格式化的表格,其中包含我们生成的不同测验的多个结果以及评估者的响应。第一个是关于科学的测验,决定是“Y”(这是一个合适的测验,测验只引用了知识库中的信息)。这里包含了更多细节,包括测验中具体有什么以及它在知识库中的位置。第二个是关于地理的,类似地决定是“Y”。第三个是关于意大利的测验,决定也是“Y”。这很有趣,因为测验确实引用了知识库中的信息,事实也来自知识库,但关于意大利的测验模型并没有明确映射到类别。这就是为什么你需要人工评估,以便你可以决定这是否是你想要生成的测验类型,或者你是否想要不同的结果(例如,说“我不知道如何生成关于意大利的测验”,而意大利正是开始时概述的主题)。

从这里,你也许可以根据收集到的信息更改提示词或决定采取不同的做法。再次强调,让人参与进来,从高层次评估系统的所有部分是否按预期工作,对我们来说是一个很好的结果。


集成到CI/CD流程

现在,我们将把该结构放回CI/CD中,使其以自动化方式运行,但创建此报告的工件,以便你可以定期审查它。

为了在持续集成中运行它,我们有一个额外的文件 save_eval_artifacts.py,它生成并存储你刚才看到的输出报告,但作为工作流程的一部分。

现在,我们将再次针对相同数据运行评估,但在持续集成管道中,展示随着我们持续工作和增长,定期使用它会是什么样子。我们将使用 save_eval_artifacts.py 文件以及原始应用和存储知识库完整内容的 quizbank.txt 文件来触发评估报告。

现在,你可以看到我们的评估在CI/CD中通过了,并且我们能够存储一个格式化的输出版本(就像之前在notebook中看到的那样),但现在它在一个HTML文件中,易于检索,以便你稍后查看。结果、描述、决定和解释与之前类似,但以团队中任何人都可以查看的方式存储,而不是仅存在于本地的notebook中。

在生产应用中,你可能会与同事分享这些结果以进行审查,帮助调试意外结果。这个反馈循环不仅使你能够解决眼前的问题,还为你提供了可用于对模型和评估流程实施战略性更新的工具。凭借这种增强的可见性,你和你的开发团队可以做出数据驱动的决策,简化调试过程,并主动解决潜在问题。

全面理解用户交互、模型响应和评估结果,是构建健壮可靠、满足并超越用户期望的LLM应用的重要组成部分。


总结 🎯

本节课中,我们一起学习了:

  1. 幻觉:LLM产生虚假或不相关输出的问题。
  2. 幻觉检测:如何使用模型评分评估来检测应用中的幻觉,通过比较输出与基准事实。
  3. 扩展测试:如何创建数据集并在多个数据点上运行评估,以全面测试应用功能。
  4. 人工评估的重要性:模型评分评估后,进行人工审查对于确保输出质量完全符合用户期望至关重要。
  5. CI/CD集成:如何将评估流程集成到持续集成/持续部署管道中,自动运行测试、生成报告并存储结果工件,便于团队协作和持续改进。

如果你想了解如何在CircleCI或你的持续集成管道中配置所有这些内容,课程包含了一个额外的notebook,展示了其核心部分以及如何为你的持续项目进行设置。

006:总结

在本节课中,我们将回顾并总结整个课程的核心内容。我们一起学习了如何将评估(Evals)与持续集成(CI)流程相结合,以构建强大、可靠的LLM应用开发流程。

课程回顾

上一节我们探讨了自动化评估流程的构建,本节中,我们来进行全面的总结。

恭喜你完成了本课程的学习。你掌握了一些非常棒的知识。

以下是你在本课程中学到的核心内容:

  • 你学习了评估(Evals)
  • 你学习了如何有效地使用评估
  • 你学习了如何在一个全面的流程中实现评估的自动化,从而使你能够与大型团队协作,快速且自信地构建出色的技术。

领域展望与鼓励

这是一个新兴的领域。将评估与持续集成流程相结合,汇集了许多核心知识,并且正在快速发展。

我很高兴你能站在这个领域的前沿,并掌握了本课程教授的所有内容。

我也非常期待看到你接下来会构建出什么。


本节课总结

在本节课中,我们一起回顾了整个《LLMOps的自动化测试》课程。我们总结了三个核心学习要点:理解评估(Evals)的概念、掌握其有效使用方法,以及学习如何将其集成到自动化CI/CD流程中。这门课程为你提供了在快速变化的LLM应用开发领域中,进行高效、可靠和协作式开发的关键工具与思路。

posted @ 2026-03-26 08:12  绝不原创的飞龙  阅读(2)  评论(0)    收藏  举报